fix(transform-typescript): do not elide injected imports (#7833)
This commit is contained in:
parent
b42b21f25c
commit
fa1547d8f8
@ -33,39 +33,42 @@ export default declare(api => {
|
||||
|
||||
Program(path, state: State) {
|
||||
state.programPath = path;
|
||||
},
|
||||
|
||||
ImportDeclaration(path, state: State) {
|
||||
// Note: this will allow both `import { } from "m"` and `import "m";`.
|
||||
// In TypeScript, the former would be elided.
|
||||
if (path.node.specifiers.length === 0) {
|
||||
return;
|
||||
}
|
||||
// remove type imports
|
||||
for (const stmt of path.get("body")) {
|
||||
if (t.isImportDeclaration(stmt)) {
|
||||
// Note: this will allow both `import { } from "m"` and `import "m";`.
|
||||
// In TypeScript, the former would be elided.
|
||||
if (stmt.node.specifiers.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let allElided = true;
|
||||
const importsToRemove: Path<Node>[] = [];
|
||||
let allElided = true;
|
||||
const importsToRemove: Path<Node>[] = [];
|
||||
|
||||
for (const specifier of path.node.specifiers) {
|
||||
const binding = path.scope.getBinding(specifier.local.name);
|
||||
for (const specifier of stmt.node.specifiers) {
|
||||
const binding = stmt.scope.getBinding(specifier.local.name);
|
||||
|
||||
// The binding may not exist if the import node was explicitly
|
||||
// injected by another plugin. Currently core does not do a good job
|
||||
// of keeping scope bindings synchronized with the AST. For now we
|
||||
// just bail if there is no binding, since chances are good that if
|
||||
// the import statement was injected then it wasn't a typescript type
|
||||
// import anyway.
|
||||
if (binding && isImportTypeOnly(binding, state.programPath)) {
|
||||
importsToRemove.push(binding.path);
|
||||
} else {
|
||||
allElided = false;
|
||||
}
|
||||
}
|
||||
// The binding may not exist if the import node was explicitly
|
||||
// injected by another plugin. Currently core does not do a good job
|
||||
// of keeping scope bindings synchronized with the AST. For now we
|
||||
// just bail if there is no binding, since chances are good that if
|
||||
// the import statement was injected then it wasn't a typescript type
|
||||
// import anyway.
|
||||
if (binding && isImportTypeOnly(binding, state.programPath)) {
|
||||
importsToRemove.push(binding.path);
|
||||
} else {
|
||||
allElided = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allElided) {
|
||||
path.remove();
|
||||
} else {
|
||||
for (const importPath of importsToRemove) {
|
||||
importPath.remove();
|
||||
if (allElided) {
|
||||
stmt.remove();
|
||||
} else {
|
||||
for (const importPath of importsToRemove) {
|
||||
importPath.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
1
packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-injected/input.mjs
vendored
Normal file
1
packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-injected/input.mjs
vendored
Normal file
@ -0,0 +1 @@
|
||||
a();
|
||||
3
packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-injected/options.json
vendored
Normal file
3
packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-injected/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["transform-typescript", "./plugin"]
|
||||
}
|
||||
2
packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-injected/output.mjs
vendored
Normal file
2
packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-injected/output.mjs
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
import local from "source";
|
||||
local();
|
||||
26
packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-injected/plugin.js
vendored
Normal file
26
packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-injected/plugin.js
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
module.exports = function({ types: t }) {
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression(path) {
|
||||
if (path.node.callee.name === "a") {
|
||||
// the import we add here should not be elided
|
||||
path.scope
|
||||
.getProgramParent()
|
||||
.path.unshiftContainer(
|
||||
"body",
|
||||
t.importDeclaration(
|
||||
[t.importDefaultSpecifier(t.identifier("local"))],
|
||||
t.stringLiteral("source")
|
||||
)
|
||||
);
|
||||
|
||||
// with this crawl, babel-plugin-transform-typescript
|
||||
// used to elide the import we just added
|
||||
// https://github.com/babel/babel/issues/7592
|
||||
path.scope.crawl();
|
||||
path.node.callee = t.identifier("local");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user