X Tutup
Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/transformation/utils/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ export function popScope(context: TransformationContext): Scope {
return scope;
}

function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) {
function isHoistableFunctionDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) {
return symbol?.declarations?.some(
d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) && !ts.isParameter(d.parent)
d => ts.isFunctionDeclaration(d) && findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)
);
}

Expand All @@ -109,7 +109,7 @@ export function hasReferencedUndefinedLocalFunction(context: TransformationConte
if (
!scope.functionDefinitions?.has(symbolId) &&
type.getCallSignatures().length > 0 &&
isDeclaredInScope(type.symbol, scope.node)
isHoistableFunctionDeclaredInScope(type.symbol, scope.node)
) {
return true;
}
Expand Down
33 changes: 33 additions & 0 deletions test/unit/__snapshots__/spread.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,24 @@ end
return ____exports"
`;

exports[`vararg spread optimization curry with indirect type 1`] = `
"local ____exports = {}
function ____exports.__main(self)
local function test(self, obj, ...)
local fn = obj.fn
return fn(nil, ...)
end
return test(
nil,
{
fn = function(____, arg) return arg end
},
\\"foobar\\"
)
end
return ____exports"
`;

exports[`vararg spread optimization finally clause 1`] = `
"local ____exports = {}
function ____exports.__main(self)
Expand All @@ -105,6 +123,21 @@ end
return ____exports"
`;

exports[`vararg spread optimization function type declared inside scope 1`] = `
"local ____exports = {}
function ____exports.__main(self)
local function test(self, ...)
local function fn(____, ...)
local args = {...}
return args[1]
end
return fn(nil, ...)
end
test(nil, \\"foobar\\")
end
return ____exports"
`;

exports[`vararg spread optimization if statement 1`] = `
"local ____exports = {}
function ____exports.__main(self)
Expand Down
24 changes: 24 additions & 0 deletions test/unit/spread.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,30 @@ describe("vararg spread optimization", () => {
.expectLuaToMatchSnapshot()
.expectToMatchJsResult();
});

test("curry with indirect type", () => {
util.testFunction`
function test<A extends any[]>(obj: {fn: (...args: A) => void}, ...args: A) {
const fn = obj.fn;
return fn(...args);
}
return test({fn: (arg: string) => arg}, "foobar");
`
.expectLuaToMatchSnapshot()
.expectToMatchJsResult();
});

test("function type declared inside scope", () => {
util.testFunction`
function test<A extends any[]>(...args: A) {
const fn: (...args: A) => A[0] = (...args) => args[0];
return fn(...args);
}
test("foobar");
`
.expectLuaToMatchSnapshot()
.expectToMatchJsResult();
});
});

describe("vararg spread de-optimization", () => {
Expand Down
X Tutup