String import/export specifier (#12091)

* feat: parse moduleExportName
* feat: add validators
* Support string specifier name in commonjs transform
* Support string specifier name in export-ns-from
* test: add loose testcases
* test: add testcases for amd and umd
* feat: support systemjs
* test: update fixtures fixed in #12110
* add plugin name typings
* test: rename test layout
* feat: implement under moduleStringNames flag
* chore: add plugin syntax module string names
* feat: support ModuleExportName as ModuleExportName
* test: update test fixtures
* fix flow errors
* docs: update AST spec
* feat: support { "some imports" as "some exports" }
* feat: support { "some imports" as "some exports" } in systemjs
* test: add test on `import { "foo" }`
* Address review comments
* add moduleStringNames to missing plugin helpers
* Apply suggestions from code review
* update test fixtures
* Update packages/babel-parser/src/parser/error-message.js
* update test fixtures

Co-Authored-By: Kai Cataldo <kai@kaicataldo.com>
Co-authored-by: Brian Ng <bng412@gmail.com>
This commit is contained in:
Huáng Jùnliàng 2020-09-21 16:50:51 -04:00 committed by Nicolò Ribaudo
parent 1b90d90fcc
commit 21d7ee2610
152 changed files with 1872 additions and 96 deletions

View File

@ -135,6 +135,12 @@ const pluginNameMap = {
url: "https://git.io/JfK3k", url: "https://git.io/JfK3k",
}, },
}, },
moduleStringNames: {
syntax: {
name: "@babel/plugin-syntax-module-string-names",
url: "https://git.io/JTL8G",
},
},
numericSeparator: { numericSeparator: {
syntax: { syntax: {
name: "@babel/plugin-syntax-numeric-separator", name: "@babel/plugin-syntax-numeric-separator",

View File

@ -19,6 +19,7 @@
"@babel/helper-replace-supers": "workspace:^7.10.4", "@babel/helper-replace-supers": "workspace:^7.10.4",
"@babel/helper-simple-access": "workspace:^7.10.4", "@babel/helper-simple-access": "workspace:^7.10.4",
"@babel/helper-split-export-declaration": "workspace:^7.11.0", "@babel/helper-split-export-declaration": "workspace:^7.11.0",
"@babel/helper-validator-identifier": "workspace:^7.10.4",
"@babel/template": "workspace:^7.10.4", "@babel/template": "workspace:^7.10.4",
"@babel/types": "workspace:^7.11.0", "@babel/types": "workspace:^7.11.0",
"lodash": "^4.17.19" "lodash": "^4.17.19"

View File

@ -10,6 +10,8 @@ import rewriteLiveReferences from "./rewrite-live-references";
import normalizeAndLoadModuleMetadata, { import normalizeAndLoadModuleMetadata, {
hasExports, hasExports,
isSideEffectImport, isSideEffectImport,
type ModuleMetadata,
type SourceModuleMetadata,
} from "./normalize-and-load-metadata"; } from "./normalize-and-load-metadata";
export { default as getModuleName } from "./get-module-name"; export { default as getModuleName } from "./get-module-name";
@ -180,33 +182,58 @@ export function buildNamespaceInitStatements(
return statements; return statements;
} }
const getTemplateForReexport = loose => { const ReexportTemplate = {
return loose loose: template.statement`EXPORTS.EXPORT_NAME = NAMESPACE_IMPORT;`,
? template.statement`EXPORTS.EXPORT_NAME = NAMESPACE.IMPORT_NAME;` looseComputed: template.statement`EXPORTS["EXPORT_NAME"] = NAMESPACE_IMPORT;`,
: template` spec: template`
Object.defineProperty(EXPORTS, "EXPORT_NAME", { Object.defineProperty(EXPORTS, "EXPORT_NAME", {
enumerable: true, enumerable: true,
get: function() { get: function() {
return NAMESPACE.IMPORT_NAME; return NAMESPACE_IMPORT;
}, },
}); });
`; `,
}; };
const buildReexportsFromMeta = (meta, metadata, loose) => { const buildReexportsFromMeta = (
meta: ModuleMetadata,
metadata: SourceModuleMetadata,
loose,
) => {
const namespace = metadata.lazy const namespace = metadata.lazy
? t.callExpression(t.identifier(metadata.name), []) ? t.callExpression(t.identifier(metadata.name), [])
: t.identifier(metadata.name); : t.identifier(metadata.name);
const templateForCurrentMode = getTemplateForReexport(loose); const { stringSpecifiers } = meta;
return Array.from(metadata.reexports, ([exportName, importName]) => return Array.from(metadata.reexports, ([exportName, importName]) => {
templateForCurrentMode({ let NAMESPACE_IMPORT;
if (stringSpecifiers.has(importName)) {
NAMESPACE_IMPORT = t.memberExpression(
t.cloneNode(namespace),
t.stringLiteral(importName),
true,
);
} else {
NAMESPACE_IMPORT = NAMESPACE_IMPORT = t.memberExpression(
t.cloneNode(namespace),
t.identifier(importName),
);
}
const astNodes = {
EXPORTS: meta.exportName, EXPORTS: meta.exportName,
EXPORT_NAME: exportName, EXPORT_NAME: exportName,
NAMESPACE: t.cloneNode(namespace), NAMESPACE_IMPORT,
IMPORT_NAME: importName, };
}), if (loose) {
); if (stringSpecifiers.has(exportName)) {
return ReexportTemplate.looseComputed(astNodes);
} else {
return ReexportTemplate.loose(astNodes);
}
} else {
return ReexportTemplate.spec(astNodes);
}
});
}; };
/** /**
@ -363,16 +390,25 @@ function buildExportInitializationStatements(
* Given a set of export names, create a set of nested assignments to * Given a set of export names, create a set of nested assignments to
* initialize them all to a given expression. * initialize them all to a given expression.
*/ */
function buildInitStatement(metadata, exportNames, initExpr) { const InitTemplate = {
computed: template.expression`EXPORTS["NAME"] = VALUE`,
default: template.expression`EXPORTS.NAME = VALUE`,
};
function buildInitStatement(metadata: ModuleMetadata, exportNames, initExpr) {
const { stringSpecifiers, exportName: EXPORTS } = metadata;
return t.expressionStatement( return t.expressionStatement(
exportNames.reduce( exportNames.reduce((acc, exportName) => {
(acc, exportName) => const params = {
template.expression`EXPORTS.NAME = VALUE`({ EXPORTS,
EXPORTS: metadata.exportName, NAME: exportName,
NAME: exportName, VALUE: acc,
VALUE: acc, };
}), if (stringSpecifiers.has(exportName)) {
initExpr, return InitTemplate.computed(params);
), } else {
return InitTemplate.default(params);
}
}, initExpr),
); );
} }

View File

@ -1,5 +1,6 @@
import { basename, extname } from "path"; import { basename, extname } from "path";
import { isIdentifierName } from "@babel/helper-validator-identifier";
import splitExportDeclaration from "@babel/helper-split-export-declaration"; import splitExportDeclaration from "@babel/helper-split-export-declaration";
export type ModuleMetadata = { export type ModuleMetadata = {
@ -15,6 +16,12 @@ export type ModuleMetadata = {
// Lookup of source file to source file metadata. // Lookup of source file to source file metadata.
source: Map<string, SourceModuleMetadata>, source: Map<string, SourceModuleMetadata>,
// List of names that should only be printed as string literals.
// i.e. `import { "any unicode" as foo } from "some-module"`
// `stringSpecifiers` is Set(1) ["any unicode"]
// In most cases `stringSpecifiers` is an empty Set
stringSpecifiers: Set<string>,
}; };
export type InteropType = "default" | "namespace" | "none"; export type InteropType = "default" | "namespace" | "none";
@ -87,13 +94,18 @@ export default function normalizeModuleAndLoadMetadata(
if (!exportName) { if (!exportName) {
exportName = programPath.scope.generateUidIdentifier("exports").name; exportName = programPath.scope.generateUidIdentifier("exports").name;
} }
const stringSpecifiers = new Set();
nameAnonymousExports(programPath); nameAnonymousExports(programPath);
const { local, source, hasExports } = getModuleMetadata(programPath, { const { local, source, hasExports } = getModuleMetadata(
loose, programPath,
lazy, {
}); loose,
lazy,
},
stringSpecifiers,
);
removeModuleDeclarations(programPath); removeModuleDeclarations(programPath);
@ -124,17 +136,48 @@ export default function normalizeModuleAndLoadMetadata(
hasExports, hasExports,
local, local,
source, source,
stringSpecifiers,
}; };
} }
function getExportSpecifierName(
path: NodePath,
stringSpecifiers: Set<string>,
): string {
if (path.isIdentifier()) {
return path.node.name;
} else if (path.isStringLiteral()) {
const stringValue = path.node.value;
// add specifier value to `stringSpecifiers` only when it can not be converted to an identifier name
// i.e In `import { "foo" as bar }`
// we do not consider `"foo"` to be a `stringSpecifier` because we can treat it as
// `import { foo as bar }`
// This helps minimize the size of `stringSpecifiers` and reduce overhead of checking valid identifier names
// when building transpiled code from metadata
if (!isIdentifierName(stringValue)) {
stringSpecifiers.add(stringValue);
}
return stringValue;
} else {
throw new Error(
`Expected export specifier to be either Identifier or StringLiteral, got ${path.node.type}`,
);
}
}
/** /**
* Get metadata about the imports and exports present in this module. * Get metadata about the imports and exports present in this module.
*/ */
function getModuleMetadata( function getModuleMetadata(
programPath: NodePath, programPath: NodePath,
{ loose, lazy }: { loose: boolean, lazy: boolean }, { loose, lazy }: { loose: boolean, lazy: boolean },
stringSpecifiers: Set<string>,
) { ) {
const localData = getLocalExportMetadata(programPath, loose); const localData = getLocalExportMetadata(
programPath,
loose,
stringSpecifiers,
);
const sourceData = new Map(); const sourceData = new Map();
const getData = sourceNode => { const getData = sourceNode => {
@ -199,7 +242,10 @@ function getModuleMetadata(
}); });
} }
} else if (spec.isImportSpecifier()) { } else if (spec.isImportSpecifier()) {
const importName = spec.get("imported").node.name; const importName = getExportSpecifierName(
spec.get("imported"),
stringSpecifiers,
);
const localName = spec.get("local").node.name; const localName = spec.get("local").node.name;
data.imports.set(localName, importName); data.imports.set(localName, importName);
@ -231,8 +277,14 @@ function getModuleMetadata(
if (!spec.isExportSpecifier()) { if (!spec.isExportSpecifier()) {
throw spec.buildCodeFrameError("Unexpected export specifier type"); throw spec.buildCodeFrameError("Unexpected export specifier type");
} }
const importName = spec.get("local").node.name; const importName = getExportSpecifierName(
const exportName = spec.get("exported").node.name; spec.get("local"),
stringSpecifiers,
);
const exportName = getExportSpecifierName(
spec.get("exported"),
stringSpecifiers,
);
data.reexports.set(exportName, importName); data.reexports.set(exportName, importName);
@ -310,6 +362,7 @@ function getModuleMetadata(
function getLocalExportMetadata( function getLocalExportMetadata(
programPath: NodePath, programPath: NodePath,
loose: boolean, loose: boolean,
stringSpecifiers: Set<string>,
): Map<string, LocalExportMetadata> { ): Map<string, LocalExportMetadata> {
const bindingKindLookup = new Map(); const bindingKindLookup = new Map();
@ -392,11 +445,13 @@ function getLocalExportMetadata(
child.get("specifiers").forEach(spec => { child.get("specifiers").forEach(spec => {
const local = spec.get("local"); const local = spec.get("local");
const exported = spec.get("exported"); const exported = spec.get("exported");
const localMetadata = getLocalMetadata(local);
const exportName = getExportSpecifierName(exported, stringSpecifiers);
if (exported.node.name === "__esModule") { if (exportName === "__esModule") {
throw exported.buildCodeFrameError('Illegal export "__esModule".'); throw exported.buildCodeFrameError('Illegal export "__esModule".');
} }
getLocalMetadata(local).names.push(exported.node.name); localMetadata.names.push(exportName);
}); });
} }
} else if (child.isExportDefaultDeclaration()) { } else if (child.isExportDefaultDeclaration()) {

View File

@ -3,7 +3,7 @@ import * as t from "@babel/types";
import template from "@babel/template"; import template from "@babel/template";
import simplifyAccess from "@babel/helper-simple-access"; import simplifyAccess from "@babel/helper-simple-access";
import type { ModuleMetadata } from "./"; import type { ModuleMetadata } from "./normalize-and-load-metadata";
export default function rewriteLiveReferences( export default function rewriteLiveReferences(
programPath: NodePath, programPath: NodePath,
@ -71,7 +71,13 @@ export default function rewriteLiveReferences(
let namespace = t.identifier(meta.name); let namespace = t.identifier(meta.name);
if (meta.lazy) namespace = t.callExpression(namespace, []); if (meta.lazy) namespace = t.callExpression(namespace, []);
return t.memberExpression(namespace, t.identifier(importName)); const computed = metadata.stringSpecifiers.has(importName);
return t.memberExpression(
namespace,
computed ? t.stringLiteral(importName) : t.identifier(importName),
computed,
);
}, },
}); });
} }
@ -135,11 +141,14 @@ const buildBindingExportAssignmentExpression = (
// class Foo {} export { Foo, Foo as Bar }; // class Foo {} export { Foo, Foo as Bar };
// as // as
// class Foo {} exports.Foo = exports.Bar = Foo; // class Foo {} exports.Foo = exports.Bar = Foo;
const { stringSpecifiers } = metadata;
const computed = stringSpecifiers.has(exportName);
return t.assignmentExpression( return t.assignmentExpression(
"=", "=",
t.memberExpression( t.memberExpression(
t.identifier(metadata.exportName), t.identifier(metadata.exportName),
t.identifier(exportName), computed ? t.stringLiteral(exportName) : t.identifier(exportName),
/* computed */ computed,
), ),
expr, expr,
); );

View File

@ -1291,7 +1291,7 @@ interface ImportDeclaration <: ModuleDeclaration {
type: "ImportDeclaration"; type: "ImportDeclaration";
importKind: null | "type" | "typeof" | "value"; importKind: null | "type" | "typeof" | "value";
specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ]; specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ];
source: Literal; source: StringLiteral;
attributes?: [ ImportAttribute ]; attributes?: [ ImportAttribute ];
} }
``` ```
@ -1305,7 +1305,7 @@ An import declaration, e.g., `import foo from "mod";`.
```js ```js
interface ImportSpecifier <: ModuleSpecifier { interface ImportSpecifier <: ModuleSpecifier {
type: "ImportSpecifier"; type: "ImportSpecifier";
imported: Identifier; imported: Identifier | StringLiteral;
} }
``` ```
@ -1352,21 +1352,24 @@ interface ExportNamedDeclaration <: ModuleDeclaration {
type: "ExportNamedDeclaration"; type: "ExportNamedDeclaration";
declaration: Declaration | null; declaration: Declaration | null;
specifiers: [ ExportSpecifier ]; specifiers: [ ExportSpecifier ];
source: Literal | null; source: StringLiteral | null;
} }
``` ```
An export named declaration, e.g., `export {foo, bar};`, `export {foo} from "mod";`, `export var foo = 1;` or `export * as foo from "bar";`. An export named declaration, e.g., `export {foo, bar};`, `export {foo} from "mod";`, `export var foo = 1;` or `export * as foo from "bar";`.
_Note: Having `declaration` populated with non-empty `specifiers` or non-null `source` results in an invalid state._ Note:
- Having `declaration` populated with non-empty `specifiers` or non-null `source` results in an invalid state.
- If `source` is `null`, for each `specifier` of `specifiers`, `specifier.local` can not be a `StringLiteral`.
### ExportSpecifier ### ExportSpecifier
```js ```js
interface ExportSpecifier <: ModuleSpecifier { interface ExportSpecifier <: ModuleSpecifier {
type: "ExportSpecifier"; type: "ExportSpecifier";
exported: Identifier; exported: Identifier | StringLiteral;
local?: Identifier; local?: Identifier | StringLiteral;
} }
``` ```
@ -1396,7 +1399,7 @@ An export default declaration, e.g., `export default function () {};` or `export
```js ```js
interface ExportAllDeclaration <: ModuleDeclaration { interface ExportAllDeclaration <: ModuleDeclaration {
type: "ExportAllDeclaration"; type: "ExportAllDeclaration";
source: Literal; source: StringLiteral;
} }
``` ```

View File

@ -43,6 +43,8 @@ export const ErrorMessages = Object.freeze({
DuplicateRegExpFlags: "Duplicate regular expression flag", DuplicateRegExpFlags: "Duplicate regular expression flag",
ElementAfterRest: "Rest element must be last element", ElementAfterRest: "Rest element must be last element",
EscapedCharNotAnIdentifier: "Invalid Unicode escape", EscapedCharNotAnIdentifier: "Invalid Unicode escape",
ExportBindingIsString:
"A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { %0 as '%1' } from 'some-module'`?",
ExportDefaultFromAsIdentifier: ExportDefaultFromAsIdentifier:
"'from' is not allowed as an identifier after 'export default'", "'from' is not allowed as an identifier after 'export default'",
ForInOfLoopInitializer: ForInOfLoopInitializer:
@ -53,6 +55,8 @@ export const ErrorMessages = Object.freeze({
IllegalLanguageModeDirective: IllegalLanguageModeDirective:
"Illegal 'use strict' directive in function with non-simple parameter list", "Illegal 'use strict' directive in function with non-simple parameter list",
IllegalReturn: "'return' outside of function", IllegalReturn: "'return' outside of function",
ImportBindingIsString:
'A string literal cannot be used as an imported binding.\n- Did you mean `import { "%0" as foo }`?',
ImportCallArgumentTrailingComma: ImportCallArgumentTrailingComma:
"Trailing comma is disallowed inside import(...) arguments", "Trailing comma is disallowed inside import(...) arguments",
ImportCallArity: "import() requires exactly %0", ImportCallArity: "import() requires exactly %0",
@ -95,6 +99,8 @@ export const ErrorMessages = Object.freeze({
"Only string literals are allowed as module attribute values", "Only string literals are allowed as module attribute values",
ModuleAttributesWithDuplicateKeys: ModuleAttributesWithDuplicateKeys:
'Duplicate key "%0" is not allowed in module attributes', 'Duplicate key "%0" is not allowed in module attributes',
ModuleExportNameHasLoneSurrogate:
"An export name cannot include a lone surrogate, found '\\u%0'",
ModuleExportUndefined: "Export '%0' is not defined", ModuleExportUndefined: "Export '%0' is not defined",
MultipleDefaultsInSwitch: "Multiple default clauses", MultipleDefaultsInSwitch: "Multiple default clauses",
NewlineAfterThrow: "Illegal newline after throw", NewlineAfterThrow: "Illegal newline after throw",

View File

@ -39,6 +39,8 @@ const FUNC_NO_FLAGS = 0b000,
FUNC_HANGING_STATEMENT = 0b010, FUNC_HANGING_STATEMENT = 0b010,
FUNC_NULLABLE_ID = 0b100; FUNC_NULLABLE_ID = 0b100;
const loneSurrogate = /[\uD800-\uDFFF]/u;
export default class StatementParser extends ExpressionParser { export default class StatementParser extends ExpressionParser {
// ### Statement parsing // ### Statement parsing
@ -1745,7 +1747,7 @@ export default class StatementParser extends ExpressionParser {
this.next(); this.next();
specifier.exported = this.parseIdentifier(true); specifier.exported = this.parseModuleExportName();
node.specifiers.push( node.specifiers.push(
this.finishNode(specifier, "ExportNamespaceSpecifier"), this.finishNode(specifier, "ExportNamespaceSpecifier"),
); );
@ -1938,19 +1940,27 @@ export default class StatementParser extends ExpressionParser {
} else if (node.specifiers && node.specifiers.length) { } else if (node.specifiers && node.specifiers.length) {
// Named exports // Named exports
for (const specifier of node.specifiers) { for (const specifier of node.specifiers) {
this.checkDuplicateExports(specifier, specifier.exported.name); const { exported } = specifier;
const exportedName =
exported.type === "Identifier" ? exported.name : exported.value;
this.checkDuplicateExports(specifier, exportedName);
// $FlowIgnore // $FlowIgnore
if (!isFrom && specifier.local) { if (!isFrom && specifier.local) {
// check for keywords used as local names const { local } = specifier;
this.checkReservedWord( if (local.type === "StringLiteral") {
specifier.local.name, this.raise(
specifier.local.start, specifier.start,
true, Errors.ExportBindingIsString,
false, local.extra.raw,
); exportedName,
// check if export is defined );
// $FlowIgnore } else {
this.scope.checkLocalExport(specifier.local); // check for keywords used as local names
this.checkReservedWord(local.name, local.start, true, false);
// check if export is defined
// $FlowIgnore
this.scope.checkLocalExport(local);
}
} }
} }
} else if (node.declaration) { } else if (node.declaration) {
@ -2006,6 +2016,7 @@ export default class StatementParser extends ExpressionParser {
checkDuplicateExports( checkDuplicateExports(
node: node:
| N.Identifier | N.Identifier
| N.StringLiteral
| N.ExportNamedDeclaration | N.ExportNamedDeclaration
| N.ExportSpecifier | N.ExportSpecifier
| N.ExportDefaultSpecifier, | N.ExportDefaultSpecifier,
@ -2041,9 +2052,9 @@ export default class StatementParser extends ExpressionParser {
} }
const node = this.startNode(); const node = this.startNode();
node.local = this.parseIdentifier(true); node.local = this.parseModuleExportName();
node.exported = this.eatContextual("as") node.exported = this.eatContextual("as")
? this.parseIdentifier(true) ? this.parseModuleExportName()
: node.local.__clone(); : node.local.__clone();
nodes.push(this.finishNode(node, "ExportSpecifier")); nodes.push(this.finishNode(node, "ExportSpecifier"));
} }
@ -2051,6 +2062,27 @@ export default class StatementParser extends ExpressionParser {
return nodes; return nodes;
} }
// https://tc39.es/ecma262/#prod-ModuleExportName
parseModuleExportName(): N.StringLiteral | N.Identifier {
if (this.match(tt.string)) {
this.expectPlugin("moduleStringNames");
const result = this.parseLiteral<N.StringLiteral>(
this.state.value,
"StringLiteral",
);
const surrogate = result.value.match(loneSurrogate);
if (surrogate) {
this.raise(
result.start,
Errors.ModuleExportNameHasLoneSurrogate,
surrogate[0].charCodeAt(0).toString(16),
);
}
return result;
}
return this.parseIdentifier(true);
}
// Parses import declaration. // Parses import declaration.
// https://tc39.es/ecma262/#prod-ImportDeclaration // https://tc39.es/ecma262/#prod-ImportDeclaration
@ -2220,17 +2252,20 @@ 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();
specifier.imported = this.parseIdentifier(true); specifier.imported = this.parseModuleExportName();
if (this.eatContextual("as")) { if (this.eatContextual("as")) {
specifier.local = this.parseIdentifier(); specifier.local = this.parseIdentifier();
} else { } else {
this.checkReservedWord( const { imported } = specifier;
specifier.imported.name, if (imported.type === "StringLiteral") {
specifier.start, throw this.raise(
true, specifier.start,
true, Errors.ImportBindingIsString,
); imported.value,
specifier.local = specifier.imported.__clone(); );
}
this.checkReservedWord(imported.name, specifier.start, true, true);
specifier.local = imported.__clone();
} }
this.checkLVal( this.checkLVal(
specifier.local, specifier.local,

View File

@ -842,7 +842,7 @@ export type ImportDeclaration = NodeBase & {
export type ImportSpecifier = ModuleSpecifier & { export type ImportSpecifier = ModuleSpecifier & {
type: "ImportSpecifier", type: "ImportSpecifier",
imported: Identifier, imported: Identifier | StringLiteral,
}; };
export type ImportDefaultSpecifier = ModuleSpecifier & { export type ImportDefaultSpecifier = ModuleSpecifier & {
@ -866,7 +866,7 @@ export type ExportNamedDeclaration = NodeBase & {
export type ExportSpecifier = NodeBase & { export type ExportSpecifier = NodeBase & {
type: "ExportSpecifier", type: "ExportSpecifier",
exported: Identifier, exported: Identifier | StringLiteral,
local: Identifier, local: Identifier,
}; };

View File

@ -0,0 +1,2 @@
export { foo as "some exports" };
var foo;

View File

@ -0,0 +1,5 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'moduleStringNames' (1:16)",
"sourceType": "module",
"plugins": []
}

View File

@ -0,0 +1 @@
import { "foo" as bar, "default" as qux } from "module-a";

View File

@ -0,0 +1,5 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'moduleStringNames' (1:9)",
"sourceType": "module",
"plugins": []
}

View File

@ -0,0 +1 @@
import {"default" as quotation} from "Confucius";

View File

@ -0,0 +1,46 @@
{
"type": "File",
"start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}},
"program": {
"type": "Program",
"start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ImportDeclaration",
"start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}},
"specifiers": [
{
"type": "ImportSpecifier",
"start":8,"end":30,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":30}},
"imported": {
"type": "StringLiteral",
"start":8,"end":17,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":17}},
"extra": {
"rawValue": "default",
"raw": "\"default\""
},
"value": "default"
},
"local": {
"type": "Identifier",
"start":21,"end":30,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":30},"identifierName":"quotation"},
"name": "quotation"
}
}
],
"source": {
"type": "StringLiteral",
"start":37,"end":48,"loc":{"start":{"line":1,"column":37},"end":{"line":1,"column":48}},
"extra": {
"rawValue": "Confucius",
"raw": "\"Confucius\""
},
"value": "Confucius"
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,2 @@
const foo = 42, bar = 42;
export { foo, bar as "foo" }

View File

@ -0,0 +1,99 @@
{
"type": "File",
"start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":28}},
"errors": [
"SyntaxError: `foo` has already been exported. Exported identifiers must be unique. (2:14)"
],
"program": {
"type": "Program",
"start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":28}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start":0,"end":25,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}},
"declarations": [
{
"type": "VariableDeclarator",
"start":6,"end":14,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":14}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"foo"},
"name": "foo"
},
"init": {
"type": "NumericLiteral",
"start":12,"end":14,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":14}},
"extra": {
"rawValue": 42,
"raw": "42"
},
"value": 42
}
},
{
"type": "VariableDeclarator",
"start":16,"end":24,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":24}},
"id": {
"type": "Identifier",
"start":16,"end":19,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":19},"identifierName":"bar"},
"name": "bar"
},
"init": {
"type": "NumericLiteral",
"start":22,"end":24,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":24}},
"extra": {
"rawValue": 42,
"raw": "42"
},
"value": 42
}
}
],
"kind": "const"
},
{
"type": "ExportNamedDeclaration",
"start":26,"end":54,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":28}},
"specifiers": [
{
"type": "ExportSpecifier",
"start":35,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12}},
"local": {
"type": "Identifier",
"start":35,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"},
"name": "foo"
},
"exported": {
"type": "Identifier",
"start":35,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"},
"name": "foo"
}
},
{
"type": "ExportSpecifier",
"start":40,"end":52,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":26}},
"local": {
"type": "Identifier",
"start":40,"end":43,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":17},"identifierName":"bar"},
"name": "bar"
},
"exported": {
"type": "StringLiteral",
"start":47,"end":52,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":26}},
"extra": {
"rawValue": "foo",
"raw": "\"foo\""
},
"value": "foo"
}
}
],
"source": null,
"declaration": null
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
export { "學而時習之,不亦說乎?", "吾道一以貫之。" as "忠恕。" } from "Confucius";

View File

@ -0,0 +1,73 @@
{
"type": "File",
"start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":62}},
"program": {
"type": "Program",
"start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":62}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExportNamedDeclaration",
"start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":62}},
"specifiers": [
{
"type": "ExportSpecifier",
"start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}},
"local": {
"type": "StringLiteral",
"start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}},
"extra": {
"rawValue": "學而時習之,不亦說乎?",
"raw": "\"學而時習之,不亦說乎?\""
},
"value": "學而時習之,不亦說乎?"
},
"exported": {
"type": "StringLiteral",
"start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}},
"extra": {
"rawValue": "學而時習之,不亦說乎?",
"raw": "\"學而時習之,不亦說乎?\""
},
"value": "學而時習之,不亦說乎?"
}
},
{
"type": "ExportSpecifier",
"start":24,"end":42,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":42}},
"local": {
"type": "StringLiteral",
"start":24,"end":33,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":33}},
"extra": {
"rawValue": "吾道一以貫之。",
"raw": "\"吾道一以貫之。\""
},
"value": "吾道一以貫之。"
},
"exported": {
"type": "StringLiteral",
"start":37,"end":42,"loc":{"start":{"line":1,"column":37},"end":{"line":1,"column":42}},
"extra": {
"rawValue": "忠恕。",
"raw": "\"忠恕。\""
},
"value": "忠恕。"
}
}
],
"source": {
"type": "StringLiteral",
"start":50,"end":61,"loc":{"start":{"line":1,"column":50},"end":{"line":1,"column":61}},
"extra": {
"rawValue": "Confucius",
"raw": "\"Confucius\""
},
"value": "Confucius"
},
"declaration": null
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
const foo = 42, bar = 42;
export { foo as "\ud800\udbff" } // should throw
export { bar as "\udbff\udfff" } // should not throw

View File

@ -0,0 +1,144 @@
{
"type": "File",
"start":0,"end":127,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":52}},
"errors": [
"SyntaxError: An export name cannot include a lone surrogate, found '\\ud800' (2:16)"
],
"program": {
"type": "Program",
"start":0,"end":127,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":52}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start":0,"end":25,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}},
"declarations": [
{
"type": "VariableDeclarator",
"start":6,"end":14,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":14}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"foo"},
"name": "foo"
},
"init": {
"type": "NumericLiteral",
"start":12,"end":14,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":14}},
"extra": {
"rawValue": 42,
"raw": "42"
},
"value": 42
}
},
{
"type": "VariableDeclarator",
"start":16,"end":24,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":24}},
"id": {
"type": "Identifier",
"start":16,"end":19,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":19},"identifierName":"bar"},
"name": "bar"
},
"init": {
"type": "NumericLiteral",
"start":22,"end":24,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":24}},
"extra": {
"rawValue": 42,
"raw": "42"
},
"value": 42
}
}
],
"kind": "const"
},
{
"type": "ExportNamedDeclaration",
"start":26,"end":58,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":32}},
"trailingComments": [
{
"type": "CommentLine",
"value": " should throw",
"start":59,"end":74,"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":48}}
}
],
"specifiers": [
{
"type": "ExportSpecifier",
"start":35,"end":56,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":30}},
"local": {
"type": "Identifier",
"start":35,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"},
"name": "foo"
},
"exported": {
"type": "StringLiteral",
"start":42,"end":56,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":30}},
"extra": {
"rawValue": "\ud800\udbff",
"raw": "\"\\ud800\\udbff\""
},
"value": "\ud800\udbff"
}
}
],
"source": null,
"declaration": null
},
{
"type": "ExportNamedDeclaration",
"start":75,"end":107,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":32}},
"leadingComments": [
{
"type": "CommentLine",
"value": " should throw",
"start":59,"end":74,"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":48}}
}
],
"trailingComments": [
{
"type": "CommentLine",
"value": " should not throw",
"start":108,"end":127,"loc":{"start":{"line":3,"column":33},"end":{"line":3,"column":52}}
}
],
"specifiers": [
{
"type": "ExportSpecifier",
"start":84,"end":105,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":30}},
"local": {
"type": "Identifier",
"start":84,"end":87,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":12},"identifierName":"bar"},
"name": "bar"
},
"exported": {
"type": "StringLiteral",
"start":91,"end":105,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":30}},
"extra": {
"rawValue": "􏿿",
"raw": "\"\\udbff\\udfff\""
},
"value": "􏿿"
}
}
],
"source": null,
"declaration": null
}
],
"directives": []
},
"comments": [
{
"type": "CommentLine",
"value": " should throw",
"start":59,"end":74,"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":48}}
},
{
"type": "CommentLine",
"value": " should not throw",
"start":108,"end":127,"loc":{"start":{"line":3,"column":33},"end":{"line":3,"column":52}}
}
]
}

View File

@ -0,0 +1 @@
import { "foo" } from "foo";

View File

@ -0,0 +1,7 @@
{
"sourceType": "module",
"plugins": [
"moduleStringNames"
],
"throws": "A string literal cannot be used as an imported binding.\n- Did you mean `import { \"foo\" as foo }`? (1:9)"
}

View File

@ -0,0 +1,2 @@
import { "foo" as bar, "default" as qux } from "module-a";
export * as "foo", { default as "quux" } from "module-b";

View File

@ -0,0 +1,111 @@
{
"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": "StringLiteral",
"start":9,"end":14,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":14}},
"extra": {
"rawValue": "foo",
"raw": "\"foo\""
},
"value": "foo"
},
"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": "StringLiteral",
"start":23,"end":32,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":32}},
"extra": {
"rawValue": "default",
"raw": "\"default\""
},
"value": "default"
},
"local": {
"type": "Identifier",
"start":36,"end":39,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":39},"identifierName":"qux"},
"name": "qux"
}
}
],
"source": {
"type": "StringLiteral",
"start":47,"end":57,"loc":{"start":{"line":1,"column":47},"end":{"line":1,"column":57}},
"extra": {
"rawValue": "module-a",
"raw": "\"module-a\""
},
"value": "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": "StringLiteral",
"start":71,"end":76,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":17}},
"extra": {
"rawValue": "foo",
"raw": "\"foo\""
},
"value": "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": "StringLiteral",
"start":91,"end":97,"loc":{"start":{"line":2,"column":32},"end":{"line":2,"column":38}},
"extra": {
"rawValue": "quux",
"raw": "\"quux\""
},
"value": "quux"
}
}
],
"source": {
"type": "StringLiteral",
"start":105,"end":115,"loc":{"start":{"line":2,"column":46},"end":{"line":2,"column":56}},
"extra": {
"rawValue": "module-b",
"raw": "\"module-b\""
},
"value": "module-b"
},
"declaration": null
}
],
"directives": []
}
}

View File

@ -0,0 +1,2 @@
const quotation = "";
export { quotation as "學而時習之,不亦說乎?" };

View File

@ -0,0 +1,64 @@
{
"type": "File",
"start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":38}},
"program": {
"type": "Program",
"start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":38}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start":0,"end":21,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":21}},
"declarations": [
{
"type": "VariableDeclarator",
"start":6,"end":20,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":20}},
"id": {
"type": "Identifier",
"start":6,"end":15,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":15},"identifierName":"quotation"},
"name": "quotation"
},
"init": {
"type": "StringLiteral",
"start":18,"end":20,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":20}},
"extra": {
"rawValue": "",
"raw": "\"\""
},
"value": ""
}
}
],
"kind": "const"
},
{
"type": "ExportNamedDeclaration",
"start":22,"end":60,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":38}},
"specifiers": [
{
"type": "ExportSpecifier",
"start":31,"end":57,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":35}},
"local": {
"type": "Identifier",
"start":31,"end":40,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":18},"identifierName":"quotation"},
"name": "quotation"
},
"exported": {
"type": "StringLiteral",
"start":44,"end":57,"loc":{"start":{"line":2,"column":22},"end":{"line":2,"column":35}},
"extra": {
"rawValue": "學而時習之,不亦說乎?",
"raw": "\"學而時習之,不亦說乎?\""
},
"value": "學而時習之,不亦說乎?"
}
}
],
"source": null,
"declaration": null
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
import {"學而時習之,不亦說乎?" as quotation} from "Confucius";

View File

@ -0,0 +1,46 @@
{
"type": "File",
"start":0,"end":53,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":53}},
"program": {
"type": "Program",
"start":0,"end":53,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":53}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ImportDeclaration",
"start":0,"end":53,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":53}},
"specifiers": [
{
"type": "ImportSpecifier",
"start":8,"end":34,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":34}},
"imported": {
"type": "StringLiteral",
"start":8,"end":21,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":21}},
"extra": {
"rawValue": "學而時習之,不亦說乎?",
"raw": "\"學而時習之,不亦說乎?\""
},
"value": "學而時習之,不亦說乎?"
},
"local": {
"type": "Identifier",
"start":25,"end":34,"loc":{"start":{"line":1,"column":25},"end":{"line":1,"column":34},"identifierName":"quotation"},
"name": "quotation"
}
}
],
"source": {
"type": "StringLiteral",
"start":41,"end":52,"loc":{"start":{"line":1,"column":41},"end":{"line":1,"column":52}},
"extra": {
"rawValue": "Confucius",
"raw": "\"Confucius\""
},
"value": "Confucius"
}
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
export * as "忠恕。" from "Confucius";

View File

@ -0,0 +1,41 @@
{
"type": "File",
"start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},
"program": {
"type": "Program",
"start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExportNamedDeclaration",
"start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},
"specifiers": [
{
"type": "ExportNamespaceSpecifier",
"start":7,"end":17,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":17}},
"exported": {
"type": "StringLiteral",
"start":12,"end":17,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":17}},
"extra": {
"rawValue": "忠恕。",
"raw": "\"忠恕。\""
},
"value": "忠恕。"
}
}
],
"source": {
"type": "StringLiteral",
"start":23,"end":34,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":34}},
"extra": {
"rawValue": "Confucius",
"raw": "\"Confucius\""
},
"value": "Confucius"
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,4 @@
{
"sourceType": "module",
"plugins": ["moduleStringNames"]
}

View File

@ -0,0 +1 @@
export { "學而時習之,不亦說乎?", "吾道一以貫之。" as "忠恕。" };

View File

@ -0,0 +1,69 @@
{
"type": "File",
"start":0,"end":45,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":45}},
"errors": [
"SyntaxError: A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { \"學而時習之,不亦說乎?\" as '學而時習之,不亦說乎?' } from 'some-module'`? (1:9)",
"SyntaxError: A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { \"吾道一以貫之。\" as '忠恕。' } from 'some-module'`? (1:24)"
],
"program": {
"type": "Program",
"start":0,"end":45,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":45}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExportNamedDeclaration",
"start":0,"end":45,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":45}},
"specifiers": [
{
"type": "ExportSpecifier",
"start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}},
"local": {
"type": "StringLiteral",
"start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}},
"extra": {
"rawValue": "學而時習之,不亦說乎?",
"raw": "\"學而時習之,不亦說乎?\""
},
"value": "學而時習之,不亦說乎?"
},
"exported": {
"type": "StringLiteral",
"start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}},
"extra": {
"rawValue": "學而時習之,不亦說乎?",
"raw": "\"學而時習之,不亦說乎?\""
},
"value": "學而時習之,不亦說乎?"
}
},
{
"type": "ExportSpecifier",
"start":24,"end":42,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":42}},
"local": {
"type": "StringLiteral",
"start":24,"end":33,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":33}},
"extra": {
"rawValue": "吾道一以貫之。",
"raw": "\"吾道一以貫之。\""
},
"value": "吾道一以貫之。"
},
"exported": {
"type": "StringLiteral",
"start":37,"end":42,"loc":{"start":{"line":1,"column":37},"end":{"line":1,"column":42}},
"extra": {
"rawValue": "忠恕。",
"raw": "\"忠恕。\""
},
"value": "忠恕。"
}
}
],
"source": null,
"declaration": null
}
],
"directives": []
}
}

View File

@ -116,6 +116,7 @@ export type ParserPlugin =
'jsx' | 'jsx' |
'logicalAssignment' | 'logicalAssignment' |
'moduleAttributes' | 'moduleAttributes' |
'moduleStringNames' |
'nullishCoalescingOperator' | 'nullishCoalescingOperator' |
'numericSeparator' | 'numericSeparator' |
'objectRestSpread' | 'objectRestSpread' |

View File

@ -27,7 +27,9 @@ export default declare(api => {
const specifier = specifiers.shift(); const specifier = specifiers.shift();
const { exported } = specifier; const { exported } = specifier;
const uid = scope.generateUidIdentifier(exported.name); const uid = scope.generateUidIdentifier(
exported.name ?? exported.value,
);
nodes.push( nodes.push(
t.importDeclaration( t.importDeclaration(

View File

@ -0,0 +1 @@
export * as "some exports" from "foo";

View File

@ -0,0 +1,7 @@
{
"plugins": [
"external-helpers",
"proposal-export-namespace-from",
"syntax-module-string-names"
]
}

View File

@ -0,0 +1,2 @@
import * as _someExports from "foo";
export { _someExports as "some exports" };

View File

@ -0,0 +1,3 @@
*.log
src
test

View File

@ -0,0 +1,19 @@
# @babel/plugin-syntax-module-string-names
> Allow parsing `import { 'any unicode' as bar }` and `export { foo as 'any unicode' }`"
See our website [@babel/plugin-syntax-module-string-names](https://babeljs.io/docs/en/next/babel-plugin-syntax-module-string-names.html) for more information.
## Install
Using npm:
```sh
npm install --save-dev @babel/plugin-syntax-module-string-names
```
or using yarn:
```sh
yarn add @babel/plugin-syntax-module-string-names --dev
```

View File

@ -0,0 +1,28 @@
{
"name": "@babel/plugin-syntax-module-string-names",
"version": "0.0.0",
"description": "Allow parsing `import { 'any unicode' as bar }` and `export { foo as 'any unicode' }`",
"repository": {
"type": "git",
"url": "https://github.com/babel/babel.git",
"directory": "packages/babel-plugin-syntax-module-string-names"
},
"license": "MIT",
"publishConfig": {
"access": "public"
},
"main": "./lib/index.js",
"exports": "./lib/index.js",
"keywords": [
"babel-plugin"
],
"dependencies": {
"@babel/helper-plugin-utils": "workspace:^7.10.4"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
},
"devDependencies": {
"@babel/core": "workspace:^7.10.4"
}
}

View File

@ -0,0 +1,13 @@
import { declare } from "@babel/helper-plugin-utils";
export default declare(api => {
api.assertVersion(7);
return {
name: "syntax-module-string-names",
manipulateOptions(opts, parserOpts) {
parserOpts.plugins.push("moduleStringNames");
},
};
});

View File

@ -0,0 +1 @@
export { "some imports" as "some exports" } from "foo";

View File

@ -0,0 +1,7 @@
define(["exports", "foo"], function (_exports, _foo) {
"use strict";
_exports.__esModule = true;
_exports["some exports"] = void 0;
_exports["some exports"] = _foo["some imports"];
});

View File

@ -0,0 +1 @@
export { "some exports" } from "foo";

View File

@ -0,0 +1,7 @@
define(["exports", "foo"], function (_exports, _foo) {
"use strict";
_exports.__esModule = true;
_exports["some exports"] = void 0;
_exports["some exports"] = _foo["some exports"];
});

View File

@ -0,0 +1 @@
export { foo as "some exports" } from "foo";

View File

@ -0,0 +1,7 @@
define(["exports", "foo"], function (_exports, _foo) {
"use strict";
_exports.__esModule = true;
_exports["some exports"] = void 0;
_exports["some exports"] = _foo.foo;
});

View File

@ -0,0 +1,2 @@
var foo, bar;
export {foo as "defaultExports", bar};

View File

@ -0,0 +1,9 @@
define(["exports"], function (_exports) {
"use strict";
_exports.__esModule = true;
_exports.bar = _exports.defaultExports = void 0;
var foo, bar;
_exports.bar = bar;
_exports.defaultExports = foo;
});

View File

@ -0,0 +1,2 @@
var foo, bar;
export {foo as "default exports", bar};

View File

@ -0,0 +1,9 @@
define(["exports"], function (_exports) {
"use strict";
_exports.__esModule = true;
_exports.bar = _exports["default exports"] = void 0;
var foo, bar;
_exports.bar = bar;
_exports["default exports"] = foo;
});

View File

@ -0,0 +1,3 @@
import { "defaultImports" as bar} from "foo";
bar;

View File

@ -0,0 +1,5 @@
define(["foo"], function (_foo) {
"use strict";
_foo.defaultImports;
});

View File

@ -0,0 +1,3 @@
import {"default imports" as bar} from "foo";
bar;

View File

@ -0,0 +1,5 @@
define(["foo"], function (_foo) {
"use strict";
_foo["default imports"];
});

View File

@ -0,0 +1,7 @@
{
"plugins": [
"external-helpers",
["transform-modules-amd", { "loose": true }],
"syntax-module-string-names"
]
}

View File

@ -0,0 +1 @@
export { "some imports" as "some exports" } from "foo";

View File

@ -0,0 +1,13 @@
define(["exports", "foo"], function (_exports, _foo) {
"use strict";
Object.defineProperty(_exports, "__esModule", {
value: true
});
Object.defineProperty(_exports, "some exports", {
enumerable: true,
get: function () {
return _foo["some imports"];
}
});
});

View File

@ -0,0 +1 @@
export { "some exports" } from "foo";

View File

@ -0,0 +1,13 @@
define(["exports", "foo"], function (_exports, _foo) {
"use strict";
Object.defineProperty(_exports, "__esModule", {
value: true
});
Object.defineProperty(_exports, "some exports", {
enumerable: true,
get: function () {
return _foo["some exports"];
}
});
});

View File

@ -0,0 +1 @@
export { foo as "some exports" } from "foo";

View File

@ -0,0 +1,13 @@
define(["exports", "foo"], function (_exports, _foo) {
"use strict";
Object.defineProperty(_exports, "__esModule", {
value: true
});
Object.defineProperty(_exports, "some exports", {
enumerable: true,
get: function () {
return _foo.foo;
}
});
});

View File

@ -0,0 +1,2 @@
var foo, bar;
export {foo as "defaultExports", bar};

View File

@ -0,0 +1,11 @@
define(["exports"], function (_exports) {
"use strict";
Object.defineProperty(_exports, "__esModule", {
value: true
});
_exports.bar = _exports.defaultExports = void 0;
var foo, bar;
_exports.bar = bar;
_exports.defaultExports = foo;
});

View File

@ -0,0 +1,2 @@
var foo, bar;
export {foo as "default exports", bar};

View File

@ -0,0 +1,11 @@
define(["exports"], function (_exports) {
"use strict";
Object.defineProperty(_exports, "__esModule", {
value: true
});
_exports.bar = _exports["default exports"] = void 0;
var foo, bar;
_exports.bar = bar;
_exports["default exports"] = foo;
});

View File

@ -0,0 +1,3 @@
import { "defaultImports" as bar} from "foo";
bar;

View File

@ -0,0 +1,5 @@
define(["foo"], function (_foo) {
"use strict";
_foo.defaultImports;
});

View File

@ -0,0 +1,3 @@
import {"default imports" as bar} from "foo";
bar;

View File

@ -0,0 +1,5 @@
define(["foo"], function (_foo) {
"use strict";
_foo["default imports"];
});

View File

@ -0,0 +1,7 @@
{
"plugins": [
"external-helpers",
"transform-modules-amd",
"syntax-module-string-names"
]
}

View File

@ -0,0 +1 @@
export { "some imports" as "some exports" } from "foo";

View File

@ -0,0 +1,8 @@
"use strict";
exports.__esModule = true;
exports["some exports"] = void 0;
var _foo = require("foo");
exports["some exports"] = _foo["some imports"];

View File

@ -0,0 +1 @@
export { "some exports" } from "foo";

View File

@ -0,0 +1,8 @@
"use strict";
exports.__esModule = true;
exports["some exports"] = void 0;
var _foo = require("foo");
exports["some exports"] = _foo["some exports"];

View File

@ -0,0 +1 @@
export { foo as "some exports" } from "foo";

View File

@ -0,0 +1,8 @@
"use strict";
exports.__esModule = true;
exports["some exports"] = void 0;
var _foo = require("foo");
exports["some exports"] = _foo.foo;

View File

@ -0,0 +1,2 @@
var foo, bar;
export {foo as "defaultExports", bar};

View File

@ -0,0 +1,7 @@
"use strict";
exports.__esModule = true;
exports.bar = exports.defaultExports = void 0;
var foo, bar;
exports.bar = bar;
exports.defaultExports = foo;

View File

@ -0,0 +1,2 @@
var foo, bar;
export {foo as "default exports", bar};

View File

@ -0,0 +1,7 @@
"use strict";
exports.__esModule = true;
exports.bar = exports["default exports"] = void 0;
var foo, bar;
exports.bar = bar;
exports["default exports"] = foo;

View File

@ -0,0 +1,3 @@
import { "defaultImports" as bar} from "foo";
bar;

View File

@ -0,0 +1,5 @@
"use strict";
var _foo = require("foo");
_foo.defaultImports;

View File

@ -0,0 +1,3 @@
import {"default imports" as bar} from "foo";
bar;

View File

@ -0,0 +1,5 @@
"use strict";
var _foo = require("foo");
_foo["default imports"];

View File

@ -0,0 +1,7 @@
{
"plugins": [
"external-helpers",
["transform-modules-commonjs", { "loose": true }],
"syntax-module-string-names"
]
}

View File

@ -0,0 +1 @@
export { "some imports" as "some exports" } from "foo";

View File

@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "some exports", {
enumerable: true,
get: function () {
return _foo["some imports"];
}
});
var _foo = require("foo");

View File

@ -0,0 +1 @@
export { "some exports" } from "foo";

View File

@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "some exports", {
enumerable: true,
get: function () {
return _foo["some exports"];
}
});
var _foo = require("foo");

View File

@ -0,0 +1 @@
export { foo as "some exports" } from "foo";

View File

@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "some exports", {
enumerable: true,
get: function () {
return _foo.foo;
}
});
var _foo = require("foo");

View File

@ -0,0 +1,2 @@
var foo, bar;
export {foo as "defaultExports", bar};

View File

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.bar = exports.defaultExports = void 0;
var foo, bar;
exports.bar = bar;
exports.defaultExports = foo;

View File

@ -0,0 +1,2 @@
var foo, bar;
export {foo as "default exports", bar};

View File

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.bar = exports["default exports"] = void 0;
var foo, bar;
exports.bar = bar;
exports["default exports"] = foo;

View File

@ -0,0 +1,3 @@
import { "defaultImports" as bar} from "foo";
bar;

View File

@ -0,0 +1,5 @@
"use strict";
var _foo = require("foo");
_foo.defaultImports;

Some files were not shown because too many files have changed in this diff Show More