js-ast-parser
Version:
把javascript代码字符串解析为AST对象
83 lines (71 loc) • 2.85 kB
text/typescript
import { AstNode } from "../AstNode";
import { Context } from "./Context";
import { Definition } from "./Definition";
import { v4 as uuidv4 } from 'uuid';
export class Scope {
definitions: Array<Definition> = [];
definitionsMap: any = {};
context: Context = new Context();
functionScope = false;
exports: any = [];
id: string;
unusedDefination: Map<AstNode, Definition> = new Map();
UndeclaredVariables: Set<any> = new Set();
constructor(public parent?: Scope) {
this.id = uuidv4();
}
addDefinition(definition: Definition) {
this.definitions.push(this.definitionsMap[definition.identifier] = definition);
}
addDefinitions(definitions: Definition[]) {
definitions.forEach(definition => this.addDefinition(definition))
}
getDefinition(identifier: string) {
return this.definitionsMap[identifier] || (this.parent && this.parent.getDefinition(identifier) || null);
}
deleteUnuse(definition: Definition) {
if (this.unusedDefination.has(definition.astNode)) {
this.unusedDefination.delete(definition.astNode);
} else if (this.parent) {
this.parent.deleteUnuse(definition);
}
}
addUnuse(definition: Definition) {
this.unusedDefination.set(definition.astNode, definition);
}
isUnuse(definition: Definition) {
return !!this.unusedDefination.get(definition.astNode);
}
fullMatchDefinition(text: string) {
return this.definitionsMap[text] || this.fullMatchParentDefinitions(text);
}
matchParentDefinitions(text: string, near = 0) {
if (this.parent) return this.parent.matchDefinitions(text, near);
return []
}
fullMatchParentDefinitions(text: string) {
if (this.parent) return this.parent.fullMatchDefinition(text);
return []
}
matchOwnDefinitions(text: string, near = 0) {
return this.definitions.reduce((result: any, definition) => {
let index;
if (definition.identifier !== text && (index = definition.identifier.indexOf(text)) > -1) {
let textLeft = definition.identifier.slice(0, index),
textRight = definition.identifier.slice(index + text.length);
result.push({
near: near,
definition : definition,
index: index,
text: text,
textLeft: textLeft,
textRight: textRight
})
}
return result;
}, [])
}
matchDefinitions(text: string, near = 0) {
return this.matchOwnDefinitions(text, near).concat(this.matchParentDefinitions(text, near + 1));
}
}