From 158eaba8265ceb344fb04ef6165ca48e209f6e4c Mon Sep 17 00:00:00 2001 From: ZhongNing Date: Wed, 25 Jun 2025 17:32:43 +0800 Subject: [PATCH] Add checks for arkts-promise-void-resolve Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICHJB7 Test scenarios: new tests added to the linter Signed-off-by: ZhongNing --- ets2panda/linter/src/lib/CookBookMsg.ts | 2 + ets2panda/linter/src/lib/FaultAttrs.ts | 1 + ets2panda/linter/src/lib/FaultDesc.ts | 1 + ets2panda/linter/src/lib/Problems.ts | 1 + ets2panda/linter/src/lib/TypeScriptLinter.ts | 44 +++++++++++++++++++ .../src/lib/utils/consts/ArkTS2Rules.ts | 3 +- .../main/arkts_promise_need_void_resolve.ets | 17 +++++++ ...ts_promise_need_void_resolve.ets.args.json | 19 ++++++++ ..._promise_need_void_resolve.ets.arkts2.json | 28 ++++++++++++ .../arkts_promise_need_void_resolve.ets.json | 17 +++++++ 10 files changed, 132 insertions(+), 1 deletion(-) create mode 100755 ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets create mode 100755 ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.args.json create mode 100755 ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.arkts2.json create mode 100755 ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.json diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index 06558eadcd..47b2e67872 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -369,6 +369,8 @@ cookBookTag[377] = cookBookTag[378] = 'Operator is not support (arkts-unsupport-operator)'; cookBookTag[381] = 'The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)'; +cookBookTag[382] = + 'Promiseconstructor only supports using resolve (undefined) (arkts-promise-with-void-type-need-undefined-as-resolve-arg)'; for (let i = 0; i <= cookBookTag.length; i++) { cookBookMsg[i] = ''; diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index 4e22d31370..8ad56ceb82 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -264,3 +264,4 @@ faultsAttrs[FaultID.NumericBigintCompare] = new FaultAttributes(376); faultsAttrs[FaultID.NondecimalBigint] = new FaultAttributes(377); faultsAttrs[FaultID.UnsupportOperator] = new FaultAttributes(378); faultsAttrs[FaultID.StateStylesBlockNeedArrowFunc] = new FaultAttributes(381); +faultsAttrs[FaultID.PromiseVoidNeedResolveArg] = new FaultAttributes(382); \ No newline at end of file diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index 8716e7d241..93eecdb0dd 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -252,3 +252,4 @@ faultDesc[FaultID.PropFunctionNotSupported] = '"prop" function is not supported' faultDesc[FaultID.SetAndPropFunctionNotSupported] = '"setAndProp" function is not supported'; faultDesc[FaultID.PropNeedCallMethodForDeepCopy] = 'Deep copy needs to call the specific method'; faultDesc[FaultID.StateStylesBlockNeedArrowFunc] = 'StateStyles needs arrow function block'; +faultDesc[FaultID.PromiseVoidNeedResolveArg] = 'Promiseconstructor only supports using resolve (undefined)'; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index b0db00e16a..55e32e0f57 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -253,6 +253,7 @@ export enum FaultID { SetAndPropFunctionNotSupported, PropNeedCallMethodForDeepCopy, StateStylesBlockNeedArrowFunc, + PromiseVoidNeedResolveArg, // this should always be last enum LAST_ID } diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 84b5a362bf..5d2959c209 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -5241,6 +5241,50 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } this.handleSendableGenericTypes(tsNewExpr); this.handleInstantiatedJsObject(tsNewExpr, sym); + this.handlePromiseNeedVoidResolve(tsNewExpr); + } + + handlePromiseNeedVoidResolve(newExpr: ts.NewExpression): void { + if (!this.options.arkts2) { + return; + } + + if (!ts.isIdentifier(newExpr.expression) || newExpr.expression.text !== 'Promise') { + return; + } + + const typeArg = newExpr.typeArguments?.[0]; + if (!typeArg) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(typeArg); + if (!(type.getFlags() & ts.TypeFlags.Void)) { + return; + } + + const executor = newExpr.arguments?.[0]; + if (!executor || !ts.isFunctionLike(executor)) { + return; + } + + const resolveParam = executor.parameters[0]; + if (resolveParam?.type) { + if (ts.isFunctionTypeNode(resolveParam.type) && + resolveParam.type.parameters.length === 0) { + this.incrementCounters(resolveParam.type,FaultID.PromiseVoidNeedResolveArg); + } + } + if (executor.body) { + ts.forEachChild(executor.body, node => { + if (ts.isCallExpression(node) && + ts.isIdentifier(node.expression) && + node.expression.text === 'resolve' && + node.arguments.length === 0) { + this.incrementCounters(node,FaultID.PromiseVoidNeedResolveArg); + } + }); + } } private checkCreatingPrimitiveTypes(tsNewExpr: ts.NewExpression): void { diff --git a/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts b/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts index ea727f914a..93fd7922ca 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts @@ -148,7 +148,8 @@ export const arkts2Rules: number[] = [ 375, 376, 377, - 378 + 378, + 382 ]; export const onlyArkts2SyntaxRules: Map = new Map([ diff --git a/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets new file mode 100755 index 0000000000..54a185e6c9 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function test(): Promise{ + return new Promise((resolve: () => void, reject) => { resolve() }) } \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.args.json b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.args.json new file mode 100755 index 0000000000..b9d72da174 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.arkts2.json b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.arkts2.json new file mode 100755 index 0000000000..83f403ba1f --- /dev/null +++ b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.arkts2.json @@ -0,0 +1,28 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 17, + "column": 40, + "endLine": 17, + "endColumn": 50, + "problem": "PromiseVoidNeedResolveArg", + "suggest": "", + "rule": "Promiseconstructor only supports using resolve (undefined) (arkts-promise-with-void-type-need-undefined-as-resolve-arg)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.json b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.json new file mode 100755 index 0000000000..127a98a334 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file -- Gitee