123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- import TokenTranslator from "./token-translator.js";
- import { normalizeOptions } from "./options.js";
- const STATE = Symbol("espree's internal state");
- const ESPRIMA_FINISH_NODE = Symbol("espree's esprimaFinishNode");
- function convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, endLoc) {
- const comment = {
- type: block ? "Block" : "Line",
- value: text
- };
- if (typeof start === "number") {
- comment.start = start;
- comment.end = end;
- comment.range = [start, end];
- }
- if (typeof startLoc === "object") {
- comment.loc = {
- start: startLoc,
- end: endLoc
- };
- }
- return comment;
- }
- export default () => Parser => {
- const tokTypes = Object.assign({}, Parser.acorn.tokTypes);
- if (Parser.acornJsx) {
- Object.assign(tokTypes, Parser.acornJsx.tokTypes);
- }
- return class Espree extends Parser {
- constructor(opts, code) {
- if (typeof opts !== "object" || opts === null) {
- opts = {};
- }
- if (typeof code !== "string" && !(code instanceof String)) {
- code = String(code);
- }
-
- const originalSourceType = opts.sourceType;
- const options = normalizeOptions(opts);
- const ecmaFeatures = options.ecmaFeatures || {};
- const tokenTranslator =
- options.tokens === true
- ? new TokenTranslator(tokTypes, code)
- : null;
-
- super({
-
- ecmaVersion: options.ecmaVersion,
- sourceType: options.sourceType,
- ranges: options.ranges,
- locations: options.locations,
- allowReserved: options.allowReserved,
-
- allowReturnOutsideFunction: options.allowReturnOutsideFunction,
-
- onToken: token => {
- if (tokenTranslator) {
-
- tokenTranslator.onToken(token, this[STATE]);
- }
- if (token.type !== tokTypes.eof) {
- this[STATE].lastToken = token;
- }
- },
-
- onComment: (block, text, start, end, startLoc, endLoc) => {
- if (this[STATE].comments) {
- const comment = convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, endLoc);
- this[STATE].comments.push(comment);
- }
- }
- }, code);
-
- this[STATE] = {
- originalSourceType: originalSourceType || options.sourceType,
- tokens: tokenTranslator ? [] : null,
- comments: options.comment === true ? [] : null,
- impliedStrict: ecmaFeatures.impliedStrict === true && this.options.ecmaVersion >= 5,
- ecmaVersion: this.options.ecmaVersion,
- jsxAttrValueToken: false,
- lastToken: null,
- templateElements: []
- };
- }
- tokenize() {
- do {
- this.next();
- } while (this.type !== tokTypes.eof);
-
- this.next();
- const extra = this[STATE];
- const tokens = extra.tokens;
- if (extra.comments) {
- tokens.comments = extra.comments;
- }
- return tokens;
- }
- finishNode(...args) {
- const result = super.finishNode(...args);
- return this[ESPRIMA_FINISH_NODE](result);
- }
- finishNodeAt(...args) {
- const result = super.finishNodeAt(...args);
- return this[ESPRIMA_FINISH_NODE](result);
- }
- parse() {
- const extra = this[STATE];
- const program = super.parse();
- program.sourceType = extra.originalSourceType;
- if (extra.comments) {
- program.comments = extra.comments;
- }
- if (extra.tokens) {
- program.tokens = extra.tokens;
- }
-
- if (program.body.length) {
- const [firstNode] = program.body;
- if (program.range) {
- program.range[0] = firstNode.range[0];
- }
- if (program.loc) {
- program.loc.start = firstNode.loc.start;
- }
- program.start = firstNode.start;
- }
- if (extra.lastToken) {
- if (program.range) {
- program.range[1] = extra.lastToken.range[1];
- }
- if (program.loc) {
- program.loc.end = extra.lastToken.loc.end;
- }
- program.end = extra.lastToken.end;
- }
-
- this[STATE].templateElements.forEach(templateElement => {
- const startOffset = -1;
- const endOffset = templateElement.tail ? 1 : 2;
- templateElement.start += startOffset;
- templateElement.end += endOffset;
- if (templateElement.range) {
- templateElement.range[0] += startOffset;
- templateElement.range[1] += endOffset;
- }
- if (templateElement.loc) {
- templateElement.loc.start.column += startOffset;
- templateElement.loc.end.column += endOffset;
- }
- });
- return program;
- }
- parseTopLevel(node) {
- if (this[STATE].impliedStrict) {
- this.strict = true;
- }
- return super.parseTopLevel(node);
- }
-
- raise(pos, message) {
- const loc = Parser.acorn.getLineInfo(this.input, pos);
- const err = new SyntaxError(message);
- err.index = pos;
- err.lineNumber = loc.line;
- err.column = loc.column + 1;
- throw err;
- }
-
- raiseRecoverable(pos, message) {
- this.raise(pos, message);
- }
-
- unexpected(pos) {
- let message = "Unexpected token";
- if (pos !== null && pos !== void 0) {
- this.pos = pos;
- if (this.options.locations) {
- while (this.pos < this.lineStart) {
- this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
- --this.curLine;
- }
- }
- this.nextToken();
- }
- if (this.end > this.start) {
- message += ` ${this.input.slice(this.start, this.end)}`;
- }
- this.raise(this.start, message);
- }
-
- jsx_readString(quote) {
- const result = super.jsx_readString(quote);
- if (this.type === tokTypes.string) {
- this[STATE].jsxAttrValueToken = true;
- }
- return result;
- }
-
- [ESPRIMA_FINISH_NODE](result) {
-
-
- if (result.type === "TemplateElement") {
-
- this[STATE].templateElements.push(result);
- }
- if (result.type.includes("Function") && !result.generator) {
- result.generator = false;
- }
- return result;
- }
- };
- };
|