UNPKG

js-ast-parser

Version:
83 lines (71 loc) 2.85 kB
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)); } }