import { BaseNode as ShaderBaseNode , CallExpression as ShaderCallExpression , DataType , Expression as ShaderExpression , ExpressionStatement , ForStatement as ShaderForStatement , FunctionDeclaration as ShaderFunctionDeclaration , Identifier , Identifier as ShaderIdentifier , IfStatement as ShaderIfStatement , Program as ShaderProgram , ReturnStatement as ShaderReturnStatement , Scope , Statement as ShaderStatement , UpdateExpression as ShaderUpdateExpression , VariableDeclaration as ShaderVariableDeclaration , VariableDeclarator as ShaderVariableDeclarator , } from '../ast/glsl-tree' ; export function addIdentifierToScope ( node , id , isFunction = false ) { if ( ! node . scope ) { node . scope = [ ] ; } if ( ! node . scope . find ( ( v ) => v . id . name === id . name ) ) { node . scope . push ( { id , alias : [ ] , isFunction , } ) ; } } param node param idName export function getIdentifierFromScope ( node , idName , isFunction = false ) { return traverseUpwards < ShaderIdentifier > ( node , ( currentNode ) => { const existed = currentNode . scope ?. find ( ( v ) => ( v . id . name === idName || v . alias . includes ( idName ) ) && ( isFunction ? v . isFunction : true ) ) ; if ( existed ) { return existed . id ; } } ) ; } param node param idName export function getScopeByIdentifierName ( node , idName , isFunction = false ) { return traverseUpwards < { id : Identifier ; alias : string [ ] ; isFunction : boolean ; } > ( node , ( currentNode ) => { const existed = currentNode . scope ?. find ( ( v ) => ( v . id . name === idName || v . alias . includes ( idName ) ) && ( isFunction ? v . isFunction : true ) ) ; if ( existed ) { return existed ; } } ) ; } export function traverseUpwards < T > ( node , test ) { let currentNode = node ; while ( currentNode ) { const result = test ( currentNode ) ; if ( result ) { return result ; } currentNode = currentNode . parent ; } }