shift-scope
Version:
produce a scope tree for Shift format ASTs
83 lines (71 loc) • 2.46 kB
JavaScript
/**
* Copyright 2015 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const Variable = require('./variable');
class ScopeType {
constructor(name) {
this.name = name;
}
}
ScopeType.GLOBAL = new ScopeType('Global');
ScopeType.MODULE = new ScopeType('Module');
ScopeType.SCRIPT = new ScopeType('Script');
ScopeType.ARROW_FUNCTION = new ScopeType('ArrowFunction');
ScopeType.FUNCTION = new ScopeType('Function');
ScopeType.FUNCTION_NAME = new ScopeType('FunctionName'); // named function expressions
ScopeType.CLASS_NAME = new ScopeType('ClassName'); // named class expressions
ScopeType.PARAMETERS = new ScopeType('Parameters');
ScopeType.PARAMETER_EXPRESSION = new ScopeType('ParameterExpression');
ScopeType.WITH = new ScopeType('With');
ScopeType.CATCH = new ScopeType('Catch');
ScopeType.BLOCK = new ScopeType('Block');
class Scope {
constructor({ children, variables, through, type, isDynamic, astNode }) {
this.children = children;
this.through = through;
this.type = type;
this.astNode = astNode;
this.variables = new Map;
variables.forEach(v => this.variables.set(v.name, v));
this.variableList = [];
for (let x of this.variables.values()) {
this.variableList.push(x);
}
this.dynamic = isDynamic || type === ScopeType.WITH || type === ScopeType.GLOBAL;
}
isGlobal() {
return this.type === ScopeType.GLOBAL;
}
lookupVariable(name) {
return this.variables.get(name);
}
}
class GlobalScope extends Scope {
constructor({ children, variables, through, astNode }) {
super({ children, variables, through, type: ScopeType.GLOBAL, isDynamic: true, astNode });
through.forEachEntry((v, k) => {
this.variables.set(k, new Variable(k, v, []));
});
this.variableList = [];
for (let x of this.variables.values()) {
this.variableList.push(x);
}
}
}
module.exports = {
ScopeType,
Scope,
GlobalScope,
};