From 1bd2ae4e2bd97010230e31a931e91acccb3c9f69 Mon Sep 17 00:00:00 2001 From: zhong_ning Date: Thu, 14 Aug 2025 12:04:23 +0800 Subject: [PATCH] fix issue for arkts-incompatible-function-types Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICSNPO Test scenarios: arkts-incompatible-function-types Signed-off-by: zhong_ning --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 60 +++++++++++ .../test/main/incompatible_function.ets | 66 ++++++++++++ .../incompatible_function.ets.arkts2.json | 100 ++++++++++++++++++ .../test/main/incompatible_function.ets.json | 93 +++++++++++++++- 4 files changed, 318 insertions(+), 1 deletion(-) diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index c2f34353a2..719c89c9d9 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -6273,6 +6273,66 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkAssignmentMatching(tsArg, tsParamType, tsArg); } } + this.checkOnClickCallback(tsCallOrNewExpr); + } + +private checkOnClickCallback(tsCallOrNewExpr: ts.CallExpression | ts.NewExpression): void { + if (!tsCallOrNewExpr.arguments || tsCallOrNewExpr.arguments.length === 0 && this.options.arkts2) { + return; + } + + const isOnClick = + ts.isPropertyAccessExpression(tsCallOrNewExpr.expression) && tsCallOrNewExpr.expression.name.text === 'onClick'; + if (!isOnClick) { + return; + } + + const objType = this.tsTypeChecker.getTypeAtLocation(tsCallOrNewExpr.expression.expression); + const declNode = TsUtils.getDeclaration(objType.getSymbol()); + if (declNode) { + const fileName = declNode.getSourceFile().fileName; + if (!fileName.includes('@ohos/')) { + return; + } + } + + const callback = tsCallOrNewExpr.arguments[0]; + if (!ts.isArrowFunction(callback)) { + return; + } + + this.checkAsyncOrPromiseFunction(callback); + } + + private checkAsyncOrPromiseFunction(callback: ts.ArrowFunction): void { + const returnsPromise = this.checkReturnsPromise(callback); + const isAsync = callback.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.AsyncKeyword; + }); + + if (isAsync || returnsPromise) { + const startPos = callback.modifiers?.[0]?.getStart() ?? callback.getStart(); + const endPos = callback.body.getEnd(); + + const errorNode = { + getStart: () => { return startPos; }, + getEnd: () => { return endPos; }, + getSourceFile: () => { return callback.getSourceFile(); } + } as ts.Node; + + this.incrementCounters(errorNode, FaultID.IncompationbleFunctionType); + } + } + + private checkReturnsPromise(callback: ts.ArrowFunction): boolean { + const callbackType = this.tsTypeChecker.getTypeAtLocation(callback); + const signatures = this.tsTypeChecker.getSignaturesOfType(callbackType, ts.SignatureKind.Call); + if (signatures.length === 0) { + return false; + } + + const returnType = this.tsTypeChecker.getReturnTypeOfSignature(signatures[0]); + return !!returnType.getProperty('then'); } private static readonly LimitedApis = new Map | null; fault: FaultID }>([ diff --git a/ets2panda/linter/test/main/incompatible_function.ets b/ets2panda/linter/test/main/incompatible_function.ets index 4330949c71..1701ac0932 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets +++ b/ets2panda/linter/test/main/incompatible_function.ets @@ -134,4 +134,70 @@ class E { Dfun(a: X|Y): X { return a; } +} + +import { Entry, Text, Column, Component, Button, ClickEvent ,Image ,ShadowOptions} from '@ohos.arkui.component' +import { State } from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog' +import util from '@ohos.util'; + +@Entry +@Component +struct MyStateSample { + @State stateVar: string = 'state var'; + message: string = 'var'; + + changeValue() { + this.getUIContext(); + this.stateVar += '~' + } + + build() { + Column(undefined) { + Text('Hello World').fontSize(20) + Button(this.message).backgroundColor('#FFFF00FF') + .onClick(async (e: ClickEvent) => { + let lock: AsyncLock = AsyncLock.request("lock_1"); + hilog.info(0x0000, 'testTag', 'On Click'); + let a = this.getUIContext(); + this.changeValue(); + + }) + Text(this.stateVar).fontSize(20) + .onClick((e: ClickEvent) => { + this.message += "~" + } as (event: ClickEvent) => void) + Child({ stateVar: this.stateVar }) + } + } +} + +interface CustomClickable { + onClick(handler: (event: ClickEvent) => void): this; +} + +function onClick(handler: (event: ClickEvent) => void): this { + return this.onClick((e: ClickEvent) => { + console.log('Before custom onClick'); + handler(e); + console.log('After custom onClick'); + }); +} + +// 将扩展方法附加到Button组件 +Button.extend({ onClick }); + +@Entry +@Component +struct MyComponent { + @State message: string = 'Click me'; + + build() { + Column() { + Button(this.message) + .onClick((e: ClickEvent) => { + this.message = 'Custom onClick worked!'; + }) + } + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json b/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json index 31c19f7df3..5b2f2475b0 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json +++ b/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json @@ -123,6 +123,106 @@ "suggest": "", "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" + }, + { + "line": 139, + "column": 1, + "endLine": 139, + "endColumn": 112, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 1, + "endLine": 140, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 1, + "endLine": 141, + "endColumn": 32, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 1, + "endLine": 142, + "endColumn": 31, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 18, + "endLine": 165, + "endColumn": 10, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 15, + "endLine": 162, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 37, + "endLine": 169, + "endColumn": 41, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 50, + "endLine": 176, + "endColumn": 54, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 10, + "endLine": 180, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 57, + "endLine": 179, + "endColumn": 61, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/incompatible_function.ets.json b/ets2panda/linter/test/main/incompatible_function.ets.json index 2844fc25ba..e2e1afdc24 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets.json +++ b/ets2panda/linter/test/main/incompatible_function.ets.json @@ -13,5 +13,96 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 139, + "column": 1, + "endLine": 139, + "endColumn": 112, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 1, + "endLine": 140, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 1, + "endLine": 141, + "endColumn": 32, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 1, + "endLine": 142, + "endColumn": 31, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 18, + "endLine": 165, + "endColumn": 10, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 15, + "endLine": 162, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 50, + "endLine": 176, + "endColumn": 54, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 10, + "endLine": 180, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 57, + "endLine": 179, + "endColumn": 61, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] } \ No newline at end of file -- Gitee