Faster tokenizer lookahead (#13341)
* refactor: simplify token context structure * add benchmark * perf: return a sub-state on tokenizer lookahead * Update packages/babel-parser/src/tokenizer/index.js Co-authored-by: Brian Ng <bng412@gmail.com> * Update packages/babel-parser/src/tokenizer/index.js Co-authored-by: Brian Ng <bng412@gmail.com> * remove irrelevant comment * fix: guard curPosition with isLookahead * add test cases Co-authored-by: Brian Ng <bng412@gmail.com>
This commit is contained in:
parent
b1f57e5fb5
commit
acf2a10899
@ -0,0 +1,22 @@
|
|||||||
|
import Benchmark from "benchmark";
|
||||||
|
import baseline from "@babel-baseline/parser";
|
||||||
|
import current from "../../lib/index.js";
|
||||||
|
import { report } from "../util.mjs";
|
||||||
|
|
||||||
|
const suite = new Benchmark.Suite();
|
||||||
|
function createInput(length) {
|
||||||
|
return "type A = " + "| (x) => void".repeat(length);
|
||||||
|
}
|
||||||
|
function benchCases(name, implementation, options) {
|
||||||
|
for (const length of [256, 512, 1024, 2048]) {
|
||||||
|
const input = createInput(length);
|
||||||
|
suite.add(`${name} ${length} arrow function types`, () => {
|
||||||
|
implementation.parse(input, options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
benchCases("baseline", baseline, { plugins: ["flow"] });
|
||||||
|
benchCases("current", current, { plugins: ["flow"] });
|
||||||
|
|
||||||
|
suite.on("cycle", report).run();
|
||||||
@ -9,7 +9,6 @@ import type Parser from "../../parser";
|
|||||||
import { types as tt, type TokenType } from "../../tokenizer/types";
|
import { types as tt, type TokenType } from "../../tokenizer/types";
|
||||||
import * as N from "../../types";
|
import * as N from "../../types";
|
||||||
import type { Pos, Position } from "../../util/location";
|
import type { Pos, Position } from "../../util/location";
|
||||||
import type State from "../../tokenizer/state";
|
|
||||||
import { types as tc } from "../../tokenizer/context";
|
import { types as tc } from "../../tokenizer/context";
|
||||||
import * as charCodes from "charcodes";
|
import * as charCodes from "charcodes";
|
||||||
import { isIteratorStart, isKeyword } from "../../util/identifier";
|
import { isIteratorStart, isKeyword } from "../../util/identifier";
|
||||||
@ -154,7 +153,7 @@ function hasTypeImportKind(node: N.Node): boolean {
|
|||||||
return node.importKind === "type" || node.importKind === "typeof";
|
return node.importKind === "type" || node.importKind === "typeof";
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMaybeDefaultImport(state: State): boolean {
|
function isMaybeDefaultImport(state: { type: TokenType, value: any }): boolean {
|
||||||
return (
|
return (
|
||||||
(state.type === tt.name || !!state.type.keyword) && state.value !== "from"
|
(state.type === tt.name || !!state.type.keyword) && state.value !== "from"
|
||||||
);
|
);
|
||||||
|
|||||||
@ -15,6 +15,10 @@ import { isIdentifierChar, isIdentifierStart } from "../../util/identifier";
|
|||||||
import type { Position } from "../../util/location";
|
import type { Position } from "../../util/location";
|
||||||
import { isNewLine } from "../../util/whitespace";
|
import { isNewLine } from "../../util/whitespace";
|
||||||
import { Errors, makeErrorTemplates, ErrorCodes } from "../../parser/error";
|
import { Errors, makeErrorTemplates, ErrorCodes } from "../../parser/error";
|
||||||
|
import type { LookaheadState } from "../../tokenizer/state";
|
||||||
|
import State from "../../tokenizer/state";
|
||||||
|
|
||||||
|
type JSXLookaheadState = LookaheadState & { inPropertyName: boolean };
|
||||||
|
|
||||||
const HEX_NUMBER = /^[\da-fA-F]+$/;
|
const HEX_NUMBER = /^[\da-fA-F]+$/;
|
||||||
const DECIMAL_NUMBER = /^\d+$/;
|
const DECIMAL_NUMBER = /^\d+$/;
|
||||||
@ -573,6 +577,14 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createLookaheadState(state: State): JSXLookaheadState {
|
||||||
|
const lookaheadState = ((super.createLookaheadState(
|
||||||
|
state,
|
||||||
|
): any): JSXLookaheadState);
|
||||||
|
lookaheadState.inPropertyName = state.inPropertyName;
|
||||||
|
return lookaheadState;
|
||||||
|
}
|
||||||
|
|
||||||
getTokenFromCode(code: number): void {
|
getTokenFromCode(code: number): void {
|
||||||
if (this.state.inPropertyName) return super.getTokenFromCode(code);
|
if (this.state.inPropertyName) return super.getTokenFromCode(code);
|
||||||
|
|
||||||
|
|||||||
@ -7,22 +7,15 @@
|
|||||||
import { types as tt } from "./types";
|
import { types as tt } from "./types";
|
||||||
|
|
||||||
export class TokContext {
|
export class TokContext {
|
||||||
constructor(
|
constructor(token: string, isExpr?: boolean, preserveSpace?: boolean) {
|
||||||
token: string,
|
|
||||||
isExpr?: boolean,
|
|
||||||
preserveSpace?: boolean,
|
|
||||||
override?: ?Function, // Takes a Tokenizer as a this-parameter, and returns void.
|
|
||||||
) {
|
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.isExpr = !!isExpr;
|
this.isExpr = !!isExpr;
|
||||||
this.preserveSpace = !!preserveSpace;
|
this.preserveSpace = !!preserveSpace;
|
||||||
this.override = override;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token: string;
|
token: string;
|
||||||
isExpr: boolean;
|
isExpr: boolean;
|
||||||
preserveSpace: boolean;
|
preserveSpace: boolean;
|
||||||
override: ?Function;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const types: {
|
export const types: {
|
||||||
@ -34,7 +27,7 @@ export const types: {
|
|||||||
templateQuasi: new TokContext("${", false),
|
templateQuasi: new TokContext("${", false),
|
||||||
parenStatement: new TokContext("(", false),
|
parenStatement: new TokContext("(", false),
|
||||||
parenExpression: new TokContext("(", true),
|
parenExpression: new TokContext("(", true),
|
||||||
template: new TokContext("`", true, true, p => p.readTmplToken()),
|
template: new TokContext("`", true, true),
|
||||||
functionExpression: new TokContext("function", true),
|
functionExpression: new TokContext("function", true),
|
||||||
functionStatement: new TokContext("function", false),
|
functionStatement: new TokContext("function", false),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import {
|
|||||||
skipWhiteSpace,
|
skipWhiteSpace,
|
||||||
} from "../util/whitespace";
|
} from "../util/whitespace";
|
||||||
import State from "./state";
|
import State from "./state";
|
||||||
|
import type { LookaheadState } from "./state";
|
||||||
|
|
||||||
const VALID_REGEX_FLAGS = new Set(["g", "m", "s", "i", "y", "u"]);
|
const VALID_REGEX_FLAGS = new Set(["g", "m", "s", "i", "y", "u"]);
|
||||||
|
|
||||||
@ -144,12 +145,10 @@ export default class Tokenizer extends ParserErrors {
|
|||||||
// Move to the next token
|
// Move to the next token
|
||||||
|
|
||||||
next(): void {
|
next(): void {
|
||||||
if (!this.isLookahead) {
|
|
||||||
this.checkKeywordEscapes();
|
this.checkKeywordEscapes();
|
||||||
if (this.options.tokens) {
|
if (this.options.tokens) {
|
||||||
this.pushToken(new Token(this.state));
|
this.pushToken(new Token(this.state));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.state.lastTokEnd = this.state.end;
|
this.state.lastTokEnd = this.state.end;
|
||||||
this.state.lastTokStart = this.state.start;
|
this.state.lastTokStart = this.state.start;
|
||||||
@ -175,14 +174,51 @@ export default class Tokenizer extends ParserErrors {
|
|||||||
return this.state.type === type;
|
return this.state.type === type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
/**
|
||||||
|
* Create a LookaheadState from current parser state
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
* @returns {LookaheadState}
|
||||||
|
* @memberof Tokenizer
|
||||||
|
*/
|
||||||
|
createLookaheadState(state: State): LookaheadState {
|
||||||
|
return {
|
||||||
|
pos: state.pos,
|
||||||
|
value: null,
|
||||||
|
type: state.type,
|
||||||
|
start: state.start,
|
||||||
|
end: state.end,
|
||||||
|
lastTokEnd: state.end,
|
||||||
|
context: [this.curContext()],
|
||||||
|
exprAllowed: state.exprAllowed,
|
||||||
|
inType: state.inType,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
lookahead(): State {
|
/**
|
||||||
|
* lookahead peeks the next token, skipping changes to token context and
|
||||||
|
* comment stack. For performance it returns a limited LookaheadState
|
||||||
|
* instead of full parser state.
|
||||||
|
*
|
||||||
|
* The { column, line } Loc info is not included in lookahead since such usage
|
||||||
|
* is rare. Although it may return other location properties e.g. `curLine` and
|
||||||
|
* `lineStart`, these properties are not listed in the LookaheadState interface
|
||||||
|
* and thus the returned value is _NOT_ reliable.
|
||||||
|
*
|
||||||
|
* The tokenizer should make best efforts to avoid using any parser state
|
||||||
|
* other than those defined in LookaheadState
|
||||||
|
*
|
||||||
|
* @returns {LookaheadState}
|
||||||
|
* @memberof Tokenizer
|
||||||
|
*/
|
||||||
|
lookahead(): LookaheadState {
|
||||||
const old = this.state;
|
const old = this.state;
|
||||||
this.state = old.clone(true);
|
// For performance we use a simpified tokenizer state structure
|
||||||
|
// $FlowIgnore
|
||||||
|
this.state = this.createLookaheadState(old);
|
||||||
|
|
||||||
this.isLookahead = true;
|
this.isLookahead = true;
|
||||||
this.next();
|
this.nextToken();
|
||||||
this.isLookahead = false;
|
this.isLookahead = false;
|
||||||
|
|
||||||
const curr = this.state;
|
const curr = this.state;
|
||||||
@ -247,17 +283,16 @@ export default class Tokenizer extends ParserErrors {
|
|||||||
|
|
||||||
nextToken(): void {
|
nextToken(): void {
|
||||||
const curContext = this.curContext();
|
const curContext = this.curContext();
|
||||||
if (!curContext?.preserveSpace) this.skipSpace();
|
if (!curContext.preserveSpace) this.skipSpace();
|
||||||
this.state.start = this.state.pos;
|
this.state.start = this.state.pos;
|
||||||
this.state.startLoc = this.state.curPosition();
|
if (!this.isLookahead) this.state.startLoc = this.state.curPosition();
|
||||||
if (this.state.pos >= this.length) {
|
if (this.state.pos >= this.length) {
|
||||||
this.finishToken(tt.eof);
|
this.finishToken(tt.eof);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const override = curContext?.override;
|
if (curContext === ct.template) {
|
||||||
if (override) {
|
this.readTmplToken();
|
||||||
override(this);
|
|
||||||
} else {
|
} else {
|
||||||
this.getTokenFromCode(this.codePointAtPos(this.state.pos));
|
this.getTokenFromCode(this.codePointAtPos(this.state.pos));
|
||||||
}
|
}
|
||||||
@ -285,7 +320,8 @@ export default class Tokenizer extends ParserErrors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
skipBlockComment(): void {
|
skipBlockComment(): void {
|
||||||
const startLoc = this.state.curPosition();
|
let startLoc;
|
||||||
|
if (!this.isLookahead) startLoc = this.state.curPosition();
|
||||||
const start = this.state.pos;
|
const start = this.state.pos;
|
||||||
const end = this.input.indexOf("*/", this.state.pos + 2);
|
const end = this.input.indexOf("*/", this.state.pos + 2);
|
||||||
if (end === -1) throw this.raise(start, Errors.UnterminatedComment);
|
if (end === -1) throw this.raise(start, Errors.UnterminatedComment);
|
||||||
@ -304,6 +340,7 @@ export default class Tokenizer extends ParserErrors {
|
|||||||
// If we are doing a lookahead right now we need to advance the position (above code)
|
// If we are doing a lookahead right now we need to advance the position (above code)
|
||||||
// but we do not want to push the comment to the state.
|
// but we do not want to push the comment to the state.
|
||||||
if (this.isLookahead) return;
|
if (this.isLookahead) return;
|
||||||
|
/*:: invariant(startLoc) */
|
||||||
|
|
||||||
this.pushComment(
|
this.pushComment(
|
||||||
true,
|
true,
|
||||||
@ -317,7 +354,8 @@ export default class Tokenizer extends ParserErrors {
|
|||||||
|
|
||||||
skipLineComment(startSkip: number): void {
|
skipLineComment(startSkip: number): void {
|
||||||
const start = this.state.pos;
|
const start = this.state.pos;
|
||||||
const startLoc = this.state.curPosition();
|
let startLoc;
|
||||||
|
if (!this.isLookahead) startLoc = this.state.curPosition();
|
||||||
let ch = this.input.charCodeAt((this.state.pos += startSkip));
|
let ch = this.input.charCodeAt((this.state.pos += startSkip));
|
||||||
if (this.state.pos < this.length) {
|
if (this.state.pos < this.length) {
|
||||||
while (!isNewLine(ch) && ++this.state.pos < this.length) {
|
while (!isNewLine(ch) && ++this.state.pos < this.length) {
|
||||||
@ -328,6 +366,7 @@ export default class Tokenizer extends ParserErrors {
|
|||||||
// If we are doing a lookahead right now we need to advance the position (above code)
|
// If we are doing a lookahead right now we need to advance the position (above code)
|
||||||
// but we do not want to push the comment to the state.
|
// but we do not want to push the comment to the state.
|
||||||
if (this.isLookahead) return;
|
if (this.isLookahead) return;
|
||||||
|
/*:: invariant(startLoc) */
|
||||||
|
|
||||||
this.pushComment(
|
this.pushComment(
|
||||||
false,
|
false,
|
||||||
@ -398,12 +437,14 @@ export default class Tokenizer extends ParserErrors {
|
|||||||
|
|
||||||
finishToken(type: TokenType, val: any): void {
|
finishToken(type: TokenType, val: any): void {
|
||||||
this.state.end = this.state.pos;
|
this.state.end = this.state.pos;
|
||||||
this.state.endLoc = this.state.curPosition();
|
|
||||||
const prevType = this.state.type;
|
const prevType = this.state.type;
|
||||||
this.state.type = type;
|
this.state.type = type;
|
||||||
this.state.value = val;
|
this.state.value = val;
|
||||||
|
|
||||||
if (!this.isLookahead) this.updateContext(prevType);
|
if (!this.isLookahead) {
|
||||||
|
this.state.endLoc = this.state.curPosition();
|
||||||
|
this.updateContext(prevType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ### Token reading
|
// ### Token reading
|
||||||
|
|||||||
@ -178,3 +178,14 @@ export default class State {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LookaheadState = {
|
||||||
|
pos: number,
|
||||||
|
value: any,
|
||||||
|
type: TokenType,
|
||||||
|
start: number,
|
||||||
|
end: number,
|
||||||
|
/* Used only in readSlashToken */
|
||||||
|
exprAllowed: boolean,
|
||||||
|
inType: boolean,
|
||||||
|
};
|
||||||
|
|||||||
2
packages/babel-parser/test/fixtures/typescript/export/internal-comments/input.ts
vendored
Normal file
2
packages/babel-parser/test/fixtures/typescript/export/internal-comments/input.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/*1*/ export /*2*/ { /*3*/ A /*4*/, /*5*/ B /*6*/ as /*7*/ C /*8*/ } /*9*/ from /*10*/ "foo";
|
||||||
|
/*1*/ export /*2*/ * /*3*/ from /*4*/ "foo"
|
||||||
242
packages/babel-parser/test/fixtures/typescript/export/internal-comments/output.json
vendored
Normal file
242
packages/babel-parser/test/fixtures/typescript/export/internal-comments/output.json
vendored
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
{
|
||||||
|
"type": "File",
|
||||||
|
"start":0,"end":137,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":43}},
|
||||||
|
"program": {
|
||||||
|
"type": "Program",
|
||||||
|
"start":0,"end":137,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":43}},
|
||||||
|
"sourceType": "module",
|
||||||
|
"interpreter": null,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "ExportNamedDeclaration",
|
||||||
|
"start":6,"end":93,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":93}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":94,"end":99,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":5}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exportKind": "value",
|
||||||
|
"specifiers": [
|
||||||
|
{
|
||||||
|
"type": "ExportSpecifier",
|
||||||
|
"start":27,"end":28,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":28}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":13,"end":18,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":18}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":21,"end":26,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":26}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "4",
|
||||||
|
"start":29,"end":34,"loc":{"start":{"line":1,"column":29},"end":{"line":1,"column":34}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "5",
|
||||||
|
"start":36,"end":41,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":41}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":27,"end":28,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":28},"identifierName":"A"},
|
||||||
|
"name": "A"
|
||||||
|
},
|
||||||
|
"exported": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":27,"end":28,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":28},"identifierName":"A"},
|
||||||
|
"name": "A"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ExportSpecifier",
|
||||||
|
"start":42,"end":60,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":60}},
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "8",
|
||||||
|
"start":61,"end":66,"loc":{"start":{"line":1,"column":61},"end":{"line":1,"column":66}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "9",
|
||||||
|
"start":69,"end":74,"loc":{"start":{"line":1,"column":69},"end":{"line":1,"column":74}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "10",
|
||||||
|
"start":80,"end":86,"loc":{"start":{"line":1,"column":80},"end":{"line":1,"column":86}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":42,"end":43,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":43},"identifierName":"B"},
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "6",
|
||||||
|
"start":44,"end":49,"loc":{"start":{"line":1,"column":44},"end":{"line":1,"column":49}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "B"
|
||||||
|
},
|
||||||
|
"exported": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":59,"end":60,"loc":{"start":{"line":1,"column":59},"end":{"line":1,"column":60},"identifierName":"C"},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "6",
|
||||||
|
"start":44,"end":49,"loc":{"start":{"line":1,"column":44},"end":{"line":1,"column":49}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "7",
|
||||||
|
"start":53,"end":58,"loc":{"start":{"line":1,"column":53},"end":{"line":1,"column":58}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "C"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"type": "StringLiteral",
|
||||||
|
"start":87,"end":92,"loc":{"start":{"line":1,"column":87},"end":{"line":1,"column":92}},
|
||||||
|
"extra": {
|
||||||
|
"rawValue": "foo",
|
||||||
|
"raw": "\"foo\""
|
||||||
|
},
|
||||||
|
"value": "foo"
|
||||||
|
},
|
||||||
|
"declaration": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ExportAllDeclaration",
|
||||||
|
"start":100,"end":137,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":43}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":94,"end":99,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":5}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exportKind": "value",
|
||||||
|
"source": {
|
||||||
|
"type": "StringLiteral",
|
||||||
|
"start":132,"end":137,"loc":{"start":{"line":2,"column":38},"end":{"line":2,"column":43}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":107,"end":112,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":18}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":115,"end":120,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":26}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "4",
|
||||||
|
"start":126,"end":131,"loc":{"start":{"line":2,"column":32},"end":{"line":2,"column":37}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extra": {
|
||||||
|
"rawValue": "foo",
|
||||||
|
"raw": "\"foo\""
|
||||||
|
},
|
||||||
|
"value": "foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": []
|
||||||
|
},
|
||||||
|
"comments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":13,"end":18,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":18}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":21,"end":26,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":26}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "4",
|
||||||
|
"start":29,"end":34,"loc":{"start":{"line":1,"column":29},"end":{"line":1,"column":34}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "5",
|
||||||
|
"start":36,"end":41,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":41}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "6",
|
||||||
|
"start":44,"end":49,"loc":{"start":{"line":1,"column":44},"end":{"line":1,"column":49}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "7",
|
||||||
|
"start":53,"end":58,"loc":{"start":{"line":1,"column":53},"end":{"line":1,"column":58}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "8",
|
||||||
|
"start":61,"end":66,"loc":{"start":{"line":1,"column":61},"end":{"line":1,"column":66}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "9",
|
||||||
|
"start":69,"end":74,"loc":{"start":{"line":1,"column":69},"end":{"line":1,"column":74}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "10",
|
||||||
|
"start":80,"end":86,"loc":{"start":{"line":1,"column":80},"end":{"line":1,"column":86}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":94,"end":99,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":5}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":107,"end":112,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":18}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":115,"end":120,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":26}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "4",
|
||||||
|
"start":126,"end":131,"loc":{"start":{"line":2,"column":32},"end":{"line":2,"column":37}}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
2
packages/babel-parser/test/fixtures/typescript/import/internal-comments/input.ts
vendored
Normal file
2
packages/babel-parser/test/fixtures/typescript/import/internal-comments/input.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/*1*/ import /*2*/ D /*3*/, /*4*/ { /*5*/ A /*6*/, /*7*/ B /*8*/ as /*9*/ C /*10*/ } /*11*/ from /*12*/ "foo";
|
||||||
|
/*1*/ import /*2*/ * /*3*/ as /*4*/ foo /*5*/ from /*6*/ "foo";
|
||||||
331
packages/babel-parser/test/fixtures/typescript/import/internal-comments/output.json
vendored
Normal file
331
packages/babel-parser/test/fixtures/typescript/import/internal-comments/output.json
vendored
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
{
|
||||||
|
"type": "File",
|
||||||
|
"start":0,"end":174,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":63}},
|
||||||
|
"program": {
|
||||||
|
"type": "Program",
|
||||||
|
"start":0,"end":174,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":63}},
|
||||||
|
"sourceType": "module",
|
||||||
|
"interpreter": null,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "ImportDeclaration",
|
||||||
|
"start":6,"end":110,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":110}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":111,"end":116,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":5}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"importKind": "value",
|
||||||
|
"specifiers": [
|
||||||
|
{
|
||||||
|
"type": "ImportDefaultSpecifier",
|
||||||
|
"start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":13,"end":18,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":18}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":21,"end":26,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":26}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20},"identifierName":"D"},
|
||||||
|
"name": "D"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ImportSpecifier",
|
||||||
|
"start":42,"end":43,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":43}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":13,"end":18,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":18}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":21,"end":26,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":26}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "4",
|
||||||
|
"start":28,"end":33,"loc":{"start":{"line":1,"column":28},"end":{"line":1,"column":33}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "5",
|
||||||
|
"start":36,"end":41,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":41}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "6",
|
||||||
|
"start":44,"end":49,"loc":{"start":{"line":1,"column":44},"end":{"line":1,"column":49}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "7",
|
||||||
|
"start":51,"end":56,"loc":{"start":{"line":1,"column":51},"end":{"line":1,"column":56}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"imported": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":42,"end":43,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":43},"identifierName":"A"},
|
||||||
|
"name": "A"
|
||||||
|
},
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":42,"end":43,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":43},"identifierName":"A"},
|
||||||
|
"name": "A"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ImportSpecifier",
|
||||||
|
"start":57,"end":75,"loc":{"start":{"line":1,"column":57},"end":{"line":1,"column":75}},
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "10",
|
||||||
|
"start":76,"end":82,"loc":{"start":{"line":1,"column":76},"end":{"line":1,"column":82}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "11",
|
||||||
|
"start":85,"end":91,"loc":{"start":{"line":1,"column":85},"end":{"line":1,"column":91}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "12",
|
||||||
|
"start":97,"end":103,"loc":{"start":{"line":1,"column":97},"end":{"line":1,"column":103}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"imported": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":57,"end":58,"loc":{"start":{"line":1,"column":57},"end":{"line":1,"column":58},"identifierName":"B"},
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "8",
|
||||||
|
"start":59,"end":64,"loc":{"start":{"line":1,"column":59},"end":{"line":1,"column":64}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "B"
|
||||||
|
},
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":74,"end":75,"loc":{"start":{"line":1,"column":74},"end":{"line":1,"column":75},"identifierName":"C"},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "8",
|
||||||
|
"start":59,"end":64,"loc":{"start":{"line":1,"column":59},"end":{"line":1,"column":64}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "9",
|
||||||
|
"start":68,"end":73,"loc":{"start":{"line":1,"column":68},"end":{"line":1,"column":73}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "C"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"type": "StringLiteral",
|
||||||
|
"start":104,"end":109,"loc":{"start":{"line":1,"column":104},"end":{"line":1,"column":109}},
|
||||||
|
"extra": {
|
||||||
|
"rawValue": "foo",
|
||||||
|
"raw": "\"foo\""
|
||||||
|
},
|
||||||
|
"value": "foo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ImportDeclaration",
|
||||||
|
"start":117,"end":174,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":63}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":111,"end":116,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":5}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"importKind": "value",
|
||||||
|
"specifiers": [
|
||||||
|
{
|
||||||
|
"type": "ImportNamespaceSpecifier",
|
||||||
|
"start":130,"end":150,"loc":{"start":{"line":2,"column":19},"end":{"line":2,"column":39}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":124,"end":129,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":18}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trailingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "5",
|
||||||
|
"start":151,"end":156,"loc":{"start":{"line":2,"column":40},"end":{"line":2,"column":45}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":147,"end":150,"loc":{"start":{"line":2,"column":36},"end":{"line":2,"column":39},"identifierName":"foo"},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":132,"end":137,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":26}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "4",
|
||||||
|
"start":141,"end":146,"loc":{"start":{"line":2,"column":30},"end":{"line":2,"column":35}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"type": "StringLiteral",
|
||||||
|
"start":168,"end":173,"loc":{"start":{"line":2,"column":57},"end":{"line":2,"column":62}},
|
||||||
|
"leadingComments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "5",
|
||||||
|
"start":151,"end":156,"loc":{"start":{"line":2,"column":40},"end":{"line":2,"column":45}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "6",
|
||||||
|
"start":162,"end":167,"loc":{"start":{"line":2,"column":51},"end":{"line":2,"column":56}}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extra": {
|
||||||
|
"rawValue": "foo",
|
||||||
|
"raw": "\"foo\""
|
||||||
|
},
|
||||||
|
"value": "foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": []
|
||||||
|
},
|
||||||
|
"comments": [
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":13,"end":18,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":18}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":21,"end":26,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":26}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "4",
|
||||||
|
"start":28,"end":33,"loc":{"start":{"line":1,"column":28},"end":{"line":1,"column":33}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "5",
|
||||||
|
"start":36,"end":41,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":41}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "6",
|
||||||
|
"start":44,"end":49,"loc":{"start":{"line":1,"column":44},"end":{"line":1,"column":49}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "7",
|
||||||
|
"start":51,"end":56,"loc":{"start":{"line":1,"column":51},"end":{"line":1,"column":56}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "8",
|
||||||
|
"start":59,"end":64,"loc":{"start":{"line":1,"column":59},"end":{"line":1,"column":64}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "9",
|
||||||
|
"start":68,"end":73,"loc":{"start":{"line":1,"column":68},"end":{"line":1,"column":73}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "10",
|
||||||
|
"start":76,"end":82,"loc":{"start":{"line":1,"column":76},"end":{"line":1,"column":82}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "11",
|
||||||
|
"start":85,"end":91,"loc":{"start":{"line":1,"column":85},"end":{"line":1,"column":91}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "12",
|
||||||
|
"start":97,"end":103,"loc":{"start":{"line":1,"column":97},"end":{"line":1,"column":103}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "1",
|
||||||
|
"start":111,"end":116,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":5}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "2",
|
||||||
|
"start":124,"end":129,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":18}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "3",
|
||||||
|
"start":132,"end":137,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":26}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "4",
|
||||||
|
"start":141,"end":146,"loc":{"start":{"line":2,"column":30},"end":{"line":2,"column":35}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "5",
|
||||||
|
"start":151,"end":156,"loc":{"start":{"line":2,"column":40},"end":{"line":2,"column":45}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CommentBlock",
|
||||||
|
"value": "6",
|
||||||
|
"start":162,"end":167,"loc":{"start":{"line":2,"column":51},"end":{"line":2,"column":56}}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user