diff --git a/package.json b/package.json index 8ab1f4a..dd7985e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "engines": { "node": ">=16" }, - "version": "5.0.0-beta.1", + "version": "5.0.0-beta.2", "type": "module", "description": "A GLSL ES 1.0 and 3.0 parser and preprocessor that can preserve whitespace and comments", "scripts": { diff --git a/src/parser/utils.ts b/src/parser/utils.ts index 2a9901a..98d4699 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -1,62 +1,112 @@ -import type { AstNode } from '../ast/index.js'; import { + FunctionOverloadIndex, FunctionScopeIndex, - Scope, + ScopeEntry, ScopeIndex, + TypeScopeEntry, TypeScopeIndex, } from './scope.js'; +export const renameBinding = (binding: ScopeEntry, newName: string) => { + binding.references.forEach((node) => { + if (node.type === 'declaration') { + node.identifier.identifier = newName; + } else if (node.type === 'identifier') { + node.identifier = newName; + } else if (node.type === 'parameter_declaration' && node.identifier) { + node.identifier.identifier = newName; + /* Ignore case of: + layout(std140,column_major) uniform; + uniform Material { + uniform vec2 prop; + } + */ + } else if (node.type !== 'interface_declarator') { + console.warn('Unknown binding node', node); + throw new Error(`Binding for type ${node.type} not recognized`); + } + }); + return binding; +}; + export const renameBindings = ( bindings: ScopeIndex, mangle: (name: string) => string ) => Object.entries(bindings).reduce((acc, [name, binding]) => { const mangled = mangle(name); - binding.references.forEach((node) => { - if (node.type === 'declaration') { - node.identifier.identifier = mangled; - } else if (node.type === 'identifier') { - node.identifier = mangled; - } else if (node.type === 'parameter_declaration' && node.identifier) { - node.identifier.identifier = mangled; - /* Ignore case of: - layout(std140,column_major) uniform; - uniform Material - { - uniform vec2 prop; - } - */ - } else if (node.type !== 'interface_declarator') { - console.warn('Unknown binding node', node); - throw new Error(`Binding for type ${node.type} not recognized`); - } - }); return { ...acc, - [mangled]: binding, + [mangled]: renameBinding(binding, mangled), }; }, {}); +export const renameType = (type: TypeScopeEntry, newName: string) => { + type.references.forEach((node) => { + if (node.type === 'type_name') { + node.identifier = newName; + } else { + console.warn('Unknown type node', node); + throw new Error(`Type ${node.type} not recognized`); + } + }); + return type; +}; + export const renameTypes = ( types: TypeScopeIndex, mangle: (name: string) => string ) => Object.entries(types).reduce((acc, [name, type]) => { const mangled = mangle(name); - type.references.forEach((node) => { - if (node.type === 'type_name') { - node.identifier = mangled; - } else { - console.warn('Unknown type node', node); - throw new Error(`Type ${node.type} not recognized`); - } - }); return { ...acc, - [mangled]: type, + [mangled]: renameType(type, mangled), }; }, {}); +export const renameFunction = ( + overloadIndex: FunctionOverloadIndex, + newName: string +) => { + Object.entries(overloadIndex).forEach(([signature, overload]) => { + overload.references.forEach((node) => { + if (node.type === 'function') { + node['prototype'].header.name.identifier = newName; + } else if ( + node.type === 'function_call' && + node.identifier.type === 'postfix' + ) { + // @ts-ignore + const specifier = node.identifier.expression.identifier.specifier; + if (specifier) { + specifier.identifier = newName; + } else { + console.warn('Unknown function node to rename', node); + throw new Error( + `Function specifier type ${node.type} not recognized` + ); + } + } else if ( + node.type === 'function_call' && + 'specifier' in node.identifier && + 'identifier' in node.identifier.specifier + ) { + node.identifier.specifier.identifier = newName; + } else if ( + node.type === 'function_call' && + node.identifier.type === 'identifier' + ) { + node.identifier.identifier = newName; + } else { + console.warn('Unknown function node to rename', node); + throw new Error(`Function for type ${node.type} not recognized`); + } + }); + }); + return overloadIndex; +}; + export const renameFunctions = ( functions: FunctionScopeIndex, mangle: (name: string) => string @@ -64,44 +114,9 @@ export const renameFunctions = ( Object.entries(functions).reduce( (acc, [fnName, overloads]) => { const mangled = mangle(fnName); - Object.entries(overloads).forEach(([signature, overload]) => { - overload.references.forEach((node) => { - if (node.type === 'function') { - node['prototype'].header.name.identifier = mangled; - } else if ( - node.type === 'function_call' && - node.identifier.type === 'postfix' - ) { - // @ts-ignore - const specifier = node.identifier.expression.identifier.specifier; - if (specifier) { - specifier.identifier = mangled; - } else { - console.warn('Unknown function node to rename', node); - throw new Error( - `Function specifier type ${node.type} not recognized` - ); - } - } else if ( - node.type === 'function_call' && - 'specifier' in node.identifier && - 'identifier' in node.identifier.specifier - ) { - node.identifier.specifier.identifier = mangled; - } else if ( - node.type === 'function_call' && - node.identifier.type === 'identifier' - ) { - node.identifier.identifier = mangled; - } else { - console.warn('Unknown function node to rename', node); - throw new Error(`Function for type ${node.type} not recognized`); - } - }); - }); return { ...acc, - [mangled]: overloads, + [mangled]: renameFunction(overloads, mangled), }; }, {}