Skip to content

Commit f034d9f

Browse files
authored
fixed vararg optimization logic (#1046)
1 parent a879b97 commit f034d9f

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

src/transformation/utils/scope.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ export function popScope(context: TransformationContext): Scope {
9292
return scope;
9393
}
9494

95-
function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) {
95+
function isHoistableFunctionDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) {
9696
return symbol?.declarations?.some(
97-
d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) && !ts.isParameter(d.parent)
97+
d => ts.isFunctionDeclaration(d) && findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)
9898
);
9999
}
100100

@@ -109,7 +109,7 @@ export function hasReferencedUndefinedLocalFunction(context: TransformationConte
109109
if (
110110
!scope.functionDefinitions?.has(symbolId) &&
111111
type.getCallSignatures().length > 0 &&
112-
isDeclaredInScope(type.symbol, scope.node)
112+
isHoistableFunctionDeclaredInScope(type.symbol, scope.node)
113113
) {
114114
return true;
115115
}

test/unit/__snapshots__/spread.spec.ts.snap

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,24 @@ end
8181
return ____exports"
8282
`;
8383

84+
exports[`vararg spread optimization curry with indirect type 1`] = `
85+
"local ____exports = {}
86+
function ____exports.__main(self)
87+
local function test(self, obj, ...)
88+
local fn = obj.fn
89+
return fn(nil, ...)
90+
end
91+
return test(
92+
nil,
93+
{
94+
fn = function(____, arg) return arg end
95+
},
96+
\\"foobar\\"
97+
)
98+
end
99+
return ____exports"
100+
`;
101+
84102
exports[`vararg spread optimization finally clause 1`] = `
85103
"local ____exports = {}
86104
function ____exports.__main(self)
@@ -105,6 +123,21 @@ end
105123
return ____exports"
106124
`;
107125

126+
exports[`vararg spread optimization function type declared inside scope 1`] = `
127+
"local ____exports = {}
128+
function ____exports.__main(self)
129+
local function test(self, ...)
130+
local function fn(____, ...)
131+
local args = {...}
132+
return args[1]
133+
end
134+
return fn(nil, ...)
135+
end
136+
test(nil, \\"foobar\\")
137+
end
138+
return ____exports"
139+
`;
140+
108141
exports[`vararg spread optimization if statement 1`] = `
109142
"local ____exports = {}
110143
function ____exports.__main(self)

test/unit/spread.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,30 @@ describe("vararg spread optimization", () => {
241241
.expectLuaToMatchSnapshot()
242242
.expectToMatchJsResult();
243243
});
244+
245+
test("curry with indirect type", () => {
246+
util.testFunction`
247+
function test<A extends any[]>(obj: {fn: (...args: A) => void}, ...args: A) {
248+
const fn = obj.fn;
249+
return fn(...args);
250+
}
251+
return test({fn: (arg: string) => arg}, "foobar");
252+
`
253+
.expectLuaToMatchSnapshot()
254+
.expectToMatchJsResult();
255+
});
256+
257+
test("function type declared inside scope", () => {
258+
util.testFunction`
259+
function test<A extends any[]>(...args: A) {
260+
const fn: (...args: A) => A[0] = (...args) => args[0];
261+
return fn(...args);
262+
}
263+
test("foobar");
264+
`
265+
.expectLuaToMatchSnapshot()
266+
.expectToMatchJsResult();
267+
});
244268
});
245269

246270
describe("vararg spread de-optimization", () => {

0 commit comments

Comments
 (0)