Skip to content

Commit

Permalink
refactor: remove ModuleDeclaration usage (#15236)
Browse files Browse the repository at this point in the history
* refactor: remove ModuleDeclaration usage

* fix: report module errors when program has expression statement
  • Loading branch information
JLHwung committed Dec 5, 2022
1 parent 3e8c8cc commit f543b61
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 25 deletions.
Expand Up @@ -142,7 +142,7 @@ export default function normalizeModuleAndLoadMetadata(
stringSpecifiers,
);

removeModuleDeclarations(programPath);
removeImportExportDeclarations(programPath);

// Reuse the imported namespace name if there is one.
for (const [, metadata] of source) {
Expand Down Expand Up @@ -558,7 +558,7 @@ function nameAnonymousExports(programPath: NodePath<t.Program>) {
});
}

function removeModuleDeclarations(programPath: NodePath<t.Program>) {
function removeImportExportDeclarations(programPath: NodePath<t.Program>) {
programPath.get("body").forEach(child => {
if (child.isImportDeclaration()) {
child.remove();
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-helpers/src/index.ts
Expand Up @@ -89,7 +89,7 @@ function getHelperMetadata(file: File): HelperMetadata {
throw child.buildCodeFrameError("Helpers can only export default");
},
Statement(child) {
if (child.isModuleDeclaration()) return;
if (child.isImportDeclaration() || child.isExportDeclaration()) return;

child.skip();
},
Expand Down
19 changes: 14 additions & 5 deletions packages/babel-node/src/_babel-node.ts
Expand Up @@ -106,10 +106,6 @@ register(babelOptions);

const replPlugin = ({ types: t }: PluginAPI): PluginObject => ({
visitor: {
ModuleDeclaration(path) {
throw path.buildCodeFrameError("Modules aren't supported in the REPL");
},

VariableDeclaration(path) {
if (path.node.kind !== "var") {
throw path.buildCodeFrameError(
Expand All @@ -119,7 +115,20 @@ const replPlugin = ({ types: t }: PluginAPI): PluginObject => ({
},

Program(path) {
if (path.get("body").some(child => child.isExpressionStatement())) return;
let hasExpressionStatement: boolean;
for (const bodyPath of path.get("body")) {
if (bodyPath.isExpressionStatement()) {
hasExpressionStatement = true;
} else if (
bodyPath.isExportDeclaration() ||
bodyPath.isImportDeclaration()
) {
throw bodyPath.buildCodeFrameError(
"Modules aren't supported in the REPL",
);
}
}
if (hasExpressionStatement) return;

// If the executed code doesn't evaluate to a value,
// prevent implicit strict mode from printing 'use strict'.
Expand Down
28 changes: 14 additions & 14 deletions packages/babel-parser/ast/spec.md
Expand Up @@ -108,7 +108,6 @@ These are the core @babel/parser (babylon) AST node types.
- [ClassExpression](#classexpression)
- [MetaProperty](#metaproperty)
- [Modules](#modules)
- [ModuleDeclaration](#moduledeclaration)
- [ModuleSpecifier](#modulespecifier)
- [Imports](#imports)
- [ImportDeclaration](#importdeclaration)
Expand All @@ -117,6 +116,7 @@ These are the core @babel/parser (babylon) AST node types.
- [ImportNamespaceSpecifier](#importnamespacespecifier)
- [ImportAttribute](#importattribute)
- [Exports](#exports)
- [ExportDeclaration](#exportdeclaration)
- [ExportNamedDeclaration](#exportnameddeclaration)
- [ExportSpecifier](#exportspecifier)
- [ExportNamespaceSpecifier](#exportnamespacespecifier)
Expand Down Expand Up @@ -275,7 +275,7 @@ interface Program <: Node {
type: "Program";
interpreter: InterpreterDirective | null;
sourceType: "script" | "module";
body: [ Statement | ModuleDeclaration ];
body: [ Statement | ImportDeclaration | ExportDeclaration ];
directives: [ Directive ];
}
```
Expand Down Expand Up @@ -1265,14 +1265,6 @@ interface MetaProperty <: Expression {

# Modules

## ModuleDeclaration

```js
interface ModuleDeclaration <: Node { }
```

A module `import` or `export` declaration.

## ModuleSpecifier

```js
Expand All @@ -1288,7 +1280,7 @@ A specifier in an import or export declaration.
### ImportDeclaration

```js
interface ImportDeclaration <: ModuleDeclaration {
interface ImportDeclaration <: Node {
type: "ImportDeclaration";
importKind: null | "type" | "typeof" | "value";
specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ];
Expand Down Expand Up @@ -1346,10 +1338,18 @@ An attribute specified on the ImportDeclaration.

## Exports

### ExportDeclaration

```js
interface ExportDeclaration <: Node {}
```

An `export` declaration.

### ExportNamedDeclaration

```js
interface ExportNamedDeclaration <: ModuleDeclaration {
interface ExportNamedDeclaration <: ExportDeclaration {
type: "ExportNamedDeclaration";
declaration: Declaration | null;
specifiers: [ ExportSpecifier | ExportNamespaceSpecifier ];
Expand Down Expand Up @@ -1400,7 +1400,7 @@ interface OptClassDeclaration <: ClassDeclaration {
id: Identifier | null;
}

interface ExportDefaultDeclaration <: ModuleDeclaration {
interface ExportDefaultDeclaration <: ExportDeclaration {
type: "ExportDefaultDeclaration";
declaration: OptFunctionDeclaration | OptClassDeclaration | Expression;
}
Expand All @@ -1411,7 +1411,7 @@ An export default declaration, e.g., `export default function () {};` or `export
### ExportAllDeclaration

```js
interface ExportAllDeclaration <: ModuleDeclaration {
interface ExportAllDeclaration <: ExportDeclaration {
type: "ExportAllDeclaration";
source: StringLiteral;
assertions?: [ ImportAttribute ];
Expand Down
4 changes: 3 additions & 1 deletion packages/babel-plugin-transform-typescript/src/enum.ts
Expand Up @@ -27,7 +27,9 @@ export default function transpileEnum(
if (seen(path.parentPath)) {
path.remove();
} else {
const isGlobal = t.isProgram(path.parent); // && !path.parent.body.some(t.isModuleDeclaration);
// todo: Consider exclude program with import/export
// && !path.parent.body.some(n => t.isImportDeclaration(n) || t.isExportDeclaration(n));
const isGlobal = t.isProgram(path.parent);
path.scope.registerDeclaration(
path.replaceWith(makeVar(node.id, t, isGlobal ? "var" : "let"))[0],
);
Expand Down
4 changes: 2 additions & 2 deletions packages/babel-traverse/src/scope/index.ts
Expand Up @@ -24,7 +24,6 @@ import {
isImportDeclaration,
isLiteral,
isMethod,
isModuleDeclaration,
isModuleSpecifier,
isNullLiteral,
isObjectExpression,
Expand All @@ -50,6 +49,7 @@ import {
isTopicReference,
isMetaProperty,
isPrivateName,
isExportDeclaration,
} from "@babel/types";
import type * as t from "@babel/types";
import { scope as scopeCache } from "../cache";
Expand All @@ -60,7 +60,7 @@ type NodePart = string | number | boolean;
function gatherNodeParts(node: t.Node, parts: NodePart[]) {
switch (node?.type) {
default:
if (isModuleDeclaration(node)) {
if (isImportDeclaration(node) || isExportDeclaration(node)) {
if (
(isExportAllDeclaration(node) ||
isExportNamedDeclaration(node) ||
Expand Down

0 comments on commit f543b61

Please sign in to comment.