From 165567968a15116731011c41664d0053d3bb54a9 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 11 Sep 2024 17:47:35 +0200 Subject: [PATCH 1/3] Resolve bug inferring context type from generic functions in type parameters --- src/transformation/utils/function-context.ts | 9 ++++++++- .../validFunctionAssignments.spec.ts | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 3055c4f53..0dccc72af 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import { CompilerOptions } from "../../CompilerOptions"; import { TransformationContext } from "../context"; import { AnnotationKind, getFileAnnotations, getNodeAnnotations } from "./annotations"; -import { findFirstNodeAbove, getAllCallSignatures, inferAssignedType } from "./typescript"; +import { findFirstNodeAbove, findFirstNonOuterParent, getAllCallSignatures, inferAssignedType } from "./typescript"; export enum ContextType { None = 0, @@ -118,6 +118,13 @@ function computeDeclarationContextType(context: TransformationContext, signature return ContextType.Void; } + if ( + ts.isArrowFunction(signatureDeclaration) && + ts.isCallExpression(findFirstNonOuterParent(signatureDeclaration)) + ) { + return ContextType.Void; + } + if ( ts.isMethodSignature(signatureDeclaration) || ts.isMethodDeclaration(signatureDeclaration) || diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index 7a68d0ea6..eea8cf53e 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -248,3 +248,21 @@ test("Does not fail on union type signatures (#896)", () => { ) .expectToHaveNoDiagnostics(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1568 +test("No false positives when using generic functions (#1568)", () => { + util.testModule` + /** @noSelf */ + declare namespace Test { + export function testCallback void>( + callback: T, + ): void; + export function testCallback2( + callback: (...args: any[]) => void, + ): void; + } + + Test.testCallback(() => {}); + Test.testCallback2(() => {}); + `.expectToHaveNoDiagnostics(); +}); From 3d8810490c05f6f4026cdfadc754197ef6b7f1ab Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 21 Sep 2024 16:35:26 +0200 Subject: [PATCH 2/3] remove previous fix --- src/transformation/utils/function-context.ts | 9 +-------- .../validation/validFunctionAssignments.spec.ts | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 0dccc72af..3055c4f53 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import { CompilerOptions } from "../../CompilerOptions"; import { TransformationContext } from "../context"; import { AnnotationKind, getFileAnnotations, getNodeAnnotations } from "./annotations"; -import { findFirstNodeAbove, findFirstNonOuterParent, getAllCallSignatures, inferAssignedType } from "./typescript"; +import { findFirstNodeAbove, getAllCallSignatures, inferAssignedType } from "./typescript"; export enum ContextType { None = 0, @@ -118,13 +118,6 @@ function computeDeclarationContextType(context: TransformationContext, signature return ContextType.Void; } - if ( - ts.isArrowFunction(signatureDeclaration) && - ts.isCallExpression(findFirstNonOuterParent(signatureDeclaration)) - ) { - return ContextType.Void; - } - if ( ts.isMethodSignature(signatureDeclaration) || ts.isMethodDeclaration(signatureDeclaration) || diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index eea8cf53e..70838073f 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -250,7 +250,7 @@ test("Does not fail on union type signatures (#896)", () => { }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1568 -test("No false positives when using generic functions (#1568)", () => { +test.only("No false positives when using generic functions (#1568)", () => { util.testModule` /** @noSelf */ declare namespace Test { From 36077bc5308f4139cb08e7dfa34533df37d1c089 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 24 Sep 2024 21:21:02 +0200 Subject: [PATCH 3/3] Fix false positive due to incorrect inference of generic function contraint --- src/transformation/utils/function-context.ts | 4 ++++ .../validation/validFunctionAssignments.spec.ts | 9 ++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 3055c4f53..5b2c0cb4e 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -140,6 +140,10 @@ function computeDeclarationContextType(context: TransformationContext, signature return ContextType.NonVoid; } + if (signatureDeclaration.parent && ts.isTypeParameterDeclaration(signatureDeclaration.parent)) { + return ContextType.NonVoid; + } + // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. const program = context.program; const options = program.getCompilerOptions() as CompilerOptions; diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index 70838073f..525b95929 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -250,19 +250,18 @@ test("Does not fail on union type signatures (#896)", () => { }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1568 -test.only("No false positives when using generic functions (#1568)", () => { +test("No false positives when using generic functions (#1568)", () => { util.testModule` /** @noSelf */ declare namespace Test { export function testCallback void>( callback: T, ): void; - export function testCallback2( - callback: (...args: any[]) => void, - ): void; } Test.testCallback(() => {}); - Test.testCallback2(() => {}); + + const f = () => {}; + Test.testCallback(f); `.expectToHaveNoDiagnostics(); });