Skip to content

Commit

Permalink
Additional utility functions for specific renames
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewRayCode committed Jul 8, 2024
1 parent 01b3e49 commit f773cfc
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 68 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
149 changes: 82 additions & 67 deletions src/parser/utils.ts
Original file line number Diff line number Diff line change
@@ -1,107 +1,122 @@
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<ScopeIndex>((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<TypeScopeIndex>((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
) =>
Object.entries(functions).reduce<FunctionScopeIndex>(
(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),
};
},
{}
Expand Down

0 comments on commit f773cfc

Please sign in to comment.