%PDF- %PDF-
Direktori : /home/opti/workflow/node_modules/acorn/src/loose/ |
Current File : /home/opti/workflow/node_modules/acorn/src/loose/state.js |
import {tokenizer, SourceLocation, tokTypes as tt, Node, lineBreak, isNewLine} from "acorn" // Registered plugins export const pluginsLoose = {} export class LooseParser { constructor(input, options = {}) { this.toks = tokenizer(input, options) this.options = this.toks.options this.input = this.toks.input this.tok = this.last = {type: tt.eof, start: 0, end: 0} if (this.options.locations) { let here = this.toks.curPosition() this.tok.loc = new SourceLocation(this.toks, here, here) } this.ahead = [] // Tokens ahead this.context = [] // Indentation contexted this.curIndent = 0 this.curLineStart = 0 this.nextLineStart = this.lineEnd(this.curLineStart) + 1 // Load plugins this.options.pluginsLoose = options.pluginsLoose || {} this.loadPlugins(this.options.pluginsLoose) } startNode() { return new Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null) } storeCurrentPos() { return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start } startNodeAt(pos) { if (this.options.locations) { return new Node(this.toks, pos[0], pos[1]) } else { return new Node(this.toks, pos) } } finishNode(node, type) { node.type = type node.end = this.last.end if (this.options.locations) node.loc.end = this.last.loc.end if (this.options.ranges) node.range[1] = this.last.end return node } dummyNode(type) { let dummy = this.startNode() dummy.type = type dummy.end = dummy.start if (this.options.locations) dummy.loc.end = dummy.loc.start if (this.options.ranges) dummy.range[1] = dummy.start this.last = {type: tt.name, start: dummy.start, end: dummy.start, loc: dummy.loc} return dummy } dummyIdent() { let dummy = this.dummyNode("Identifier") dummy.name = "✖" return dummy } dummyString() { let dummy = this.dummyNode("Literal") dummy.value = dummy.raw = "✖" return dummy } eat(type) { if (this.tok.type === type) { this.next() return true } else { return false } } isContextual(name) { return this.tok.type === tt.name && this.tok.value === name } eatContextual(name) { return this.tok.value === name && this.eat(tt.name) } canInsertSemicolon() { return this.tok.type === tt.eof || this.tok.type === tt.braceR || lineBreak.test(this.input.slice(this.last.end, this.tok.start)) } semicolon() { return this.eat(tt.semi) } expect(type) { if (this.eat(type)) return true for (let i = 1; i <= 2; i++) { if (this.lookAhead(i).type == type) { for (let j = 0; j < i; j++) this.next() return true } } } pushCx() { this.context.push(this.curIndent) } popCx() { this.curIndent = this.context.pop() } lineEnd(pos) { while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) ++pos return pos } indentationAfter(pos) { for (let count = 0;; ++pos) { let ch = this.input.charCodeAt(pos) if (ch === 32) ++count else if (ch === 9) count += this.options.tabSize else return count } } closes(closeTok, indent, line, blockHeuristic) { if (this.tok.type === closeTok || this.tok.type === tt.eof) return true return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() && (!blockHeuristic || this.nextLineStart >= this.input.length || this.indentationAfter(this.nextLineStart) < indent) } tokenStartsLine() { for (let p = this.tok.start - 1; p >= this.curLineStart; --p) { let ch = this.input.charCodeAt(p) if (ch !== 9 && ch !== 32) return false } return true } extend(name, f) { this[name] = f(this[name]) } loadPlugins(pluginConfigs) { for (let name in pluginConfigs) { let plugin = pluginsLoose[name] if (!plugin) throw new Error("Plugin '" + name + "' not found") plugin(this, pluginConfigs[name]) } } }