diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json index e6a8017193e9c249bc88e3f1ca9ccf98f4639d94..556c6afb512740191480593bb154249a2c6025dc 100644 --- a/ets2panda/linter/rule-config.json +++ b/ets2panda/linter/rule-config.json @@ -43,6 +43,7 @@ "arkts-class-static-initialization", "arkts-invalid-identifier", "arkts-no-import-json-file", + "arkts-no-import-namespace-with-star-as-var", "arkts-no-extends-expression", "arkts-no-ts-like-function-call", "arkts-method-inherit-rule", diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index a99f72046c0ea148319576a5c3979911e5a9ed05..bc58627a76cd63a4fc0ab355d695f65b3bb2b12b 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -267,6 +267,7 @@ cookBookTag[237] = 'Array and tuple are different type(arkts-no-tuples-arrays)'; cookBookTag[238] = 'The static property has no initializer (arkts-class-static-initialization)'; cookBookTag[239] = 'This keyword cannot be used as identifiers (arkts-invalid-identifier)'; cookBookTag[245] = 'JSON files cannot be imported (arkts-no-import-json-file)'; +cookBookTag[249] = 'The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)'; cookBookTag[251] = '"!!" for bidirectional data binding is not supported (arkui-no-!!-bidirectional-data-binding)'; cookBookTag[252] = '"$$" for bidirectional data binding is not supported (arkui-no-$$-bidirectional-data-binding)'; cookBookTag[253] = '"${variable}" for decorator binding is not supported (arkui-link-decorator-passing)'; diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index 24902b1ec9be55ebb71d987607070802238dfc54..db0782ff97ca777838979c6d5eaf6a4fcbc28d1f 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -176,6 +176,7 @@ faultsAttrs[FaultID.NoTuplesArrays] = new FaultAttributes(237); faultsAttrs[FaultID.ClassstaticInitialization] = new FaultAttributes(238); faultsAttrs[FaultID.InvalidIdentifier] = new FaultAttributes(239); faultsAttrs[FaultID.NoImportJsonFile] = new FaultAttributes(245); +faultsAttrs[FaultID.NoImportNamespaceStarAsVar] = new FaultAttributes(249); faultsAttrs[FaultID.DoubleExclaBindingNotSupported] = new FaultAttributes(251); faultsAttrs[FaultID.DoubleDollarBindingNotSupported] = new FaultAttributes(252); faultsAttrs[FaultID.DollarBindingNotSupported] = new FaultAttributes(253); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index 25fe395b073c1a37b74217053bc5f3b9b967664a..870641ded773ac8ff750be35f422fbb55959c33c 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -171,6 +171,7 @@ faultDesc[FaultID.AvoidUnionTypes] = 'Union types'; faultDesc[FaultID.TaggedTemplates] = 'Tagged template'; faultDesc[FaultID.InvalidIdentifier] = 'Invalid identifiers'; faultDesc[FaultID.NoImportJsonFile] = 'No import JSON file'; +faultDesc[FaultID.NoImportNamespaceStarAsVar] = 'No import namespace star as var'; faultDesc[FaultID.ExtendsExpression] = 'Extends Expression'; faultDesc[FaultID.NumericSemantics] = 'Numeric semantics'; faultDesc[FaultID.AnimatableExtendDecoratorTransform] = '"@AnimatableExtend" decorator'; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index ab24db5928960e58ed088f0fd98e4bb03b95d9b4..77278cfff44c4f6e4f64dd7c844d5aa4cbc88967 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -171,6 +171,7 @@ export enum FaultID { IncompationbleFunctionType, InvalidIdentifier, NoImportJsonFile, + NoImportNamespaceStarAsVar, ExtendsExpression, NumericSemantics, AnimatableExtendDecoratorTransform, diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 9a0f958dd60d3038f55a62e81d0ad1584875003d..a477cb0db4263e3906925dbf8b65e45d5c09276a 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -4358,6 +4358,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (isNewArkTS && this.tsTypeChecker.isArgumentsSymbol(tsIdentSym)) { this.incrementCounters(node, FaultID.ArgumentsObject); } + this.checkInvalidNamespaceUsage(node); } private handlePropertyDescriptorInScenarios(node: ts.Node): void { @@ -4432,6 +4433,30 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private checkInvalidNamespaceUsage(node: ts.Identifier): void { + if (!this.options.arkts2) { + return; + } + if (ts.isNamespaceImport(node.parent)) { + return; + } + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + if (!symbol) { + return; + } + const isNamespace = symbol.declarations?.some((decl) => { + return ts.isNamespaceImport(decl); + }); + if (!isNamespace) { + return; + } + const parent = node.parent; + const isValidUsage = ts.isPropertyAccessExpression(parent) && parent.expression === node; + if (!isValidUsage) { + this.incrementCounters(node, FaultID.NoImportNamespaceStarAsVar); + } + } + private handleGlobalThisCase(node: ts.Identifier, isArkTs2: boolean | undefined): void { let faultId = FaultID.GlobalThis; let targetNode: ts.Node = node; diff --git a/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets new file mode 100644 index 0000000000000000000000000000000000000000..9047c6adaa90e6b51042b2fc658562ac1b77f991 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets @@ -0,0 +1,46 @@ +/* + * 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 * as host from './file1'; +const alias = host; // error +alias.run(); + +function getHost() { + return host; // error +} +const edgeCase = getHost(); + +function run(h: any) { + h.doSomething(); +} +run(host); // error + +host(); // error + +const { foo } = host; // error + +let g; +g = host; // error + +host.doSomething() // valid +new host.Host(); // valid + +const h2 = host.h2(); // valid + +function f1() { + return host.b(); // valid +} + +const fn = () => host.work(); // valid \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.args.json b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.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": "" + } +} diff --git a/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.arkts2.json b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1266c69bfca5190fe69b7b4b806747aa9610c8d6 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.arkts2.json @@ -0,0 +1,178 @@ +{ + "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": 7, + "endLine": 17, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 15, + "endLine": 17, + "endColumn": 19, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 17, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 14, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 27, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 20, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 9, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 5, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 17, + "endLine": 32, + "endColumn": 21, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 6, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 9, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 14, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 12, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 12, + "endLine": 46, + "endColumn": 29, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.json b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..5714e6776f3b4184dfef47779816d432f445ec38 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.json @@ -0,0 +1,108 @@ +{ + "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": 7, + "endLine": 17, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 17, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 27, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 20, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 6, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 12, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 12, + "endLine": 46, + "endColumn": 29, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +}