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 scope for typescript export removals #10034

Merged
merged 1 commit into from May 29, 2019
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
4 changes: 3 additions & 1 deletion packages/babel-plugin-transform-typescript/src/enum.js
Expand Up @@ -24,7 +24,9 @@ export default function transpileEnum(path, t) {
path.remove();
} else {
const isGlobal = t.isProgram(path.parent); // && !path.parent.body.some(t.isModuleDeclaration);
path.replaceWith(makeVar(node.id, t, isGlobal ? "var" : "let"));
path.scope.registerDeclaration(
path.replaceWith(makeVar(node.id, t, isGlobal ? "var" : "let"))[0],
);
}
break;
}
Expand Down
56 changes: 7 additions & 49 deletions packages/babel-plugin-transform-typescript/src/index.js
Expand Up @@ -17,22 +17,8 @@ function isInType(path) {
}
}

function isTSExportableDeclaration(node) {
// all kinds of type exports that transpile to nothing
// exception is enums, since they transpile to JS values
return (
t.isTSInterfaceDeclaration(node) ||
t.isTSTypeAliasDeclaration(node) ||
t.isTSModuleDeclaration(node) ||
(t.isVariableDeclaration(node) && node.declare) ||
(t.isClassDeclaration(node) && node.declare) ||
t.isTSDeclareFunction(node)
);
}

interface State {
programPath: any;
exportableTSNames: Set<string>;
}

const PARSED_PARAMS = new WeakSet();
Expand All @@ -55,7 +41,6 @@ export default declare((api, { jsxPragma = "React" }) => {

Program(path, state: State) {
state.programPath = path;
state.exportableTSNames = new Set();

const { file } = state;

Expand All @@ -68,32 +53,6 @@ export default declare((api, { jsxPragma = "React" }) => {
}
}

// find exportable top level type declarations
for (const stmt of path.get("body")) {
if (isTSExportableDeclaration(stmt.node)) {
if (stmt.node.id && stmt.node.id.name) {
state.exportableTSNames.add(stmt.node.id.name);
} else if (
stmt.node.declarations &&
stmt.node.declarations.length > 0
) {
for (const declaration of stmt.node.declarations) {
if (declaration.id && declaration.id.name) {
state.exportableTSNames.add(declaration.id.name);
}
}
}
} else if (
t.isExportNamedDeclaration(stmt.node) &&
stmt.node.specifiers.length === 0 &&
isTSExportableDeclaration(stmt.node.declaration) &&
stmt.node.declaration.id &&
stmt.node.declaration.id.name
) {
state.exportableTSNames.add(stmt.node.declaration.id.name);
}
}

// remove type imports
for (const stmt of path.get("body")) {
if (t.isImportDeclaration(stmt)) {
Expand Down Expand Up @@ -136,31 +95,30 @@ export default declare((api, { jsxPragma = "React" }) => {
}
},

ExportNamedDeclaration(path, { exportableTSNames }) {
ExportNamedDeclaration(path) {
// remove export declaration if it's exporting only types
if (
path.node.specifiers.length > 0 &&
!path.node.specifiers.find(
exportSpecifier =>
!exportableTSNames.has(exportSpecifier.local.name),
!path.node.specifiers.find(exportSpecifier =>
path.scope.hasOwnBinding(exportSpecifier.local.name),
)
) {
path.remove();
}
},

ExportSpecifier(path, { exportableTSNames }) {
ExportSpecifier(path) {
// remove type exports
if (exportableTSNames.has(path.node.local.name)) {
if (!path.scope.hasOwnBinding(path.node.local.name)) {
path.remove();
}
},

ExportDefaultDeclaration(path, { exportableTSNames }) {
ExportDefaultDeclaration(path) {
// remove whole declaration if it's exporting a TS type
if (
t.isIdentifier(path.node.declaration) &&
exportableTSNames.has(path.node.declaration.name)
!path.scope.hasOwnBinding(path.node.declaration.name)
) {
path.remove();
}
Expand Down
@@ -1,3 +1,4 @@
; // Otherwise-empty file
declare const x: number;
declare function f(): void;
declare class C {}
Expand All @@ -7,42 +8,3 @@ declare module M {}
declare namespace N {}
export interface I {}
export type T = number;
export class C2 {}

export { x, f, E, C }; // only E
export { M, N, I as I1, T as T1 }; // everything removed
export {
x as x2,
f as f2,
C as CC2,
E as E2,
M as M2,
N as N2,
I as I2,
T as T2,
C2 as C3
}; // only E and C2

interface II2 {}
type AA = {};
enum BB {
K
}
enum BB {
L = "LL"
}
export { II2, AA, BB }; // only BB
export { II2 as II3, AA as AA2 }; // everything removed
export { BB as BB1 }; // as-is

interface II3 {}
type AA2 = {};
enum BB2 {}
function foo() {}
export { II3 as default, AA2 as A, BB2 as BB3, foo }; // only BB2 and foo

// export an interface before declaration
export default Bar;
export { Bar } // everything removed
export { Bar as Bar2, C2 as C4 } // only C4
interface Bar {}
@@ -1,32 +1 @@
export class C2 {}
export { E }; // only E

// everything removed
export { E as E2, C2 as C3 }; // only E and C2

var BB;

(function (BB) {
BB[BB["K"] = 0] = "K";
})(BB || (BB = {}));

(function (BB) {
BB["L"] = "LL";
})(BB || (BB = {}));

export { BB }; // only BB

// everything removed
export { BB as BB1 }; // as-is

var BB2;

(function (BB2) {})(BB2 || (BB2 = {}));

function foo() {}

export { BB2 as BB3, foo }; // only BB2 and foo
// export an interface before declaration

// everything removed
export { C2 as C4 }; // only C4
; // Otherwise-empty file
@@ -0,0 +1,11 @@
export class N {
f1(value: N.I) {
value.f2();
}
}
export declare namespace N {
export interface I {
f2();
}
}
export default N;
@@ -0,0 +1,7 @@
export class N {
f1(value) {
value.f2();
}

}
export default N;
@@ -0,0 +1,48 @@
declare const x: number;
declare function f(): void;
declare class C {}
declare enum E {}
declare module "m" {}
declare module M {}
declare namespace N {}
export interface I {}
export type T = number;
export class C2 {}

export { x, f, E, C }; // Not-even E
export { M, N, I as I1, T as T1 }; // everything removed
export {
x as x2,
f as f2,
C as CC2,
E as E2,
M as M2,
N as N2,
I as I2,
T as T2,
C2 as C3
}; // only C2->C3

interface II2 {}
type AA = {};
enum BB {
K
}
enum BB {
L = "LL"
}
export { II2, AA, BB }; // only BB
export { II2 as II3, AA as AA2 }; // everything removed
export { BB as BB1 }; // BB->BB1

interface II3 {}
type AA2 = {};
enum BB2 {}
function foo() {}
export { II3 as default, AA2 as A, BB2 as BB3, foo }; // only BB2->BB3 and foo

// export an interface before declaration
export default Bar;
export { Bar } // everything removed
export { Bar as Bar2, C2 as C4 } // only C2->C4
interface Bar {}
@@ -0,0 +1,30 @@
export class C2 {}
// everything removed
export { C2 as C3 }; // only C2->C3

var BB;

(function (BB) {
BB[BB["K"] = 0] = "K";
})(BB || (BB = {}));

(function (BB) {
BB["L"] = "LL";
})(BB || (BB = {}));

export { BB }; // only BB

// everything removed
export { BB as BB1 }; // BB->BB1

var BB2;

(function (BB2) {})(BB2 || (BB2 = {}));

function foo() {}

export { BB2 as BB3, foo }; // only BB2->BB3 and foo
// export an interface before declaration

// everything removed
export { C2 as C4 }; // only C2->C4
@@ -1,2 +1,3 @@
; // Otherwise-empty file
export interface I {}
export default interface A {}
@@ -0,0 +1 @@
; // Otherwise-empty file
@@ -0,0 +1,2 @@
export class N {}
export default N;
@@ -0,0 +1,2 @@
export class N {}
export default N;