js-ast: Add ExportExternalSpecifier node to distinguish export specifiers that are coming from another file
MODIFY
packages/@romejs/js-analysis/evaluators/index.ts
packages/@romejs/js-analysis/evaluators/index.ts
@@ -165,6 +165,9 @@ evaluators.set('ExportDefaultDeclaration', ExportDefaultDeclaration);
import ExportDefaultSpecifier from './modules/ExportDefaultSpecifier';
evaluators.set('ExportDefaultSpecifier', ExportDefaultSpecifier);
+import ExportExternalSpecifier from './modules/ExportExternalSpecifier';
+evaluators.set('ExportExternalSpecifier', ExportExternalSpecifier);
+
import ExportLocalSpecifier from './modules/ExportLocalSpecifier';
evaluators.set('ExportLocalSpecifier', ExportLocalSpecifier);

ADD
packages/@romejs/js-analysis/evaluators/modules/ExportExternalSpecifier.ts
+/**
+* Copyright (c) Facebook, Inc. and its affiliates.
+*
+* This source code is licensed under the MIT license found in the
+* LICENSE file in the root directory of this source tree.
+*/
+
+import {AnyNode, ExportExternalSpecifier, exportExternalSpecifier} from '@romejs/js-ast';
+
+export default function ExportExternalSpecifier(node: AnyNode) {
+ node = exportExternalSpecifier.assert(node);
+ throw new Error('unimplemented');
+}
+
\ No newline at end of file

MODIFY
packages/@romejs/js-analysis/evaluators/modules/ExportNamedDeclaration.ts
packages/@romejs/js-analysis/evaluators/modules/ExportNamedDeclaration.ts
@@ -67,7 +67,10 @@ export default function ExportNamedDeclaration(
const {specifiers} = node;
if (specifiers !== undefined) {
for (const specifier of specifiers) {
- if (specifier.type === 'ExportLocalSpecifier') {
+ if (
+ specifier.type === 'ExportLocalSpecifier' ||
+ specifier.type === 'ExportExternalSpecifier'
+ ) {
let type;
if (source === undefined) {
type = scope.evaluate(specifier.local);

MODIFY
packages/@romejs/js-ast/index.ts
packages/@romejs/js-ast/index.ts
@@ -63,6 +63,7 @@ export * from './statements/EmptyStatement';
export * from './modules/ExportAllDeclaration';
export * from './modules/ExportDefaultDeclaration';
export * from './modules/ExportDefaultSpecifier';
+export * from './modules/ExportExternalSpecifier';
export * from './modules/ExportLocalSpecifier';
export * from './modules/ExportNamedDeclaration';
export * from './modules/ExportNamespaceSpecifier';

ADD
packages/@romejs/js-ast/modules/ExportExternalSpecifier.ts
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import {JSNodeBase, Identifier, ConstExportModuleKind} from '../index';
+import {createBuilder} from '../utils';
+
+export type ExportExternalSpecifier = JSNodeBase & {
+ type: 'ExportExternalSpecifier';
+ exported: Identifier;
+ local: Identifier;
+ exportKind?: ConstExportModuleKind;
+};
+
+export const exportExternalSpecifier = createBuilder<ExportExternalSpecifier>(
+ 'ExportExternalSpecifier',
+ {
+ bindingKeys: {},
+ visitorKeys: {
+ exported: true,
+ local: true,
+ },
+ },
+);

MODIFY
packages/@romejs/js-ast/modules/ExportNamedDeclaration.ts
packages/@romejs/js-ast/modules/ExportNamedDeclaration.ts
@@ -22,13 +22,15 @@ import {
TSInterfaceDeclaration,
TSDeclareFunction,
FlowOpaqueType,
+ ExportExternalSpecifier,
} from '../index';
import {createBuilder} from '../utils';
export type AnyExportSpecifier =
| ExportLocalSpecifier
| ExportNamespaceSpecifier
- | ExportDefaultSpecifier;
+ | ExportDefaultSpecifier
+ | ExportExternalSpecifier;
export type ExportNamedDeclaration = JSNodeBase & {
type: 'ExportNamedDeclaration';

MODIFY
packages/@romejs/js-ast/unions.ts
packages/@romejs/js-ast/unions.ts
@@ -124,7 +124,7 @@ export type AnyAuxiliary =
| n.ClassPropertyMeta
| n.ComputedMemberProperty
| n.ComputedPropertyKey
- | n.ExportDefaultSpecifier
+ | n.AnyExportSpecifier
| n.FunctionHead
| n.PatternMeta
| n.PrivateName
@@ -402,6 +402,7 @@ export type AnyNode =
| n.ExportAllDeclaration
| n.ExportDefaultDeclaration
| n.ExportDefaultSpecifier
+ | n.ExportExternalSpecifier
| n.ExportLocalSpecifier
| n.ExportNamedDeclaration
| n.ExportNamespaceSpecifier

MODIFY
packages/@romejs/js-compiler/transforms/compileForBundle/legacy/esToCJSTransform.ts
packages/@romejs/js-compiler/transforms/compileForBundle/legacy/esToCJSTransform.ts
@@ -134,7 +134,10 @@ export default {
}
// TODO skip type exports
- if (specifier.type === 'ExportLocalSpecifier') {
+ if (
+ specifier.type === 'ExportLocalSpecifier' ||
+ specifier.type === 'ExportExternalSpecifier'
+ ) {
if (source === undefined) {
const binding = path.scope.getBinding(specifier.local.name);

MODIFY
packages/@romejs/js-generator/generators/index.ts
packages/@romejs/js-generator/generators/index.ts
@@ -159,6 +159,9 @@ generators.set('ExportDefaultDeclaration', ExportDefaultDeclaration);
import ExportDefaultSpecifier from './modules/ExportDefaultSpecifier';
generators.set('ExportDefaultSpecifier', ExportDefaultSpecifier);
+import ExportExternalSpecifier from './modules/ExportExternalSpecifier';
+generators.set('ExportExternalSpecifier', ExportExternalSpecifier);
+
import ExportLocalSpecifier from './modules/ExportLocalSpecifier';
generators.set('ExportLocalSpecifier', ExportLocalSpecifier);

ADD
packages/@romejs/js-generator/generators/modules/ExportExternalSpecifier.ts
+/**
+* Copyright (c) Facebook, Inc. and its affiliates.
+*
+* This source code is licensed under the MIT license found in the
+* LICENSE file in the root directory of this source tree.
+*/
+
+import Generator from '../../Generator';
+import {AnyNode, ExportExternalSpecifier, exportExternalSpecifier} from '@romejs/js-ast';
+
+export default function ExportExternalSpecifier(generator: Generator, node: AnyNode) {
+ node = exportExternalSpecifier.assert(node);
+ throw new Error('unimplemented');
+}

MODIFY
packages/@romejs/js-parser/parser/modules.ts
packages/@romejs/js-parser/parser/modules.ts
@@ -29,6 +29,7 @@ import {
ImportDefaultSpecifier,
ImportNamespaceSpecifier,
ImportSpecifierLocal,
+ ExportExternalSpecifier,
} from '@romejs/js-ast';
import {getBindingIdentifiers} from '@romejs/js-ast-utils';
import {
@@ -83,7 +84,9 @@ export function parseExport(
let exportKind: ConstExportModuleKind = 'value';
let source;
let declaration: undefined | AnyStatement;
- let specifiers: undefined | Array<ExportLocalSpecifier>;
+ let specifiers:
+ | undefined
+ | Array<ExportLocalSpecifier | ExportExternalSpecifier>;
// export * from '...'';
if (shouldParseExportStar(parser)) {
@@ -186,6 +189,10 @@ export function parseExport(
}
}
+ if (source !== undefined && specifiers !== undefined) {
+ specifiers = convertLocalToExternalSpecifiers(specifiers);
+ }
+
const node: ExportNamedDeclaration = {
loc: parser.finishLoc(start),
type: 'ExportNamedDeclaration',
@@ -197,6 +204,22 @@ export function parseExport(
return node;
}
+function convertLocalToExternalSpecifiers(
+ specifiers: Array<ExportExternalSpecifier | ExportLocalSpecifier>,
+): Array<ExportExternalSpecifier> {
+ return specifiers.map(specifier => {
+ if (specifier.type === 'ExportLocalSpecifier') {
+ return {
+ ...specifier,
+ type: 'ExportExternalSpecifier',
+ local: toIdentifier(specifier.local),
+ };
+ } else {
+ return specifier;
+ }
+ });
+}
+
function parseExportDefaultExpression(
parser: JSParser,
): ExportDefaultDeclaration['declaration'] {
@@ -473,7 +496,7 @@ function shouldParseExportDeclaration(parser: JSParser): boolean {
function checkExport(
parser: JSParser,
- specifiers: undefined | Array<ExportLocalSpecifier>,
+ specifiers: undefined | Array<ExportLocalSpecifier | ExportExternalSpecifier>,
declaration: undefined | AnyNode,
checkNames: boolean = false,
isDefault: boolean = false,

js-ast: Add ExportExternalSpecifier node to distinguish export specifiers that are coming from another file