From 29d07c8645b4b1de9de98cad131c859df5360f98 Mon Sep 17 00:00:00 2001 From: Igor Rossinski Date: Fri, 15 Mar 2024 04:25:49 +0300 Subject: [PATCH] [ArkTS Linter] issue #15218 - autfix for multiple static blocks Signed-off-by: Igor Rossinski --- ets2panda/linter/lib/TypeScriptLinter.ts | 17 ++++++++----- .../linter/lib/autofixes/AutofixTitles.ts | 1 + ets2panda/linter/lib/autofixes/Autofixer.ts | 16 +++++++++++++ .../test/class_static_block.ts.autofix.json | 24 +++++++++++++++++++ .../test/class_static_block.ts.autofix.skip | 14 ----------- .../linter/test_rules/rule16.ts.autofix.json | 24 +++++++++++++++++++ .../linter/test_rules/rule16.ts.autofix.skip | 14 ----------- 7 files changed, 76 insertions(+), 34 deletions(-) create mode 100644 ets2panda/linter/test/class_static_block.ts.autofix.json delete mode 100644 ets2panda/linter/test/class_static_block.ts.autofix.skip create mode 100644 ets2panda/linter/test_rules/rule16.ts.autofix.json delete mode 100644 ets2panda/linter/test_rules/rule16.ts.autofix.skip diff --git a/ets2panda/linter/lib/TypeScriptLinter.ts b/ets2panda/linter/lib/TypeScriptLinter.ts index 350da098e5..e3a2c71819 100644 --- a/ets2panda/linter/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/lib/TypeScriptLinter.ts @@ -1348,14 +1348,19 @@ export class TypeScriptLinter { } private processClassStaticBlocks(classDecl: ts.ClassDeclaration): void { - let hasStaticBlock = false; + let staticBlocksCntr = 0; + const staticBlockNodes: ts.Node[] = []; for (const element of classDecl.members) { if (ts.isClassStaticBlockDeclaration(element)) { - if (hasStaticBlock) { - this.incrementCounters(element, FaultID.MultipleStaticBlocks); - } else { - hasStaticBlock = true; - } + staticBlockNodes[staticBlocksCntr] = element; + staticBlocksCntr++; + } + } + if (staticBlocksCntr > 1) { + const autofix = this.autofixer?.fixMultipleStaticBlocks(staticBlockNodes); + // autofixes for all additional static blocks are the same + for (let i = 1; i < staticBlocksCntr; i++) { + this.incrementCounters(staticBlockNodes[i], FaultID.MultipleStaticBlocks, autofix); } } } diff --git a/ets2panda/linter/lib/autofixes/AutofixTitles.ts b/ets2panda/linter/lib/autofixes/AutofixTitles.ts index cfe1abcaf7..69b5430bef 100644 --- a/ets2panda/linter/lib/autofixes/AutofixTitles.ts +++ b/ets2panda/linter/lib/autofixes/AutofixTitles.ts @@ -17,6 +17,7 @@ export const cookBookRefToFixTitle: Map = new Map([ [1, 'Replace property name with identifier'], [3, 'Replace with \'private\' modifier'], + [16, 'Combine static block statements into one static block'], [25, 'Replace with field declaration'], [29, 'Replace with dot notation'], [46, 'Convert to arrow function'], diff --git a/ets2panda/linter/lib/autofixes/Autofixer.ts b/ets2panda/linter/lib/autofixes/Autofixer.ts index da63c5279c..ea0f2fa1ea 100644 --- a/ets2panda/linter/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/lib/autofixes/Autofixer.ts @@ -477,6 +477,22 @@ export class Autofixer { return [{ start: tsFunctionDeclaration.getStart(), end: tsFunctionDeclaration.getEnd(), replacementText: text }]; } + fixMultipleStaticBlocks(nodes: ts.Node[]): Autofix[] | undefined { + const autofix: Autofix[] | undefined = []; + let body = (nodes[0] as ts.ClassStaticBlockDeclaration).body; + let bodyStatements: ts.Statement[] = []; + bodyStatements = bodyStatements.concat(body.statements); + for (let i = 1; i < nodes.length; i++) { + bodyStatements = bodyStatements.concat((nodes[i] as ts.ClassStaticBlockDeclaration).body.statements); + autofix[i] = { start: nodes[i].getStart(), end: nodes[i].getEnd(), replacementText: '' }; + } + body = ts.factory.createBlock(bodyStatements, true); + // static blocks shouldn't have modifiers + const statickBlock = ts.factory.createClassStaticBlockDeclaration(body); + const text = this.printer.printNode(ts.EmitHint.Unspecified, statickBlock, nodes[0].getSourceFile()); + autofix[0] = { start: nodes[0].getStart(), end: nodes[0].getEnd(), replacementText: text }; + return autofix; + } private readonly privateIdentifierCache = new Map(); diff --git a/ets2panda/linter/test/class_static_block.ts.autofix.json b/ets2panda/linter/test/class_static_block.ts.autofix.json new file mode 100644 index 0000000000..50133db9e1 --- /dev/null +++ b/ets2panda/linter/test/class_static_block.ts.autofix.json @@ -0,0 +1,24 @@ +{ + "nodes": [ + { + "line": 23, + "column": 3, + "problem": "MultipleStaticBlocks", + "autofixable": true, + "autofix": [ + { + "start": 642, + "end": 674, + "replacementText": "static {\n C.s = 'string';\n C.n = C.s.length;\n}" + }, + { + "start": 698, + "end": 732, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Only one static block is supported (arkts-no-multiple-static-blocks)" + } + ] +} diff --git a/ets2panda/linter/test/class_static_block.ts.autofix.skip b/ets2panda/linter/test/class_static_block.ts.autofix.skip deleted file mode 100644 index 13982e9c91..0000000000 --- a/ets2panda/linter/test/class_static_block.ts.autofix.skip +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2023-2024 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. - */ diff --git a/ets2panda/linter/test_rules/rule16.ts.autofix.json b/ets2panda/linter/test_rules/rule16.ts.autofix.json new file mode 100644 index 0000000000..97fd192931 --- /dev/null +++ b/ets2panda/linter/test_rules/rule16.ts.autofix.json @@ -0,0 +1,24 @@ +{ + "nodes": [ + { + "line": 22, + "column": 5, + "problem": "MultipleStaticBlocks", + "autofixable": true, + "autofix": [ + { + "start": 646, + "end": 679, + "replacementText": "static {\n C.s = \"aa\";\n C.s = C.s + \"bb\";\n}" + }, + { + "start": 684, + "end": 723, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Only one static block is supported (arkts-no-multiple-static-blocks)" + } + ] +} diff --git a/ets2panda/linter/test_rules/rule16.ts.autofix.skip b/ets2panda/linter/test_rules/rule16.ts.autofix.skip deleted file mode 100644 index 13982e9c91..0000000000 --- a/ets2panda/linter/test_rules/rule16.ts.autofix.skip +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2023-2024 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. - */ -- Gitee