Skip to content

Commit

Permalink
feat: don't replace functions when text length would increase (#178)
Browse files Browse the repository at this point in the history
## PR Checklist

- [x] Addresses an existing open issue: fixes #3
- [x] That issue was marked as [`status: accepting
prs`](/~https://github.com/JoshuaKGoldberg/ts-function-inliner/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)
- [x] Steps in
[CONTRIBUTING.md](/~https://github.com/JoshuaKGoldberg/ts-function-inliner/blob/main/.github/CONTRIBUTING.md)
were taken

## Overview

Per the linked issue, this stops the transform from _increasing_ text
size. Long functions will no longer be inlined.

Also adds support for function expressions in variables, as that came up
in threshold testing.
  • Loading branch information
JoshuaKGoldberg authored Jun 3, 2024
1 parent 2ccbf68 commit b35e937
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 31 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"lint-staged": {
"*": "prettier --ignore-unknown --write"
},
"dependencies": {
"cached-factory": "^0.0.2"
},
"devDependencies": {
"@prettier/sync": "^0.5.0",
"@release-it/conventional-changelog": "^8.0.0",
Expand Down
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions src/getFunctionDeclarationFromCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ export function getFunctionDeclarationFromCall(
node: ts.CallExpression,
typeChecker: ts.TypeChecker,
) {
let declaration = typeChecker.getSymbolAtLocation(node.expression)
?.valueDeclaration;
let declaration: ts.Node | undefined = typeChecker.getSymbolAtLocation(
node.expression,
)?.valueDeclaration;

if (!declaration) {
return undefined;
}

if (ts.isVariableDeclaration(declaration)) {
declaration = declaration.initializer;
}

if (!declaration) {
return undefined;
Expand Down
4 changes: 3 additions & 1 deletion src/isFunctionDeclarationWithBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ export const isFunctionWithBody = (
node: ts.Node,
): node is FunctionLikeWithBody => {
return (
(ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) &&
(ts.isFunctionDeclaration(node) ||
ts.isFunctionExpression(node) ||
ts.isMethodDeclaration(node)) &&
!!node.body
);
};
230 changes: 203 additions & 27 deletions src/transformerProgram.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,23 @@ function expectResultToBe(actual: string, expected: string) {
);
}

function expectResultToEndWith(actual: string, expected: string) {
const normalized = normalizeFile(actual);

expect(normalized.indexOf(expected)).toBeCloseTo(
normalized.length - expected.length,
-1,
);
}

describe("transformerProgram", () => {
describe("function contents", () => {
test("BinaryExpression", () => {
const result = getResult(`
function addToStringLength(base: string) {
return base.length + 3;
}
addToStringLength("abc");
`);

Expand All @@ -75,7 +84,7 @@ describe("transformerProgram", () => {
function addToStringLength(base) {
return base.length + 3;
}
"abc".length + 3;
`,
);
Expand All @@ -86,7 +95,7 @@ describe("transformerProgram", () => {
function incrementCount(count: number) {
return count++;
}
const value = 123;
incrementCount(value);
`);
Expand All @@ -97,7 +106,7 @@ describe("transformerProgram", () => {
function incrementCount(count) {
return count++;
}
const value = 123;
value++;
`,
Expand All @@ -109,7 +118,7 @@ describe("transformerProgram", () => {
function isNotEmpty(text: string) {
return !!text.length;
}
isNotEmpty("Boo! 👻");
`);

Expand All @@ -119,55 +128,44 @@ describe("transformerProgram", () => {
function isNotEmpty(text) {
return !!text.length;
}
!!"Boo! 👻".length;
`,
);
});
});

test("function kind", () => {
describe("function kinds", () => {
test("FunctionExpression in object property", () => {
const result = getResult(`
const Utils = {
isNotEmpty: function (text: string) {
return !!text.length;
}
}
Utils.isNotEmpty("Boo! 👻");
`);

expectResultToBe(
result,
`
const Utils = {
isNotEmpty: function (text) {
return !!text.length;
}
}
!!"Boo! 👻".length;
`,
);
expectResultToEndWith(result, `!!"Boo! 👻".length;`);
});

test("FunctionExpression in variable", () => {
const result = getResult(`
const isNotEmpty = function (text: string) {
const isTextNotEmpty = function (text: string) {
return !!text.length;
}
isNotEmpty("Boo! 👻");
};
isTextNotEmpty("Boo! 👻");
`);

expectResultToBe(
result,
`
const isNotEmpty = function (text) {
const isTextNotEmpty = function (text) {
return !!text.length;
}
};
!!"Boo! 👻".length;
`,
);
Expand Down Expand Up @@ -196,4 +194,182 @@ describe("transformerProgram", () => {
);
});
});

describe("size thresholds", () => {
describe("FunctionExpressions: inline", () => {
test("longer name than body", () => {
const result = getResult(`
const Utils = {
longerName: function longerName(a: number) {
return a + 1.2;
},
};
Utils.longerName(3);
`);

expectResultToEndWith(result, "3 + 1.2");
});

test("shorter name than body", () => {
const result = getResult(`
const Utils = {
shorterName: function shorterName(a: number) {
return a + 1.000000000000000002;
},
};
Utils.shorterName(3);
`);

expectResultToEndWith(result, "Utils.shorterName(3);");
});
});

describe("FunctionExpressions: method", () => {
test("longer name than body", () => {
const result = getResult(`
const Utils = {
longerName(a: number) {
return a + 1.2;
};
}
Utils.longerName(3);
`);

expectResultToEndWith(result, `3 + 1.2;`);
});

test("shorter name than body", () => {
const result = getResult(`
const Utils = {
shortName(a: number) {
return a + 1.000000000000000002;
}
};
Utils.shortName(3);
`);

expectResultToEndWith(result, `Utils.shortName(3);`);
});
});

describe("FunctionExpressions: property", () => {
test("longer name than body", () => {
const result = getResult(`
const Utils = {
longerName: function (a: number) {
return a + 1.2;
}
};
Utils.longerName(3);
`);

expectResultToEndWith(result, `3 + 1.2;`);
});

test("shorter name than body", () => {
const result = getResult(`
const Utils = {
shortName: function(a: number) {
return a + 1.000000000000000002;
}
};
Utils.shortName(3);
`);

expectResultToEndWith(result, `Utils.shortName(3);`);
});
});

describe("property FunctionDeclarations", () => {
test("longer name than body", () => {
const result = getResult(`
function longerName(a: number) {
return a + 1.2;
}
const Utils = { longerName: longerName };
Utils.longerName(3);
`);

expectResultToEndWith(result, `3 + 1.2;`);
});

test("shorter name than body", () => {
const result = getResult(`
function shorterName(a: number) {
return a + 1.000000000000000002;
}
const Utils = { shorterName: shorterName };
Utils.shorterName(3);
`);

expectResultToEndWith(result, `Utils.shorterName(3);`);
});
});

describe("shorthand property FunctionDeclarations", () => {
test("longer name than body", () => {
const result = getResult(`
function longerName(a: number) {
return a + 1.2;
}
const Utils = { longerName };
Utils.longerName(3);
`);

expectResultToEndWith(result, `3 + 1.2;`);
});

test("shorter name than body", () => {
const result = getResult(`
function shorterName(a: number) {
return a + 1.000000000000000002;
}
const Utils = { shorterName };
Utils.shorterName(3);
`);

expectResultToEndWith(result, `Utils.shorterName(3);`);
});
});

describe("standalone FunctionDeclarations", () => {
test("longer name than body", () => {
const result = getResult(`
function longerName(a: number) {
return a + 1.2;
}
longerName(3);
`);

expectResultToEndWith(result, `3 + 1.2;`);
});

test("shorter name than body", () => {
const result = getResult(`
function shorterName(a: number) {
return a + 1.000000000000000002;
}
shorterName(3);
`);

expectResultToEndWith(result, `shorterName(3);`);
});
});
});
});
Loading

0 comments on commit b35e937

Please sign in to comment.