Skip to content

Commit

Permalink
[ts] Strip type-only namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Jul 19, 2023
1 parent f28ff8a commit c2b0a0d
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 24 deletions.
65 changes: 41 additions & 24 deletions packages/babel-plugin-transform-typescript/src/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export default function transpileNamespace(
const name = path.node.id.name;
const value = handleNested(path, t.cloneNode(path.node, true));
const bound = path.scope.hasOwnBinding(name);
if (path.parent.type === "ExportNamedDeclaration") {
if (value === null) {
path.remove();
} else if (path.parent.type === "ExportNamedDeclaration") {
if (!bound) {
path.parentPath.insertAfter(value);
path.replaceWith(getDeclaration(name));
Expand Down Expand Up @@ -119,7 +121,7 @@ function handleNested(
path: NodePath,
node: t.TSModuleDeclaration,
parentExport?: t.Expression,
) {
): t.Statement | null {
const names = new Set();
const realName = node.id;
t.assertIdentifier(realName);
Expand All @@ -134,6 +136,8 @@ function handleNested(
// }
[t.exportNamedDeclaration(node.body)];

let isEmpty = true;

for (let i = 0; i < namespaceTopLevel.length; i++) {
const subNode = namespaceTopLevel[i];

Expand All @@ -146,26 +150,31 @@ function handleNested(
}

const transformed = handleNested(path, subNode);
const moduleName = subNode.id.name;
if (names.has(moduleName)) {
namespaceTopLevel[i] = transformed;
} else {
names.add(moduleName);
namespaceTopLevel.splice(
i++,
1,
getDeclaration(moduleName),
transformed,
);
if (transformed !== null) {
isEmpty = false;
const moduleName = subNode.id.name;
if (names.has(moduleName)) {
namespaceTopLevel[i] = transformed;
} else {
names.add(moduleName);
namespaceTopLevel.splice(
i++,
1,
getDeclaration(moduleName),
transformed,
);
}
}
continue;
}
case "TSEnumDeclaration":
case "FunctionDeclaration":
case "ClassDeclaration":
isEmpty = false;
names.add(subNode.id.name);
continue;
case "VariableDeclaration": {
isEmpty = false;
// getBindingIdentifiers returns an object without prototype.
// eslint-disable-next-line guard-for-in
for (const name in t.getBindingIdentifiers(subNode)) {
Expand All @@ -174,6 +183,7 @@ function handleNested(
continue;
}
default:
isEmpty &&= t.isTypeScript(subNode);
// Neither named declaration nor export, continue to next item.
continue;
case "ExportNamedDeclaration":
Expand All @@ -189,6 +199,7 @@ function handleNested(
case "TSEnumDeclaration":
case "FunctionDeclaration":
case "ClassDeclaration": {
isEmpty = false;
const itemName = subNode.declaration.id.name;
names.add(itemName);
namespaceTopLevel.splice(
Expand All @@ -206,6 +217,7 @@ function handleNested(
break;
}
case "VariableDeclaration": {
isEmpty = false;
const nodes = handleVariableDeclaration(
subNode.declaration,
name,
Expand All @@ -225,22 +237,27 @@ function handleNested(
subNode.declaration,
t.identifier(name),
);
const moduleName = subNode.declaration.id.name;
if (names.has(moduleName)) {
namespaceTopLevel[i] = transformed;
} else {
names.add(moduleName);
namespaceTopLevel.splice(
i++,
1,
getDeclaration(moduleName),
transformed,
);
if (transformed !== null) {
isEmpty = false;
const moduleName = subNode.declaration.id.name;
if (names.has(moduleName)) {
namespaceTopLevel[i] = transformed;
} else {
names.add(moduleName);
namespaceTopLevel.splice(
i++,
1,
getDeclaration(moduleName),
transformed,
);
}
}
}
}
}

if (isEmpty) return null;

// {}
let fallthroughValue: t.Expression = t.objectExpression([]);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace a {
namespace b {}
namespace c { var x }
namespace d {
namespace e {}
}
}

namespace WithTypes {
namespace a { type A = 1 }
namespace b { interface B {} }
namespace c { import C = a }
namespace d { declare class D {} }
}

namespace WithValues {
namespace a { class A {} }
namespace b { enum B {} }
namespace c { function C() {} }
namespace d { var D }
namespace e { E; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
let a;
(function (_a) {
let c;
(function (_c) {
var x;
})(c || (c = {}));
})(a || (a = {}));
let WithTypes;
(function (_WithTypes) {
let d;
(function (_d2) {})(d || (d = {}));
})(WithTypes || (WithTypes = {}));
let WithValues;
(function (_WithValues) {
let a;
(function (_a3) {
class A {}
})(a || (a = {}));
let b;
(function (_b3) {
let B = /*#__PURE__*/function (B) {
return B;
}({});
})(b || (b = {}));
let c;
(function (_c3) {
function C() {}
})(c || (c = {}));
let d;
(function (_d3) {
var D;
})(d || (d = {}));
let e;
(function (_e2) {
E;
})(e || (e = {}));
})(WithValues || (WithValues = {}));

0 comments on commit c2b0a0d

Please sign in to comment.