From cbdb276c25c9dda6d101e35996151a6242bbed81 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Sun, 29 May 2022 11:56:16 +0200 Subject: [PATCH] fix: Try harder to construct a use chain in synthetic AST This should work around a more strict DCE in rollup > 2.75 --- package-lock.json | 6 ++++- src/transform/DeclarationScope.ts | 13 +++++++--- src/transform/astHelpers.ts | 36 +++++++++++++++++++++----- tests/testcases/type-typeof/index.d.ts | 1 - 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d74a135..8bae9fa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,10 +5,10 @@ "requires": true, "packages": { "": { - "name": "rollup-plugin-dts", "version": "4.2.2", "license": "LGPL-3.0", "dependencies": { + "@babel/code-frame": "^7.16.7", "magic-string": "^0.26.1" }, "devDependencies": { @@ -559,6 +559,7 @@ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { + "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -713,6 +714,9 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.3.tgz", "integrity": "sha512-YA29fLU6MAYSaDxIQYrGGOcbXlDmG96h0krGGYObroezcQ0KgEPM3+7MtKD/qeuUbFuAJXvKZee5dA1dpwq1PQ==", "dev": true, + "dependencies": { + "fsevents": "~2.3.2" + }, "bin": { "rollup": "dist/bin/rollup" }, diff --git a/src/transform/DeclarationScope.ts b/src/transform/DeclarationScope.ts index b2404313..e3f1a3f1 100644 --- a/src/transform/DeclarationScope.ts +++ b/src/transform/DeclarationScope.ts @@ -6,6 +6,7 @@ import { createIdentifier, createIIFE, createReference, + createReturn, Range, withStartEnd, } from "./astHelpers.js"; @@ -37,6 +38,7 @@ interface DeclarationScopeOptions { export class DeclarationScope { declaration: ESTree.FunctionDeclaration; iife?: ESTree.ExpressionStatement; + private returnExpr: ESTree.ArrayExpression; constructor({ id, range }: DeclarationScopeOptions) { if (id) { @@ -46,6 +48,9 @@ export class DeclarationScope { this.iife = iife; this.declaration = fn as any; } + const ret = createReturn(); + this.declaration.body.body.push(ret.stmt); + this.returnExpr = ret.expr; } /** @@ -67,9 +72,6 @@ export class DeclarationScope { this.scopes[this.scopes.length - 1]?.add(name); } - pushRaw(expr: ESTree.AssignmentPattern) { - this.declaration.params.push(expr); - } pushReference(id: ESTree.Expression) { let name: string | undefined; // We convert references from TS AST to ESTree @@ -90,7 +92,10 @@ export class DeclarationScope { } } } - this.pushRaw(createReference(id)); + const { ident, expr } = createReference(id); + + this.declaration.params.push(expr); + this.returnExpr.elements.push(ident); } pushIdentifierReference(id: ts.Identifier) { this.pushReference(createIdentifier(id)); diff --git a/src/transform/astHelpers.ts b/src/transform/astHelpers.ts index 42c49036..80b7a4b6 100644 --- a/src/transform/astHelpers.ts +++ b/src/transform/astHelpers.ts @@ -22,14 +22,18 @@ export function createProgram(node: ts.SourceFile): ESTree.Program { * Creates a reference to `id`: * `_ = ${id}` */ -export function createReference(id: ESTree.Expression): ESTree.AssignmentPattern { +export function createReference(id: ESTree.Expression): { ident: ESTree.Identifier; expr: ESTree.AssignmentPattern } { + const ident: ESTree.Identifier = { + type: "Identifier", + name: String(IDs++), + }; return { - type: "AssignmentPattern", - left: { - type: "Identifier", - name: String(IDs++), + ident, + expr: { + type: "AssignmentPattern", + left: ident, + right: id, }, - right: id, }; } @@ -47,7 +51,7 @@ export function createIdentifier(node: ts.Identifier): ESTree.Identifier { * Create a new Scope which is always included * `(function (_ = MARKER) {})()` */ -export function createIIFE(range: Range) { +export function createIIFE(range: Range): { fn: ESTree.FunctionExpression; iife: ESTree.ExpressionStatement } { const fn = withStartEnd( { type: "FunctionExpression", @@ -72,6 +76,24 @@ export function createIIFE(range: Range) { return { fn, iife }; } +/** + * Create a dummy ReturnStatement with an ArrayExpression: + * `return [];` + */ +export function createReturn(): { stmt: ESTree.Statement; expr: ESTree.ArrayExpression } { + const expr: ESTree.ArrayExpression = { + type: "ArrayExpression", + elements: [], + }; + return { + expr, + stmt: { + type: "ReturnStatement", + argument: expr, + }, + }; +} + /** * Create a new Declaration and Scope for `id`: * `function ${id}(_ = MARKER) {}` diff --git a/tests/testcases/type-typeof/index.d.ts b/tests/testcases/type-typeof/index.d.ts index 5bf25d02..000ecac7 100644 --- a/tests/testcases/type-typeof/index.d.ts +++ b/tests/testcases/type-typeof/index.d.ts @@ -1,4 +1,3 @@ interface A {} declare const a: A; export declare function typeQuery(): typeof a; -export {};