From 711d5ec3bf5943b192d1cc952ebd8449d8a50d6c Mon Sep 17 00:00:00 2001 From: sefayilmazunal Date: Tue, 8 Jul 2025 08:49:52 +0300 Subject: [PATCH] AsyncLock autofix Description: autofix added for arkts-limited-stdlib-no-import-concurrency Issue: #ICKQYO Signed-off-by: sefayilmazunal --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 5 +- .../linter/src/lib/autofixes/Autofixer.ts | 64 +++++++++++------ .../src/lib/utils/consts/ArkuiImportList.ts | 70 +++++++++---------- ...rktsutils_locks_asynclock.ets.autofix.json | 38 ---------- ...rktsutils_locks_asynclock.ets.migrate.json | 38 ---------- ...no_support_arktsutils_locks_asynclock.ets} | 4 +- ...t_arktsutils_locks_asynclock.ets.args.json | 21 ++++++ ...rktsutils_locks_asynclock.ets.arkts2.json} | 0 ...rktsutils_locks_asynclock.ets.autofix.json | 60 ++++++++++++++++ ...pport_arktsutils_locks_asynclock.ets.json} | 0 ...rktsutils_locks_asynclock.ets.migrate.ets} | 6 +- ...rktsutils_locks_asynclock.ets.migrate.json | 58 +++++++++++++++ 12 files changed, 223 insertions(+), 141 deletions(-) delete mode 100644 ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.autofix.json delete mode 100644 ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.migrate.json rename ets2panda/linter/test/concurrent/{ no_support_arktsutils_locks_asynclock.ets => no_support_arktsutils_locks_asynclock.ets} (87%) create mode 100644 ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.args.json rename ets2panda/linter/test/concurrent/{ no_support_arktsutils_locks_asynclock.ets.arkts2.json => no_support_arktsutils_locks_asynclock.ets.arkts2.json} (100%) create mode 100644 ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.autofix.json rename ets2panda/linter/test/concurrent/{ no_support_arktsutils_locks_asynclock.ets.json => no_support_arktsutils_locks_asynclock.ets.json} (100%) rename ets2panda/linter/test/concurrent/{ no_support_arktsutils_locks_asynclock.ets.migrate.ets => no_support_arktsutils_locks_asynclock.ets.migrate.ets} (87%) create mode 100644 ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.json diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index ca04dbcfcd..390e30eb58 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -2076,7 +2076,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleObjectLiteralAssignmentToClass(tsBinaryExpr); this.handleAssignmentNotsLikeSmartType(tsBinaryExpr); } - + private handleNumericPublicStatic(node: ts.PropertyDeclaration): void { if (!this.options.arkts2) { return; @@ -7218,7 +7218,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } if (parent.name.text === ARKTSUTILS_LOCKS_MEMBER) { - this.incrementCounters(node, FaultID.LimitedStdLibNoImportConcurrency); + const autofix = this.autofixer?.fixConcurrencyLock(parent); + this.incrementCounters(node, FaultID.LimitedStdLibNoImportConcurrency, autofix); } }; diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index c3cab4c0e3..c968d4a9e8 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -988,11 +988,11 @@ export class Autofixer { const propertyChain: string[] = [propertyName]; let current: ts.Node = node; - + while (current.parent && ts.isElementAccessExpression(current.parent)) { const parentArg = current.parent.argumentExpression; if (ts.isStringLiteral(parentArg)) { - propertyChain.push(parentArg.text); + propertyChain.push(parentArg.text); } current = current.parent; } @@ -2475,17 +2475,15 @@ export class Autofixer { const prev = allSpecifiers[specIndex - 1]; start = prev.getEnd(); } - fixes.push({ - start: start, - end: end, - replacementText: '' - }); + fixes.push({ start: start, end: end, replacementText: '' }); } const alias = specToRemove.name; - const original = specToRemove.propertyName ?? specToRemove.name; - const replacements = this.replaceIdentifierUsages(alias, original.getText()); - fixes.push(...replacements); + const original = specToRemove.propertyName; + if (original) { + const replacements = this.replaceIdentifierUsages(alias, original.getText()); + fixes.push(...replacements); + } return fixes; } @@ -3717,11 +3715,11 @@ export class Autofixer { }); if (items.length > 1) { - const formattedList = items - .map((item) => { + const formattedList = items. + map((item) => { return ` ${item.trim()},`; - }) - .join('\n'); + }). + join('\n'); return `{\n${formattedList}\n}`; } return `{${importList}}`; @@ -4089,6 +4087,26 @@ export class Autofixer { return { replacementText, start: identifier.getStart(), end: identifier.getEnd() }; } + fixConcurrencyLock(locksProp: ts.PropertyAccessExpression): Autofix[] | undefined { + // 1) Ensure the next property is `.AsyncLock` + const asyncLockProp = locksProp.parent; + if (!ts.isPropertyAccessExpression(asyncLockProp)) { + return undefined; + } + + // 2) Find the enclosing `new` expression + const newExpr = asyncLockProp.parent; + if (!ts.isNewExpression(newExpr)) { + return undefined; + } + + const className = asyncLockProp.name.getText(); + const replacement = ts.factory.createNewExpression(ts.factory.createIdentifier(className), undefined, []); + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, replacement, newExpr.getSourceFile()); + + return [{ start: newExpr.getStart(), end: newExpr.getEnd(), replacementText }]; + } + fixSharedArrayBufferConstructor(node: ts.NewExpression): Autofix[] | undefined { void this; @@ -4701,16 +4719,16 @@ export class Autofixer { const expr = callExpr.expression; const hasOptionalChain = !!callExpr.questionDotToken; - const replacementText = hasOptionalChain - ? `${expr.getText()}${callExpr.questionDotToken.getText()}unsafeCall` - : `${expr.getText()}.unsafeCall`; + const replacementText = hasOptionalChain ? + `${expr.getText()}${callExpr.questionDotToken.getText()}unsafeCall` : + `${expr.getText()}.unsafeCall`; return [{ - start: expr.getStart(), - end: hasOptionalChain - ? callExpr.questionDotToken.getEnd() - : expr.getEnd(), - replacementText + start: expr.getStart(), + end: hasOptionalChain ? + callExpr.questionDotToken.getEnd() : + expr.getEnd(), + replacementText }]; } @@ -5120,7 +5138,7 @@ export class Autofixer { fixNumericPublicStatic(node: ts.PropertyDeclaration): Autofix[] | undefined { if (!node?.name || node.type) { - return undefined + return undefined; }; const typeNode = ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); const modifiers = ts.getModifiers(node) || []; diff --git a/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts b/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts index 3beae87577..f8ab0145c5 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts @@ -1616,52 +1616,52 @@ export const arkuiImportList: Set = new Set([ ]); export const arkTsBuiltInTypeName: Set = new Set([ - 'Object', - 'Function', - 'Boolean', - 'Symbol', - 'Number', - 'BigInt', - 'Math', + 'Object', + 'Function', + 'Boolean', + 'Symbol', + 'Number', + 'BigInt', + 'Math', 'Date', - 'String', + 'String', 'RegExp', - 'Array', - 'Int8Array', - 'Uint8Array', - 'Uint8ClampedArray', - 'Int16Array', - 'Uint16Array', - 'Int32Array', + 'Array', + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array', - 'BigInt64Array', + 'BigInt64Array', 'BigUint64Array', - 'Map', - 'Set', + 'Map', + 'Set', 'WeakMap', 'WeakSet', - 'ArrayBuffer', - 'SharedArrayBuffer', - 'DataView', - 'JSON', - 'Promise', - 'Generator', - 'GeneratorFunction', + 'ArrayBuffer', + 'SharedArrayBuffer', + 'DataView', + 'JSON', + 'Promise', + 'Generator', + 'GeneratorFunction', 'AsyncFunction', - 'AsyncGenerator', - 'AsyncGeneratorFunction', - 'Reflect', - 'Proxy', + 'AsyncGenerator', + 'AsyncGeneratorFunction', + 'Reflect', + 'Proxy', 'Error', 'EvalError', - 'RangeError', - 'ReferenceError', - 'SyntaxError', - 'TypeError', - 'URIError', + 'RangeError', + 'ReferenceError', + 'SyntaxError', + 'TypeError', + 'URIError', 'AggregateError', 'Intl', 'WebAssembly' -]); \ No newline at end of file +]); diff --git a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.autofix.json b/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.autofix.json deleted file mode 100644 index 31d218b8f0..0000000000 --- a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.autofix.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "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": 18, - "column": 28, - "endLine": 18, - "endColumn": 33, - "problem": "LimitedStdLibNoImportConcurrency", - "suggest": "", - "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 28, - "endLine": 20, - "endColumn": 33, - "problem": "LimitedStdLibNoImportConcurrency", - "suggest": "", - "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.migrate.json b/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.migrate.json deleted file mode 100644 index 31d218b8f0..0000000000 --- a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.migrate.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "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": 18, - "column": 28, - "endLine": 18, - "endColumn": 33, - "problem": "LimitedStdLibNoImportConcurrency", - "suggest": "", - "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 28, - "endLine": 20, - "endColumn": 33, - "problem": "LimitedStdLibNoImportConcurrency", - "suggest": "", - "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets similarity index 87% rename from ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets rename to ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets index 3ad92e0865..d94d1d8c0e 100644 --- a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets @@ -15,6 +15,6 @@ import { ArkTSUtils } from '../main/oh_modules/@kit.ArkTS'; -let lock1 = new ArkTSUtils.locks.AsyncLock(); +let lock1 = new ArkTSUtils.locks.AsyncLock(); -let lock2 = new ArkTSUtils.locks.AsyncLock(); \ No newline at end of file +let lock2 = new ArkTSUtils.locks.AsyncLock(); diff --git a/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.args.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.args.json new file mode 100644 index 0000000000..6958168fef --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.args.json @@ -0,0 +1,21 @@ +{ + "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": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.arkts2.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.arkts2.json similarity index 100% rename from ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.arkts2.json rename to ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.arkts2.json diff --git a/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.autofix.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.autofix.json new file mode 100644 index 0000000000..34839afbd9 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.autofix.json @@ -0,0 +1,60 @@ +{ + "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": 18, + "column": 28, + "endLine": 18, + "endColumn": 33, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 678, + "end": 710, + "replacementText": "new AsyncLock()", + "line": 18, + "column": 28, + "endLine": 18, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 33, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 725, + "end": 757, + "replacementText": "new AsyncLock()", + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.json similarity index 100% rename from ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.json rename to ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.json diff --git a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.migrate.ets b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.ets similarity index 87% rename from ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.migrate.ets rename to ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.ets index c8cd4f5b48..e4b1c6ec60 100644 --- a/ets2panda/linter/test/concurrent/ no_support_arktsutils_locks_asynclock.ets.migrate.ets +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.ets @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + import { ArkTSUtils } from '../main/oh_modules/@kit.ArkTS'; -let lock1 = new ArkTSUtils.locks.AsyncLock(); +let lock1 = new AsyncLock(); -let lock2 = new ArkTSUtils.locks.AsyncLock(); \ No newline at end of file +let lock2 = new AsyncLock(); diff --git a/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.json new file mode 100644 index 0000000000..7b88b28ed4 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 18, + "column": 5, + "endLine": 18, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 17, + "endLine": 18, + "endColumn": 26, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 26, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} -- Gitee