nl_tokens: main function
pl_tokens: function process ( ast , scope ) { ast . scope = scope ; ast . names = [ ] ; ast . scopes = [ ] ; var varWalker = function ( token , scope ) { scope . declarations . push ( { type : 'var' , name : <mask> . id . name , parent : this . top ( 1 ) , loc : token . loc . start } ) ; scope . put ( token . id . name , { type : 'var' , token : token . init , loc : token . loc . start } ) ; } ; return walker . walk ( ast , { VariableDeclarator : varWalker , FunctionDeclaration : fnWalker , FunctionExpression : fnWalker , ArrowFunctionExpression : fnWalker , ExpressionStatement : function ( token ) { if ( token . directive && token . directive . toLowerCase ( ) === 'use strict' ) scope . strict = true ; } , CatchClause : function ( token , scope ) { var newScope = new Scope ( 'catch' , scope ) ; scope . put ( token . param . name , { type : 'catch' , token : null } ) ; token . body . scope = newScope ; this . scopes . push ( scope ) ; } , Identifier : function ( token , scope ) { var parent = this . top ( 1 ) ; // let insane begin! // todo implement more efficient solution in a future version var isLabel = parent . type === 'LabeledStatement' || parent . type === 'ContinueStatement' || parent . type === 'BreakStatement' ; var isFunctionName = parent . type === 'FunctionDeclaration' || parent . type === 'FunctionExpression' || parent . type === 'ClassDeclaration' || parent . type === 'ClassExpression' ; var isProperty = parent . type === 'Property' ; var isMemberExpression = parent . type === 'MemberExpression' ; var isAssignmentExpression = parent . type === 'AssignmentExpression' ; var isVariableDeclarator = parent . type === 'VariableDeclarator' ; if ( isLabel || isFunctionName || isProperty || isMemberExpression || isAssignmentExpression || isVariableDeclarator ) { var isObjectKey = isProperty && parent . key === token && parent . computed ; var isObjectValue = isProperty && parent . value === token ; var isMemberExpressionProperty = isMemberExpression && parent . property === token && parent . computed ; var isMemberExpressionObject = isMemberExpression && parent . object === token ; var isVariableInit = isVariableDeclarator && parent . init === token ; var isLeftOfAssignment = isAssignmentExpression && parent . left === token && parent . operator !== '=' ; var isRightOfAssignment = isAssignmentExpression && parent . right === token ; // is it for..in variable? (mark its name as used) var isVarInForIn = false ; if ( isVariableDeclarator ) { var declarationParent = this . top ( 3 ) ; isVarInForIn = declarationParent && declarationParent . type === 'ForInStatement' ; } if ( isFunctionName || isLabel || ! isObjectKey && ! isObjectValue && ! isMemberExpressionProperty && ! isMemberExpressionObject && ! isLeftOfAssignment && ! isRightOfAssignment && ! isVariableInit && ! isVarInForIn ) return ; } this . names . push ( { scope : scope , token : token } ) ; } } , { names : ast . names , scopes : ast . scopes } ) ; }