Skip to content

Commit 2c2475d

Browse files
1 parent aa3499d commit 2c2475d

File tree

4 files changed

+148
-146
lines changed

4 files changed

+148
-146
lines changed

Source/Artifact/Inliner.ts

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import ts from "typescript";
1+
import ts, { type SourceFile } from "typescript";
22

33
interface InlinerOptions {
44
allowComplexExpressions?: boolean;
@@ -86,11 +86,9 @@ class ExpressionAnalyzer {
8686

8787
let result = false;
8888

89-
ts.forEachChild(node, (child) => {
90-
if (hasSideEffects(child)) {
91-
result = true;
92-
}
93-
});
89+
ts.forEachChild(node, (child) =>
90+
hasSideEffects(child) ? (result = true) : null,
91+
);
9492

9593
return result;
9694
};
@@ -122,21 +120,17 @@ class ExpressionAnalyzer {
122120
}
123121

124122
if (ts.isBinaryExpression(node)) {
125-
const op = node.operatorToken.kind;
126-
127123
// Division could throw
128-
if (op === ts.SyntaxKind.SlashToken) {
124+
if (node.operatorToken.kind === ts.SyntaxKind.SlashToken) {
129125
return true;
130126
}
131127
}
132128

133129
let result = false;
134130

135-
ts.forEachChild(node, (child) => {
136-
if (hasRuntimeRisks(child)) {
137-
result = true;
138-
}
139-
});
131+
ts.forEachChild(node, (child) =>
132+
hasRuntimeRisks(child) ? (result = true) : null,
133+
);
140134

141135
return result;
142136
};
@@ -174,6 +168,7 @@ class ScopeAnalyzer {
174168
if (ts.isVariableDeclaration(child)) {
175169
this.collectBindings(child.name, scope);
176170
}
171+
177172
ts.forEachChild(child, visitNode);
178173
};
179174

@@ -209,8 +204,10 @@ class ScopeAnalyzer {
209204
if (scope?.has(symbol)) {
210205
return true;
211206
}
207+
212208
current = current.parent;
213209
}
210+
214211
return false;
215212
}
216213
}
@@ -281,36 +278,34 @@ class VariableInliner {
281278
}
282279

283280
if (ts.isArrayBindingPattern(pattern)) {
284-
const elements: ts.Expression[] = pattern.elements.map(
285-
(element) => {
281+
return ts.factory.createArrayLiteralExpression(
282+
pattern.elements.map((element) => {
286283
if (ts.isBindingElement(element)) {
287284
return (
288285
element.initializer ||
289286
ts.factory.createIdentifier("undefined")
290287
);
291288
}
289+
292290
return ts.factory.createIdentifier("undefined");
293-
},
291+
}),
294292
);
295-
296-
return ts.factory.createArrayLiteralExpression(elements);
297293
}
298294

299295
throw new Error("Unsupported binding pattern type");
300296
}
301297

302298
private shouldInlineExpression(node: ts.Expression): boolean {
303-
const analysis = this.expressionAnalyzer.analyzeComplexity(node);
304-
305-
if (!analysis.safe) {
299+
if (!this.expressionAnalyzer.analyzeComplexity(node).safe) {
306300
this.statistics.skippedVariables.complexity++;
307301

308302
return false;
309303
}
310304

311-
const size = this.expressionAnalyzer.getExpressionSize(node);
312-
313-
if (size > this.options.maxExpressionSize) {
305+
if (
306+
this.expressionAnalyzer.getExpressionSize(node) >
307+
this.options.maxExpressionSize
308+
) {
314309
this.statistics.skippedVariables.size++;
315310

316311
return false;
@@ -345,11 +340,7 @@ class VariableInliner {
345340
this.statistics.totalVariables +=
346341
node.declarationList.declarations.length;
347342

348-
return this.transformVariableStatement(
349-
node,
350-
typeChecker,
351-
context,
352-
);
343+
return this.transformVariableStatement(node, typeChecker);
353344
}
354345

355346
return ts.visitEachChild(node, visit, context);
@@ -358,23 +349,21 @@ class VariableInliner {
358349
return visit;
359350
};
360351

361-
const transformed = ts.transform(sourceFile, [transformer])
362-
.transformed[0];
363-
364352
// Generate output
365-
const printer = ts.createPrinter({
366-
newLine: ts.NewLineKind.LineFeed,
367-
removeComments: !this.options.preserveComments,
368-
});
369-
370353
this.statistics.optimizationTime = Date.now() - startTime;
371354

372355
const result: TransformationResult = {
373-
code: printer.printNode(
374-
ts.EmitHint.SourceFile,
375-
transformed,
376-
sourceFile,
377-
),
356+
code: ts
357+
.createPrinter({
358+
newLine: ts.NewLineKind.LineFeed,
359+
removeComments: !this.options.preserveComments,
360+
})
361+
.printNode(
362+
ts.EmitHint.SourceFile,
363+
ts.transform(sourceFile, [transformer])
364+
.transformed[0] as SourceFile,
365+
sourceFile,
366+
),
378367
statistics: this.statistics,
379368
};
380369

@@ -385,6 +374,7 @@ class VariableInliner {
385374

386375
return result;
387376
}
377+
388378
private transformVariableStatement(
389379
node: ts.VariableStatement,
390380
typeChecker: ts.TypeChecker,
@@ -396,16 +386,20 @@ class VariableInliner {
396386
if (ts.isIdentifier(name)) {
397387
if (this.isVariableExcluded(name.text)) {
398388
this.statistics.skippedVariables.excluded++;
389+
399390
return true;
400391
}
401392

402393
const symbol = typeChecker.getSymbolAtLocation(name);
403-
if (!symbol) return true;
394+
395+
if (!symbol) {
396+
return true;
397+
}
404398

405399
// Check usage count
406-
const references = this.findReferences(symbol, typeChecker);
407-
if (references.length !== 1) {
400+
if (this.findReferences(symbol, typeChecker).length !== 1) {
408401
this.statistics.skippedVariables.multiple++;
402+
409403
return true;
410404
}
411405

@@ -415,30 +409,29 @@ class VariableInliner {
415409
this.shouldInlineExpression(decl.initializer)
416410
) {
417411
this.statistics.inlinedVariables++;
412+
418413
return false;
419414
}
420415
} else if (
421416
(ts.isArrayBindingPattern(name) ||
422417
ts.isObjectBindingPattern(name)) &&
423418
this.options.inlineDestructuring
424419
) {
425-
if (!decl.initializer) return true;
420+
if (!decl.initializer) {
421+
return true;
422+
}
426423

427424
// Check if we can inline the destructuring pattern
428425
if (this.canInlineDestructuring(name, decl.initializer)) {
429426
try {
430427
// Transform the destructuring pattern and check if it's safe to inline
431-
const transformedExpression =
432-
this.handleDestructuring(
433-
name,
434-
decl.initializer,
435-
);
436428
if (
437429
this.shouldInlineExpression(
438-
transformedExpression,
430+
this.handleDestructuring(name),
439431
)
440432
) {
441433
this.statistics.inlinedVariables++;
434+
442435
return false; // Remove this declaration from the list
443436
}
444437
} catch (error) {
@@ -447,11 +440,13 @@ class VariableInliner {
447440
"Failed to transform destructuring pattern:",
448441
error,
449442
);
443+
450444
return true;
451445
}
452446
}
453447

454448
this.statistics.skippedVariables.complexity++;
449+
455450
return true;
456451
}
457452

@@ -496,6 +491,7 @@ class VariableInliner {
496491
ts.isCallExpression(initializer)
497492
);
498493
}
494+
499495
return false;
500496
}
501497

@@ -541,6 +537,7 @@ class VariableInliner {
541537
if (ts.isArrayBindingPattern(pattern)) {
542538
for (const element of pattern.elements) {
543539
if (ts.isOmittedExpression(element)) continue;
540+
544541
if (element.dotDotDotToken) {
545542
// Spread operators make inlining more complex
546543
return false;
@@ -559,7 +556,9 @@ class VariableInliner {
559556

560557
const root = symbol.declarations?.[0]?.getSourceFile();
561558

562-
if (!root) return references;
559+
if (!root) {
560+
return references;
561+
}
563562

564563
const visit = (node: ts.Node) => {
565564
if (ts.isIdentifier(node)) {
@@ -569,6 +568,7 @@ class VariableInliner {
569568
references.push(node);
570569
}
571570
}
571+
572572
ts.forEachChild(node, visit);
573573
};
574574

@@ -581,6 +581,7 @@ class VariableInliner {
581581
if (this.options.includeVariables.length > 0) {
582582
return !this.options.includeVariables.includes(name);
583583
}
584+
584585
return this.options.excludeVariables.includes(name);
585586
}
586587

@@ -608,9 +609,7 @@ async function optimizeTypeScriptFile(
608609
throw new Error(`Source file '${filePath}' not found`);
609610
}
610611

611-
const inliner = new VariableInliner(options);
612-
613-
return inliner.transform(sourceFile, program);
612+
return new VariableInliner(options).transform(sourceFile, program);
614613
}
615614

616615
export {

0 commit comments

Comments
 (0)