diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index c76987b4d5a7f6a5dff9eb2f356b4c82d7f7ff49..3a00d7f00a93fe74f41d4459926e7299fe2f47f8 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -8584,16 +8584,39 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private isInterfaceImportNeeded(identifier: ts.Identifier): boolean { + const name = identifier.getText(); return ( - arkuiImportList.has(identifier.getText()) && - !skipImportDecoratorName.has(identifier.getText()) && - !this.interfacesAlreadyImported.has(identifier.getText()) && + arkuiImportList.has(name) && + !skipImportDecoratorName.has(name) && + !this.interfacesAlreadyImported.has(name) && !this.isParentAlreadyImported(identifier.parent) && !this.isDeclarationInSameFile(identifier) && + !this.isDeprecatedInterface(identifier) && !TypeScriptLinter.isWrappedByExtendDecorator(identifier) ); } + private isDeprecatedInterface(node: ts.Identifier): boolean { + const symbol = this.tsUtils.trueSymbolAtLocation(node); + const decl = TsUtils.getDeclaration(symbol); + if (!decl) { + return false; + } + + const parName = this.tsUtils.getParentSymbolName(symbol); + const parameters = ts.isFunctionLike(decl) ? decl.parameters : undefined; + const returnType = ts.isFunctionLike(decl) ? decl.type?.getText() : undefined; + const fileName = path.basename(decl.getSourceFile().fileName) + ''; + + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parName === undefined ? DEPRECATE_UNNAMED : parName, + parameters, + returnType, + fileName + ); + return this.isMatchedDeprecatedApi(node.getText(), deprecatedApiCheckMap); + } + private static isWrappedByExtendDecorator(node: ts.Identifier): boolean { const wrappedSkipComponents = new Set([CustomInterfaceName.AnimatableExtend, CustomInterfaceName.Extend]); if (ts.isCallExpression(node.parent)) { diff --git a/ets2panda/linter/test/main/interface_import_5.ets b/ets2panda/linter/test/main/interface_import_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..40a37c6d1f71b41c2537a5c7757a3427b1046d14 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.ets @@ -0,0 +1,39 @@ +/* + * 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. + */ + +import * from './ui_modules/common'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + // 建议使用this.getUIContext().getHostContext() + let context: Context = getContext(this) as Context; + console.info("CacheDir:" + context.cacheDir); + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.args.json b/ets2panda/linter/test/main/interface_import_5.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.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" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_5.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ab357ad279ff77ea2af752ae0ac40dd9db49b6bc --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.ets.arkts2.json @@ -0,0 +1,118 @@ +{ + "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": 31, + "column": 36, + "endLine": 31, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FontWeight\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 26, + "endLine": 31, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.autofix.json b/ets2panda/linter/test/main/interface_import_5.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..0c7503cb107134012bc1620f5d08607ab9b661c7 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.ets.autofix.json @@ -0,0 +1,228 @@ +{ + "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": 31, + "column": 36, + "endLine": 31, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "autofix": [ + { + "start": 967, + "end": 977, + "replacementText": "getUIContext().getHostContext", + "line": 31, + "column": 36, + "endLine": 31, + "endColumn": 46 + } + ], + "suggest": "", + "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"FontWeight\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 26, + "endLine": 31, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.json b/ets2panda/linter/test/main/interface_import_5.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.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 diff --git a/ets2panda/linter/test/main/interface_import_5.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_5.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..577c9eb653c860c85e1bd3fc30815c63857367ec --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.ets.migrate.ets @@ -0,0 +1,51 @@ +/* + * 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. + */ + +import { + Entry, + Component, + State, + Row, + Column, + Text, + FontWeight, + Context, + getUIContext, +} from '@kit.ArkUI'; + +import * from './ui_modules/common'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + // 建议使用this.getUIContext().getHostContext() + let context: Context = getUIContext().getHostContext(this) as Context; + console.info("CacheDir:" + context.cacheDir); + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.migrate.json b/ets2panda/linter/test/main/interface_import_5.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.ets.migrate.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 diff --git a/ets2panda/linter/test/main/ui_modules/common.d.ts b/ets2panda/linter/test/main/ui_modules/common.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0826d63c20edceb60d75502249644a9f16d49e0 --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/common.d.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ + +declare function getContext(component?: Object): Context; \ No newline at end of file