Refactor import and export parsing (#9326)
* [parser] Refactor import parsing * [parser] Refactor export parsing * Fix types
This commit is contained in:
parent
f77c450cda
commit
65febdd13a
@ -1470,35 +1470,109 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
|
|
||||||
// Parses module export declaration.
|
// Parses module export declaration.
|
||||||
|
|
||||||
// TODO: better type. Node is an N.AnyExport.
|
parseExport(node: N.Node): N.AnyExport {
|
||||||
parseExport(node: N.Node): N.Node {
|
const hasDefault = this.maybeParseExportDefaultSpecifier(node);
|
||||||
// export * from '...'
|
const parseAfterDefault = !hasDefault || this.eat(tt.comma);
|
||||||
if (this.shouldParseExportStar()) {
|
const hasStar = parseAfterDefault && this.eatExportStar(node);
|
||||||
this.parseExportStar(node);
|
const hasNamespace =
|
||||||
if (node.type === "ExportAllDeclaration") return node;
|
hasStar && this.maybeParseExportNamespaceSpecifier(node);
|
||||||
} else if (this.isExportDefaultSpecifier()) {
|
const parseAfterNamespace =
|
||||||
this.expectPlugin("exportDefaultFrom");
|
parseAfterDefault && (!hasNamespace || this.eat(tt.comma));
|
||||||
const specifier = this.startNode();
|
const isFromRequired = hasDefault || hasStar;
|
||||||
specifier.exported = this.parseIdentifier(true);
|
|
||||||
const specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
|
if (hasStar && !hasNamespace) {
|
||||||
node.specifiers = specifiers;
|
if (hasDefault) this.unexpected();
|
||||||
if (this.match(tt.comma) && this.lookahead().type === tt.star) {
|
|
||||||
this.expect(tt.comma);
|
|
||||||
const specifier = this.startNode();
|
|
||||||
this.expect(tt.star);
|
|
||||||
this.expectContextual("as");
|
|
||||||
specifier.exported = this.parseIdentifier();
|
|
||||||
specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier"));
|
|
||||||
} else {
|
|
||||||
this.parseExportSpecifiersMaybe(node);
|
|
||||||
}
|
|
||||||
this.parseExportFrom(node, true);
|
this.parseExportFrom(node, true);
|
||||||
} else if (this.eat(tt._default)) {
|
|
||||||
|
return this.finishNode(node, "ExportAllDeclaration");
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasSpecifiers = this.maybeParseExportNamedSpecifiers(node);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(hasDefault && parseAfterDefault && !hasStar && !hasSpecifiers) ||
|
||||||
|
(hasNamespace && parseAfterNamespace && !hasSpecifiers)
|
||||||
|
) {
|
||||||
|
throw this.unexpected(null, tt.braceL);
|
||||||
|
}
|
||||||
|
|
||||||
|
let hasDeclaration;
|
||||||
|
if (isFromRequired || hasSpecifiers) {
|
||||||
|
hasDeclaration = false;
|
||||||
|
this.parseExportFrom(node, isFromRequired);
|
||||||
|
} else {
|
||||||
|
hasDeclaration = this.maybeParseExportDeclaration(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFromRequired || hasSpecifiers || hasDeclaration) {
|
||||||
|
this.checkExport(node, true);
|
||||||
|
return this.finishNode(node, "ExportNamedDeclaration");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.eat(tt._default)) {
|
||||||
// export default ...
|
// export default ...
|
||||||
node.declaration = this.parseExportDefaultExpression();
|
node.declaration = this.parseExportDefaultExpression();
|
||||||
this.checkExport(node, true, true);
|
this.checkExport(node, true, true);
|
||||||
|
|
||||||
return this.finishNode(node, "ExportDefaultDeclaration");
|
return this.finishNode(node, "ExportDefaultDeclaration");
|
||||||
} else if (this.shouldParseExportDeclaration()) {
|
}
|
||||||
|
|
||||||
|
throw this.unexpected(null, tt.braceL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
eatExportStar(node: N.Node): boolean {
|
||||||
|
return this.eat(tt.star);
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeParseExportDefaultSpecifier(node: N.Node): boolean {
|
||||||
|
if (this.isExportDefaultSpecifier()) {
|
||||||
|
// export defaultObj ...
|
||||||
|
this.expectPlugin("exportDefaultFrom");
|
||||||
|
const specifier = this.startNode();
|
||||||
|
specifier.exported = this.parseIdentifier(true);
|
||||||
|
node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeParseExportNamespaceSpecifier(node: N.Node): boolean {
|
||||||
|
if (this.isContextual("as")) {
|
||||||
|
if (!node.specifiers) node.specifiers = [];
|
||||||
|
this.expectPlugin("exportNamespaceFrom");
|
||||||
|
|
||||||
|
const specifier = this.startNodeAt(
|
||||||
|
this.state.lastTokStart,
|
||||||
|
this.state.lastTokStartLoc,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.next();
|
||||||
|
|
||||||
|
specifier.exported = this.parseIdentifier(true);
|
||||||
|
node.specifiers.push(
|
||||||
|
this.finishNode(specifier, "ExportNamespaceSpecifier"),
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeParseExportNamedSpecifiers(node: N.Node): boolean {
|
||||||
|
if (this.match(tt.braceL)) {
|
||||||
|
if (!node.specifiers) node.specifiers = [];
|
||||||
|
node.specifiers.push(...this.parseExportSpecifiers());
|
||||||
|
|
||||||
|
node.source = null;
|
||||||
|
node.declaration = null;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeParseExportDeclaration(node: N.Node): boolean {
|
||||||
|
if (this.shouldParseExportDeclaration()) {
|
||||||
if (this.isContextual("async")) {
|
if (this.isContextual("async")) {
|
||||||
const next = this.lookahead();
|
const next = this.lookahead();
|
||||||
|
|
||||||
@ -1511,14 +1585,10 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
node.specifiers = [];
|
node.specifiers = [];
|
||||||
node.source = null;
|
node.source = null;
|
||||||
node.declaration = this.parseExportDeclaration(node);
|
node.declaration = this.parseExportDeclaration(node);
|
||||||
} else {
|
|
||||||
// export { x, y as z } [from '...']
|
return true;
|
||||||
node.declaration = null;
|
|
||||||
node.specifiers = this.parseExportSpecifiers();
|
|
||||||
this.parseExportFrom(node);
|
|
||||||
}
|
}
|
||||||
this.checkExport(node, true);
|
return false;
|
||||||
return this.finishNode(node, "ExportNamedDeclaration");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isAsyncFunction() {
|
isAsyncFunction() {
|
||||||
@ -1605,17 +1675,9 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseExportSpecifiersMaybe(node: N.ExportNamedDeclaration): void {
|
|
||||||
if (this.eat(tt.comma)) {
|
|
||||||
node.specifiers = node.specifiers.concat(this.parseExportSpecifiers());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseExportFrom(node: N.ExportNamedDeclaration, expect?: boolean): void {
|
parseExportFrom(node: N.ExportNamedDeclaration, expect?: boolean): void {
|
||||||
if (this.eatContextual("from")) {
|
if (this.eatContextual("from")) {
|
||||||
node.source = this.match(tt.string)
|
node.source = this.parseImportSource();
|
||||||
? this.parseExprAtom()
|
|
||||||
: this.unexpected();
|
|
||||||
this.checkExport(node);
|
this.checkExport(node);
|
||||||
} else {
|
} else {
|
||||||
if (expect) {
|
if (expect) {
|
||||||
@ -1628,39 +1690,6 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
this.semicolon();
|
this.semicolon();
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldParseExportStar(): boolean {
|
|
||||||
return this.match(tt.star);
|
|
||||||
}
|
|
||||||
|
|
||||||
parseExportStar(node: N.ExportNamedDeclaration): void {
|
|
||||||
this.expect(tt.star);
|
|
||||||
|
|
||||||
if (this.isContextual("as")) {
|
|
||||||
this.parseExportNamespace(node);
|
|
||||||
} else {
|
|
||||||
this.parseExportFrom(node, true);
|
|
||||||
this.finishNode(node, "ExportAllDeclaration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseExportNamespace(node: N.ExportNamedDeclaration): void {
|
|
||||||
this.expectPlugin("exportNamespaceFrom");
|
|
||||||
|
|
||||||
const specifier = this.startNodeAt(
|
|
||||||
this.state.lastTokStart,
|
|
||||||
this.state.lastTokStartLoc,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.next();
|
|
||||||
|
|
||||||
specifier.exported = this.parseIdentifier(true);
|
|
||||||
|
|
||||||
node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")];
|
|
||||||
|
|
||||||
this.parseExportSpecifiersMaybe(node);
|
|
||||||
this.parseExportFrom(node, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldParseExportDeclaration(): boolean {
|
shouldParseExportDeclaration(): boolean {
|
||||||
if (this.match(tt.at)) {
|
if (this.match(tt.at)) {
|
||||||
this.expectOnePlugin(["decorators", "decorators-legacy"]);
|
this.expectOnePlugin(["decorators", "decorators-legacy"]);
|
||||||
@ -1760,27 +1789,24 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkDuplicateExports(
|
checkDuplicateExports(
|
||||||
node: N.Identifier | N.ExportNamedDeclaration | N.ExportSpecifier,
|
node:
|
||||||
|
| N.Identifier
|
||||||
|
| N.ExportNamedDeclaration
|
||||||
|
| N.ExportSpecifier
|
||||||
|
| N.ExportDefaultSpecifier,
|
||||||
name: string,
|
name: string,
|
||||||
): void {
|
): void {
|
||||||
if (this.state.exportedIdentifiers.indexOf(name) > -1) {
|
if (this.state.exportedIdentifiers.indexOf(name) > -1) {
|
||||||
this.raiseDuplicateExportError(node, name);
|
throw this.raise(
|
||||||
|
node.start,
|
||||||
|
name === "default"
|
||||||
|
? "Only one default export allowed per module."
|
||||||
|
: `\`${name}\` has already been exported. Exported identifiers must be unique.`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.state.exportedIdentifiers.push(name);
|
this.state.exportedIdentifiers.push(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
raiseDuplicateExportError(
|
|
||||||
node: N.Identifier | N.ExportNamedDeclaration | N.ExportSpecifier,
|
|
||||||
name: string,
|
|
||||||
): empty {
|
|
||||||
throw this.raise(
|
|
||||||
node.start,
|
|
||||||
name === "default"
|
|
||||||
? "Only one default export allowed per module."
|
|
||||||
: `\`${name}\` has already been exported. Exported identifiers must be unique.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses a comma-separated list of module exports.
|
// Parses a comma-separated list of module exports.
|
||||||
|
|
||||||
parseExportSpecifiers(): Array<N.ExportSpecifier> {
|
parseExportSpecifiers(): Array<N.ExportSpecifier> {
|
||||||
@ -1820,23 +1846,26 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
|
|
||||||
// Parses import declaration.
|
// Parses import declaration.
|
||||||
|
|
||||||
parseImport(node: N.Node): N.ImportDeclaration | N.TsImportEqualsDeclaration {
|
parseImport(node: N.Node): N.AnyImport {
|
||||||
// import '...'
|
// import '...'
|
||||||
if (this.match(tt.string)) {
|
node.specifiers = [];
|
||||||
node.specifiers = [];
|
if (!this.match(tt.string)) {
|
||||||
node.source = this.parseExprAtom();
|
const hasDefault = this.maybeParseDefaultImportSpecifier(node);
|
||||||
} else {
|
const parseNext = !hasDefault || this.eat(tt.comma);
|
||||||
node.specifiers = [];
|
const hasStar = parseNext && this.maybeParseStarImportSpecifier(node);
|
||||||
this.parseImportSpecifiers(node);
|
if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node);
|
||||||
this.expectContextual("from");
|
this.expectContextual("from");
|
||||||
node.source = this.match(tt.string)
|
|
||||||
? this.parseExprAtom()
|
|
||||||
: this.unexpected();
|
|
||||||
}
|
}
|
||||||
|
node.source = this.parseImportSource();
|
||||||
this.semicolon();
|
this.semicolon();
|
||||||
return this.finishNode(node, "ImportDeclaration");
|
return this.finishNode(node, "ImportDeclaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseImportSource(): N.StringLiteral {
|
||||||
|
if (!this.match(tt.string)) this.unexpected();
|
||||||
|
return this.parseExprAtom();
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
shouldParseDefaultImport(node: N.ImportDeclaration): boolean {
|
shouldParseDefaultImport(node: N.ImportDeclaration): boolean {
|
||||||
return this.match(tt.name);
|
return this.match(tt.name);
|
||||||
@ -1853,9 +1882,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
node.specifiers.push(this.finishNode(specifier, type));
|
node.specifiers.push(this.finishNode(specifier, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses a comma-separated list of module imports.
|
maybeParseDefaultImportSpecifier(node: N.ImportDeclaration): boolean {
|
||||||
parseImportSpecifiers(node: N.ImportDeclaration): void {
|
|
||||||
let first = true;
|
|
||||||
if (this.shouldParseDefaultImport(node)) {
|
if (this.shouldParseDefaultImport(node)) {
|
||||||
// import defaultObj, { x, y as z } from '...'
|
// import defaultObj, { x, y as z } from '...'
|
||||||
this.parseImportSpecifierLocal(
|
this.parseImportSpecifierLocal(
|
||||||
@ -1864,10 +1891,12 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
"ImportDefaultSpecifier",
|
"ImportDefaultSpecifier",
|
||||||
"default import specifier",
|
"default import specifier",
|
||||||
);
|
);
|
||||||
|
return true;
|
||||||
if (!this.eat(tt.comma)) return;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeParseStarImportSpecifier(node: N.ImportDeclaration): boolean {
|
||||||
if (this.match(tt.star)) {
|
if (this.match(tt.star)) {
|
||||||
const specifier = this.startNode();
|
const specifier = this.startNode();
|
||||||
this.next();
|
this.next();
|
||||||
@ -1879,10 +1908,13 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
"ImportNamespaceSpecifier",
|
"ImportNamespaceSpecifier",
|
||||||
"import namespace specifier",
|
"import namespace specifier",
|
||||||
);
|
);
|
||||||
|
return true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseNamedImportSpecifiers(node: N.ImportDeclaration) {
|
||||||
|
let first = true;
|
||||||
this.expect(tt.braceL);
|
this.expect(tt.braceL);
|
||||||
while (!this.eat(tt.braceR)) {
|
while (!this.eat(tt.braceR)) {
|
||||||
if (first) {
|
if (first) {
|
||||||
|
|||||||
@ -1847,17 +1847,15 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
super.assertModuleNodeAllowed(node);
|
super.assertModuleNodeAllowed(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseExport(
|
parseExport(node: N.Node): N.AnyExport {
|
||||||
node: N.ExportNamedDeclaration | N.ExportAllDeclaration,
|
const decl = super.parseExport(node);
|
||||||
): N.ExportNamedDeclaration | N.ExportAllDeclaration {
|
|
||||||
node = super.parseExport(node);
|
|
||||||
if (
|
if (
|
||||||
node.type === "ExportNamedDeclaration" ||
|
decl.type === "ExportNamedDeclaration" ||
|
||||||
node.type === "ExportAllDeclaration"
|
decl.type === "ExportAllDeclaration"
|
||||||
) {
|
) {
|
||||||
node.exportKind = node.exportKind || "value";
|
decl.exportKind = decl.exportKind || "value";
|
||||||
}
|
}
|
||||||
return node;
|
return decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration {
|
parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration {
|
||||||
@ -1893,27 +1891,26 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldParseExportStar(): boolean {
|
eatExportStar(node: N.Node): boolean {
|
||||||
return (
|
if (super.eatExportStar(...arguments)) return true;
|
||||||
super.shouldParseExportStar() ||
|
|
||||||
(this.isContextual("type") && this.lookahead().type === tt.star)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
parseExportStar(node: N.ExportNamedDeclaration): void {
|
if (this.isContextual("type") && this.lookahead().type === tt.star) {
|
||||||
if (this.eatContextual("type")) {
|
|
||||||
node.exportKind = "type";
|
node.exportKind = "type";
|
||||||
|
this.next();
|
||||||
|
this.next();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.parseExportStar(node);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseExportNamespace(node: N.ExportNamedDeclaration) {
|
maybeParseExportNamespaceSpecifier(node: N.Node): boolean {
|
||||||
if (node.exportKind === "type") {
|
const pos = this.state.start;
|
||||||
this.unexpected();
|
const hasNamespace = super.maybeParseExportNamespaceSpecifier(node);
|
||||||
|
if (hasNamespace && node.exportKind === "type") {
|
||||||
|
this.unexpected(pos);
|
||||||
}
|
}
|
||||||
|
return hasNamespace;
|
||||||
return super.parseExportNamespace(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseClassId(node: N.Class, isStatement: boolean, optionalId: ?boolean) {
|
parseClassId(node: N.Class, isStatement: boolean, optionalId: ?boolean) {
|
||||||
@ -2225,7 +2222,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse typeof and type imports
|
// parse typeof and type imports
|
||||||
parseImportSpecifiers(node: N.ImportDeclaration): void {
|
maybeParseDefaultImportSpecifier(node: N.ImportDeclaration): boolean {
|
||||||
node.importKind = "value";
|
node.importKind = "value";
|
||||||
|
|
||||||
let kind = null;
|
let kind = null;
|
||||||
@ -2252,7 +2249,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.parseImportSpecifiers(node);
|
return super.maybeParseDefaultImportSpecifier(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse import-type/typeof shorthand
|
// parse import-type/typeof shorthand
|
||||||
|
|||||||
@ -1615,16 +1615,14 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
*/
|
*/
|
||||||
checkDuplicateExports() {}
|
checkDuplicateExports() {}
|
||||||
|
|
||||||
parseImport(
|
parseImport(node: N.Node): N.AnyImport {
|
||||||
node: N.Node,
|
|
||||||
): N.ImportDeclaration | N.TsImportEqualsDeclaration {
|
|
||||||
if (this.match(tt.name) && this.lookahead().type === tt.eq) {
|
if (this.match(tt.name) && this.lookahead().type === tt.eq) {
|
||||||
return this.tsParseImportEqualsDeclaration(node);
|
return this.tsParseImportEqualsDeclaration(node);
|
||||||
}
|
}
|
||||||
return super.parseImport(node);
|
return super.parseImport(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseExport(node: N.Node): N.Node {
|
parseExport(node: N.Node): N.AnyExport {
|
||||||
if (this.match(tt._import)) {
|
if (this.match(tt._import)) {
|
||||||
// `export import A = B;`
|
// `export import A = B;`
|
||||||
this.expect(tt._import);
|
this.expect(tt._import);
|
||||||
|
|||||||
@ -783,7 +783,9 @@ export type AnyExport =
|
|||||||
| ExportNamedDeclaration
|
| ExportNamedDeclaration
|
||||||
| ExportDefaultDeclaration
|
| ExportDefaultDeclaration
|
||||||
| ExportAllDeclaration
|
| ExportAllDeclaration
|
||||||
| TsExportAssignment;
|
| TsExportAssignment
|
||||||
|
| TsImportEqualsDeclaration
|
||||||
|
| TsNamespaceExportDeclaration;
|
||||||
|
|
||||||
export type ModuleSpecifier = NodeBase & {
|
export type ModuleSpecifier = NodeBase & {
|
||||||
local: Identifier,
|
local: Identifier,
|
||||||
@ -820,7 +822,7 @@ export type ImportNamespaceSpecifier = ModuleSpecifier & {
|
|||||||
export type ExportNamedDeclaration = NodeBase & {
|
export type ExportNamedDeclaration = NodeBase & {
|
||||||
type: "ExportNamedDeclaration",
|
type: "ExportNamedDeclaration",
|
||||||
declaration: ?Declaration,
|
declaration: ?Declaration,
|
||||||
specifiers: $ReadOnlyArray<ExportSpecifier>,
|
specifiers: $ReadOnlyArray<ExportSpecifier | ExportDefaultSpecifier>,
|
||||||
source: ?Literal,
|
source: ?Literal,
|
||||||
|
|
||||||
exportKind?: "type" | "value", // TODO: Not in spec
|
exportKind?: "type" | "value", // TODO: Not in spec
|
||||||
@ -831,6 +833,11 @@ export type ExportSpecifier = NodeBase & {
|
|||||||
exported: Identifier,
|
exported: Identifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ExportDefaultSpecifier = NodeBase & {
|
||||||
|
type: "ExportDefaultSpecifier",
|
||||||
|
exported: Identifier,
|
||||||
|
};
|
||||||
|
|
||||||
export type ExportDefaultDeclaration = NodeBase & {
|
export type ExportDefaultDeclaration = NodeBase & {
|
||||||
type: "ExportDefaultDeclaration",
|
type: "ExportDefaultDeclaration",
|
||||||
declaration:
|
declaration:
|
||||||
|
|||||||
@ -145,7 +145,8 @@
|
|||||||
"raw": "\"bar\""
|
"raw": "\"bar\""
|
||||||
},
|
},
|
||||||
"value": "bar"
|
"value": "bar"
|
||||||
}
|
},
|
||||||
|
"declaration": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"directives": []
|
"directives": []
|
||||||
|
|||||||
@ -145,7 +145,8 @@
|
|||||||
"raw": "\"bar\""
|
"raw": "\"bar\""
|
||||||
},
|
},
|
||||||
"value": "bar"
|
"value": "bar"
|
||||||
}
|
},
|
||||||
|
"declaration": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"directives": []
|
"directives": []
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user