refactor: add parse*Literal parser routines (#13333)
* refactor: simplify parseLiteral interface * refactor: extract specific methods on parsing literals * fix: avoid StringLiteral type comparison * add test cases * fix: remove redundant node * Update packages/babel-parser/src/plugins/flow/index.js Co-authored-by: Federico Ciardi <fed.ciardi@gmail.com> * update test fixtures * fix: refine parseLiteral typings Co-authored-by: Federico Ciardi <fed.ciardi@gmail.com>
This commit is contained in:
parent
053f94fc77
commit
461ba2531a
@ -1068,33 +1068,28 @@ export default class ExpressionParser extends LValParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case tt.regexp: {
|
case tt.regexp: {
|
||||||
const value = this.state.value;
|
return this.parseRegExpLiteral(this.state.value);
|
||||||
node = this.parseLiteral(value.value, "RegExpLiteral");
|
|
||||||
node.pattern = value.pattern;
|
|
||||||
node.flags = value.flags;
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case tt.num:
|
case tt.num:
|
||||||
return this.parseLiteral(this.state.value, "NumericLiteral");
|
return this.parseNumericLiteral(this.state.value);
|
||||||
|
|
||||||
case tt.bigint:
|
case tt.bigint:
|
||||||
return this.parseLiteral(this.state.value, "BigIntLiteral");
|
return this.parseBigIntLiteral(this.state.value);
|
||||||
|
|
||||||
case tt.decimal:
|
case tt.decimal:
|
||||||
return this.parseLiteral(this.state.value, "DecimalLiteral");
|
return this.parseDecimalLiteral(this.state.value);
|
||||||
|
|
||||||
case tt.string:
|
case tt.string:
|
||||||
return this.parseLiteral(this.state.value, "StringLiteral");
|
return this.parseStringLiteral(this.state.value);
|
||||||
|
|
||||||
case tt._null:
|
case tt._null:
|
||||||
node = this.startNode();
|
return this.parseNullLiteral();
|
||||||
this.next();
|
|
||||||
return this.finishNode(node, "NullLiteral");
|
|
||||||
|
|
||||||
case tt._true:
|
case tt._true:
|
||||||
|
return this.parseBooleanLiteral(true);
|
||||||
case tt._false:
|
case tt._false:
|
||||||
return this.parseBooleanLiteral();
|
return this.parseBooleanLiteral(false);
|
||||||
|
|
||||||
case tt.parenL:
|
case tt.parenL:
|
||||||
return this.parseParenAndDistinguishExpression(canBeArrow);
|
return this.parseParenAndDistinguishExpression(canBeArrow);
|
||||||
@ -1290,13 +1285,6 @@ export default class ExpressionParser extends LValParser {
|
|||||||
return this.finishNode(node, "Super");
|
return this.finishNode(node, "Super");
|
||||||
}
|
}
|
||||||
|
|
||||||
parseBooleanLiteral(): N.BooleanLiteral {
|
|
||||||
const node = this.startNode();
|
|
||||||
node.value = this.match(tt._true);
|
|
||||||
this.next();
|
|
||||||
return this.finishNode(node, "BooleanLiteral");
|
|
||||||
}
|
|
||||||
|
|
||||||
parseMaybePrivateName(
|
parseMaybePrivateName(
|
||||||
isPrivateNameAllowed: boolean,
|
isPrivateNameAllowed: boolean,
|
||||||
): N.PrivateName | N.Identifier {
|
): N.PrivateName | N.Identifier {
|
||||||
@ -1398,21 +1386,60 @@ export default class ExpressionParser extends LValParser {
|
|||||||
return this.parseMetaProperty(node, id, "meta");
|
return this.parseMetaProperty(node, id, "meta");
|
||||||
}
|
}
|
||||||
|
|
||||||
parseLiteral<T: N.Literal>(
|
parseLiteralAtNode<T: N.Node>(
|
||||||
value: any,
|
value: any,
|
||||||
type: /*T["kind"]*/ string,
|
type: $ElementType<T, "type">,
|
||||||
startPos?: number,
|
node: any,
|
||||||
startLoc?: Position,
|
|
||||||
): T {
|
): T {
|
||||||
startPos = startPos || this.state.start;
|
|
||||||
startLoc = startLoc || this.state.startLoc;
|
|
||||||
|
|
||||||
const node = this.startNodeAt(startPos, startLoc);
|
|
||||||
this.addExtra(node, "rawValue", value);
|
this.addExtra(node, "rawValue", value);
|
||||||
this.addExtra(node, "raw", this.input.slice(startPos, this.state.end));
|
this.addExtra(node, "raw", this.input.slice(node.start, this.state.end));
|
||||||
node.value = value;
|
node.value = value;
|
||||||
this.next();
|
this.next();
|
||||||
return this.finishNode(node, type);
|
return this.finishNode<T>(node, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseLiteral<T: N.Node>(value: any, type: $ElementType<T, "type">): T {
|
||||||
|
const node = this.startNode();
|
||||||
|
return this.parseLiteralAtNode(value, type, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseStringLiteral(value: any) {
|
||||||
|
return this.parseLiteral<N.StringLiteral>(value, "StringLiteral");
|
||||||
|
}
|
||||||
|
|
||||||
|
parseNumericLiteral(value: any) {
|
||||||
|
return this.parseLiteral<N.NumericLiteral>(value, "NumericLiteral");
|
||||||
|
}
|
||||||
|
|
||||||
|
parseBigIntLiteral(value: any) {
|
||||||
|
return this.parseLiteral<N.BigIntLiteral>(value, "BigIntLiteral");
|
||||||
|
}
|
||||||
|
|
||||||
|
parseDecimalLiteral(value: any) {
|
||||||
|
return this.parseLiteral<N.DecimalLiteral>(value, "DecimalLiteral");
|
||||||
|
}
|
||||||
|
|
||||||
|
parseRegExpLiteral(value: { value: any, pattern: string, flags: string }) {
|
||||||
|
const node = this.parseLiteral<N.RegExpLiteral>(
|
||||||
|
value.value,
|
||||||
|
"RegExpLiteral",
|
||||||
|
);
|
||||||
|
node.pattern = value.pattern;
|
||||||
|
node.flags = value.flags;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseBooleanLiteral(value: boolean) {
|
||||||
|
const node = this.startNode();
|
||||||
|
node.value = value;
|
||||||
|
this.next();
|
||||||
|
return this.finishNode<N.BooleanLiteral>(node, "BooleanLiteral");
|
||||||
|
}
|
||||||
|
|
||||||
|
parseNullLiteral() {
|
||||||
|
const node = this.startNode();
|
||||||
|
this.next();
|
||||||
|
return this.finishNode<N.NullLiteral>(node, "NullLiteral");
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://tc39.es/ecma262/#prod-CoverParenthesizedExpressionAndArrowParameterList
|
// https://tc39.es/ecma262/#prod-CoverParenthesizedExpressionAndArrowParameterList
|
||||||
|
|||||||
@ -2041,7 +2041,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
// $FlowIgnore
|
// $FlowIgnore
|
||||||
if (!isFrom && specifier.local) {
|
if (!isFrom && specifier.local) {
|
||||||
const { local } = specifier;
|
const { local } = specifier;
|
||||||
if (local.type === "StringLiteral") {
|
if (local.type !== "Identifier") {
|
||||||
this.raise(
|
this.raise(
|
||||||
specifier.start,
|
specifier.start,
|
||||||
Errors.ExportBindingIsString,
|
Errors.ExportBindingIsString,
|
||||||
@ -2157,10 +2157,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
// https://tc39.es/ecma262/#prod-ModuleExportName
|
// https://tc39.es/ecma262/#prod-ModuleExportName
|
||||||
parseModuleExportName(): N.StringLiteral | N.Identifier {
|
parseModuleExportName(): N.StringLiteral | N.Identifier {
|
||||||
if (this.match(tt.string)) {
|
if (this.match(tt.string)) {
|
||||||
const result = this.parseLiteral<N.StringLiteral>(
|
const result = this.parseStringLiteral(this.state.value);
|
||||||
this.state.value,
|
|
||||||
"StringLiteral",
|
|
||||||
);
|
|
||||||
const surrogate = result.value.match(loneSurrogate);
|
const surrogate = result.value.match(loneSurrogate);
|
||||||
if (surrogate) {
|
if (surrogate) {
|
||||||
this.raise(
|
this.raise(
|
||||||
@ -2259,7 +2256,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
// parse AssertionKey : IdentifierName, StringLiteral
|
// parse AssertionKey : IdentifierName, StringLiteral
|
||||||
const keyName = this.state.value;
|
const keyName = this.state.value;
|
||||||
if (this.match(tt.string)) {
|
if (this.match(tt.string)) {
|
||||||
node.key = this.parseLiteral<N.StringLiteral>(keyName, "StringLiteral");
|
node.key = this.parseStringLiteral(keyName);
|
||||||
} else {
|
} else {
|
||||||
node.key = this.parseIdentifier(true);
|
node.key = this.parseIdentifier(true);
|
||||||
}
|
}
|
||||||
@ -2291,10 +2288,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
Errors.ModuleAttributeInvalidValue,
|
Errors.ModuleAttributeInvalidValue,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
node.value = this.parseLiteral<N.StringLiteral>(
|
node.value = this.parseStringLiteral(this.state.value);
|
||||||
this.state.value,
|
|
||||||
"StringLiteral",
|
|
||||||
);
|
|
||||||
this.finishNode<N.ImportAttribute>(node, "ImportAttribute");
|
this.finishNode<N.ImportAttribute>(node, "ImportAttribute");
|
||||||
attrs.push(node);
|
attrs.push(node);
|
||||||
} while (this.eat(tt.comma));
|
} while (this.eat(tt.comma));
|
||||||
@ -2345,7 +2339,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
Errors.ModuleAttributeInvalidValue,
|
Errors.ModuleAttributeInvalidValue,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
node.value = this.parseLiteral(this.state.value, "StringLiteral");
|
node.value = this.parseStringLiteral(this.state.value);
|
||||||
this.finishNode(node, "ImportAttribute");
|
this.finishNode(node, "ImportAttribute");
|
||||||
attrs.push(node);
|
attrs.push(node);
|
||||||
} while (this.eat(tt.comma));
|
} while (this.eat(tt.comma));
|
||||||
@ -2424,12 +2418,13 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
// https://tc39.es/ecma262/#prod-ImportSpecifier
|
// https://tc39.es/ecma262/#prod-ImportSpecifier
|
||||||
parseImportSpecifier(node: N.ImportDeclaration): void {
|
parseImportSpecifier(node: N.ImportDeclaration): void {
|
||||||
const specifier = this.startNode();
|
const specifier = this.startNode();
|
||||||
|
const importedIsString = this.match(tt.string);
|
||||||
specifier.imported = this.parseModuleExportName();
|
specifier.imported = this.parseModuleExportName();
|
||||||
if (this.eatContextual("as")) {
|
if (this.eatContextual("as")) {
|
||||||
specifier.local = this.parseIdentifier();
|
specifier.local = this.parseIdentifier();
|
||||||
} else {
|
} else {
|
||||||
const { imported } = specifier;
|
const { imported } = specifier;
|
||||||
if (imported.type === "StringLiteral") {
|
if (importedIsString) {
|
||||||
throw this.raise(
|
throw this.raise(
|
||||||
specifier.start,
|
specifier.start,
|
||||||
Errors.ImportBindingIsString,
|
Errors.ImportBindingIsString,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import { types as tt, TokenType } from "../tokenizer/types";
|
import { TokenType } from "../tokenizer/types";
|
||||||
import type Parser from "../parser";
|
import type Parser from "../parser";
|
||||||
import type { ExpressionErrors } from "../parser/util";
|
import type { ExpressionErrors } from "../parser/util";
|
||||||
import * as N from "../types";
|
import * as N from "../types";
|
||||||
@ -9,7 +9,7 @@ import { Errors } from "../parser/error";
|
|||||||
|
|
||||||
export default (superClass: Class<Parser>): Class<Parser> =>
|
export default (superClass: Class<Parser>): Class<Parser> =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
estreeParseRegExpLiteral({ pattern, flags }: N.RegExpLiteral): N.Node {
|
parseRegExpLiteral({ pattern, flags }): N.Node {
|
||||||
let regex = null;
|
let regex = null;
|
||||||
try {
|
try {
|
||||||
regex = new RegExp(pattern, flags);
|
regex = new RegExp(pattern, flags);
|
||||||
@ -17,13 +17,13 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
// In environments that don't support these flags value will
|
// In environments that don't support these flags value will
|
||||||
// be null as the regex can't be represented natively.
|
// be null as the regex can't be represented natively.
|
||||||
}
|
}
|
||||||
const node = this.estreeParseLiteral(regex);
|
const node = this.estreeParseLiteral<N.EstreeRegExpLiteral>(regex);
|
||||||
node.regex = { pattern, flags };
|
node.regex = { pattern, flags };
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
estreeParseBigIntLiteral(value: any): N.Node {
|
parseBigIntLiteral(value: any): N.Node {
|
||||||
// https://github.com/estree/estree/blob/master/es2020.md#bigintliteral
|
// https://github.com/estree/estree/blob/master/es2020.md#bigintliteral
|
||||||
let bigInt;
|
let bigInt;
|
||||||
try {
|
try {
|
||||||
@ -32,13 +32,13 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
} catch {
|
} catch {
|
||||||
bigInt = null;
|
bigInt = null;
|
||||||
}
|
}
|
||||||
const node = this.estreeParseLiteral(bigInt);
|
const node = this.estreeParseLiteral<N.EstreeBigIntLiteral>(bigInt);
|
||||||
node.bigint = String(node.value || value);
|
node.bigint = String(node.value || value);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
estreeParseDecimalLiteral(value: any): N.Node {
|
parseDecimalLiteral(value: any): N.Node {
|
||||||
// https://github.com/estree/estree/blob/master/experimental/decimal.md
|
// https://github.com/estree/estree/blob/master/experimental/decimal.md
|
||||||
// todo: use BigDecimal when node supports it.
|
// todo: use BigDecimal when node supports it.
|
||||||
const decimal = null;
|
const decimal = null;
|
||||||
@ -48,8 +48,24 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
estreeParseLiteral(value: any): N.Node {
|
estreeParseLiteral<T: N.Node>(value: any) {
|
||||||
return this.parseLiteral(value, "Literal");
|
return this.parseLiteral<T>(value, "Literal");
|
||||||
|
}
|
||||||
|
|
||||||
|
parseStringLiteral(value: any): N.Node {
|
||||||
|
return this.estreeParseLiteral(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseNumericLiteral(value: any): any {
|
||||||
|
return this.estreeParseLiteral(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseNullLiteral(): N.Node {
|
||||||
|
return this.estreeParseLiteral(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseBooleanLiteral(value: boolean): N.BooleanLiteral {
|
||||||
|
return this.estreeParseLiteral(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
directiveToStmt(directive: N.Directive): N.ExpressionStatement {
|
directiveToStmt(directive: N.Directive): N.ExpressionStatement {
|
||||||
@ -165,35 +181,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
classBody.body.push(method);
|
classBody.body.push(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseExprAtom(refExpressionErrors?: ?ExpressionErrors): N.Expression {
|
|
||||||
switch (this.state.type) {
|
|
||||||
case tt.num:
|
|
||||||
case tt.string:
|
|
||||||
return this.estreeParseLiteral(this.state.value);
|
|
||||||
|
|
||||||
case tt.regexp:
|
|
||||||
return this.estreeParseRegExpLiteral(this.state.value);
|
|
||||||
|
|
||||||
case tt.bigint:
|
|
||||||
return this.estreeParseBigIntLiteral(this.state.value);
|
|
||||||
|
|
||||||
case tt.decimal:
|
|
||||||
return this.estreeParseDecimalLiteral(this.state.value);
|
|
||||||
|
|
||||||
case tt._null:
|
|
||||||
return this.estreeParseLiteral(null);
|
|
||||||
|
|
||||||
case tt._true:
|
|
||||||
return this.estreeParseLiteral(true);
|
|
||||||
|
|
||||||
case tt._false:
|
|
||||||
return this.estreeParseLiteral(false);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return super.parseExprAtom(refExpressionErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseMaybePrivateName(...args: [boolean]): any {
|
parseMaybePrivateName(...args: [boolean]): any {
|
||||||
const node = super.parseMaybePrivateName(...args);
|
const node = super.parseMaybePrivateName(...args);
|
||||||
if (
|
if (
|
||||||
@ -230,13 +217,8 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
return node.name;
|
return node.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseLiteral<T: N.Literal>(
|
parseLiteral<T: N.Node>(value: any, type: $ElementType<T, "type">): T {
|
||||||
value: any,
|
const node = super.parseLiteral<T>(value, type);
|
||||||
type: /*T["kind"]*/ string,
|
|
||||||
startPos?: number,
|
|
||||||
startLoc?: Position,
|
|
||||||
): T {
|
|
||||||
const node = super.parseLiteral(value, type, startPos, startLoc);
|
|
||||||
node.raw = node.extra.raw;
|
node.raw = node.extra.raw;
|
||||||
delete node.extra;
|
delete node.extra;
|
||||||
|
|
||||||
|
|||||||
@ -1536,7 +1536,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
return this.finishNode(node, "FunctionTypeAnnotation");
|
return this.finishNode(node, "FunctionTypeAnnotation");
|
||||||
|
|
||||||
case tt.string:
|
case tt.string:
|
||||||
return this.parseLiteral(
|
return this.parseLiteral<N.StringLiteralTypeAnnotation>(
|
||||||
this.state.value,
|
this.state.value,
|
||||||
"StringLiteralTypeAnnotation",
|
"StringLiteralTypeAnnotation",
|
||||||
);
|
);
|
||||||
@ -1545,26 +1545,27 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
case tt._false:
|
case tt._false:
|
||||||
node.value = this.match(tt._true);
|
node.value = this.match(tt._true);
|
||||||
this.next();
|
this.next();
|
||||||
return this.finishNode(node, "BooleanLiteralTypeAnnotation");
|
return this.finishNode<N.BooleanLiteralTypeAnnotation>(
|
||||||
|
node,
|
||||||
|
"BooleanLiteralTypeAnnotation",
|
||||||
|
);
|
||||||
|
|
||||||
case tt.plusMin:
|
case tt.plusMin:
|
||||||
if (this.state.value === "-") {
|
if (this.state.value === "-") {
|
||||||
this.next();
|
this.next();
|
||||||
if (this.match(tt.num)) {
|
if (this.match(tt.num)) {
|
||||||
return this.parseLiteral(
|
return this.parseLiteralAtNode<N.NumberLiteralTypeAnnotation>(
|
||||||
-this.state.value,
|
-this.state.value,
|
||||||
"NumberLiteralTypeAnnotation",
|
"NumberLiteralTypeAnnotation",
|
||||||
node.start,
|
node,
|
||||||
node.loc.start,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.match(tt.bigint)) {
|
if (this.match(tt.bigint)) {
|
||||||
return this.parseLiteral(
|
return this.parseLiteralAtNode<N.BigIntLiteralTypeAnnotation>(
|
||||||
-this.state.value,
|
-this.state.value,
|
||||||
"BigIntLiteralTypeAnnotation",
|
"BigIntLiteralTypeAnnotation",
|
||||||
node.start,
|
node,
|
||||||
node.loc.start,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2669,7 +2670,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
// parse import-type/typeof shorthand
|
// parse import-type/typeof shorthand
|
||||||
parseImportSpecifier(node: N.ImportDeclaration): void {
|
parseImportSpecifier(node: N.ImportDeclaration): void {
|
||||||
const specifier = this.startNode();
|
const specifier = this.startNode();
|
||||||
const firstIdentLoc = this.state.start;
|
const firstIdentIsString = this.match(tt.string);
|
||||||
const firstIdent = this.parseModuleExportName();
|
const firstIdent = this.parseModuleExportName();
|
||||||
|
|
||||||
let specifierTypeKind = null;
|
let specifierTypeKind = null;
|
||||||
@ -2713,13 +2714,15 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
specifier.local = specifier.imported.__clone();
|
specifier.local = specifier.imported.__clone();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (firstIdent.type === "StringLiteral") {
|
if (firstIdentIsString) {
|
||||||
|
/*:: invariant(firstIdent instanceof N.StringLiteral) */
|
||||||
throw this.raise(
|
throw this.raise(
|
||||||
specifier.start,
|
specifier.start,
|
||||||
Errors.ImportBindingIsString,
|
Errors.ImportBindingIsString,
|
||||||
firstIdent.value,
|
firstIdent.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
/*:: invariant(firstIdent instanceof N.Node) */
|
||||||
isBinding = true;
|
isBinding = true;
|
||||||
specifier.imported = firstIdent;
|
specifier.imported = firstIdent;
|
||||||
specifier.importKind = null;
|
specifier.importKind = null;
|
||||||
@ -2731,7 +2734,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
|
|
||||||
if (nodeIsTypeImport && specifierIsTypeImport) {
|
if (nodeIsTypeImport && specifierIsTypeImport) {
|
||||||
this.raise(
|
this.raise(
|
||||||
firstIdentLoc,
|
specifier.start,
|
||||||
FlowErrors.ImportTypeShorthandOnlyInPureImport,
|
FlowErrors.ImportTypeShorthandOnlyInPureImport,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -3388,14 +3391,14 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
const endOfInit = () => this.match(tt.comma) || this.match(tt.braceR);
|
const endOfInit = () => this.match(tt.comma) || this.match(tt.braceR);
|
||||||
switch (this.state.type) {
|
switch (this.state.type) {
|
||||||
case tt.num: {
|
case tt.num: {
|
||||||
const literal = this.parseLiteral(this.state.value, "NumericLiteral");
|
const literal = this.parseNumericLiteral(this.state.value);
|
||||||
if (endOfInit()) {
|
if (endOfInit()) {
|
||||||
return { type: "number", pos: literal.start, value: literal };
|
return { type: "number", pos: literal.start, value: literal };
|
||||||
}
|
}
|
||||||
return { type: "invalid", pos: startPos };
|
return { type: "invalid", pos: startPos };
|
||||||
}
|
}
|
||||||
case tt.string: {
|
case tt.string: {
|
||||||
const literal = this.parseLiteral(this.state.value, "StringLiteral");
|
const literal = this.parseStringLiteral(this.state.value);
|
||||||
if (endOfInit()) {
|
if (endOfInit()) {
|
||||||
return { type: "string", pos: literal.start, value: literal };
|
return { type: "string", pos: literal.start, value: literal };
|
||||||
}
|
}
|
||||||
@ -3403,7 +3406,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
}
|
}
|
||||||
case tt._true:
|
case tt._true:
|
||||||
case tt._false: {
|
case tt._false: {
|
||||||
const literal = this.parseBooleanLiteral();
|
const literal = this.parseBooleanLiteral(this.match(tt._true));
|
||||||
if (endOfInit()) {
|
if (endOfInit()) {
|
||||||
return {
|
return {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
|
|||||||
@ -98,7 +98,8 @@ export type Literal =
|
|||||||
| StringLiteral
|
| StringLiteral
|
||||||
| BooleanLiteral
|
| BooleanLiteral
|
||||||
| NumericLiteral
|
| NumericLiteral
|
||||||
| BigIntLiteral;
|
| BigIntLiteral
|
||||||
|
| DecimalLiteral;
|
||||||
|
|
||||||
export type RegExpLiteral = NodeBase & {
|
export type RegExpLiteral = NodeBase & {
|
||||||
type: "RegExpLiteral",
|
type: "RegExpLiteral",
|
||||||
@ -130,6 +131,11 @@ export type BigIntLiteral = NodeBase & {
|
|||||||
value: number,
|
value: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DecimalLiteral = NodeBase & {
|
||||||
|
type: "DecimalLiteral",
|
||||||
|
value: number,
|
||||||
|
};
|
||||||
|
|
||||||
export type ParserOutput = {
|
export type ParserOutput = {
|
||||||
comments: $ReadOnlyArray<Comment>,
|
comments: $ReadOnlyArray<Comment>,
|
||||||
errors: Array<ParsingError>,
|
errors: Array<ParsingError>,
|
||||||
@ -1066,7 +1072,44 @@ export type FlowOptionalIndexedAccessType = Node & {
|
|||||||
optional: boolean,
|
optional: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type StringLiteralTypeAnnotation = NodeBase & {
|
||||||
|
type: "StringLiteralTypeAnnotation",
|
||||||
|
value: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BooleanLiteralTypeAnnotation = NodeBase & {
|
||||||
|
type: "BooleanLiteralTypeAnnotation",
|
||||||
|
value: boolean,
|
||||||
|
};
|
||||||
|
export type NumberLiteralTypeAnnotation = NodeBase & {
|
||||||
|
type: "NumberLiteralTypeAnnotation",
|
||||||
|
value: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BigIntLiteralTypeAnnotation = NodeBase & {
|
||||||
|
type: "BigIntLiteralTypeAnnotation",
|
||||||
|
//todo(flow): use bigint when Flow supports BigInt
|
||||||
|
value: number,
|
||||||
|
};
|
||||||
|
|
||||||
// ESTree
|
// ESTree
|
||||||
|
export type EstreeLiteral = NodeBase & {
|
||||||
|
type: "Literal",
|
||||||
|
value: any,
|
||||||
|
};
|
||||||
|
|
||||||
|
type EstreeRegExpLiteralRegex = {
|
||||||
|
pattern: string,
|
||||||
|
flags: string,
|
||||||
|
};
|
||||||
|
export type EstreeRegExpLiteral = EstreeLiteral & {
|
||||||
|
regex: EstreeRegExpLiteralRegex,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EstreeBigIntLiteral = EstreeLiteral & {
|
||||||
|
value: number | null,
|
||||||
|
bigint: string,
|
||||||
|
};
|
||||||
|
|
||||||
export type EstreeProperty = NodeBase & {
|
export type EstreeProperty = NodeBase & {
|
||||||
type: "Property",
|
type: "Property",
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
import foo from "foo.json" assert { type: "json" };
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["flow", "jsx", "estree", "importAssertions"],
|
||||||
|
"sourceType": "module"
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"type": "File",
|
||||||
|
"start":0,"end":51,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":51}},
|
||||||
|
"program": {
|
||||||
|
"type": "Program",
|
||||||
|
"start":0,"end":51,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":51}},
|
||||||
|
"sourceType": "module",
|
||||||
|
"interpreter": null,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "ImportDeclaration",
|
||||||
|
"start":0,"end":51,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":51}},
|
||||||
|
"specifiers": [
|
||||||
|
{
|
||||||
|
"type": "ImportDefaultSpecifier",
|
||||||
|
"start":7,"end":10,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":10}},
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":7,"end":10,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":10},"identifierName":"foo"},
|
||||||
|
"name": "foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"importKind": "value",
|
||||||
|
"source": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start":16,"end":26,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":26}},
|
||||||
|
"value": "foo.json",
|
||||||
|
"raw": "\"foo.json\""
|
||||||
|
},
|
||||||
|
"assertions": [
|
||||||
|
{
|
||||||
|
"type": "ImportAttribute",
|
||||||
|
"start":36,"end":48,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":48}},
|
||||||
|
"key": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":36,"end":40,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":40},"identifierName":"type"},
|
||||||
|
"name": "type"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start":42,"end":48,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":48}},
|
||||||
|
"value": "json",
|
||||||
|
"raw": "\"json\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
2
packages/babel-parser/test/fixtures/estree/module-string-names/mixed/input.js
vendored
Normal file
2
packages/babel-parser/test/fixtures/estree/module-string-names/mixed/input.js
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import { "foo" as bar, "default" as qux } from "module-a";
|
||||||
|
export * as "foo", { default as "quux" } from "module-b";
|
||||||
3
packages/babel-parser/test/fixtures/estree/module-string-names/mixed/options.json
vendored
Normal file
3
packages/babel-parser/test/fixtures/estree/module-string-names/mixed/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"sourceType": "module"
|
||||||
|
}
|
||||||
96
packages/babel-parser/test/fixtures/estree/module-string-names/mixed/output.json
vendored
Normal file
96
packages/babel-parser/test/fixtures/estree/module-string-names/mixed/output.json
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
{
|
||||||
|
"type": "File",
|
||||||
|
"start":0,"end":116,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":57}},
|
||||||
|
"program": {
|
||||||
|
"type": "Program",
|
||||||
|
"start":0,"end":116,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":57}},
|
||||||
|
"sourceType": "module",
|
||||||
|
"interpreter": null,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "ImportDeclaration",
|
||||||
|
"start":0,"end":58,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":58}},
|
||||||
|
"specifiers": [
|
||||||
|
{
|
||||||
|
"type": "ImportSpecifier",
|
||||||
|
"start":9,"end":21,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":21}},
|
||||||
|
"imported": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start":9,"end":14,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":14}},
|
||||||
|
"value": "foo",
|
||||||
|
"raw": "\"foo\""
|
||||||
|
},
|
||||||
|
"importKind": null,
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":18,"end":21,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":21},"identifierName":"bar"},
|
||||||
|
"name": "bar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ImportSpecifier",
|
||||||
|
"start":23,"end":39,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":39}},
|
||||||
|
"imported": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start":23,"end":32,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":32}},
|
||||||
|
"value": "default",
|
||||||
|
"raw": "\"default\""
|
||||||
|
},
|
||||||
|
"importKind": null,
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":36,"end":39,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":39},"identifierName":"qux"},
|
||||||
|
"name": "qux"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"importKind": "value",
|
||||||
|
"source": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start":47,"end":57,"loc":{"start":{"line":1,"column":47},"end":{"line":1,"column":57}},
|
||||||
|
"value": "module-a",
|
||||||
|
"raw": "\"module-a\""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ExportNamedDeclaration",
|
||||||
|
"start":59,"end":116,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":57}},
|
||||||
|
"specifiers": [
|
||||||
|
{
|
||||||
|
"type": "ExportNamespaceSpecifier",
|
||||||
|
"start":66,"end":76,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":17}},
|
||||||
|
"exported": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start":71,"end":76,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":17}},
|
||||||
|
"value": "foo",
|
||||||
|
"raw": "\"foo\""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ExportSpecifier",
|
||||||
|
"start":80,"end":97,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":38}},
|
||||||
|
"local": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start":80,"end":87,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":28},"identifierName":"default"},
|
||||||
|
"name": "default"
|
||||||
|
},
|
||||||
|
"exported": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start":91,"end":97,"loc":{"start":{"line":2,"column":32},"end":{"line":2,"column":38}},
|
||||||
|
"value": "quux",
|
||||||
|
"raw": "\"quux\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start":105,"end":115,"loc":{"start":{"line":2,"column":46},"end":{"line":2,"column":56}},
|
||||||
|
"value": "module-b",
|
||||||
|
"raw": "\"module-b\""
|
||||||
|
},
|
||||||
|
"declaration": null,
|
||||||
|
"exportKind": "value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user