Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use named imports for babel types #13685

Merged
merged 4 commits into from Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 49 additions & 0 deletions babel.config.js
Expand Up @@ -202,6 +202,7 @@ module.exports = function (api) {
{
test: sources.map(normalize),
assumptions: sourceAssumptions,
plugins: [transformNamedBabelTypesImportToDestructuring],
},
{
test: unambiguousSources.map(normalize),
Expand Down Expand Up @@ -455,6 +456,54 @@ function pluginPackageJsonMacro({ types: t }) {
};
}

// transform `import { x } from "@babel/types"` to `import * as _t from "@babel/types"; const { x } = _t;
function transformNamedBabelTypesImportToDestructuring({
types: {
cloneNode,
importNamespaceSpecifier,
objectPattern,
objectProperty,
variableDeclarator,
variableDeclaration,
},
}) {
return {
name: "transform-babel-types-named-imports",
visitor: {
ImportDeclaration(path) {
const { node } = path;
if (
node.importKind === "value" &&
node.source.value === "@babel/types" &&
node.specifiers[0].type === "ImportSpecifier"
) {
const hoistedDestructuringProperties = [];
for (const { imported, local } of node.specifiers) {
hoistedDestructuringProperties.push(
objectProperty(
imported,
local,
false,
imported.name === local.name
)
);
}
const babelTypeNsImport = path.scope.generateUidIdentifier("t");
node.specifiers = [importNamespaceSpecifier(babelTypeNsImport)];
path.insertAfter([
variableDeclaration("const", [
variableDeclarator(
objectPattern(hoistedDestructuringProperties),
cloneNode(babelTypeNsImport)
),
]),
]);
}
},
},
};
}

function pluginImportMetaUrl({ types: t, template }) {
const isImportMeta = node =>
t.isMetaProperty(node) &&
Expand Down
101 changes: 61 additions & 40 deletions packages/babel-core/src/tools/build-external-helpers.ts
@@ -1,7 +1,28 @@
import * as helpers from "@babel/helpers";
import generator from "@babel/generator";
import template from "@babel/template";
import * as t from "@babel/types";
import {
arrayExpression,
assignmentExpression,
binaryExpression,
blockStatement,
callExpression,
cloneNode,
conditionalExpression,
exportNamedDeclaration,
exportSpecifier,
expressionStatement,
functionExpression,
identifier,
memberExpression,
objectExpression,
program,
stringLiteral,
unaryExpression,
variableDeclaration,
variableDeclarator,
} from "@babel/types";
import type * as t from "@babel/types";
import File from "../transformation/file/file";

// Wrapped to avoid wasting time parsing this when almost no-one uses
Expand All @@ -22,39 +43,39 @@ const buildUmdWrapper = replacements =>
`(replacements);

function buildGlobal(allowlist?: Array<string>) {
const namespace = t.identifier("babelHelpers");
const namespace = identifier("babelHelpers");

const body: t.Statement[] = [];
const container = t.functionExpression(
const container = functionExpression(
null,
[t.identifier("global")],
t.blockStatement(body),
[identifier("global")],
blockStatement(body),
);
const tree = t.program([
t.expressionStatement(
t.callExpression(container, [
const tree = program([
expressionStatement(
callExpression(container, [
// typeof global === "undefined" ? self : global
t.conditionalExpression(
t.binaryExpression(
conditionalExpression(
binaryExpression(
"===",
t.unaryExpression("typeof", t.identifier("global")),
t.stringLiteral("undefined"),
unaryExpression("typeof", identifier("global")),
stringLiteral("undefined"),
),
t.identifier("self"),
t.identifier("global"),
identifier("self"),
identifier("global"),
),
]),
),
]);

body.push(
t.variableDeclaration("var", [
t.variableDeclarator(
variableDeclaration("var", [
variableDeclarator(
namespace,
t.assignmentExpression(
assignmentExpression(
"=",
t.memberExpression(t.identifier("global"), namespace),
t.objectExpression([]),
memberExpression(identifier("global"), namespace),
objectExpression([]),
),
),
]),
Expand All @@ -70,57 +91,57 @@ function buildModule(allowlist?: Array<string>) {
const refs = buildHelpers(body, null, allowlist);

body.unshift(
t.exportNamedDeclaration(
exportNamedDeclaration(
null,
Object.keys(refs).map(name => {
return t.exportSpecifier(t.cloneNode(refs[name]), t.identifier(name));
return exportSpecifier(cloneNode(refs[name]), identifier(name));
}),
),
);

return t.program(body, [], "module");
return program(body, [], "module");
}

function buildUmd(allowlist?: Array<string>) {
const namespace = t.identifier("babelHelpers");
const namespace = identifier("babelHelpers");

const body: t.Statement[] = [];
body.push(
t.variableDeclaration("var", [
t.variableDeclarator(namespace, t.identifier("global")),
variableDeclaration("var", [
variableDeclarator(namespace, identifier("global")),
]),
);

buildHelpers(body, namespace, allowlist);

return t.program([
return program([
buildUmdWrapper({
FACTORY_PARAMETERS: t.identifier("global"),
BROWSER_ARGUMENTS: t.assignmentExpression(
FACTORY_PARAMETERS: identifier("global"),
BROWSER_ARGUMENTS: assignmentExpression(
"=",
t.memberExpression(t.identifier("root"), namespace),
t.objectExpression([]),
memberExpression(identifier("root"), namespace),
objectExpression([]),
),
COMMON_ARGUMENTS: t.identifier("exports"),
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
COMMON_ARGUMENTS: identifier("exports"),
AMD_ARGUMENTS: arrayExpression([stringLiteral("exports")]),
FACTORY_BODY: body,
UMD_ROOT: t.identifier("this"),
UMD_ROOT: identifier("this"),
}),
]);
}

function buildVar(allowlist?: Array<string>) {
const namespace = t.identifier("babelHelpers");
const namespace = identifier("babelHelpers");

const body: t.Statement[] = [];
body.push(
t.variableDeclaration("var", [
t.variableDeclarator(namespace, t.objectExpression([])),
variableDeclaration("var", [
variableDeclarator(namespace, objectExpression([])),
]),
);
const tree = t.program(body);
const tree = program(body);
buildHelpers(body, namespace, allowlist);
body.push(t.expressionStatement(namespace));
body.push(expressionStatement(namespace));
return tree;
}

Expand All @@ -131,8 +152,8 @@ function buildHelpers(
) {
const getHelperReference = (name: string) => {
return namespace
? t.memberExpression(namespace, t.identifier(name))
: t.identifier(`_${name}`);
? memberExpression(namespace, identifier(name))
: identifier(`_${name}`);
};

const refs = {};
Expand Down
7 changes: 4 additions & 3 deletions packages/babel-core/src/transformation/file/file.ts
Expand Up @@ -3,7 +3,8 @@ import { NodePath, Scope } from "@babel/traverse";
import type { HubInterface } from "@babel/traverse";
import { codeFrameColumns } from "@babel/code-frame";
import traverse from "@babel/traverse";
import * as t from "@babel/types";
import { cloneNode, interpreterDirective } from "@babel/types";
import type * as t from "@babel/types";
import { getModuleName } from "@babel/helper-module-transforms";
import semver from "semver";

Expand Down Expand Up @@ -89,7 +90,7 @@ export default class File {
}
set shebang(value: string) {
if (value) {
this.path.get("interpreter").replaceWith(t.interpreterDirective(value));
this.path.get("interpreter").replaceWith(interpreterDirective(value));
} else {
this.path.get("interpreter").remove();
}
Expand Down Expand Up @@ -176,7 +177,7 @@ export default class File {

addHelper(name: string): t.Identifier {
const declar = this.declarations[name];
if (declar) return t.cloneNode(declar);
if (declar) return cloneNode(declar);

const generator = this.get("helperGenerator");
if (generator) {
Expand Down
7 changes: 4 additions & 3 deletions packages/babel-core/src/transformation/normalize-file.ts
Expand Up @@ -2,7 +2,8 @@ import fs from "fs";
import path from "path";
import buildDebug from "debug";
import type { Handler } from "gensync";
import * as t from "@babel/types";
import { file, traverseFast } from "@babel/types";
import type * as t from "@babel/types";
import type { PluginPasses } from "../config";
import convertSourceMap from "convert-source-map";
import type { SourceMapConverter as Converter } from "convert-source-map";
Expand All @@ -29,7 +30,7 @@ export default function* normalizeFile(

if (ast) {
if (ast.type === "Program") {
ast = t.file(ast, [], []);
ast = file(ast, [], []);
} else if (ast.type !== "File") {
throw new Error("AST root must be a Program or File node");
}
Expand Down Expand Up @@ -119,7 +120,7 @@ function extractCommentsFromList(regex, comments, lastComment) {

function extractComments(regex, ast) {
let lastComment = null;
t.traverseFast(ast, node => {
traverseFast(ast, node => {
[node.leadingComments, lastComment] = extractCommentsFromList(
regex,
node.leadingComments,
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-generator/src/generators/base.ts
@@ -1,5 +1,5 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import type * as t from "@babel/types";
import * as charCodes from "charcodes";

export function File(this: Printer, node: t.File) {
Expand Down
8 changes: 5 additions & 3 deletions packages/babel-generator/src/generators/classes.ts
@@ -1,9 +1,11 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import {
isExportDefaultDeclaration,
isExportNamedDeclaration,
} from "@babel/types";
import type * as t from "@babel/types";
import * as charCodes from "charcodes";

const { isExportDefaultDeclaration, isExportNamedDeclaration } = t;

export function ClassDeclaration(
this: Printer,
node: t.ClassDeclaration,
Expand Down
9 changes: 7 additions & 2 deletions packages/babel-generator/src/generators/expressions.ts
@@ -1,8 +1,13 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import {
isCallExpression,
isLiteral,
isMemberExpression,
isNewExpression,
} from "@babel/types";
import type * as t from "@babel/types";
import * as n from "../node";

const { isCallExpression, isLiteral, isMemberExpression, isNewExpression } = t;
export function UnaryExpression(this: Printer, node: t.UnaryExpression) {
if (
node.operator === "void" ||
Expand Down
4 changes: 2 additions & 2 deletions packages/babel-generator/src/generators/flow.ts
@@ -1,8 +1,8 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import { isDeclareExportDeclaration, isStatement } from "@babel/types";
import type * as t from "@babel/types";
import { ExportAllDeclaration } from "./modules";

const { isDeclareExportDeclaration, isStatement } = t;
export function AnyTypeAnnotation(this: Printer) {
this.word("any");
}
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-generator/src/generators/jsx.ts
@@ -1,5 +1,5 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import type * as t from "@babel/types";

export function JSXAttribute(this: Printer, node: t.JSXAttribute) {
this.print(node.name, node);
Expand Down
4 changes: 2 additions & 2 deletions packages/babel-generator/src/generators/methods.ts
@@ -1,7 +1,7 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import { isIdentifier } from "@babel/types";
import type * as t from "@babel/types";

const { isIdentifier } = t;
export function _params(this: Printer, node: any) {
this.print(node.typeParameters, node);
this.token("(");
Expand Down
7 changes: 3 additions & 4 deletions packages/babel-generator/src/generators/modules.ts
@@ -1,14 +1,13 @@
import type Printer from "../printer";
import * as t from "@babel/types";

const {
import {
isClassDeclaration,
isExportDefaultSpecifier,
isExportNamespaceSpecifier,
isImportDefaultSpecifier,
isImportNamespaceSpecifier,
isStatement,
} = t;
} from "@babel/types";
import type * as t from "@babel/types";

export function ImportSpecifier(this: Printer, node: t.ImportSpecifier) {
if (node.importKind === "type" || node.importKind === "typeof") {
Expand Down
9 changes: 7 additions & 2 deletions packages/babel-generator/src/generators/statements.ts
@@ -1,8 +1,13 @@
import type Printer from "../printer";
import * as t from "@babel/types";
import {
isFor,
isForStatement,
isIfStatement,
isStatement,
} from "@babel/types";
import type * as t from "@babel/types";
import * as charCodes from "charcodes";

const { isFor, isForStatement, isIfStatement, isStatement } = t;
export function WithStatement(this: Printer, node: t.WithStatement) {
this.word("with");
this.space();
Expand Down