Skip to content

Commit a624d0d

Browse files
committed
respect @noself on interface containing call signature
1 parent ef946a3 commit a624d0d

3 files changed

Lines changed: 71 additions & 0 deletions

File tree

src/transformation/utils/function-context.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,19 @@ function computeDeclarationContextType(context: TransformationContext, signature
143143
return ContextType.NonVoid;
144144
}
145145

146+
// Call signature inside a class or interface respects @noSelf on the enclosing class/interface
147+
if (ts.isCallSignatureDeclaration(signatureDeclaration)) {
148+
const scopeDeclaration = findFirstNodeAbove(
149+
signatureDeclaration,
150+
(n): n is ts.ClassLikeDeclaration | ts.InterfaceDeclaration =>
151+
ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n)
152+
);
153+
154+
if (scopeDeclaration !== undefined && getNodeAnnotations(scopeDeclaration).has(AnnotationKind.NoSelf)) {
155+
return ContextType.Void;
156+
}
157+
}
158+
146159
// When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule.
147160
const program = context.program;
148161
const options = program.getCompilerOptions() as CompilerOptions;

test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
exports[`@noSelf on declared function removes context argument 1`] = `"myFunction()"`;
44

5+
exports[`@noSelf on interface with call signature removes context argument 1`] = `
6+
"func = function()
7+
end
8+
func()"
9+
`;
10+
511
exports[`@noSelf on method inside class declaration removes context argument 1`] = `"holder.myMethod()"`;
612

713
exports[`@noSelf on method inside interface declaration removes context argument 1`] = `"holder.myMethod()"`;
@@ -10,6 +16,18 @@ exports[`@noSelf on method inside namespace declaration removes context argument
1016

1117
exports[`@noSelf on parent class declaration removes context argument 1`] = `"holder.myMethod()"`;
1218

19+
exports[`@noSelf on parent interface applies to property with interface call-signature type 1`] = `
20+
"demo = {func = function()
21+
end}
22+
demo.func()"
23+
`;
24+
25+
exports[`@noSelf on parent interface applies to property with type-literal call signature 1`] = `
26+
"demo = {func = function()
27+
end}
28+
demo.func()"
29+
`;
30+
1331
exports[`@noSelf on parent interface declaration removes context argument 1`] = `"holder.myMethod()"`;
1432

1533
exports[`@noSelf on parent namespace declaration removes context argument 1`] = `"MyNamespace.myMethod()"`;

test/unit/functions/noSelfAnnotation.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,46 @@ test("@noSelf on static class methods with string key access", () => {
6565
`.expectLuaToMatchSnapshot();
6666
});
6767

68+
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1661
69+
test("@noSelf on interface with call signature removes context argument", () => {
70+
util.testModule`
71+
/** @noSelf */
72+
interface CallSignature {
73+
(): void;
74+
}
75+
const func: CallSignature = () => {};
76+
func();
77+
`.expectLuaToMatchSnapshot();
78+
});
79+
80+
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1661
81+
test("@noSelf on parent interface applies to property with interface call-signature type", () => {
82+
util.testModule`
83+
/** @noSelf */
84+
interface CallSignature {
85+
(): void;
86+
}
87+
/** @noSelf */
88+
interface DemoType {
89+
func: CallSignature;
90+
}
91+
const demo: DemoType = { func: () => {} };
92+
demo.func();
93+
`.expectLuaToMatchSnapshot();
94+
});
95+
96+
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1661
97+
test("@noSelf on parent interface applies to property with type-literal call signature", () => {
98+
util.testModule`
99+
/** @noSelf */
100+
interface DemoType {
101+
func: { (): void };
102+
}
103+
const demo: DemoType = { func: () => {} };
104+
demo.func();
105+
`.expectLuaToMatchSnapshot();
106+
});
107+
68108
// additional coverage for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1292
69109
test("explicit this parameter respected over @noSelf", () => {
70110
util.testModule`

0 commit comments

Comments
 (0)