From c979cc7aacf221313906961e9300f0e00c414fca Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Thu, 26 Oct 2023 13:06:10 +0300 Subject: [PATCH 01/49] Revert "[arkts linter] fix #14030: add new rule, rework ESObject reporting, #14009" This reverts commit 7864dd1409b500eb8efdbaca72a23e10c05ee0a4. --- linter-4.2/docs/rules/recipe144.md | 3 +- linter-4.2/docs/rules/recipe151.md | 54 ---- linter-4.2/src/CookBookMsg.ts | 1 - linter-4.2/src/Problems.ts | 7 +- linter-4.2/src/TypeScriptLinter.ts | 197 ++++++++----- linter-4.2/src/TypeScriptLinterConfig.ts | 4 +- linter-4.2/src/Utils.ts | 175 +++-------- linter-4.2/test/es_object.ts | 19 +- linter-4.2/test/es_object.ts.relax.json | 269 +++++++---------- linter-4.2/test/es_object.ts.strict.json | 271 +++++++----------- .../test/function_expression.ts.autofix.json | 16 +- .../test/function_expression.ts.relax.json | 4 +- .../test/function_expression.ts.strict.json | 12 +- .../function_object_methods.ts.relax.json | 46 +-- .../function_object_methods.ts.strict.json | 46 +-- linter-4.2/test/limited_stdlib_api.ts | 10 +- .../test/limited_stdlib_api.ts.autofix.json | 268 ++++++++--------- .../test/limited_stdlib_api.ts.relax.json | 248 +++++++--------- .../test/limited_stdlib_api.ts.strict.json | 248 +++++++--------- linter-4.2/test/new_target.ts.relax.json | 2 +- linter-4.2/test/new_target.ts.strict.json | 2 +- linter-4.2/test/oh_modules/ohos_lib.ts | 3 - linter-4.2/test/symbol_api.ts.relax.json | 24 +- linter-4.2/test/symbol_api.ts.strict.json | 24 +- linter-4.2/test/utility_types.ts.relax.json | 4 +- linter-4.2/test/utility_types.ts.strict.json | 4 +- linter-4.2/test_rules/rule132.ts.autofix.json | 2 +- linter-4.2/test_rules/rule132.ts.relax.json | 2 +- linter-4.2/test_rules/rule132.ts.strict.json | 2 +- linter/docs/rules/recipe144.md | 3 +- linter/docs/rules/recipe151.md | 54 ---- linter/src/Autofixer.ts | 2 +- linter/src/CookBookMsg.ts | 1 - linter/src/FaultAttrs.ts | 180 ++++++------ linter/src/FaultDesc.ts | 6 +- linter/src/LinterRunner.ts | 2 +- linter/src/Problems.ts | 39 +++ linter/src/TypeScriptLinter.ts | 195 ++++++++----- linter/src/TypeScriptLinterConfig.ts | 2 +- .../src/ts-diagnostics/TSCCompiledProgram.ts | 2 +- linter/src/utils/TsUtils.ts | 45 ++- .../src/utils/consts/AllowedStdSymbolAPI.ts | 16 ++ .../consts/LimitedStandardUtilityTypes.ts | 20 +- linter/src/utils/consts/LimitedStdApi.ts | 155 ---------- .../utils/consts/LimitedStdArrayBufferAPI.ts | 16 ++ .../src/utils/consts/LimitedStdGlobalFunc.ts | 18 ++ .../src/utils/consts/LimitedStdGlobalVar.ts | 16 ++ .../src/utils/consts/LimitedStdObjectAPI.ts | 22 ++ .../utils/consts/LimitedStdProxyHandlerAPI.ts | 19 ++ .../src/utils/consts/LimitedStdReflectAPI.ts | 19 ++ linter/src/utils/consts/Problems.ts | 104 ------- linter/test/es_object.ts | 19 +- linter/test/es_object.ts.relax.json | 269 +++++++---------- linter/test/es_object.ts.strict.json | 271 +++++++----------- .../test/function_expression.ts.autofix.json | 16 +- linter/test/function_expression.ts.relax.json | 4 +- .../test/function_expression.ts.strict.json | 12 +- .../function_object_methods.ts.relax.json | 46 +-- .../function_object_methods.ts.strict.json | 46 +-- linter/test/limited_stdlib_api.ts | 8 +- .../test/limited_stdlib_api.ts.autofix.json | 254 +++++++--------- linter/test/limited_stdlib_api.ts.relax.json | 234 +++++++-------- linter/test/limited_stdlib_api.ts.strict.json | 234 +++++++-------- linter/test/new_target.ts.relax.json | 2 +- linter/test/new_target.ts.strict.json | 2 +- linter/test/oh_modules/ohos_lib.ts | 3 - linter/test/symbol_api.ts.relax.json | 24 +- linter/test/symbol_api.ts.strict.json | 24 +- linter/test/utility_types.ts.relax.json | 4 +- linter/test/utility_types.ts.strict.json | 4 +- linter/test_rules/rule132.ts.autofix.json | 2 +- linter/test_rules/rule132.ts.relax.json | 2 +- linter/test_rules/rule132.ts.strict.json | 2 +- 73 files changed, 1779 insertions(+), 2606 deletions(-) delete mode 100644 linter-4.2/docs/rules/recipe151.md delete mode 100644 linter/docs/rules/recipe151.md create mode 100644 linter/src/Problems.ts create mode 100644 linter/src/utils/consts/AllowedStdSymbolAPI.ts delete mode 100644 linter/src/utils/consts/LimitedStdApi.ts create mode 100644 linter/src/utils/consts/LimitedStdArrayBufferAPI.ts create mode 100644 linter/src/utils/consts/LimitedStdGlobalFunc.ts create mode 100644 linter/src/utils/consts/LimitedStdGlobalVar.ts create mode 100644 linter/src/utils/consts/LimitedStdObjectAPI.ts create mode 100644 linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts create mode 100644 linter/src/utils/consts/LimitedStdReflectAPI.ts delete mode 100644 linter/src/utils/consts/Problems.ts diff --git a/linter-4.2/docs/rules/recipe144.md b/linter-4.2/docs/rules/recipe144.md index 28acf4a49..975ae2131 100644 --- a/linter-4.2/docs/rules/recipe144.md +++ b/linter-4.2/docs/rules/recipe144.md @@ -9,7 +9,8 @@ The most part of the restricted APIs relates to manipulating objects in a dynamic manner, which is not compatible with static typing. The usage of the following APIs is prohibited: -Properties and functions of the global object: ``eval`` +Properties and functions of the global object: ``eval``, +``Infinity``, ``NaN``, ``isFinite``, ``isNaN``, ``parseFloat``, ``parseInt`` ``Object``: ``__proto__``, ``__defineGetter__``, ``__defineSetter__``, ``__lookupGetter__``, ``__lookupSetter__``, ``assign``, ``create``, diff --git a/linter-4.2/docs/rules/recipe151.md b/linter-4.2/docs/rules/recipe151.md deleted file mode 100644 index 0b00ba643..000000000 --- a/linter-4.2/docs/rules/recipe151.md +++ /dev/null @@ -1,54 +0,0 @@ -# Usage of ``ESObject`` type is restricted - -Rule ``arkts-limited-esobject`` - -**Severity: warning** - -ArkTS does not allow using ``ESObject`` type in some cases. The most part of limitations -are put in place in order to prevent spread of dynamic objects in the static codebase. -The only scenario where it is permited to use ``ESObject`` as type specifier is in local -variable declaration. Initialization of variables with ``ESObject`` type is also limited. -Such variables can only be initialized with values that originate from interop: -other ``ESObject`` typed variables, any, unknown, variables with anonymous type, etc. -It is prohibited to initialize ``ESObject`` typed variable with statically typed value. -Varaible of type ``ESObject`` can only be passed to interop calls and assigned to other -variables of type ``ESObject``. - - -## ArkTS - - -``` - // lib.d.ts - declare function foo(): any; - declare function bar(a: any): number; - - // main.ets - let e0: ESObject = foo(); // CTE - ``ESObject`` typed variable can only be local - - function f() { - let e1 = foo(); // CTE - type of e1 is `any` - let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values - let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values - let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values - let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values - let e6: ESObject = foo(); // OK - explicitly annotaded as ESObject - let e7 = e6; // OK - initialize ESObject with ESObject - e6['prop'] // CTE - can't access dynamic properties of ESObject - e6[1] // CTE - can't access dynamic properties of ESObject - e6.prop // CTE - can't access dynamic properties of ESObject - bar(e6) // OK - ESObject is passed to interop call - } -``` - - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 029: Indexed access is not supported for fields (``arkts-no-props-by-index``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 137: ``globalThis`` is not supported (``arkts-no-globalthis``) - - diff --git a/linter-4.2/src/CookBookMsg.ts b/linter-4.2/src/CookBookMsg.ts index c097345da..6f90d98ea 100644 --- a/linter-4.2/src/CookBookMsg.ts +++ b/linter-4.2/src/CookBookMsg.ts @@ -170,4 +170,3 @@ cookBookTag[147] = 'No dependencies on TypeScript code are currently allowed (ar cookBookTag[148] = 'No decorators except ArkUI decorators are currently allowed (arkts-no-decorators-except-arkui)'; cookBookTag[149] = 'Classes cannot be used as objects (arkts-no-classes-as-obj)'; cookBookTag[150] = '"import" statements after other statements are not allowed (arkts-no-misplaced-imports)'; -cookBookTag[151] = 'Usage of "ESObject" type is restricted (arkts-limited-esobject)'; diff --git a/linter-4.2/src/Problems.ts b/linter-4.2/src/Problems.ts index 98bd4701b..69dab34fb 100644 --- a/linter-4.2/src/Problems.ts +++ b/linter-4.2/src/Problems.ts @@ -34,7 +34,8 @@ export enum FaultID { NewTarget, DefiniteAssignment, Prototype, GlobalThis, UtilityType, PropertyDeclOnFunction, FunctionApplyBindCall, ConstAssertion, ImportAssertion, SpreadOperator, LimitedStdLibApi, ErrorSuppression, StrictDiagnostic, UnsupportedDecorators, ImportAfterStatement, - EsObjectType, LAST_ID, // this should always be last enum + EsObjectType, EsObjectAssignment, EsObjectAccess, + LAST_ID, // this should always be last enum` } export class FaultAttributs { @@ -130,4 +131,6 @@ faultsAttrs[FaultID.ErrorSuppression] = {cookBookRef: '146',}; faultsAttrs[FaultID.UnsupportedDecorators] = {warning: true, cookBookRef: '148',}; faultsAttrs[FaultID.ClassAsObject] = {cookBookRef: '149',}; faultsAttrs[FaultID.ImportAfterStatement] = {cookBookRef: '150',}; -faultsAttrs[FaultID.EsObjectType] = {warning: true, cookBookRef: '151',}; +faultsAttrs[FaultID.EsObjectType] = {warning: true, cookBookRef: '8'}; +faultsAttrs[FaultID.EsObjectAssignment] = {warning: true, cookBookRef: '8'}; +faultsAttrs[FaultID.EsObjectAccess] = {warning: true, cookBookRef: '8'}; diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 27442da9f..34126f27d 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -668,18 +668,25 @@ export class TypeScriptLinter { } private handlePropertyAccessExpression(node: ts.Node) { + if (ts.isCallExpression(node.parent) && node == node.parent.expression) { + return; + } + let propertyAccessNode = node as ts.PropertyAccessExpression; const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode); const baseExprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode.expression); const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); - if (!!baseExprSym && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { - this.incrementCounters(propertyAccessNode, FaultID.EsObjectType); - } if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { this.incrementCounters(propertyAccessNode.name, FaultID.Prototype); } + if (!!exprSym && this.tsUtils.isSymbolAPI(exprSym) && !TsUtils.ALLOWED_STD_SYMBOL_API.includes(exprSym.getName())) { + this.incrementCounters(propertyAccessNode, FaultID.SymbolType); + } + if (baseExprSym !== undefined && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { + this.incrementCounters(propertyAccessNode, FaultID.EsObjectAccess); + } } private handlePropertyAssignmentOrDeclaration(node: ts.Node) { @@ -1187,7 +1194,9 @@ export class TypeScriptLinter { } const typeNode = this.tsUtils.getVariableDeclarationTypeNode(tsLhsExpr); - this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); + if (!!typeNode) { + this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); + } } } @@ -1230,41 +1239,39 @@ export class TypeScriptLinter { if (this.tsUtils.needToDeduceStructuralIdentity(tsVarType, tsInitType, tsVarInit)) { this.incrementCounters(tsVarDecl, FaultID.StructuralIdentity); } + + this.handleEsObjectAssignment(tsVarDecl, tsVarDecl.type, tsVarInit); } - this.handleEsObjectDelaration(tsVarDecl); this.handleDeclarationInferredType(tsVarDecl); this.handleDefiniteAssignmentAssertion(tsVarDecl); } - private handleEsObjectDelaration(node: ts.VariableDeclaration) { - const isDeclaredESObject = !!node.type && this.tsUtils.isEsObjectType(node.type); - const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); - const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); - const isLocal = this.tsUtils.isInsideBlock(node) - if ((isDeclaredESObject || isInitializedWithESObject) && !isLocal) { - this.incrementCounters(node, FaultID.EsObjectType); - return; + private handleEsObjectAssignment(node: ts.Node, type: ts.TypeNode, value: ts.Node) { + if (!this.tsUtils.isEsObjectType(type)) { + let valueTypeNode = this.tsUtils.getVariableDeclarationTypeNode(value); + if (!!valueTypeNode && this.tsUtils.isEsObjectType(valueTypeNode)) { + this.incrementCounters(node, FaultID.EsObjectAssignment); + } + + return } - if (node.initializer) { - this.handleEsObjectAssignment(node, node.type, node.initializer); + if (ts.isArrayLiteralExpression(value) || ts.isObjectLiteralExpression(value)) { + this.incrementCounters(node, FaultID.EsObjectAssignment); + return; } - } - private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node) { - const isTypeAnnotated = !!nodeDeclType; - const isDeclaredESObject = !!nodeDeclType && this.tsUtils.isEsObjectType(nodeDeclType); - const initalizerTypeNode = this.tsUtils.getVariableDeclarationTypeNode(initializer); - const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); - if (isTypeAnnotated && !isDeclaredESObject && isInitializedWithESObject) { - this.incrementCounters(node, FaultID.EsObjectType); + const valueType = this.tsTypeChecker.getTypeAtLocation(value); + if (this.tsUtils.isUnsupportedType(valueType)) { return; } - if (isDeclaredESObject && !this.tsUtils.isValueAssignableToESObject(initializer)) { - this.incrementCounters(node, FaultID.EsObjectType); + if (this.tsUtils.isAnonymousType(valueType)) { + return; } + + this.incrementCounters(node, FaultID.EsObjectAssignment); } private handleCatchClause(node: ts.Node) { @@ -1479,18 +1486,18 @@ export class TypeScriptLinter { private handleIdentifier(node: ts.Node) { let tsIdentifier = node as ts.Identifier; let tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); - if (!tsIdentSym) { - return; - } - if ( - (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && - (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && - tsIdentifier.text === 'globalThis' - ) { - this.incrementCounters(tsIdentifier, FaultID.GlobalThis); - } else { - this.checkLimitedStdLib(tsIdentifier, tsIdentSym); - this.handleRestrictedValues(tsIdentifier, tsIdentSym); + + if (tsIdentSym !== undefined) { + if ( + (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && + (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && + tsIdentifier.text === "globalThis" + ) + this.incrementCounters(node, FaultID.GlobalThis); + else if (this.tsUtils.isGlobalSymbol(tsIdentSym) && TsUtils.LIMITED_STD_GLOBAL_VAR.includes(tsIdentSym.getName())) + this.incrementCounters(node, FaultID.LimitedStdLibApi); + else + this.handleRestrictedValues(tsIdentifier, tsIdentSym); } } @@ -1631,7 +1638,7 @@ export class TypeScriptLinter { } if (this.tsUtils.hasEsObjectType(tsElementAccessExpr.expression)) { - this.incrementCounters(node, FaultID.EsObjectType); + this.incrementCounters(node, FaultID.EsObjectAccess); } } @@ -1699,22 +1706,25 @@ export class TypeScriptLinter { this.handleImportCall(tsCallExpr); this.handleRequireCall(tsCallExpr); - if (!!calleeSym) { + // NOTE: Keep handleFunctionApplyBindPropCall above handleGenericCallWithNoTypeArgs here!!! + if (calleeSym !== undefined) { + this.handleStdlibAPICall(tsCallExpr, calleeSym); + this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); if (this.tsUtils.symbolHasEsObjectType(calleeSym)) { - this.incrementCounters(tsCallExpr, FaultID.EsObjectType); - } - // need to process Symbol call separatey in order to not report two times when using Symbol API - if (this.tsUtils.isStdSymbol(calleeSym)) { - this.incrementCounters(tsCallExpr, FaultID.SymbolType); + this.incrementCounters(tsCallExpr, FaultID.EsObjectAccess); } } - if (!!callSignature) { + if (callSignature !== undefined) { if (!this.tsUtils.isLibrarySymbol(calleeSym)) { this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); } this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } this.handleLibraryTypeCall(tsCallExpr, calleeType); + + if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { + this.incrementCounters(node, FaultID.EsObjectAccess); + } } private handleImportCall(tsCallExpr: ts.CallExpression) { @@ -1784,6 +1794,22 @@ export class TypeScriptLinter { } } + + private static listApplyBindCallApis = [ + "Function.apply", + "Function.call", + "Function.bind", + "CallableFunction.apply", + "CallableFunction.call", + "CallableFunction.bind" + ]; + private handleFunctionApplyBindPropCall(tsCallExpr: ts.CallExpression, calleeSym: ts.Symbol) { + const exprName = this.tsTypeChecker.getFullyQualifiedName(calleeSym); + if (TypeScriptLinter.listApplyBindCallApis.includes(exprName)) { + this.incrementCounters(tsCallExpr, FaultID.FunctionApplyBindCall); + } + } + private handleStructIdentAndUndefinedInArgs(tsCallOrNewExpr: ts.CallExpression | ts.NewExpression, callSignature: ts.Signature) { if (!tsCallOrNewExpr.arguments) { return; @@ -1823,17 +1849,37 @@ export class TypeScriptLinter { } } - private checkLimitedStdLib(node: ts.Node, symbol: ts.Symbol) { - const parName = this.tsUtils.getParentSymbolName(symbol); - const res = parName ? TsUtils.LIMITED_STD_API.get(parName) : undefined; - if (res && res.arr.includes(symbol.name)) { - this.incrementCounters(node, res.fault); + + // let re = new RegExp("^(" + arr.reduce((acc, v) => ((acc ? (acc + "|") : "") + v)) +")$") + private static LimitedApis = new Map | null, fault: FaultID}> ([ + ["global", {arr: TsUtils.LIMITED_STD_GLOBAL_FUNC, fault: FaultID.LimitedStdLibApi}], + ["Object", {arr: TsUtils.LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], + ["ObjectConstructor", {arr: TsUtils.LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], + ["Reflect", {arr: TsUtils.LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi}], + ["ProxyHandler", {arr: TsUtils.LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi}], + ["ArrayBuffer", {arr: TsUtils.LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], + ["ArrayBufferConstructor", {arr: TsUtils.LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], + ["Symbol", {arr: null, fault: FaultID.SymbolType}], + ["SymbolConstructor", {arr: null, fault: FaultID.SymbolType}], + ]) + + private handleStdlibAPICall(callExpr: ts.CallExpression, calleeSym: ts.Symbol) { + const name = calleeSym.getName(); + const parName = this.tsUtils.getParentSymbolName(calleeSym); + if (parName === undefined) { + if (TsUtils.LIMITED_STD_GLOBAL_FUNC.includes(name)) { + this.incrementCounters(callExpr, FaultID.LimitedStdLibApi); + return; + } + let escapedName = calleeSym.escapedName; + if (escapedName === 'Symbol' || escapedName === 'SymbolConstructor') { + this.incrementCounters(callExpr, FaultID.SymbolType); + } return; } - const name = this.tsTypeChecker.getFullyQualifiedName(symbol); - if (TsUtils.LIMITED_STD_GLOBAL_API.includes(name)) { - this.incrementCounters(node, FaultID.LimitedStdLibApi) - return; + let lookup = TypeScriptLinter.LimitedApis.get(parName); + if (lookup !== undefined && (lookup.arr === null || lookup.arr.includes(name))) { + this.incrementCounters(callExpr, lookup.fault); } } @@ -1916,38 +1962,35 @@ export class TypeScriptLinter { } private handleTypeReference(node: ts.Node) { - const typeRef = node as ts.TypeReferenceNode; + let typeRef = node as ts.TypeReferenceNode; - const isESObject = this.tsUtils.isEsObjectType(typeRef); - const isPossiblyValidContext = this.tsUtils.isEsObjectPossiblyAllowed(typeRef); - if (isESObject && !isPossiblyValidContext) { - this.incrementCounters(node, FaultID.EsObjectType); - return; - } - - const typeName = this.tsUtils.entityNameToString(typeRef.typeName); - const isStdUtilityType = TsUtils.LIMITED_STANDARD_UTILITY_TYPES.includes(typeName); - if (isStdUtilityType) { + if ( + ts.isIdentifier(typeRef.typeName) && + TsUtils.LIMITED_STANDARD_UTILITY_TYPES.includes(typeRef.typeName.text) + ) this.incrementCounters(node, FaultID.UtilityType); - return; + else if (this.tsUtils.isEsObjectType(typeRef) && !this.tsUtils.isEsObjectAllowed(typeRef)) { + this.incrementCounters(node, FaultID.EsObjectType); } - - // Using Partial type is allowed only when its argument type is either Class or Interface. - const isStdPartial = this.tsUtils.entityNameToString(typeRef.typeName) === 'Partial'; - const hasSingleTypeArgument = !!typeRef.typeArguments && typeRef.typeArguments.length === 1; - const firstTypeArg = !!typeRef.typeArguments && hasSingleTypeArgument && typeRef.typeArguments[0]; - const argType = firstTypeArg && this.tsTypeChecker.getTypeFromTypeNode(firstTypeArg); - if (isStdPartial && argType && !argType.isClassOrInterface()) { - this.incrementCounters(node, FaultID.UtilityType); - return; + else if ( + ts.isIdentifier(typeRef.typeName) && + typeRef.typeName.text === "Partial" && + typeRef.typeArguments && + typeRef.typeArguments.length === 1 + ) { + // Using Partial type is allowed only when its argument type is either Class or Interface. + let argType = this.tsTypeChecker.getTypeFromTypeNode( + typeRef.typeArguments[0] + ); + if (!argType || !argType.isClassOrInterface()) + this.incrementCounters(node, FaultID.UtilityType); } } private handleMetaProperty(node: ts.Node) { let tsMetaProperty = node as ts.MetaProperty; - if (tsMetaProperty.name.text === "target") { + if (tsMetaProperty.name.text === "target") this.incrementCounters(node, FaultID.NewTarget); - } } private handleStructDeclaration(node: ts.Node) { diff --git a/linter-4.2/src/TypeScriptLinterConfig.ts b/linter-4.2/src/TypeScriptLinterConfig.ts index 1639e5664..fcb5d1988 100644 --- a/linter-4.2/src/TypeScriptLinterConfig.ts +++ b/linter-4.2/src/TypeScriptLinterConfig.ts @@ -118,7 +118,9 @@ export class LinterConfig { LinterConfig.nodeDesc[FaultID.StrictDiagnostic] = 'Strict diagnostic'; LinterConfig.nodeDesc[FaultID.UnsupportedDecorators] = 'Unsupported decorators'; LinterConfig.nodeDesc[FaultID.ImportAfterStatement] = 'Import declaration after other declaration or statement'; - LinterConfig.nodeDesc[FaultID.EsObjectType] = 'Restricted "ESObject" type'; + LinterConfig.nodeDesc[FaultID.EsObjectType] = '"ESObject" type'; + LinterConfig.nodeDesc[FaultID.EsObjectAssignment] = '"ESObject" type assignment'; + LinterConfig.nodeDesc[FaultID.EsObjectAccess] = '"ESObject" access'; LinterConfig.initTsSyntaxKindNames(); } diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 03674b19e..360d36bb1 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -18,7 +18,6 @@ import * as ts from 'typescript'; import { ProblemInfo } from './ProblemInfo'; import { AutofixInfo } from './AutofixInfo'; import { LinterConfig } from './TypeScriptLinterConfig' -import { FaultID } from "./Problems"; export function logTscDiagnostic(diagnostics: readonly ts.Diagnostic[], log: (message: any, ...args: any[]) => void) { diagnostics.forEach((diagnostic) => { @@ -106,123 +105,26 @@ export enum CheckType { export class TsUtils { static readonly ES_OBJECT = 'ESObject' - private static readonly LIMITED_STD_ARRAYBUFFER_API = [ - // properties - // methods - 'isView' + static readonly LIMITED_STD_GLOBAL_FUNC = [ + 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt' ]; - - private static readonly LIMITED_STD_OBJECT_API = [ - // properties - '__proto__', - // methods - '__defineGetter__', - '__defineSetter__', - '__lookupGetter__', - '__lookupSetter__', - 'assign', - 'create', - 'defineProperties', - 'defineProperty', - 'freeze', - 'fromEntries', - 'getOwnPropertyDescriptor', - 'getOwnPropertyDescriptors', - 'getOwnPropertySymbols', - 'getPrototypeOf', - 'hasOwnProperty', - 'is', - 'isExtensible', - 'isFrozen', - 'isPrototypeOf', - 'isSealed', - 'preventExtensions', - 'propertyIsEnumerable', - 'seal', - 'setPrototypeOf', - ]; - - private static readonly LIMITED_STD_PROXYHANDLER_API = [ - // properties - // methods - 'apply', - 'construct', - 'defineProperty', - 'deleteProperty', - 'get', - 'getOwnPropertyDescriptor', - 'getPrototypeOf', - 'has', - 'isExtensible', - 'ownKeys', - 'preventExtensions', - 'set', - 'setPrototypeOf' + static readonly LIMITED_STD_GLOBAL_VAR = ['Infinity', 'NaN']; + static readonly LIMITED_STD_OBJECT_API = [ + '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'assign', 'create', + 'defineProperties', 'defineProperty', 'freeze', 'fromEntries', 'getOwnPropertyDescriptor', + 'getOwnPropertyDescriptors', 'getOwnPropertySymbols', 'getPrototypeOf', 'hasOwnProperty', 'is', + 'isExtensible', 'isFrozen', 'isPrototypeOf', 'isSealed', 'preventExtensions', 'propertyIsEnumerable', + 'seal', 'setPrototypeOf' ]; - - private static readonly LIMITED_STD_REFLECT_API = [ - // properties - // methods - 'apply', - 'construct', - 'defineProperty', - 'deleteProperty', - 'getOwnPropertyDescriptor', - 'getPrototypeOf', - 'isExtensible', - 'preventExtensions', - 'setPrototypeOf', + static readonly LIMITED_STD_REFLECT_API = [ + 'apply', 'construct', 'defineProperty', 'deleteProperty', 'getOwnPropertyDescriptor', 'getPrototypeOf', + 'isExtensible', 'preventExtensions', 'setPrototypeOf' ]; - - private static readonly LIMITED_STD_SYMBOL_API = [ - 'Symbol', - // properties - 'asyncIterator', - 'description', - 'hasInstance', - 'isConcatSpreadable', - 'match', - 'matchAll', - 'replace', - 'search', - 'species', - 'split', - 'toPrimitive', - 'toStringTag', - 'unscopables', - // methods - 'for', - 'keyFor', - 'toString', - 'valueOf', - ]; - - private static readonly LIMITED_STD_FUNCTION_API = [ - // properties - // methods - 'apply', - 'bind', - 'call', + static readonly LIMITED_STD_PROXYHANDLER_API = [ + 'apply', 'construct', 'defineProperty', 'deleteProperty', 'get', 'getOwnPropertyDescriptor', 'getPrototypeOf', + 'has', 'isExtensible', 'ownKeys', 'preventExtensions', 'set', 'setPrototypeOf' ]; - - static readonly LIMITED_STD_GLOBAL_API = [ - // properties - // methods - 'eval', - ]; - - static readonly LIMITED_STD_API = new Map, fault: FaultID}> ([ - ['Object', {arr: TsUtils.LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], - ['ObjectConstructor', {arr: TsUtils.LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], - ['Reflect', {arr: TsUtils.LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi}], - ['ProxyHandler', {arr: TsUtils.LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi}], - ['ArrayBuffer', {arr: TsUtils.LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], - ['ArrayBufferConstructor', {arr: TsUtils.LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], - ['Symbol', {arr: TsUtils.LIMITED_STD_SYMBOL_API, fault: FaultID.SymbolType}], - ['SymbolConstructor', {arr: TsUtils.LIMITED_STD_SYMBOL_API, fault: FaultID.SymbolType}], - ['Function', {arr: TsUtils.LIMITED_STD_FUNCTION_API, fault: FaultID.FunctionApplyBindCall}], - ['CallableFunction', {arr: TsUtils.LIMITED_STD_FUNCTION_API, fault: FaultID.FunctionApplyBindCall}], - ]) + static readonly LIMITED_STD_ARRAYBUFFER_API = ['isView']; static readonly NON_INITIALIZABLE_PROPERTY_DECORATORS = ['Link', 'Consume', 'ObjectLink', 'Prop', 'BuilderParam']; @@ -240,6 +142,8 @@ export class TsUtils { 'ThisType', 'Uppercase', 'Lowercase', 'Capitalize', 'Uncapitalize', ]; + static readonly ALLOWED_STD_SYMBOL_API = ['iterator'] + static readonly ARKUI_DECORATORS = [ 'AnimatableExtend', 'Builder', @@ -1196,7 +1100,7 @@ export class TsUtils { public isStdObjectAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Object'); + return !!parentName && (parentName === 'Object' || parentName === 'ObjectConstructor'); } public isStdReflectAPI(symbol: ts.Symbol): boolean { @@ -1211,22 +1115,18 @@ export class TsUtils { public isStdArrayAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Array'); + return !!parentName && (parentName === 'Array' || parentName === 'ArrayConstructor'); } public isStdArrayBufferAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'ArrayBuffer'); - } - - public isStdSymbol(symbol: ts.Symbol): boolean { - const name = this.tsTypeChecker.getFullyQualifiedName(symbol) - return name === 'Symbol'; + return !!parentName && (parentName === 'ArrayBuffer' || parentName === 'ArrayBufferConstructor'); } - public isStdSymbolAPI(symbol: ts.Symbol): boolean { + public isSymbolAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && parentName === 'Symbol'; + let name = parentName ? parentName : symbol.escapedName; + return name === 'Symbol' || name === 'SymbolConstructor'; } public isDefaultImport(importSpec: ts.ImportSpecifier): boolean { @@ -1477,29 +1377,22 @@ export class TsUtils { typeNode.typeName.text == TsUtils.ES_OBJECT; } - public isInsideBlock(node: ts.Node): boolean { - let par = node.parent - while (par) { - if (ts.isBlock(par)) { + public isEsObjectAllowed(typeRef: ts.TypeReferenceNode): boolean { + let node = typeRef.parent; + + if (!this.isVarDeclaration(node)) { + return false; + } + + while (node) { + if (ts.isBlock(node)) { return true; } - par = par.parent; + node = node.parent; } return false; } - public isEsObjectPossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean { - return ts.isVariableDeclaration(typeRef.parent); - } - - public isValueAssignableToESObject(node: ts.Node): boolean { - if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) { - return false; - } - const valueType = this.tsTypeChecker.getTypeAtLocation(node); - return this.isUnsupportedType(valueType) || this.isAnonymousType(valueType) - } - public getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { let sym = this.trueSymbolAtLocation(node); if (sym === undefined) { diff --git a/linter-4.2/test/es_object.ts b/linter-4.2/test/es_object.ts index 445b5c0c0..d9715b772 100644 --- a/linter-4.2/test/es_object.ts +++ b/linter-4.2/test/es_object.ts @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { fooOh, barOh } from './oh_modules/ohos_lib' + type ESObject = any class A {} @@ -174,20 +174,3 @@ interface CL extends ESObject {} export interface CLS extends ESObject {} foo2({ k: 'k', h: {t: 1}}) // we can assign anything to the esobject, even untyped literal -let q1: ESObject = 1; // CTE - ``ESObject`` typed variable can only be local -let q2: ESObject = fooOh(); // CTE - ``ESObject`` typed variable can only be local -let q3: ESObject = q2; // CTE - ``ESObject`` typed variable can only be local -function f() { - let e1 = fooOh(); // CTE - type of e1 is `any` - let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values - let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values - let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values - let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values - let e6: ESObject = fooOh(); // OK - explicitly annotaded as ESObject - let e7: ESObject = e6; // OK - initialize ESObject with ESObject - e6['prop'] // CTE - can't access dynamic properties of ESObject - e6[1] // CTE - can't access dynamic properties of ESObject - e6.prop // CTE - can't access dynamic properties of ESObject - barOh(e6) // OK - ESObject is passed to interop call - e6 = e7 // OK - ESObject is assigned to ESObject -} diff --git a/linter-4.2/test/es_object.ts.relax.json b/linter-4.2/test/es_object.ts.relax.json index f3d5acdb4..10bd5f5bd 100644 --- a/linter-4.2/test/es_object.ts.relax.json +++ b/linter-4.2/test/es_object.ts.relax.json @@ -23,234 +23,234 @@ }, { "line": 20, - "column": 5, + "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 77, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 78, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 79, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 80, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 82, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 83, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 85, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 86, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 87, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 88, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 90, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 91, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 93, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 94, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 95, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 96, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 98, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 99, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 114, @@ -486,37 +486,37 @@ { "line": 115, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 176, @@ -594,83 +594,6 @@ "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" - }, - { - "line": 177, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 178, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 179, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 181, - "column": 9, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 182, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 183, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 184, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 185, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 188, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 189, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 190, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/es_object.ts.strict.json b/linter-4.2/test/es_object.ts.strict.json index 5c869e41f..10bd5f5bd 100644 --- a/linter-4.2/test/es_object.ts.strict.json +++ b/linter-4.2/test/es_object.ts.strict.json @@ -23,234 +23,234 @@ }, { "line": 20, - "column": 5, + "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 77, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 78, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 79, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 80, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 82, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 83, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 85, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 86, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 87, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 88, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 90, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 91, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 93, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 94, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 95, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 96, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 98, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 99, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 114, @@ -486,37 +486,37 @@ { "line": 115, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 176, @@ -594,83 +594,6 @@ "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" - }, - { - "line": 177, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 178, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 179, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 181, - "column": 9, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 182, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 183, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 184, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 185, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 188, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 189, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 190, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" } - ] + ] } \ No newline at end of file diff --git a/linter-4.2/test/function_expression.ts.autofix.json b/linter-4.2/test/function_expression.ts.autofix.json index 90e6f3f3b..c571fa05a 100644 --- a/linter-4.2/test/function_expression.ts.autofix.json +++ b/linter-4.2/test/function_expression.ts.autofix.json @@ -335,6 +335,14 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, + { + "line": 102, + "column": 15, + "problem": "FunctionApplyBindCall", + "autofixable": false, + "suggest": "", + "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" + }, { "line": 102, "column": 15, @@ -350,14 +358,6 @@ "suggest": "", "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, - { - "line": 104, - "column": 7, - "problem": "FunctionApplyBindCall", - "autofixable": false, - "suggest": "", - "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" - }, { "line": 108, "column": 16, diff --git a/linter-4.2/test/function_expression.ts.relax.json b/linter-4.2/test/function_expression.ts.relax.json index 8e6077236..48f6e1a27 100644 --- a/linter-4.2/test/function_expression.ts.relax.json +++ b/linter-4.2/test/function_expression.ts.relax.json @@ -57,8 +57,8 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { - "line": 104, - "column": 7, + "line": 102, + "column": 15, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" diff --git a/linter-4.2/test/function_expression.ts.strict.json b/linter-4.2/test/function_expression.ts.strict.json index 1233c4e7d..fe4750449 100644 --- a/linter-4.2/test/function_expression.ts.strict.json +++ b/linter-4.2/test/function_expression.ts.strict.json @@ -206,16 +206,16 @@ { "line": 102, "column": 15, - "problem": "FunctionExpression", + "problem": "FunctionApplyBindCall", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" + "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { - "line": 104, - "column": 7, - "problem": "FunctionApplyBindCall", + "line": 102, + "column": 15, + "problem": "FunctionExpression", "suggest": "", - "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { "line": 108, diff --git a/linter-4.2/test/function_object_methods.ts.relax.json b/linter-4.2/test/function_object_methods.ts.relax.json index 790856d4f..96e3fcaf1 100644 --- a/linter-4.2/test/function_object_methods.ts.relax.json +++ b/linter-4.2/test/function_object_methods.ts.relax.json @@ -23,7 +23,7 @@ }, { "line": 29, - "column": 35, + "column": 21, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -37,21 +37,21 @@ }, { "line": 30, - "column": 45, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 37, - "column": 37, + "column": 23, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 38, - "column": 40, + "column": 21, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -65,7 +65,7 @@ }, { "line": 68, - "column": 44, + "column": 22, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -79,42 +79,42 @@ }, { "line": 70, - "column": 35, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 75, - "column": 48, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 78, - "column": 48, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 81, - "column": 31, + "column": 9, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 82, - "column": 31, + "column": 9, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 87, - "column": 32, + "column": 16, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -128,7 +128,7 @@ }, { "line": 94, - "column": 37, + "column": 20, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -142,42 +142,42 @@ }, { "line": 96, - "column": 30, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 101, - "column": 42, + "column": 25, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 104, - "column": 42, + "column": 25, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 107, - "column": 20, + "column": 3, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 108, - "column": 20, + "column": 3, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 113, - "column": 21, + "column": 10, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -226,35 +226,35 @@ }, { "line": 136, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 137, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 138, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 139, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 141, - "column": 5, + "column": 1, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" diff --git a/linter-4.2/test/function_object_methods.ts.strict.json b/linter-4.2/test/function_object_methods.ts.strict.json index 2a7c8ccd9..e90572ea9 100644 --- a/linter-4.2/test/function_object_methods.ts.strict.json +++ b/linter-4.2/test/function_object_methods.ts.strict.json @@ -23,7 +23,7 @@ }, { "line": 29, - "column": 35, + "column": 21, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -37,21 +37,21 @@ }, { "line": 30, - "column": 45, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 37, - "column": 37, + "column": 23, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 38, - "column": 40, + "column": 21, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -65,7 +65,7 @@ }, { "line": 68, - "column": 44, + "column": 22, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -79,42 +79,42 @@ }, { "line": 70, - "column": 35, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 75, - "column": 48, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 78, - "column": 48, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 81, - "column": 31, + "column": 9, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 82, - "column": 31, + "column": 9, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 87, - "column": 32, + "column": 16, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -128,7 +128,7 @@ }, { "line": 94, - "column": 37, + "column": 20, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -142,42 +142,42 @@ }, { "line": 96, - "column": 30, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 101, - "column": 42, + "column": 25, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 104, - "column": 42, + "column": 25, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 107, - "column": 20, + "column": 3, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 108, - "column": 20, + "column": 3, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 113, - "column": 21, + "column": 10, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -254,35 +254,35 @@ }, { "line": 136, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 137, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 138, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 139, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 141, - "column": 5, + "column": 1, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" diff --git a/linter-4.2/test/limited_stdlib_api.ts b/linter-4.2/test/limited_stdlib_api.ts index 0cc445fe7..918ecda77 100644 --- a/linter-4.2/test/limited_stdlib_api.ts +++ b/linter-4.2/test/limited_stdlib_api.ts @@ -28,7 +28,7 @@ decodeURIComponent(''); escape(''); unescape(''); -// global and window are not portabe, so they are excluded from test suite +global.eval('console.log("foo")'); globalThis.eval('console.log("foo")'); class C {} @@ -90,10 +90,4 @@ if (handler.set) handler.set(c, "prop", 1, c); if (handler.setPrototypeOf) handler.setPrototypeOf(c, null); /// Array -ArrayBuffer.isView({}); - -Number.NaN; -Number.isFinite(1); -Number.isNaN(2); -Number.parseFloat('3'); -Number.parseInt('4', 10); +ArrayBuffer.isView({}); \ No newline at end of file diff --git a/linter-4.2/test/limited_stdlib_api.ts.autofix.json b/linter-4.2/test/limited_stdlib_api.ts.autofix.json index 6286f4c5d..7c2eb1d35 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.autofix.json +++ b/linter-4.2/test/limited_stdlib_api.ts.autofix.json @@ -1,4 +1,18 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 17, @@ -9,24 +23,80 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { - "line": 32, + "line": 18, + "column": 11, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 19, + "column": 11, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 20, "column": 1, - "problem": "GlobalThis", + "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 21, + "column": 1, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 22, + "column": 1, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 23, + "column": 1, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 31, + "column": 1, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 32, - "column": 12, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, + { + "line": 32, + "column": 1, + "problem": "GlobalThis", + "autofixable": false, + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + }, { "line": 43, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -34,7 +104,7 @@ }, { "line": 44, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -42,7 +112,7 @@ }, { "line": 45, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -58,7 +128,7 @@ }, { "line": 46, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -66,7 +136,7 @@ }, { "line": 48, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -74,7 +144,7 @@ }, { "line": 49, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -82,7 +152,7 @@ }, { "line": 50, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -90,7 +160,7 @@ }, { "line": 51, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -98,7 +168,7 @@ }, { "line": 52, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -106,7 +176,7 @@ }, { "line": 53, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -114,7 +184,7 @@ }, { "line": 54, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -122,7 +192,7 @@ }, { "line": 55, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -130,7 +200,7 @@ }, { "line": 56, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -138,7 +208,7 @@ }, { "line": 57, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -146,7 +216,7 @@ }, { "line": 58, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -154,7 +224,7 @@ }, { "line": 59, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -162,7 +232,7 @@ }, { "line": 60, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -170,7 +240,7 @@ }, { "line": 61, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -178,7 +248,7 @@ }, { "line": 62, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -186,7 +256,7 @@ }, { "line": 63, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -194,7 +264,7 @@ }, { "line": 66, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -202,7 +272,7 @@ }, { "line": 67, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -218,7 +288,7 @@ }, { "line": 68, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -234,7 +304,7 @@ }, { "line": 69, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -242,7 +312,7 @@ }, { "line": 70, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -250,7 +320,7 @@ }, { "line": 71, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -258,7 +328,7 @@ }, { "line": 72, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -266,7 +336,7 @@ }, { "line": 73, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -274,7 +344,7 @@ }, { "line": 74, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -290,15 +360,7 @@ }, { "line": 78, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 78, - "column": 28, + "column": 20, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -306,23 +368,7 @@ }, { "line": 79, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 79, - "column": 32, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 80, - "column": 13, + "column": 24, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -330,7 +376,7 @@ }, { "line": 80, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -346,15 +392,7 @@ }, { "line": 81, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 81, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -362,23 +400,7 @@ }, { "line": 82, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 82, - "column": 26, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 83, - "column": 13, + "column": 18, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -386,15 +408,7 @@ }, { "line": 83, - "column": 47, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 84, - "column": 13, + "column": 39, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -402,7 +416,7 @@ }, { "line": 84, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -410,23 +424,7 @@ }, { "line": 85, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 85, - "column": 26, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 86, - "column": 13, + "column": 18, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -434,7 +432,7 @@ }, { "line": 86, - "column": 35, + "column": 27, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -442,23 +440,7 @@ }, { "line": 87, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 87, - "column": 30, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 88, - "column": 13, + "column": 22, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -466,15 +448,7 @@ }, { "line": 88, - "column": 40, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 89, - "column": 13, + "column": 32, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -482,7 +456,7 @@ }, { "line": 89, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -490,15 +464,7 @@ }, { "line": 90, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 90, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -506,7 +472,7 @@ }, { "line": 93, - "column": 13, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", diff --git a/linter-4.2/test/limited_stdlib_api.ts.relax.json b/linter-4.2/test/limited_stdlib_api.ts.relax.json index 7f5db9e71..2cca52540 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.relax.json +++ b/linter-4.2/test/limited_stdlib_api.ts.relax.json @@ -1,4 +1,18 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 17, @@ -8,36 +22,85 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { - "line": 32, + "line": 18, + "column": 11, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 19, + "column": 11, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 20, "column": 1, - "problem": "GlobalThis", + "problem": "LimitedStdLibApi", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 21, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 22, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 23, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 31, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 32, - "column": 12, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, + { + "line": 32, + "column": 1, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + }, { "line": 43, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 44, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 45, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -51,133 +114,133 @@ }, { "line": 46, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 48, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 49, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 50, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 51, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 52, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 53, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 54, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 55, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 56, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 57, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 58, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 59, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 60, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 61, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 62, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 63, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 66, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 67, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -191,7 +254,7 @@ }, { "line": 68, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -205,42 +268,42 @@ }, { "line": 69, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 70, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 71, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 72, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 73, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 74, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -254,42 +317,21 @@ }, { "line": 78, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 78, - "column": 28, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 79, - "column": 13, + "column": 20, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 79, - "column": 32, + "column": 24, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 80, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 80, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -303,147 +345,77 @@ }, { "line": 81, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 81, - "column": 37, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 82, - "column": 13, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 82, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 83, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 83, - "column": 47, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 84, - "column": 13, + "column": 39, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 84, - "column": 37, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 85, - "column": 13, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 85, - "column": 26, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 86, - "column": 13, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 86, - "column": 35, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 87, - "column": 13, + "column": 27, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 87, - "column": 30, + "column": 22, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 88, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 88, - "column": 40, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 89, - "column": 13, + "column": 32, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 89, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 90, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 90, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 93, - "column": 13, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" diff --git a/linter-4.2/test/limited_stdlib_api.ts.strict.json b/linter-4.2/test/limited_stdlib_api.ts.strict.json index 7f5db9e71..2cca52540 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.strict.json +++ b/linter-4.2/test/limited_stdlib_api.ts.strict.json @@ -1,4 +1,18 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 17, @@ -8,36 +22,85 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { - "line": 32, + "line": 18, + "column": 11, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 19, + "column": 11, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 20, "column": 1, - "problem": "GlobalThis", + "problem": "LimitedStdLibApi", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 21, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 22, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 23, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 31, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 32, - "column": 12, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, + { + "line": 32, + "column": 1, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + }, { "line": 43, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 44, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 45, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -51,133 +114,133 @@ }, { "line": 46, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 48, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 49, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 50, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 51, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 52, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 53, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 54, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 55, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 56, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 57, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 58, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 59, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 60, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 61, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 62, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 63, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 66, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 67, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -191,7 +254,7 @@ }, { "line": 68, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -205,42 +268,42 @@ }, { "line": 69, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 70, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 71, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 72, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 73, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 74, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -254,42 +317,21 @@ }, { "line": 78, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 78, - "column": 28, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 79, - "column": 13, + "column": 20, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 79, - "column": 32, + "column": 24, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 80, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 80, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -303,147 +345,77 @@ }, { "line": 81, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 81, - "column": 37, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 82, - "column": 13, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 82, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 83, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 83, - "column": 47, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 84, - "column": 13, + "column": 39, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 84, - "column": 37, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 85, - "column": 13, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 85, - "column": 26, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 86, - "column": 13, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 86, - "column": 35, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 87, - "column": 13, + "column": 27, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 87, - "column": 30, + "column": 22, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 88, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 88, - "column": 40, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 89, - "column": 13, + "column": 32, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 89, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 90, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 90, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 93, - "column": 13, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" diff --git a/linter-4.2/test/new_target.ts.relax.json b/linter-4.2/test/new_target.ts.relax.json index 0b83a1198..5ec99daa2 100644 --- a/linter-4.2/test/new_target.ts.relax.json +++ b/linter-4.2/test/new_target.ts.relax.json @@ -16,7 +16,7 @@ "nodes": [ { "line": 19, - "column": 12, + "column": 5, "problem": "LimitedStdLibApi" }, { diff --git a/linter-4.2/test/new_target.ts.strict.json b/linter-4.2/test/new_target.ts.strict.json index 0b83a1198..5ec99daa2 100644 --- a/linter-4.2/test/new_target.ts.strict.json +++ b/linter-4.2/test/new_target.ts.strict.json @@ -16,7 +16,7 @@ "nodes": [ { "line": 19, - "column": 12, + "column": 5, "problem": "LimitedStdLibApi" }, { diff --git a/linter-4.2/test/oh_modules/ohos_lib.ts b/linter-4.2/test/oh_modules/ohos_lib.ts index c69856185..a0aa74c87 100644 --- a/linter-4.2/test/oh_modules/ohos_lib.ts +++ b/linter-4.2/test/oh_modules/ohos_lib.ts @@ -20,6 +20,3 @@ export interface OhosI { export function ohFunction1({d: OhosI}): void {} // incorrect usage, but it was an issue, so we check it too export function ohFunction2(p: {d: OhosI}): void {} - -export function fooOh(): any {} -export function barOh(a: any) {} diff --git a/linter-4.2/test/symbol_api.ts.relax.json b/linter-4.2/test/symbol_api.ts.relax.json index e62c8c7b7..c2211cf10 100644 --- a/linter-4.2/test/symbol_api.ts.relax.json +++ b/linter-4.2/test/symbol_api.ts.relax.json @@ -16,77 +16,77 @@ "nodes": [ { "line": 16, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 17, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 18, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 20, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 21, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 22, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 23, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 24, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 25, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 26, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 27, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" @@ -107,7 +107,7 @@ }, { "line": 33, - "column": 17, + "column": 10, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" diff --git a/linter-4.2/test/symbol_api.ts.strict.json b/linter-4.2/test/symbol_api.ts.strict.json index e62c8c7b7..c2211cf10 100644 --- a/linter-4.2/test/symbol_api.ts.strict.json +++ b/linter-4.2/test/symbol_api.ts.strict.json @@ -16,77 +16,77 @@ "nodes": [ { "line": 16, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 17, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 18, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 20, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 21, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 22, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 23, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 24, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 25, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 26, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 27, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" @@ -107,7 +107,7 @@ }, { "line": 33, - "column": 17, + "column": 10, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" diff --git a/linter-4.2/test/utility_types.ts.relax.json b/linter-4.2/test/utility_types.ts.relax.json index fe6131546..63a56e5cd 100644 --- a/linter-4.2/test/utility_types.ts.relax.json +++ b/linter-4.2/test/utility_types.ts.relax.json @@ -266,7 +266,7 @@ }, { "line": 178, - "column": 18, + "column": 12, "problem": "FunctionApplyBindCall" }, { @@ -286,7 +286,7 @@ }, { "line": 187, - "column": 60, + "column": 54, "problem": "FunctionApplyBindCall" }, { diff --git a/linter-4.2/test/utility_types.ts.strict.json b/linter-4.2/test/utility_types.ts.strict.json index c5686de4b..cb2916b9d 100644 --- a/linter-4.2/test/utility_types.ts.strict.json +++ b/linter-4.2/test/utility_types.ts.strict.json @@ -291,7 +291,7 @@ }, { "line": 178, - "column": 18, + "column": 12, "problem": "FunctionApplyBindCall" }, { @@ -316,7 +316,7 @@ }, { "line": 187, - "column": 60, + "column": 54, "problem": "FunctionApplyBindCall" }, { diff --git a/linter-4.2/test_rules/rule132.ts.autofix.json b/linter-4.2/test_rules/rule132.ts.autofix.json index d1868ca7f..9002b4276 100644 --- a/linter-4.2/test_rules/rule132.ts.autofix.json +++ b/linter-4.2/test_rules/rule132.ts.autofix.json @@ -2,7 +2,7 @@ "nodes": [ { "line": 7, - "column": 16, + "column": 9, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", diff --git a/linter-4.2/test_rules/rule132.ts.relax.json b/linter-4.2/test_rules/rule132.ts.relax.json index 21468ce90..192c3aa10 100644 --- a/linter-4.2/test_rules/rule132.ts.relax.json +++ b/linter-4.2/test_rules/rule132.ts.relax.json @@ -2,7 +2,7 @@ "nodes": [ { "line": 7, - "column": 16, + "column": 9, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" diff --git a/linter-4.2/test_rules/rule132.ts.strict.json b/linter-4.2/test_rules/rule132.ts.strict.json index 21468ce90..192c3aa10 100644 --- a/linter-4.2/test_rules/rule132.ts.strict.json +++ b/linter-4.2/test_rules/rule132.ts.strict.json @@ -2,7 +2,7 @@ "nodes": [ { "line": 7, - "column": 16, + "column": 9, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" diff --git a/linter/docs/rules/recipe144.md b/linter/docs/rules/recipe144.md index 0bbcfefd4..b28c181c5 100644 --- a/linter/docs/rules/recipe144.md +++ b/linter/docs/rules/recipe144.md @@ -9,7 +9,8 @@ The most part of the restricted APIs relates to manipulating objects in a dynamic manner, which is not compatible with static typing. The usage of the following APIs is prohibited: -Properties and functions of the global object: ``eval`` +Properties and functions of the global object: ``eval``, +``Infinity``, ``NaN``, ``isFinite``, ``isNaN``, ``parseFloat``, ``parseInt`` ``Object``: ``__proto__``, ``__defineGetter__``, ``__defineSetter__``, ``__lookupGetter__``, ``__lookupSetter__``, ``assign``, ``create``, diff --git a/linter/docs/rules/recipe151.md b/linter/docs/rules/recipe151.md deleted file mode 100644 index 0b00ba643..000000000 --- a/linter/docs/rules/recipe151.md +++ /dev/null @@ -1,54 +0,0 @@ -# Usage of ``ESObject`` type is restricted - -Rule ``arkts-limited-esobject`` - -**Severity: warning** - -ArkTS does not allow using ``ESObject`` type in some cases. The most part of limitations -are put in place in order to prevent spread of dynamic objects in the static codebase. -The only scenario where it is permited to use ``ESObject`` as type specifier is in local -variable declaration. Initialization of variables with ``ESObject`` type is also limited. -Such variables can only be initialized with values that originate from interop: -other ``ESObject`` typed variables, any, unknown, variables with anonymous type, etc. -It is prohibited to initialize ``ESObject`` typed variable with statically typed value. -Varaible of type ``ESObject`` can only be passed to interop calls and assigned to other -variables of type ``ESObject``. - - -## ArkTS - - -``` - // lib.d.ts - declare function foo(): any; - declare function bar(a: any): number; - - // main.ets - let e0: ESObject = foo(); // CTE - ``ESObject`` typed variable can only be local - - function f() { - let e1 = foo(); // CTE - type of e1 is `any` - let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values - let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values - let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values - let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values - let e6: ESObject = foo(); // OK - explicitly annotaded as ESObject - let e7 = e6; // OK - initialize ESObject with ESObject - e6['prop'] // CTE - can't access dynamic properties of ESObject - e6[1] // CTE - can't access dynamic properties of ESObject - e6.prop // CTE - can't access dynamic properties of ESObject - bar(e6) // OK - ESObject is passed to interop call - } -``` - - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 029: Indexed access is not supported for fields (``arkts-no-props-by-index``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 137: ``globalThis`` is not supported (``arkts-no-globalthis``) - - diff --git a/linter/src/Autofixer.ts b/linter/src/Autofixer.ts index 59c1cc2d3..f6dc5129d 100644 --- a/linter/src/Autofixer.ts +++ b/linter/src/Autofixer.ts @@ -15,7 +15,7 @@ import * as ts from 'typescript'; import { AutofixInfo } from './autofixes/AutofixInfo'; -import { FaultID } from './utils/consts/Problems'; +import { FaultID } from './Problems'; import { isAssignmentOperator } from './utils/functions/isAssignmentOperator'; export const AUTOFIX_ALL: AutofixInfo = { diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index e977c8e19..aba65028d 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -170,4 +170,3 @@ cookBookTag[147] = 'No dependencies on TypeScript code are currently allowed (ar cookBookTag[148] = 'No decorators except ArkUI decorators are currently allowed (arkts-no-decorators-except-arkui)'; cookBookTag[149] = 'Classes cannot be used as objects (arkts-no-classes-as-obj)'; cookBookTag[150] = '"import" statements after other statements are not allowed (arkts-no-misplaced-imports)'; -cookBookTag[151] = 'Usage of "ESObject" type is restricted (arkts-limited-esobject)'; diff --git a/linter/src/FaultAttrs.ts b/linter/src/FaultAttrs.ts index d4bb026cf..a40ad5b38 100644 --- a/linter/src/FaultAttrs.ts +++ b/linter/src/FaultAttrs.ts @@ -1,19 +1,19 @@ /* * Copyright (c) 2022-2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the 'License'); + * 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, + * 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 { FaultID } from './utils/consts/Problems'; +import { FaultID } from './Problems'; export class FaultAttributs { migratable?: boolean; @@ -23,89 +23,91 @@ export class FaultAttributs { export const faultsAttrs: FaultAttributs[] = []; -faultsAttrs[FaultID.LiteralAsPropertyName] = { migratable: true, cookBookRef: '1' }; -faultsAttrs[FaultID.ComputedPropertyName] = { cookBookRef: '1' }; -faultsAttrs[FaultID.SymbolType] = { cookBookRef: '2' }; -faultsAttrs[FaultID.PrivateIdentifier] = { migratable: true, cookBookRef: '3' }; -faultsAttrs[FaultID.DeclWithDuplicateName] = { migratable: true, cookBookRef: '4' }; -faultsAttrs[FaultID.VarDeclaration] = { migratable: true, cookBookRef: '5' }; -faultsAttrs[FaultID.AnyType] = { cookBookRef: '8' }; -faultsAttrs[FaultID.UnknownType] = { cookBookRef: '8' }; -faultsAttrs[FaultID.CallSignature] = { cookBookRef: '14' }; -faultsAttrs[FaultID.ConstructorType] = { cookBookRef: '15' }; -faultsAttrs[FaultID.MultipleStaticBlocks] = { cookBookRef: '16' }; -faultsAttrs[FaultID.IndexMember] = { cookBookRef: '17' }; -faultsAttrs[FaultID.IntersectionType] = { cookBookRef: '19' }; -faultsAttrs[FaultID.ThisType] = { cookBookRef: '21' }; -faultsAttrs[FaultID.ConditionalType] = { cookBookRef: '22' }; -faultsAttrs[FaultID.ParameterProperties] = { migratable: true, cookBookRef: '25' }; -faultsAttrs[FaultID.ConstructorIface] = { cookBookRef: '27' }; -faultsAttrs[FaultID.IndexedAccessType] = { cookBookRef: '28' }; -faultsAttrs[FaultID.PropertyAccessByIndex] = { migratable: true, cookBookRef: '29' }; -faultsAttrs[FaultID.StructuralIdentity] = { cookBookRef: '30' }; -faultsAttrs[FaultID.GenericCallNoTypeArgs] = { cookBookRef: '34' }; -faultsAttrs[FaultID.RegexLiteral] = { cookBookRef: '37' }; -faultsAttrs[FaultID.ObjectLiteralNoContextType] = { cookBookRef: '38' }; -faultsAttrs[FaultID.ObjectTypeLiteral] = { cookBookRef: '40' }; -faultsAttrs[FaultID.ArrayLiteralNoContextType] = { cookBookRef: '43' }; -faultsAttrs[FaultID.FunctionExpression] = { migratable: true, cookBookRef: '46' }; -faultsAttrs[FaultID.LambdaWithTypeParameters] = { migratable: true, cookBookRef: '49' }; -faultsAttrs[FaultID.ClassExpression] = { migratable: true, cookBookRef: '50' }; -faultsAttrs[FaultID.ImplementsClass] = { cookBookRef: '51' }; -faultsAttrs[FaultID.MethodReassignment] = { cookBookRef: '52' }; -faultsAttrs[FaultID.TypeAssertion] = { migratable: true, cookBookRef: '53' }; -faultsAttrs[FaultID.JsxElement] = { cookBookRef: '54' }; -faultsAttrs[FaultID.UnaryArithmNotNumber] = { cookBookRef: '55' }; -faultsAttrs[FaultID.DeleteOperator] = { cookBookRef: '59' }; -faultsAttrs[FaultID.TypeQuery] = { cookBookRef: '60' }; -faultsAttrs[FaultID.InstanceofUnsupported] = { cookBookRef: '65' }; -faultsAttrs[FaultID.InOperator] = { cookBookRef: '66' }; -faultsAttrs[FaultID.DestructuringAssignment] = { migratable: true, cookBookRef: '69' }; -faultsAttrs[FaultID.CommaOperator] = { cookBookRef: '71' }; -faultsAttrs[FaultID.DestructuringDeclaration] = { migratable: true, cookBookRef: '74' }; -faultsAttrs[FaultID.CatchWithUnsupportedType] = { migratable: true, cookBookRef: '79' }; -faultsAttrs[FaultID.ForInStatement] = { cookBookRef: '80' }; -faultsAttrs[FaultID.MappedType] = { cookBookRef: '83' }; -faultsAttrs[FaultID.WithStatement] = { cookBookRef: '84' }; -faultsAttrs[FaultID.ThrowStatement] = { migratable: true, cookBookRef: '87' }; -faultsAttrs[FaultID.LimitedReturnTypeInference] = { migratable: true, cookBookRef: '90'}; -faultsAttrs[FaultID.DestructuringParameter] = { cookBookRef: '91' }; -faultsAttrs[FaultID.LocalFunction] = { migratable: true, cookBookRef: '92' }; -faultsAttrs[FaultID.FunctionContainsThis] = { cookBookRef: '93' }; -faultsAttrs[FaultID.GeneratorFunction] = { cookBookRef: '94' }; -faultsAttrs[FaultID.YieldExpression] = { cookBookRef: '94' }; -faultsAttrs[FaultID.IsOperator] = { cookBookRef: '96' }; -faultsAttrs[FaultID.SpreadOperator] = { cookBookRef: '99' }; -faultsAttrs[FaultID.IntefaceExtendDifProps] = { cookBookRef: '102' }; -faultsAttrs[FaultID.InterfaceMerging] = { cookBookRef: '103' }; -faultsAttrs[FaultID.InterfaceExtendsClass] = { cookBookRef: '104' }; -faultsAttrs[FaultID.ConstructorFuncs] = { cookBookRef: '106' }; -faultsAttrs[FaultID.EnumMemberNonConstInit] = { cookBookRef: '111' }; -faultsAttrs[FaultID.EnumMerging] = { cookBookRef: '113' }; -faultsAttrs[FaultID.NamespaceAsObject] = { cookBookRef: '114' }; -faultsAttrs[FaultID.NonDeclarationInNamespace] = { cookBookRef: '116' }; -faultsAttrs[FaultID.ImportFromPath] = { cookBookRef: '119' }; -faultsAttrs[FaultID.TypeOnlyImport] = { migratable: true, cookBookRef: '118' }; -faultsAttrs[FaultID.DefaultImport] = { migratable: true, cookBookRef: '120' }; -faultsAttrs[FaultID.ImportAssignment] = { cookBookRef: '121' }; -faultsAttrs[FaultID.ExportAssignment] = { cookBookRef: '126' }; -faultsAttrs[FaultID.TypeOnlyExport] = { migratable: true, cookBookRef: '127' }; -faultsAttrs[FaultID.ShorthandAmbientModuleDecl] = { cookBookRef: '128' }; -faultsAttrs[FaultID.WildcardsInModuleName] = { cookBookRef: '129' }; -faultsAttrs[FaultID.UMDModuleDefinition] = { cookBookRef: '130' }; -faultsAttrs[FaultID.NewTarget] = { cookBookRef: '132' }; -faultsAttrs[FaultID.DefiniteAssignment] = { warning: true, cookBookRef: '134' }; -faultsAttrs[FaultID.Prototype] = { cookBookRef: '136' }; -faultsAttrs[FaultID.GlobalThis] = { cookBookRef: '137' }; -faultsAttrs[FaultID.UtilityType] = { cookBookRef: '138' }; -faultsAttrs[FaultID.PropertyDeclOnFunction] = { cookBookRef: '139' }; -faultsAttrs[FaultID.FunctionApplyBindCall] = { cookBookRef: '140' }; -faultsAttrs[FaultID.ConstAssertion] = { cookBookRef: '142' }; -faultsAttrs[FaultID.ImportAssertion] = { cookBookRef: '143' }; -faultsAttrs[FaultID.LimitedStdLibApi] = { cookBookRef: '144' }; -faultsAttrs[FaultID.StrictDiagnostic] = { cookBookRef: '145' }; -faultsAttrs[FaultID.ErrorSuppression] = { cookBookRef: '146' }; -faultsAttrs[FaultID.UnsupportedDecorators] = { warning: true, cookBookRef: '148' }; -faultsAttrs[FaultID.ClassAsObject] = { cookBookRef: '149' }; -faultsAttrs[FaultID.ImportAfterStatement] = { cookBookRef: '150' }; -faultsAttrs[FaultID.EsObjectType] = { warning: true, cookBookRef: '151' }; +faultsAttrs[FaultID.LiteralAsPropertyName] = {migratable: true, cookBookRef: '1',}; +faultsAttrs[FaultID.ComputedPropertyName] = {cookBookRef: '1',}; +faultsAttrs[FaultID.SymbolType] = {cookBookRef: '2',}; +faultsAttrs[FaultID.PrivateIdentifier] = {migratable: true, cookBookRef: '3',}; +faultsAttrs[FaultID.DeclWithDuplicateName] = {migratable: true, cookBookRef: '4',}; +faultsAttrs[FaultID.VarDeclaration] = {migratable: true, cookBookRef: '5',}; +faultsAttrs[FaultID.AnyType] = {cookBookRef: '8'}; +faultsAttrs[FaultID.UnknownType] = {cookBookRef: '8',}; +faultsAttrs[FaultID.CallSignature] = {cookBookRef: '14',}; +faultsAttrs[FaultID.ConstructorType] = {cookBookRef: '15',}; +faultsAttrs[FaultID.MultipleStaticBlocks] = {cookBookRef: '16',}; +faultsAttrs[FaultID.IndexMember] = {cookBookRef: '17',}; +faultsAttrs[FaultID.IntersectionType] = {cookBookRef: '19',}; +faultsAttrs[FaultID.ThisType] = {cookBookRef: '21',}; +faultsAttrs[FaultID.ConditionalType] = {cookBookRef: '22',}; +faultsAttrs[FaultID.ParameterProperties] = {migratable: true, cookBookRef: '25',}; +faultsAttrs[FaultID.ConstructorIface] = {cookBookRef: '27',}; +faultsAttrs[FaultID.IndexedAccessType] = {cookBookRef: '28',}; +faultsAttrs[FaultID.PropertyAccessByIndex] = {migratable: true, cookBookRef: '29',}; +faultsAttrs[FaultID.StructuralIdentity] = {cookBookRef: '30',}; +faultsAttrs[FaultID.GenericCallNoTypeArgs] = {cookBookRef: '34',}; +faultsAttrs[FaultID.RegexLiteral] = {cookBookRef: '37',}; +faultsAttrs[FaultID.ObjectLiteralNoContextType] = {cookBookRef: '38',}; +faultsAttrs[FaultID.ObjectTypeLiteral] = {cookBookRef: '40',}; +faultsAttrs[FaultID.ArrayLiteralNoContextType] = {cookBookRef: '43',}; +faultsAttrs[FaultID.FunctionExpression] = {migratable: true, cookBookRef: '46',}; +faultsAttrs[FaultID.LambdaWithTypeParameters] = {migratable: true, cookBookRef: '49',}; +faultsAttrs[FaultID.ClassExpression] = {migratable: true, cookBookRef: '50',}; +faultsAttrs[FaultID.ImplementsClass] = {cookBookRef: '51',}; +faultsAttrs[FaultID.MethodReassignment] = {cookBookRef: '52',}; +faultsAttrs[FaultID.TypeAssertion] = {migratable: true, cookBookRef: '53',}; +faultsAttrs[FaultID.JsxElement] = {cookBookRef: '54',}; +faultsAttrs[FaultID.UnaryArithmNotNumber] = {cookBookRef: '55',}; +faultsAttrs[FaultID.DeleteOperator] = {cookBookRef: '59',}; +faultsAttrs[FaultID.TypeQuery] = {cookBookRef: '60',}; +faultsAttrs[FaultID.InstanceofUnsupported] = {cookBookRef: '65',}; +faultsAttrs[FaultID.InOperator] = {cookBookRef: '66',}; +faultsAttrs[FaultID.DestructuringAssignment] = {migratable: true, cookBookRef: '69',}; +faultsAttrs[FaultID.CommaOperator] = {cookBookRef: '71',}; +faultsAttrs[FaultID.DestructuringDeclaration] = {migratable: true, cookBookRef: '74',}; +faultsAttrs[FaultID.CatchWithUnsupportedType] = {migratable: true, cookBookRef: '79',}; +faultsAttrs[FaultID.ForInStatement] = {cookBookRef: '80',}; +faultsAttrs[FaultID.MappedType] = {cookBookRef: '83',}; +faultsAttrs[FaultID.WithStatement] = {cookBookRef: '84',}; +faultsAttrs[FaultID.ThrowStatement] = {migratable: true, cookBookRef: '87',}; +faultsAttrs[FaultID.LimitedReturnTypeInference] = {migratable: true, cookBookRef: '90',}; +faultsAttrs[FaultID.DestructuringParameter] = {cookBookRef: '91',}; +faultsAttrs[FaultID.LocalFunction] = {migratable: true, cookBookRef: '92',}; +faultsAttrs[FaultID.FunctionContainsThis] = {cookBookRef: '93',}; +faultsAttrs[FaultID.GeneratorFunction] = {cookBookRef: '94',}; +faultsAttrs[FaultID.YieldExpression] = {cookBookRef: '94',}; +faultsAttrs[FaultID.IsOperator] = {cookBookRef: '96',}; +faultsAttrs[FaultID.SpreadOperator] = {cookBookRef: '99',}; +faultsAttrs[FaultID.IntefaceExtendDifProps] = {cookBookRef: '102',}; +faultsAttrs[FaultID.InterfaceMerging] = {cookBookRef: '103',}; +faultsAttrs[FaultID.InterfaceExtendsClass] = {cookBookRef: '104',}; +faultsAttrs[FaultID.ConstructorFuncs] = {cookBookRef: '106',}; +faultsAttrs[FaultID.EnumMemberNonConstInit] = {cookBookRef: '111',}; +faultsAttrs[FaultID.EnumMerging] = {cookBookRef: '113',}; +faultsAttrs[FaultID.NamespaceAsObject] = {cookBookRef: '114',}; +faultsAttrs[FaultID.NonDeclarationInNamespace] = {cookBookRef: '116',}; +faultsAttrs[FaultID.ImportFromPath] = {cookBookRef: '119',}; +faultsAttrs[FaultID.TypeOnlyImport] = {migratable: true, cookBookRef: '118',}; +faultsAttrs[FaultID.DefaultImport] = {migratable: true, cookBookRef: '120',}; +faultsAttrs[FaultID.ImportAssignment] = {cookBookRef: '121',}; +faultsAttrs[FaultID.ExportAssignment] = {cookBookRef: '126',}; +faultsAttrs[FaultID.TypeOnlyExport] = {migratable: true, cookBookRef: '127',}; +faultsAttrs[FaultID.ShorthandAmbientModuleDecl] = {cookBookRef: '128',}; +faultsAttrs[FaultID.WildcardsInModuleName] = {cookBookRef: '129',}; +faultsAttrs[FaultID.UMDModuleDefinition] = {cookBookRef: '130',}; +faultsAttrs[FaultID.NewTarget] = {cookBookRef: '132',}; +faultsAttrs[FaultID.DefiniteAssignment] = {warning: true, cookBookRef: '134',}; +faultsAttrs[FaultID.Prototype] = {cookBookRef: '136',}; +faultsAttrs[FaultID.GlobalThis] = {cookBookRef: '137',}; +faultsAttrs[FaultID.UtilityType] = {cookBookRef: '138',}; +faultsAttrs[FaultID.PropertyDeclOnFunction] = {cookBookRef: '139',}; +faultsAttrs[FaultID.FunctionApplyBindCall] = {cookBookRef: '140',}; +faultsAttrs[FaultID.ConstAssertion] = {cookBookRef: '142',}; +faultsAttrs[FaultID.ImportAssertion] = {cookBookRef: '143',}; +faultsAttrs[FaultID.LimitedStdLibApi] = {cookBookRef: '144',}; +faultsAttrs[FaultID.StrictDiagnostic] = {cookBookRef: '145',}; +faultsAttrs[FaultID.ErrorSuppression] = {cookBookRef: '146',}; +faultsAttrs[FaultID.UnsupportedDecorators] = {warning: true, cookBookRef: '148',}; +faultsAttrs[FaultID.ClassAsObject] = {cookBookRef: '149',}; +faultsAttrs[FaultID.ImportAfterStatement] = {cookBookRef: '150',}; +faultsAttrs[FaultID.EsObjectType] = {warning: true, cookBookRef: '8'}; +faultsAttrs[FaultID.EsObjectAssignment] = {warning: true, cookBookRef: '8'}; +faultsAttrs[FaultID.EsObjectAccess] = {warning: true, cookBookRef: '8'}; diff --git a/linter/src/FaultDesc.ts b/linter/src/FaultDesc.ts index c61b136e7..c49b1f3bc 100644 --- a/linter/src/FaultDesc.ts +++ b/linter/src/FaultDesc.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { FaultID } from './utils/consts/Problems'; +import { FaultID } from './Problems'; export const faultDesc: string[] = []; @@ -102,4 +102,6 @@ faultDesc[FaultID.ErrorSuppression] = 'Error suppression annotation'; faultDesc[FaultID.StrictDiagnostic] = 'Strict diagnostic'; faultDesc[FaultID.UnsupportedDecorators] = 'Unsupported decorators'; faultDesc[FaultID.ImportAfterStatement] = 'Import declaration after other declaration or statement'; -faultDesc[FaultID.EsObjectType] = 'Restricted "ESObject" type'; +faultDesc[FaultID.EsObjectType] = '"ESObject" type'; +faultDesc[FaultID.EsObjectAssignment] = '"ESObject" type assignment'; +faultDesc[FaultID.EsObjectAccess] = '"ESObject" access'; diff --git a/linter/src/LinterRunner.ts b/linter/src/LinterRunner.ts index 0e701f2ba..1494b65fd 100644 --- a/linter/src/LinterRunner.ts +++ b/linter/src/LinterRunner.ts @@ -16,7 +16,7 @@ import * as ts from 'typescript'; import { ProblemInfo } from './ProblemInfo'; import { TypeScriptLinter, consoleLog } from './TypeScriptLinter'; -import { FaultID } from './utils/consts/Problems'; +import { FaultID } from './Problems'; import { faultDesc } from './FaultDesc'; import { faultsAttrs } from './FaultAttrs'; import { LintRunResult } from './LintRunResult'; diff --git a/linter/src/Problems.ts b/linter/src/Problems.ts new file mode 100644 index 000000000..245ea31e7 --- /dev/null +++ b/linter/src/Problems.ts @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022-2023 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. + */ + +export enum FaultID { + AnyType, SymbolType, ObjectLiteralNoContextType, ArrayLiteralNoContextType, + ComputedPropertyName, LiteralAsPropertyName, TypeQuery, RegexLiteral, IsOperator, + DestructuringParameter, YieldExpression, InterfaceMerging, EnumMerging, InterfaceExtendsClass, IndexMember, WithStatement, + ThrowStatement, IndexedAccessType, UnknownType, ForInStatement, InOperator, + ImportFromPath, FunctionExpression, IntersectionType, + ObjectTypeLiteral, CommaOperator, LimitedReturnTypeInference, + LambdaWithTypeParameters, ClassExpression, DestructuringAssignment, + DestructuringDeclaration, VarDeclaration, CatchWithUnsupportedType, DeleteOperator, + DeclWithDuplicateName, UnaryArithmNotNumber, ConstructorType, ConstructorIface, ConstructorFuncs, CallSignature, + TypeAssertion, PrivateIdentifier, LocalFunction, + ConditionalType, MappedType, NamespaceAsObject, ClassAsObject, + NonDeclarationInNamespace, GeneratorFunction, FunctionContainsThis, PropertyAccessByIndex, JsxElement, + EnumMemberNonConstInit, ImplementsClass, MethodReassignment, MultipleStaticBlocks, ThisType, + IntefaceExtendDifProps, StructuralIdentity, TypeOnlyImport, TypeOnlyExport, DefaultImport, + ExportAssignment, ImportAssignment, + GenericCallNoTypeArgs, ParameterProperties, + InstanceofUnsupported, ShorthandAmbientModuleDecl, WildcardsInModuleName, UMDModuleDefinition, + NewTarget, DefiniteAssignment, Prototype, GlobalThis, + UtilityType, PropertyDeclOnFunction, FunctionApplyBindCall, ConstAssertion, ImportAssertion, + SpreadOperator, LimitedStdLibApi, ErrorSuppression, StrictDiagnostic, UnsupportedDecorators, ImportAfterStatement, + EsObjectType, EsObjectAssignment, EsObjectAccess, + LAST_ID, // this should always be last enum` +} diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 15d018ed5..0b26d2f95 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -16,7 +16,7 @@ import * as ts from 'typescript'; import * as path from 'node:path'; import { TsUtils, CheckType } from './utils/TsUtils'; -import { FaultID } from './utils/consts/Problems'; +import { FaultID } from './Problems'; import { faultsAttrs } from './FaultAttrs'; import { faultDesc } from './FaultDesc'; import { cookBookMsg, cookBookTag } from './CookBookMsg'; @@ -27,6 +27,13 @@ import { ProblemInfo } from './ProblemInfo'; import { ProblemSeverity } from './ProblemSeverity'; import Logger from '../utils/logger'; import { ARKUI_DECORATORS } from './utils/consts/ArkUIDecorators'; +import { LIMITED_STD_GLOBAL_FUNC } from './utils/consts/LimitedStdGlobalFunc'; +import { LIMITED_STD_GLOBAL_VAR } from './utils/consts/LimitedStdGlobalVar'; +import { LIMITED_STD_OBJECT_API } from './utils/consts/LimitedStdObjectAPI'; +import { LIMITED_STD_REFLECT_API } from './utils/consts/LimitedStdReflectAPI'; +import { LIMITED_STD_PROXYHANDLER_API } from './utils/consts/LimitedStdProxyHandlerAPI'; +import { LIMITED_STD_ARRAYBUFFER_API } from './utils/consts/LimitedStdArrayBufferAPI'; +import { ALLOWED_STD_SYMBOL_API } from './utils/consts/AllowedStdSymbolAPI'; import { NON_INITIALIZABLE_PROPERTY_DECORATORS, NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS } from './utils/consts/NonInitializablePropertyDecorators'; import { NON_RETURN_FUNCTION_DECORATORS } from './utils/consts/NonReturnFunctionDecorators'; @@ -48,7 +55,6 @@ import { TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE, LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; -import { LIMITED_STD_API, LIMITED_STD_GLOBAL_API } from './utils/consts/LimitedStdApi'; const logger = Logger.getLogger(); @@ -573,22 +579,29 @@ export class TypeScriptLinter { } private handlePropertyAccessExpression(node: ts.Node) { + if (ts.isCallExpression(node.parent) && node == node.parent.expression) { + return; + } + let propertyAccessNode = node as ts.PropertyAccessExpression; const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode); const baseExprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode.expression); const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); - if (!!baseExprSym && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { - this.incrementCounters(propertyAccessNode, FaultID.EsObjectType); - } if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { this.incrementCounters(propertyAccessNode.name, FaultID.Prototype); } + if (!!exprSym && this.tsUtils.isSymbolAPI(exprSym) && !ALLOWED_STD_SYMBOL_API.includes(exprSym.getName())) { + this.incrementCounters(propertyAccessNode, FaultID.SymbolType); + } if (TypeScriptLinter.advancedClassChecks && this.tsUtils.isClassObjectExpression(propertyAccessNode.expression)) { // missing exact rule this.incrementCounters(propertyAccessNode.expression, FaultID.ClassAsObject); } + if (baseExprSym !== undefined && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { + this.incrementCounters(propertyAccessNode, FaultID.EsObjectAccess); + } } private handlePropertyAssignmentOrDeclaration(node: ts.Node) { @@ -908,7 +921,9 @@ export class TypeScriptLinter { if (this.tsUtils.needToDeduceStructuralIdentity(leftOperandType, rightOperandType, tsRhsExpr)) { this.incrementCounters(tsBinaryExpr, FaultID.StructuralIdentity); } - this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); + if (typeNode) { + this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); + } break; default: return; @@ -995,40 +1010,38 @@ export class TypeScriptLinter { if (this.tsUtils.needToDeduceStructuralIdentity(tsVarType, tsInitType, tsVarInit)) { this.incrementCounters(tsVarDecl, FaultID.StructuralIdentity); } + + this.handleEsObjectAssignment(tsVarDecl, tsVarDecl.type, tsVarInit); } - this.handleEsObjectDelaration(tsVarDecl); this.handleDeclarationInferredType(tsVarDecl); this.handleDefiniteAssignmentAssertion(tsVarDecl); } - private handleEsObjectDelaration(node: ts.VariableDeclaration) { - const isDeclaredESObject = !!node.type && this.tsUtils.isEsObjectType(node.type); - const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); - const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); - const isLocal = this.tsUtils.isInsideBlock(node) - if ((isDeclaredESObject || isInitializedWithESObject) && !isLocal) { - this.incrementCounters(node, FaultID.EsObjectType); - return; + private handleEsObjectAssignment(node: ts.Node, type: ts.TypeNode, value: ts.Node) { + if (!this.tsUtils.isEsObjectType(type)) { + let valueTypeNode = this.tsUtils.getVariableDeclarationTypeNode(value); + if (!!valueTypeNode && this.tsUtils.isEsObjectType(valueTypeNode)) { + this.incrementCounters(node, FaultID.EsObjectAssignment); + } + + return } - if (node.initializer) { - this.handleEsObjectAssignment(node, node.type, node.initializer); + if (ts.isArrayLiteralExpression(value) || ts.isObjectLiteralExpression(value)) { + this.incrementCounters(node, FaultID.EsObjectAssignment); + return; } - } - private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node) { - const isTypeAnnotated = !!nodeDeclType; - const isDeclaredESObject = isTypeAnnotated && this.tsUtils.isEsObjectType(nodeDeclType); - const initalizerTypeNode = this.tsUtils.getVariableDeclarationTypeNode(initializer); - const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); - if (isTypeAnnotated && !isDeclaredESObject && isInitializedWithESObject) { - this.incrementCounters(node, FaultID.EsObjectType); + const valueType = this.tsTypeChecker.getTypeAtLocation(value); + if (this.tsUtils.isUnsupportedType(valueType)) { return; } - if (isDeclaredESObject && !this.tsUtils.isValueAssignableToESObject(initializer)) { - this.incrementCounters(node, FaultID.EsObjectType); + if (this.tsUtils.isAnonymousType(valueType)) { + return; } + + this.incrementCounters(node, FaultID.EsObjectAssignment); } private handleCatchClause(node: ts.Node) { @@ -1233,18 +1246,17 @@ export class TypeScriptLinter { private handleIdentifier(node: ts.Node) { let tsIdentifier = node as ts.Identifier; let tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); - if (!tsIdentSym) { - return; - } - if ( - (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && - (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && - tsIdentifier.text === 'globalThis' - ) { - this.incrementCounters(tsIdentifier, FaultID.GlobalThis); - } else { - this.checkLimitedStdLib(tsIdentifier, tsIdentSym); - this.handleRestrictedValues(tsIdentifier, tsIdentSym); + if (tsIdentSym !== undefined) { + if ( + (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && + (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && + tsIdentifier.text === 'globalThis' + ) + this.incrementCounters(node, FaultID.GlobalThis); + else if (this.tsUtils.isGlobalSymbol(tsIdentSym) && LIMITED_STD_GLOBAL_VAR.includes(tsIdentSym.getName())) + this.incrementCounters(node, FaultID.LimitedStdLibApi); + else + this.handleRestrictedValues(tsIdentifier, tsIdentSym); } } @@ -1326,7 +1338,7 @@ export class TypeScriptLinter { } if (this.tsUtils.hasEsObjectType(tsElementAccessExpr.expression)) { - this.incrementCounters(node, FaultID.EsObjectType); + this.incrementCounters(node, FaultID.EsObjectAccess); } } @@ -1391,22 +1403,25 @@ export class TypeScriptLinter { this.handleImportCall(tsCallExpr); this.handleRequireCall(tsCallExpr); - if (!!calleeSym) { + // NOTE: Keep handleFunctionApplyBindPropCall above handleGenericCallWithNoTypeArgs here!!! + if (calleeSym !== undefined) { + this.handleStdlibAPICall(tsCallExpr, calleeSym); + this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); if (this.tsUtils.symbolHasEsObjectType(calleeSym)) { - this.incrementCounters(tsCallExpr, FaultID.EsObjectType); - } - // need to process Symbol call separatey in order to not report two times when using Symbol API - if (this.tsUtils.isStdSymbol(calleeSym)) { - this.incrementCounters(tsCallExpr, FaultID.SymbolType); + this.incrementCounters(tsCallExpr, FaultID.EsObjectAccess); } } - if (!!callSignature) { + if (callSignature !== undefined) { if (!this.tsUtils.isLibrarySymbol(calleeSym)) { this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); } this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } this.handleLibraryTypeCall(tsCallExpr, calleeType); + + if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { + this.incrementCounters(node, FaultID.EsObjectAccess); + } } private handleImportCall(tsCallExpr: ts.CallExpression) { @@ -1467,6 +1482,21 @@ export class TypeScriptLinter { } } + private static listApplyBindCallApis = [ + 'Function.apply', + 'Function.call', + 'Function.bind', + 'CallableFunction.apply', + 'CallableFunction.call', + 'CallableFunction.bind' + ]; + private handleFunctionApplyBindPropCall(tsCallExpr: ts.CallExpression, calleeSym: ts.Symbol) { + const exprName = this.tsTypeChecker.getFullyQualifiedName(calleeSym); + if (TypeScriptLinter.listApplyBindCallApis.includes(exprName)) { + this.incrementCounters(tsCallExpr, FaultID.FunctionApplyBindCall); + } + } + private handleStructIdentAndUndefinedInArgs(tsCallOrNewExpr: ts.CallExpression | ts.NewExpression, callSignature: ts.Signature) { if (!tsCallOrNewExpr.arguments) { return; @@ -1498,17 +1528,35 @@ export class TypeScriptLinter { } } - private checkLimitedStdLib(node: ts.Node, symbol: ts.Symbol) { - const parName = this.tsUtils.getParentSymbolName(symbol); - const res = parName ? LIMITED_STD_API.get(parName) : undefined; - if (res && res.arr.includes(symbol.name)) { - this.incrementCounters(node, res.fault); + private static LimitedApis = new Map | null, fault: FaultID}> ([ + ['global', {arr: LIMITED_STD_GLOBAL_FUNC, fault: FaultID.LimitedStdLibApi}], + ['Object', {arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], + ['ObjectConstructor', {arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], + ['Reflect', {arr: LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi}], + ['ProxyHandler', {arr: LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi}], + ['ArrayBuffer', {arr: LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], + ['ArrayBufferConstructor', {arr: LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], + ['Symbol', {arr: null, fault: FaultID.SymbolType}], + ['SymbolConstructor', {arr: null, fault: FaultID.SymbolType}], + ]) + + private handleStdlibAPICall(callExpr: ts.CallExpression, calleeSym: ts.Symbol) { + const name = calleeSym.getName(); + const parName = this.tsUtils.getParentSymbolName(calleeSym); + if (parName === undefined) { + if (LIMITED_STD_GLOBAL_FUNC.includes(name)) { + this.incrementCounters(callExpr, FaultID.LimitedStdLibApi); + return; + } + let escapedName = calleeSym.escapedName; + if (escapedName === 'Symbol' || escapedName === 'SymbolConstructor') { + this.incrementCounters(callExpr, FaultID.SymbolType); + } return; } - const name = this.tsTypeChecker.getFullyQualifiedName(symbol); - if (LIMITED_STD_GLOBAL_API.includes(name)) { - this.incrementCounters(node, FaultID.LimitedStdLibApi) - return; + let lookup = TypeScriptLinter.LimitedApis.get(parName); + if (lookup !== undefined && (lookup.arr === null || lookup.arr.includes(name))) { + this.incrementCounters(callExpr, lookup.fault); } } @@ -1600,37 +1648,26 @@ export class TypeScriptLinter { } private handleTypeReference(node: ts.Node) { - const typeRef = node as ts.TypeReferenceNode; - - const isESObject = this.tsUtils.isEsObjectType(typeRef); - const isPossiblyValidContext = this.tsUtils.isEsObjectPossiblyAllowed(typeRef); - if (isESObject && !isPossiblyValidContext) { + let typeRef = node as ts.TypeReferenceNode; + if (this.tsUtils.isEsObjectType(typeRef) && !this.tsUtils.isEsObjectAllowed(typeRef)) { this.incrementCounters(node, FaultID.EsObjectType); - return; - } - - const typeName = this.tsUtils.entityNameToString(typeRef.typeName); - const isStdUtilityType = LIMITED_STANDARD_UTILITY_TYPES.includes(typeName); - if (isStdUtilityType) { - this.incrementCounters(node, FaultID.UtilityType); - return; - } - - // Using Partial type is allowed only when its argument type is either Class or Interface. - const isStdPartial = this.tsUtils.entityNameToString(typeRef.typeName) === 'Partial'; - const hasSingleTypeArgument = !!typeRef.typeArguments && typeRef.typeArguments.length === 1; - const argType = hasSingleTypeArgument && this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[0]); - if (isStdPartial && argType && !argType.isClassOrInterface()) { + } else if (ts.isIdentifier(typeRef.typeName) && LIMITED_STANDARD_UTILITY_TYPES.includes(typeRef.typeName.text)) this.incrementCounters(node, FaultID.UtilityType); - return; + else if ( + ts.isIdentifier(typeRef.typeName) && typeRef.typeName.text === 'Partial' && + typeRef.typeArguments && typeRef.typeArguments.length === 1 + ) { + // Using Partial type is allowed only when its argument type is either Class or Interface. + let argType = this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[0]); + if (!argType || !argType.isClassOrInterface()) + this.incrementCounters(node, FaultID.UtilityType); } } private handleMetaProperty(node: ts.Node) { let tsMetaProperty = node as ts.MetaProperty; - if (tsMetaProperty.name.text === 'target') { + if (tsMetaProperty.name.text === 'target') this.incrementCounters(node, FaultID.NewTarget); - } } private handleStructDeclaration(node: ts.Node) { diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/src/TypeScriptLinterConfig.ts index 58f32df62..83427d5e6 100644 --- a/linter/src/TypeScriptLinterConfig.ts +++ b/linter/src/TypeScriptLinterConfig.ts @@ -14,7 +14,7 @@ */ import * as ts from 'typescript'; -import { FaultID } from './utils/consts/Problems'; +import { FaultID } from './Problems'; export class LinterConfig { // The SyntaxKind enum defines additional elements at the end of the enum diff --git a/linter/src/ts-diagnostics/TSCCompiledProgram.ts b/linter/src/ts-diagnostics/TSCCompiledProgram.ts index 36faaf7c3..9ebcb1fab 100644 --- a/linter/src/ts-diagnostics/TSCCompiledProgram.ts +++ b/linter/src/ts-diagnostics/TSCCompiledProgram.ts @@ -19,7 +19,7 @@ import { ProblemSeverity } from '../ProblemSeverity'; import { LintOptions } from '../LintOptions'; import { TypeScriptDiagnosticsExtractor } from './TypeScriptDiagnosticsExtractor'; import { compile } from '../CompilerWrapper'; -import { FaultID } from '../utils/consts/Problems'; +import { FaultID } from '../Problems'; import { faultsAttrs } from '../FaultAttrs'; export interface TSCCompiledProgram { diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index c2ee9fef0..17d2f6e7b 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -902,7 +902,7 @@ export class TsUtils { public isStdObjectAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Object'); + return !!parentName && (parentName === 'Object' || parentName === 'ObjectConstructor'); } public isStdReflectAPI(symbol: ts.Symbol): boolean { @@ -917,22 +917,18 @@ export class TsUtils { public isStdArrayAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Array'); + return !!parentName && (parentName === 'Array' || parentName === 'ArrayConstructor'); } public isStdArrayBufferAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'ArrayBuffer'); + return !!parentName && (parentName === 'ArrayBuffer' || parentName === 'ArrayBufferConstructor'); } - public isStdSymbol(symbol: ts.Symbol): boolean { - const name = this.tsTypeChecker.getFullyQualifiedName(symbol) - return name === 'Symbol'; - } - - public isStdSymbolAPI(symbol: ts.Symbol): boolean { + public isSymbolAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Symbol'); + let name = parentName ? parentName : symbol.escapedName; + return name === 'Symbol' || name === 'SymbolConstructor'; } public isDefaultImport(importSpec: ts.ImportSpecifier): boolean { @@ -1141,29 +1137,22 @@ export class TsUtils { typeNode.typeName.text == ES_OBJECT; } - public isInsideBlock(node: ts.Node): boolean { - let par = node.parent - while (par) { - if (ts.isBlock(par)) { + public isEsObjectAllowed(typeRef: ts.TypeReferenceNode): boolean { + let node = typeRef.parent; + + if (!this.isVarDeclaration(node)) { + return false; + } + + while (node) { + if (ts.isBlock(node)) { return true; } - par = par.parent; + node = node.parent; } return false; } - public isEsObjectPossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean { - return ts.isVariableDeclaration(typeRef.parent); - } - - public isValueAssignableToESObject(node: ts.Node): boolean { - if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) { - return false; - } - const valueType = this.tsTypeChecker.getTypeAtLocation(node); - return this.isUnsupportedType(valueType) || this.isAnonymousType(valueType) - } - public getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { let sym = this.trueSymbolAtLocation(node); if (sym === undefined) { @@ -1193,7 +1182,7 @@ export class TsUtils { public isEsObjectSymbol(sym: ts.Symbol): boolean { let decl = this.getDeclaration(sym); return !!decl && ts.isTypeAliasDeclaration(decl) && decl.name.escapedText == ES_OBJECT && - decl.type.kind === ts.SyntaxKind.AnyKeyword; + decl.type.kind == ts.SyntaxKind.AnyKeyword; } public isAnonymousType(type: ts.Type): boolean { diff --git a/linter/src/utils/consts/AllowedStdSymbolAPI.ts b/linter/src/utils/consts/AllowedStdSymbolAPI.ts new file mode 100644 index 000000000..69c95812a --- /dev/null +++ b/linter/src/utils/consts/AllowedStdSymbolAPI.ts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +export const ALLOWED_STD_SYMBOL_API = ['iterator']; diff --git a/linter/src/utils/consts/LimitedStandardUtilityTypes.ts b/linter/src/utils/consts/LimitedStandardUtilityTypes.ts index 259443d99..ba9181506 100644 --- a/linter/src/utils/consts/LimitedStandardUtilityTypes.ts +++ b/linter/src/utils/consts/LimitedStandardUtilityTypes.ts @@ -14,21 +14,7 @@ */ export const LIMITED_STANDARD_UTILITY_TYPES = [ - 'Awaited', - 'Pick', - 'Omit', - 'Exclude', - 'Extract', - 'NonNullable', - 'Parameters', - 'ConstructorParameters', - 'ReturnType', - 'InstanceType', - 'ThisParameterType', - 'OmitThisParameter', - 'ThisType', - 'Uppercase', - 'Lowercase', - 'Capitalize', - 'Uncapitalize', + 'Awaited', 'Pick', 'Omit', 'Exclude', 'Extract', 'NonNullable', 'Parameters', + 'ConstructorParameters', 'ReturnType', 'InstanceType', 'ThisParameterType', 'OmitThisParameter', + 'ThisType', 'Uppercase', 'Lowercase', 'Capitalize', 'Uncapitalize', ]; diff --git a/linter/src/utils/consts/LimitedStdApi.ts b/linter/src/utils/consts/LimitedStdApi.ts deleted file mode 100644 index 1599fbfe9..000000000 --- a/linter/src/utils/consts/LimitedStdApi.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2023-2023 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 { FaultID } from "./Problems"; - -/** - * ArrayBuffer - */ -const LIMITED_STD_ARRAYBUFFER_API = [ - // properties - // methods - 'isView' -]; - -/** - * Object - */ -const LIMITED_STD_OBJECT_API = [ - // properties - '__proto__', - // methods - '__defineGetter__', - '__defineSetter__', - '__lookupGetter__', - '__lookupSetter__', - 'assign', - 'create', - 'defineProperties', - 'defineProperty', - 'freeze', - 'fromEntries', - 'getOwnPropertyDescriptor', - 'getOwnPropertyDescriptors', - 'getOwnPropertySymbols', - 'getPrototypeOf', - 'hasOwnProperty', - 'is', - 'isExtensible', - 'isFrozen', - 'isPrototypeOf', - 'isSealed', - 'preventExtensions', - 'propertyIsEnumerable', - 'seal', - 'setPrototypeOf', -]; - -/** - * Proxy - */ -const LIMITED_STD_PROXYHANDLER_API = [ - // properties - // methods - 'apply', - 'construct', - 'defineProperty', - 'deleteProperty', - 'get', - 'getOwnPropertyDescriptor', - 'getPrototypeOf', - 'has', - 'isExtensible', - 'ownKeys', - 'preventExtensions', - 'set', - 'setPrototypeOf' -]; - -/** - * Reflect - */ -const LIMITED_STD_REFLECT_API = [ - // properties - // methods - 'apply', - 'construct', - 'defineProperty', - 'deleteProperty', - 'getOwnPropertyDescriptor', - 'getPrototypeOf', - 'isExtensible', - 'preventExtensions', - 'setPrototypeOf', -]; - -/** - * Symbol - */ -const LIMITED_STD_SYMBOL_API = [ - 'Symbol', - // properties - 'asyncIterator', - 'description', - 'hasInstance', - 'isConcatSpreadable', - 'match', - 'matchAll', - 'replace', - 'search', - 'species', - 'split', - 'toPrimitive', - 'toStringTag', - 'unscopables', - // methods - 'for', - 'keyFor', - 'toString', - 'valueOf', -]; - -/** - * Function - */ -const LIMITED_STD_FUNCTION_API = [ - // properties - // methods - 'apply', - 'bind', - 'call', -]; - -/** - * Global - */ -export const LIMITED_STD_GLOBAL_API = [ - // properties - // methods - 'eval', -]; - -export const LIMITED_STD_API = new Map, fault: FaultID}> ([ - ['Object', {arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], - ['ObjectConstructor', {arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], - ['Reflect', {arr: LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi}], - ['ProxyHandler', {arr: LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi}], - ['ArrayBuffer', {arr: LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], - ['ArrayBufferConstructor', {arr: LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], - ['Symbol', {arr: LIMITED_STD_SYMBOL_API, fault: FaultID.SymbolType}], - ['SymbolConstructor', {arr: LIMITED_STD_SYMBOL_API, fault: FaultID.SymbolType}], - ['Function', {arr: LIMITED_STD_FUNCTION_API, fault: FaultID.FunctionApplyBindCall}], - ['CallableFunction', {arr: LIMITED_STD_FUNCTION_API, fault: FaultID.FunctionApplyBindCall}], -]) diff --git a/linter/src/utils/consts/LimitedStdArrayBufferAPI.ts b/linter/src/utils/consts/LimitedStdArrayBufferAPI.ts new file mode 100644 index 000000000..39605128f --- /dev/null +++ b/linter/src/utils/consts/LimitedStdArrayBufferAPI.ts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +export const LIMITED_STD_ARRAYBUFFER_API = ['isView']; diff --git a/linter/src/utils/consts/LimitedStdGlobalFunc.ts b/linter/src/utils/consts/LimitedStdGlobalFunc.ts new file mode 100644 index 000000000..eec858299 --- /dev/null +++ b/linter/src/utils/consts/LimitedStdGlobalFunc.ts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +export const LIMITED_STD_GLOBAL_FUNC = [ + 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt' +]; diff --git a/linter/src/utils/consts/LimitedStdGlobalVar.ts b/linter/src/utils/consts/LimitedStdGlobalVar.ts new file mode 100644 index 000000000..fd0b48816 --- /dev/null +++ b/linter/src/utils/consts/LimitedStdGlobalVar.ts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +export const LIMITED_STD_GLOBAL_VAR = ['Infinity', 'NaN']; diff --git a/linter/src/utils/consts/LimitedStdObjectAPI.ts b/linter/src/utils/consts/LimitedStdObjectAPI.ts new file mode 100644 index 000000000..55b7ffede --- /dev/null +++ b/linter/src/utils/consts/LimitedStdObjectAPI.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +export const LIMITED_STD_OBJECT_API = [ + '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'assign', 'create', + 'defineProperties', 'defineProperty', 'freeze', 'fromEntries', 'getOwnPropertyDescriptor', + 'getOwnPropertyDescriptors', 'getOwnPropertySymbols', 'getPrototypeOf', + 'hasOwnProperty', 'is', 'isExtensible', 'isFrozen', 'isPrototypeOf', 'isSealed', 'preventExtensions', + 'propertyIsEnumerable', 'seal', 'setPrototypeOf' +]; diff --git a/linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts b/linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts new file mode 100644 index 000000000..7113b2b5c --- /dev/null +++ b/linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +export const LIMITED_STD_PROXYHANDLER_API = [ + 'apply', 'construct', 'defineProperty', 'deleteProperty', 'get', 'getOwnPropertyDescriptor', 'getPrototypeOf', + 'has', 'isExtensible', 'ownKeys', 'preventExtensions', 'set', 'setPrototypeOf' +]; diff --git a/linter/src/utils/consts/LimitedStdReflectAPI.ts b/linter/src/utils/consts/LimitedStdReflectAPI.ts new file mode 100644 index 000000000..e1f58f802 --- /dev/null +++ b/linter/src/utils/consts/LimitedStdReflectAPI.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +export const LIMITED_STD_REFLECT_API = [ + 'apply', 'construct', 'defineProperty', 'deleteProperty', 'getOwnPropertyDescriptor', 'getPrototypeOf', + 'isExtensible', 'preventExtensions', 'setPrototypeOf' +]; diff --git a/linter/src/utils/consts/Problems.ts b/linter/src/utils/consts/Problems.ts deleted file mode 100644 index 3d1def20d..000000000 --- a/linter/src/utils/consts/Problems.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2022-2023 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. - */ - -export enum FaultID { - AnyType, - SymbolType, - ObjectLiteralNoContextType, - ArrayLiteralNoContextType, - ComputedPropertyName, - LiteralAsPropertyName, - TypeQuery, - RegexLiteral, - IsOperator, - DestructuringParameter, - YieldExpression, - InterfaceMerging, - EnumMerging, - InterfaceExtendsClass, - IndexMember, - WithStatement, - ThrowStatement, - IndexedAccessType, - UnknownType, - ForInStatement, - InOperator, - ImportFromPath, - FunctionExpression, - IntersectionType, - ObjectTypeLiteral, - CommaOperator, - LimitedReturnTypeInference, - LambdaWithTypeParameters, - ClassExpression, - DestructuringAssignment, - DestructuringDeclaration, - VarDeclaration, - CatchWithUnsupportedType, - DeleteOperator, - DeclWithDuplicateName, - UnaryArithmNotNumber, - ConstructorType, - ConstructorIface, - ConstructorFuncs, - CallSignature, - TypeAssertion, - PrivateIdentifier, - LocalFunction, - ConditionalType, - MappedType, - NamespaceAsObject, - ClassAsObject, - NonDeclarationInNamespace, - GeneratorFunction, - FunctionContainsThis, - PropertyAccessByIndex, - JsxElement, - EnumMemberNonConstInit, - ImplementsClass, - MethodReassignment, - MultipleStaticBlocks, - ThisType, - IntefaceExtendDifProps, - StructuralIdentity, - TypeOnlyImport, - TypeOnlyExport, - DefaultImport, - ExportAssignment, - ImportAssignment, - GenericCallNoTypeArgs, - ParameterProperties, - InstanceofUnsupported, - ShorthandAmbientModuleDecl, - WildcardsInModuleName, - UMDModuleDefinition, - NewTarget, - DefiniteAssignment, - Prototype, - GlobalThis, - UtilityType, - PropertyDeclOnFunction, - FunctionApplyBindCall, - ConstAssertion, - ImportAssertion, - SpreadOperator, - LimitedStdLibApi, - ErrorSuppression, - StrictDiagnostic, - UnsupportedDecorators, - ImportAfterStatement, - EsObjectType, - LAST_ID, // this should always be last enum` -} diff --git a/linter/test/es_object.ts b/linter/test/es_object.ts index 445b5c0c0..d9715b772 100644 --- a/linter/test/es_object.ts +++ b/linter/test/es_object.ts @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { fooOh, barOh } from './oh_modules/ohos_lib' + type ESObject = any class A {} @@ -174,20 +174,3 @@ interface CL extends ESObject {} export interface CLS extends ESObject {} foo2({ k: 'k', h: {t: 1}}) // we can assign anything to the esobject, even untyped literal -let q1: ESObject = 1; // CTE - ``ESObject`` typed variable can only be local -let q2: ESObject = fooOh(); // CTE - ``ESObject`` typed variable can only be local -let q3: ESObject = q2; // CTE - ``ESObject`` typed variable can only be local -function f() { - let e1 = fooOh(); // CTE - type of e1 is `any` - let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values - let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values - let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values - let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values - let e6: ESObject = fooOh(); // OK - explicitly annotaded as ESObject - let e7: ESObject = e6; // OK - initialize ESObject with ESObject - e6['prop'] // CTE - can't access dynamic properties of ESObject - e6[1] // CTE - can't access dynamic properties of ESObject - e6.prop // CTE - can't access dynamic properties of ESObject - barOh(e6) // OK - ESObject is passed to interop call - e6 = e7 // OK - ESObject is assigned to ESObject -} diff --git a/linter/test/es_object.ts.relax.json b/linter/test/es_object.ts.relax.json index f3d5acdb4..10bd5f5bd 100644 --- a/linter/test/es_object.ts.relax.json +++ b/linter/test/es_object.ts.relax.json @@ -23,234 +23,234 @@ }, { "line": 20, - "column": 5, + "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 77, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 78, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 79, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 80, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 82, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 83, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 85, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 86, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 87, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 88, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 90, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 91, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 93, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 94, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 95, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 96, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 98, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 99, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 114, @@ -486,37 +486,37 @@ { "line": 115, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 176, @@ -594,83 +594,6 @@ "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" - }, - { - "line": 177, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 178, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 179, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 181, - "column": 9, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 182, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 183, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 184, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 185, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 188, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 189, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 190, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" } ] } \ No newline at end of file diff --git a/linter/test/es_object.ts.strict.json b/linter/test/es_object.ts.strict.json index 5c869e41f..10bd5f5bd 100644 --- a/linter/test/es_object.ts.strict.json +++ b/linter/test/es_object.ts.strict.json @@ -23,234 +23,234 @@ }, { "line": 20, - "column": 5, + "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 77, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 78, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 79, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 80, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAccess", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 82, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 83, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 85, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 86, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 87, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 88, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 90, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 91, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 93, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 94, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 95, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 96, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 98, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 99, "column": 5, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 114, @@ -486,37 +486,37 @@ { "line": 115, "column": 9, - "problem": "EsObjectType", + "problem": "EsObjectAssignment", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 176, @@ -594,83 +594,6 @@ "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" - }, - { - "line": 177, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 178, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 179, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 181, - "column": 9, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 182, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 183, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 184, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 185, - "column": 9, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 188, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 189, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" - }, - { - "line": 190, - "column": 5, - "problem": "EsObjectType", - "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" } - ] + ] } \ No newline at end of file diff --git a/linter/test/function_expression.ts.autofix.json b/linter/test/function_expression.ts.autofix.json index 90e6f3f3b..c571fa05a 100644 --- a/linter/test/function_expression.ts.autofix.json +++ b/linter/test/function_expression.ts.autofix.json @@ -335,6 +335,14 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, + { + "line": 102, + "column": 15, + "problem": "FunctionApplyBindCall", + "autofixable": false, + "suggest": "", + "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" + }, { "line": 102, "column": 15, @@ -350,14 +358,6 @@ "suggest": "", "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, - { - "line": 104, - "column": 7, - "problem": "FunctionApplyBindCall", - "autofixable": false, - "suggest": "", - "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" - }, { "line": 108, "column": 16, diff --git a/linter/test/function_expression.ts.relax.json b/linter/test/function_expression.ts.relax.json index 8e6077236..48f6e1a27 100644 --- a/linter/test/function_expression.ts.relax.json +++ b/linter/test/function_expression.ts.relax.json @@ -57,8 +57,8 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { - "line": 104, - "column": 7, + "line": 102, + "column": 15, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" diff --git a/linter/test/function_expression.ts.strict.json b/linter/test/function_expression.ts.strict.json index 1233c4e7d..fe4750449 100644 --- a/linter/test/function_expression.ts.strict.json +++ b/linter/test/function_expression.ts.strict.json @@ -206,16 +206,16 @@ { "line": 102, "column": 15, - "problem": "FunctionExpression", + "problem": "FunctionApplyBindCall", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" + "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { - "line": 104, - "column": 7, - "problem": "FunctionApplyBindCall", + "line": 102, + "column": 15, + "problem": "FunctionExpression", "suggest": "", - "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { "line": 108, diff --git a/linter/test/function_object_methods.ts.relax.json b/linter/test/function_object_methods.ts.relax.json index 790856d4f..96e3fcaf1 100644 --- a/linter/test/function_object_methods.ts.relax.json +++ b/linter/test/function_object_methods.ts.relax.json @@ -23,7 +23,7 @@ }, { "line": 29, - "column": 35, + "column": 21, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -37,21 +37,21 @@ }, { "line": 30, - "column": 45, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 37, - "column": 37, + "column": 23, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 38, - "column": 40, + "column": 21, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -65,7 +65,7 @@ }, { "line": 68, - "column": 44, + "column": 22, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -79,42 +79,42 @@ }, { "line": 70, - "column": 35, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 75, - "column": 48, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 78, - "column": 48, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 81, - "column": 31, + "column": 9, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 82, - "column": 31, + "column": 9, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 87, - "column": 32, + "column": 16, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -128,7 +128,7 @@ }, { "line": 94, - "column": 37, + "column": 20, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -142,42 +142,42 @@ }, { "line": 96, - "column": 30, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 101, - "column": 42, + "column": 25, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 104, - "column": 42, + "column": 25, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 107, - "column": 20, + "column": 3, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 108, - "column": 20, + "column": 3, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 113, - "column": 21, + "column": 10, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -226,35 +226,35 @@ }, { "line": 136, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 137, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 138, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 139, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 141, - "column": 5, + "column": 1, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" diff --git a/linter/test/function_object_methods.ts.strict.json b/linter/test/function_object_methods.ts.strict.json index 2a7c8ccd9..e90572ea9 100644 --- a/linter/test/function_object_methods.ts.strict.json +++ b/linter/test/function_object_methods.ts.strict.json @@ -23,7 +23,7 @@ }, { "line": 29, - "column": 35, + "column": 21, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -37,21 +37,21 @@ }, { "line": 30, - "column": 45, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 37, - "column": 37, + "column": 23, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 38, - "column": 40, + "column": 21, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -65,7 +65,7 @@ }, { "line": 68, - "column": 44, + "column": 22, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -79,42 +79,42 @@ }, { "line": 70, - "column": 35, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 75, - "column": 48, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 78, - "column": 48, + "column": 26, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 81, - "column": 31, + "column": 9, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 82, - "column": 31, + "column": 9, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 87, - "column": 32, + "column": 16, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -128,7 +128,7 @@ }, { "line": 94, - "column": 37, + "column": 20, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -142,42 +142,42 @@ }, { "line": 96, - "column": 30, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 101, - "column": 42, + "column": 25, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 104, - "column": 42, + "column": 25, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 107, - "column": 20, + "column": 3, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 108, - "column": 20, + "column": 3, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 113, - "column": 21, + "column": 10, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" @@ -254,35 +254,35 @@ }, { "line": 136, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 137, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 138, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 139, - "column": 23, + "column": 13, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" }, { "line": 141, - "column": 5, + "column": 1, "problem": "FunctionApplyBindCall", "suggest": "", "rule": "\"Function.apply\", \"Function.bind\", \"Function.call\" are not supported (arkts-no-func-apply-bind-call)" diff --git a/linter/test/limited_stdlib_api.ts b/linter/test/limited_stdlib_api.ts index 500c10c9b..e0213de3b 100644 --- a/linter/test/limited_stdlib_api.ts +++ b/linter/test/limited_stdlib_api.ts @@ -28,7 +28,7 @@ decodeURIComponent(''); escape(''); unescape(''); -// global and window are not portable, so they are excluded from test suite. +global.eval('console.log("foo")'); globalThis.eval('console.log("foo")'); const evl = "eval('console.log(1)')"; const res: void = Function(evl)(); @@ -121,9 +121,3 @@ ArrayBuffer.isView({}); let a: number[] = []; let b = new ArrayBuffer(1); Array.isArray(a); - -Number.NaN; -Number.isFinite(1); -Number.isNaN(2); -Number.parseFloat('3'); -Number.parseInt('4', 10); diff --git a/linter/test/limited_stdlib_api.ts.autofix.json b/linter/test/limited_stdlib_api.ts.autofix.json index ddabd1f89..e4aca6e3c 100644 --- a/linter/test/limited_stdlib_api.ts.autofix.json +++ b/linter/test/limited_stdlib_api.ts.autofix.json @@ -23,24 +23,80 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { - "line": 32, + "line": 18, + "column": 11, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 19, + "column": 11, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 20, "column": 1, - "problem": "GlobalThis", + "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 21, + "column": 1, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 22, + "column": 1, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 23, + "column": 1, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 31, + "column": 1, + "problem": "LimitedStdLibApi", + "autofixable": false, + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 32, - "column": 12, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, + { + "line": 32, + "column": 1, + "problem": "GlobalThis", + "autofixable": false, + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + }, { "line": 56, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -48,7 +104,7 @@ }, { "line": 57, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -56,7 +112,7 @@ }, { "line": 58, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -72,7 +128,7 @@ }, { "line": 59, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -80,7 +136,7 @@ }, { "line": 61, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -88,7 +144,7 @@ }, { "line": 62, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -96,7 +152,7 @@ }, { "line": 63, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -104,7 +160,7 @@ }, { "line": 64, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -112,7 +168,7 @@ }, { "line": 65, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -120,7 +176,7 @@ }, { "line": 66, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -128,7 +184,7 @@ }, { "line": 67, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -136,7 +192,7 @@ }, { "line": 68, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -144,7 +200,7 @@ }, { "line": 69, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -152,7 +208,7 @@ }, { "line": 70, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -160,7 +216,7 @@ }, { "line": 71, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -168,7 +224,7 @@ }, { "line": 72, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -176,7 +232,7 @@ }, { "line": 73, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -184,7 +240,7 @@ }, { "line": 74, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -192,7 +248,7 @@ }, { "line": 75, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -200,7 +256,7 @@ }, { "line": 76, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -208,7 +264,7 @@ }, { "line": 85, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -216,7 +272,7 @@ }, { "line": 86, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -232,7 +288,7 @@ }, { "line": 87, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -248,7 +304,7 @@ }, { "line": 88, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -256,7 +312,7 @@ }, { "line": 90, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -264,7 +320,7 @@ }, { "line": 91, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -272,7 +328,7 @@ }, { "line": 92, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -280,7 +336,7 @@ }, { "line": 93, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -288,7 +344,7 @@ }, { "line": 94, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -304,15 +360,7 @@ }, { "line": 105, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 105, - "column": 28, + "column": 20, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -320,23 +368,7 @@ }, { "line": 106, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 106, - "column": 32, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 107, - "column": 13, + "column": 24, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -344,7 +376,7 @@ }, { "line": 107, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -360,15 +392,7 @@ }, { "line": 108, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 108, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -376,23 +400,7 @@ }, { "line": 109, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 109, - "column": 26, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 110, - "column": 13, + "column": 18, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -400,15 +408,7 @@ }, { "line": 110, - "column": 47, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 111, - "column": 13, + "column": 39, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -416,7 +416,7 @@ }, { "line": 111, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -424,23 +424,7 @@ }, { "line": 112, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 112, - "column": 26, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 113, - "column": 13, + "column": 18, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -448,7 +432,7 @@ }, { "line": 113, - "column": 35, + "column": 27, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -456,23 +440,7 @@ }, { "line": 114, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 114, - "column": 30, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 115, - "column": 13, + "column": 22, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -480,15 +448,7 @@ }, { "line": 115, - "column": 40, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 116, - "column": 13, + "column": 32, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -496,7 +456,7 @@ }, { "line": 116, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -504,15 +464,7 @@ }, { "line": 117, - "column": 13, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 117, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", @@ -520,7 +472,7 @@ }, { "line": 120, - "column": 13, + "column": 1, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", diff --git a/linter/test/limited_stdlib_api.ts.relax.json b/linter/test/limited_stdlib_api.ts.relax.json index d77e760a8..055ef99ee 100644 --- a/linter/test/limited_stdlib_api.ts.relax.json +++ b/linter/test/limited_stdlib_api.ts.relax.json @@ -22,36 +22,85 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { - "line": 32, + "line": 18, + "column": 11, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 19, + "column": 11, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 20, "column": 1, - "problem": "GlobalThis", + "problem": "LimitedStdLibApi", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 21, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 22, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 23, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 31, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 32, - "column": 12, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, + { + "line": 32, + "column": 1, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + }, { "line": 56, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 57, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 58, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -65,133 +114,133 @@ }, { "line": 59, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 61, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 62, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 63, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 64, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 65, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 66, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 67, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 68, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 69, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 70, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 71, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 72, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 73, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 74, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 75, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 76, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 85, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 86, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -205,7 +254,7 @@ }, { "line": 87, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -219,42 +268,42 @@ }, { "line": 88, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 90, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 91, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 92, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 93, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 94, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -268,42 +317,21 @@ }, { "line": 105, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 105, - "column": 28, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 106, - "column": 13, + "column": 20, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 106, - "column": 32, + "column": 24, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 107, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 107, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -317,147 +345,77 @@ }, { "line": 108, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 108, - "column": 37, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 109, - "column": 13, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 109, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 110, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 110, - "column": 47, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 111, - "column": 13, + "column": 39, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 111, - "column": 37, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 112, - "column": 13, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 112, - "column": 26, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 113, - "column": 13, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 113, - "column": 35, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 114, - "column": 13, + "column": 27, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 114, - "column": 30, + "column": 22, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 115, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 115, - "column": 40, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 116, - "column": 13, + "column": 32, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 116, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 117, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 117, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 120, - "column": 13, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" diff --git a/linter/test/limited_stdlib_api.ts.strict.json b/linter/test/limited_stdlib_api.ts.strict.json index d77e760a8..055ef99ee 100644 --- a/linter/test/limited_stdlib_api.ts.strict.json +++ b/linter/test/limited_stdlib_api.ts.strict.json @@ -22,36 +22,85 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { - "line": 32, + "line": 18, + "column": 11, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 19, + "column": 11, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 20, "column": 1, - "problem": "GlobalThis", + "problem": "LimitedStdLibApi", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 21, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 22, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 23, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" + }, + { + "line": 31, + "column": 1, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 32, - "column": 12, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, + { + "line": 32, + "column": 1, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)" + }, { "line": 56, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 57, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 58, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -65,133 +114,133 @@ }, { "line": 59, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 61, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 62, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 63, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 64, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 65, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 66, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 67, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 68, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 69, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 70, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 71, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 72, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 73, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 74, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 75, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 76, - "column": 8, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 85, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 86, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -205,7 +254,7 @@ }, { "line": 87, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -219,42 +268,42 @@ }, { "line": 88, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 90, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 91, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 92, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 93, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 94, - "column": 9, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -268,42 +317,21 @@ }, { "line": 105, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 105, - "column": 28, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 106, - "column": 13, + "column": 20, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 106, - "column": 32, + "column": 24, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 107, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 107, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" @@ -317,147 +345,77 @@ }, { "line": 108, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 108, - "column": 37, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 109, - "column": 13, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 109, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 110, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 110, - "column": 47, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 111, - "column": 13, + "column": 39, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 111, - "column": 37, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 112, - "column": 13, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 112, - "column": 26, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 113, - "column": 13, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 113, - "column": 35, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 114, - "column": 13, + "column": 27, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 114, - "column": 30, + "column": 22, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 115, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 115, - "column": 40, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 116, - "column": 13, + "column": 32, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 116, - "column": 26, + "column": 18, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 117, - "column": 13, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 117, - "column": 37, + "column": 29, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, { "line": 120, - "column": 13, + "column": 1, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" diff --git a/linter/test/new_target.ts.relax.json b/linter/test/new_target.ts.relax.json index 0b83a1198..5ec99daa2 100644 --- a/linter/test/new_target.ts.relax.json +++ b/linter/test/new_target.ts.relax.json @@ -16,7 +16,7 @@ "nodes": [ { "line": 19, - "column": 12, + "column": 5, "problem": "LimitedStdLibApi" }, { diff --git a/linter/test/new_target.ts.strict.json b/linter/test/new_target.ts.strict.json index 0b83a1198..5ec99daa2 100644 --- a/linter/test/new_target.ts.strict.json +++ b/linter/test/new_target.ts.strict.json @@ -16,7 +16,7 @@ "nodes": [ { "line": 19, - "column": 12, + "column": 5, "problem": "LimitedStdLibApi" }, { diff --git a/linter/test/oh_modules/ohos_lib.ts b/linter/test/oh_modules/ohos_lib.ts index c69856185..a0aa74c87 100644 --- a/linter/test/oh_modules/ohos_lib.ts +++ b/linter/test/oh_modules/ohos_lib.ts @@ -20,6 +20,3 @@ export interface OhosI { export function ohFunction1({d: OhosI}): void {} // incorrect usage, but it was an issue, so we check it too export function ohFunction2(p: {d: OhosI}): void {} - -export function fooOh(): any {} -export function barOh(a: any) {} diff --git a/linter/test/symbol_api.ts.relax.json b/linter/test/symbol_api.ts.relax.json index e62c8c7b7..c2211cf10 100644 --- a/linter/test/symbol_api.ts.relax.json +++ b/linter/test/symbol_api.ts.relax.json @@ -16,77 +16,77 @@ "nodes": [ { "line": 16, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 17, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 18, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 20, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 21, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 22, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 23, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 24, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 25, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 26, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 27, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" @@ -107,7 +107,7 @@ }, { "line": 33, - "column": 17, + "column": 10, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" diff --git a/linter/test/symbol_api.ts.strict.json b/linter/test/symbol_api.ts.strict.json index e62c8c7b7..c2211cf10 100644 --- a/linter/test/symbol_api.ts.strict.json +++ b/linter/test/symbol_api.ts.strict.json @@ -16,77 +16,77 @@ "nodes": [ { "line": 16, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 17, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 18, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 20, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 21, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 22, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 23, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 24, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 25, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 26, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" }, { "line": 27, - "column": 16, + "column": 9, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" @@ -107,7 +107,7 @@ }, { "line": 33, - "column": 17, + "column": 10, "problem": "SymbolType", "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)" diff --git a/linter/test/utility_types.ts.relax.json b/linter/test/utility_types.ts.relax.json index fe6131546..63a56e5cd 100644 --- a/linter/test/utility_types.ts.relax.json +++ b/linter/test/utility_types.ts.relax.json @@ -266,7 +266,7 @@ }, { "line": 178, - "column": 18, + "column": 12, "problem": "FunctionApplyBindCall" }, { @@ -286,7 +286,7 @@ }, { "line": 187, - "column": 60, + "column": 54, "problem": "FunctionApplyBindCall" }, { diff --git a/linter/test/utility_types.ts.strict.json b/linter/test/utility_types.ts.strict.json index c5686de4b..cb2916b9d 100644 --- a/linter/test/utility_types.ts.strict.json +++ b/linter/test/utility_types.ts.strict.json @@ -291,7 +291,7 @@ }, { "line": 178, - "column": 18, + "column": 12, "problem": "FunctionApplyBindCall" }, { @@ -316,7 +316,7 @@ }, { "line": 187, - "column": 60, + "column": 54, "problem": "FunctionApplyBindCall" }, { diff --git a/linter/test_rules/rule132.ts.autofix.json b/linter/test_rules/rule132.ts.autofix.json index d1868ca7f..9002b4276 100644 --- a/linter/test_rules/rule132.ts.autofix.json +++ b/linter/test_rules/rule132.ts.autofix.json @@ -2,7 +2,7 @@ "nodes": [ { "line": 7, - "column": 16, + "column": 9, "problem": "LimitedStdLibApi", "autofixable": false, "suggest": "", diff --git a/linter/test_rules/rule132.ts.relax.json b/linter/test_rules/rule132.ts.relax.json index 21468ce90..192c3aa10 100644 --- a/linter/test_rules/rule132.ts.relax.json +++ b/linter/test_rules/rule132.ts.relax.json @@ -2,7 +2,7 @@ "nodes": [ { "line": 7, - "column": 16, + "column": 9, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" diff --git a/linter/test_rules/rule132.ts.strict.json b/linter/test_rules/rule132.ts.strict.json index 21468ce90..192c3aa10 100644 --- a/linter/test_rules/rule132.ts.strict.json +++ b/linter/test_rules/rule132.ts.strict.json @@ -2,7 +2,7 @@ "nodes": [ { "line": 7, - "column": 16, + "column": 9, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" -- Gitee From 5601721a633789160ec409e90b381bb65e4ff8e5 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Fri, 20 Oct 2023 13:23:49 +0300 Subject: [PATCH 02/49] [ArkTS Linter] #13972: Iterate over all child nodes to not miss comment directives between punctuation tokens. Change-Id: I9b820591bc9cb82cdd2045e12315390eba0b05a3 Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 26 +++++++++-- linter-4.2/src/TypeScriptLinterConfig.ts | 2 +- linter-4.2/test/ts_ignore.ts.relax.json | 57 ++++++++++++++++++------ linter-4.2/test/ts_ignore.ts.strict.json | 57 ++++++++++++++++++------ linter/src/TypeScriptLinter.ts | 11 ++++- linter/src/TypeScriptLinterConfig.ts | 2 +- linter/test/ts_ignore.ts.relax.json | 57 ++++++++++++++++++------ linter/test/ts_ignore.ts.strict.json | 57 ++++++++++++++++++------ 8 files changed, 211 insertions(+), 58 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 34126f27d..77cd2fa72 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -61,6 +61,7 @@ export class TypeScriptLinter { currentErrorLine: number; currentWarningLine: number; staticBlocks: Set; + walkedComments: Set; libraryTypeCallDiagnosticChecker: LibraryTypeCallDiagnosticChecker; private sourceFile?: ts.SourceFile; @@ -83,6 +84,7 @@ export class TypeScriptLinter { this.currentErrorLine = 0; this.currentWarningLine = 0; this.staticBlocks = new Set(); + this.walkedComments = new Set(); this.libraryTypeCallDiagnosticChecker = new LibraryTypeCallDiagnosticChecker(TypeScriptLinter.filteredDiagnosticMessages); for (let i = 0; i < FaultID.LAST_ID; i++) { @@ -254,7 +256,12 @@ export class TypeScriptLinter { } } - ts.forEachChild(node, visitTSNodeImpl); + // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. + // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. + // to traverse child nodes. + for (const child of node.getChildren()) { + visitTSNodeImpl(child); + } } } @@ -1188,6 +1195,8 @@ export class TypeScriptLinter { ) { this.incrementCounters(node, FaultID.InstanceofUnsupported); } + } else if (tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.InKeyword) { + this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.InOperator); } else if (tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.EqualsToken) { if (this.tsUtils.needToDeduceStructuralIdentity(leftOperandType, rightOperandType, tsRhsExpr)) { this.incrementCounters(tsBinaryExpr, FaultID.StructuralIdentity); @@ -2059,7 +2068,12 @@ export class TypeScriptLinter { ); if (leadingComments) { for (const comment of leadingComments) { - this.checkErrorSuppressingAnnotation(comment, srcText); + // In the real-time linter comment from the first line is double proccessed. + // It may be caused by tsc, but it should be investigated. This is a workaround + if (!this.walkedComments.has(comment.pos) && comment.pos !== comment.end) { + this.walkedComments.add(comment.pos); + this.checkErrorSuppressingAnnotation(comment, srcText); + } } } } @@ -2071,7 +2085,12 @@ export class TypeScriptLinter { ); if (trailingComments) { for (const comment of trailingComments) { - this.checkErrorSuppressingAnnotation(comment, srcText); + // In the real-time linter comment from the first line is double proccessed. + // It may be caused by tsc, but it should be investigated. This is a workaround + if (!this.walkedComments.has(comment.pos) && comment.pos !== comment.end) { + this.walkedComments.add(comment.pos); + this.checkErrorSuppressingAnnotation(comment, srcText); + } } } } @@ -2240,6 +2259,7 @@ export class TypeScriptLinter { } public lint(sourceFile: ts.SourceFile) { + this.walkedComments.clear(); this.sourceFile = sourceFile; this.visitTSNode(this.sourceFile); } diff --git a/linter-4.2/src/TypeScriptLinterConfig.ts b/linter-4.2/src/TypeScriptLinterConfig.ts index fcb5d1988..423c18076 100644 --- a/linter-4.2/src/TypeScriptLinterConfig.ts +++ b/linter-4.2/src/TypeScriptLinterConfig.ts @@ -175,7 +175,7 @@ export class LinterConfig { [ts.SyntaxKind.TypePredicate, FaultID.IsOperator], [ts.SyntaxKind.YieldExpression, FaultID.YieldExpression], [ts.SyntaxKind.IndexSignature, FaultID.IndexMember], [ts.SyntaxKind.WithStatement, FaultID.WithStatement], [ts.SyntaxKind.IndexedAccessType, FaultID.IndexedAccessType],[ts.SyntaxKind.UnknownKeyword, FaultID.UnknownType], - [ts.SyntaxKind.InKeyword, FaultID.InOperator], [ts.SyntaxKind.CallSignature, FaultID.CallSignature], + [ts.SyntaxKind.CallSignature, FaultID.CallSignature], [ts.SyntaxKind.IntersectionType, FaultID.IntersectionType], [ts.SyntaxKind.TypeLiteral, FaultID.ObjectTypeLiteral], [ts.SyntaxKind.ConstructorType, FaultID.ConstructorFuncs], [ts.SyntaxKind.PrivateIdentifier, FaultID.PrivateIdentifier], diff --git a/linter-4.2/test/ts_ignore.ts.relax.json b/linter-4.2/test/ts_ignore.ts.relax.json index d1f517671..8342e1744 100644 --- a/linter-4.2/test/ts_ignore.ts.relax.json +++ b/linter-4.2/test/ts_ignore.ts.relax.json @@ -17,62 +17,93 @@ { "line": 16, "column": 1, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 21, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 25, "column": 19, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 30, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 33, "column": 2, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 43, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 52, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 53, "column": 3, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 55, "column": 22, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 58, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 75, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 18, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Type 'null' is not assignable to type 'number'.", + "rule": "Type 'null' is not assignable to type 'number'." } ] -} +} \ No newline at end of file diff --git a/linter-4.2/test/ts_ignore.ts.strict.json b/linter-4.2/test/ts_ignore.ts.strict.json index d1f517671..8342e1744 100644 --- a/linter-4.2/test/ts_ignore.ts.strict.json +++ b/linter-4.2/test/ts_ignore.ts.strict.json @@ -17,62 +17,93 @@ { "line": 16, "column": 1, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 21, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 25, "column": 19, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 30, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 33, "column": 2, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 43, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 52, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 53, "column": 3, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 55, "column": 22, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 58, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 75, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 18, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Type 'null' is not assignable to type 'number'.", + "rule": "Type 'null' is not assignable to type 'number'." } ] -} +} \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 0b26d2f95..a8910ce93 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -268,7 +268,13 @@ export class TypeScriptLinter { handler.call(self, node); } } - ts.forEachChild(node, visitTSNodeImpl); + + // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. + // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. + // to traverse child nodes. + for (const child of node.getChildren()) { + visitTSNodeImpl(child); + } } } @@ -917,6 +923,9 @@ export class TypeScriptLinter { case ts.SyntaxKind.InstanceOfKeyword: this.processBinaryInstanceOf(node, tsLhsExpr, leftOperandType); break; + case ts.SyntaxKind.InKeyword: + this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.InOperator); + break; case ts.SyntaxKind.EqualsToken: if (this.tsUtils.needToDeduceStructuralIdentity(leftOperandType, rightOperandType, tsRhsExpr)) { this.incrementCounters(tsBinaryExpr, FaultID.StructuralIdentity); diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/src/TypeScriptLinterConfig.ts index 83427d5e6..03ebd743e 100644 --- a/linter/src/TypeScriptLinterConfig.ts +++ b/linter/src/TypeScriptLinterConfig.ts @@ -81,7 +81,7 @@ export class LinterConfig { [ts.SyntaxKind.TypePredicate, FaultID.IsOperator], [ts.SyntaxKind.YieldExpression, FaultID.YieldExpression], [ts.SyntaxKind.IndexSignature, FaultID.IndexMember], [ts.SyntaxKind.WithStatement, FaultID.WithStatement], [ts.SyntaxKind.IndexedAccessType, FaultID.IndexedAccessType], [ts.SyntaxKind.UnknownKeyword, FaultID.UnknownType], - [ts.SyntaxKind.InKeyword, FaultID.InOperator], [ts.SyntaxKind.CallSignature, FaultID.CallSignature], + [ts.SyntaxKind.CallSignature, FaultID.CallSignature], [ts.SyntaxKind.IntersectionType, FaultID.IntersectionType], [ts.SyntaxKind.TypeLiteral, FaultID.ObjectTypeLiteral], [ts.SyntaxKind.ConstructorType, FaultID.ConstructorFuncs], [ts.SyntaxKind.PrivateIdentifier, FaultID.PrivateIdentifier], diff --git a/linter/test/ts_ignore.ts.relax.json b/linter/test/ts_ignore.ts.relax.json index d1f517671..8342e1744 100644 --- a/linter/test/ts_ignore.ts.relax.json +++ b/linter/test/ts_ignore.ts.relax.json @@ -17,62 +17,93 @@ { "line": 16, "column": 1, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 21, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 25, "column": 19, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 30, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 33, "column": 2, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 43, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 52, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 53, "column": 3, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 55, "column": 22, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 58, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 75, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 18, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Type 'null' is not assignable to type 'number'.", + "rule": "Type 'null' is not assignable to type 'number'." } ] -} +} \ No newline at end of file diff --git a/linter/test/ts_ignore.ts.strict.json b/linter/test/ts_ignore.ts.strict.json index d1f517671..8342e1744 100644 --- a/linter/test/ts_ignore.ts.strict.json +++ b/linter/test/ts_ignore.ts.strict.json @@ -17,62 +17,93 @@ { "line": 16, "column": 1, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 21, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 25, "column": 19, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 30, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 33, "column": 2, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 43, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 52, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 53, "column": 3, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 55, "column": 22, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 58, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 75, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 18, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Type 'null' is not assignable to type 'number'.", + "rule": "Type 'null' is not assignable to type 'number'." } ] -} +} \ No newline at end of file -- Gitee From 90a207788f3a30c71659ce224ad621d4f3ef77ca Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 23 Oct 2023 13:41:10 +0300 Subject: [PATCH 03/49] [ArkTS Linter] Fix #14071: Check generic type constraint for element access expression. Change-Id: If469236ae117f681976f589dffca12bc4c4bb9d0 Signed-off-by: Evgeniy Okolnov --- linter-4.2/scripts/update-test-results.mjs | 24 +++++++------ linter-4.2/src/TypeScriptLinter.ts | 4 +-- linter-4.2/src/Utils.ts | 11 ++++++ linter-4.2/test/property_access_by_index.ts | 30 ++++++++++++++++ .../property_access_by_index.ts.autofix.json | 34 +++++++++++++++++++ .../property_access_by_index.ts.relax.json | 17 ++++++++++ .../property_access_by_index.ts.strict.json | 32 +++++++++++++++++ linter/scripts/update-test-results.mjs | 24 +++++++------ linter/src/TypeScriptLinter.ts | 2 +- linter/src/utils/TsUtils.ts | 11 ++++++ linter/test/property_access_by_index.ts | 30 ++++++++++++++++ .../property_access_by_index.ts.autofix.json | 34 +++++++++++++++++++ .../property_access_by_index.ts.relax.json | 17 ++++++++++ .../property_access_by_index.ts.strict.json | 32 +++++++++++++++++ 14 files changed, 278 insertions(+), 24 deletions(-) create mode 100644 linter-4.2/test/property_access_by_index.ts create mode 100644 linter-4.2/test/property_access_by_index.ts.autofix.json create mode 100644 linter-4.2/test/property_access_by_index.ts.relax.json create mode 100644 linter-4.2/test/property_access_by_index.ts.strict.json create mode 100644 linter/test/property_access_by_index.ts create mode 100644 linter/test/property_access_by_index.ts.autofix.json create mode 100644 linter/test/property_access_by_index.ts.relax.json create mode 100644 linter/test/property_access_by_index.ts.strict.json diff --git a/linter-4.2/scripts/update-test-results.mjs b/linter-4.2/scripts/update-test-results.mjs index dc579e424..45029c37e 100644 --- a/linter-4.2/scripts/update-test-results.mjs +++ b/linter-4.2/scripts/update-test-results.mjs @@ -37,7 +37,7 @@ const RESULTS_DIR = 'results' let testDirs = []; // forces to update all tests regardless of whether there was diff in a test result -const force_update = false; +let force_update = false; for (let arg of process.argv.slice(2)) { if (arg === '--force') @@ -72,33 +72,37 @@ function readTestFile(filePath) { function updateTest(testDir, testFile, mode) { let resultExt = RESULT_EXT[mode]; - let testFileWithExt = testFile + resultExt; + let resultFileWithExt = testFile + resultExt; + let resultFilePath = path.join(testDir, resultFileWithExt); // Do not update autofix result if test is skipped - if (mode === Mode.AUTOFIX && fs.existsSync(path.join(testDir, testFileWithExt + AUTOFIX_SKIP_EXT))) { + if (mode === Mode.AUTOFIX && fs.existsSync(path.join(testDir, testFile + AUTOFIX_SKIP_EXT))) { return; } - // Update test result when 'diff' exists or the 'force' option is enabled. - if (!fs.existsSync(path.join(testDir, RESULTS_DIR, testFileWithExt + DIFF_EXT)) && !force_update) { + // Update test result when: + // - '.diff' exists + // - expected '.json' doesn't exist + // - 'force' option is enabled + if (fs.existsSync(resultFilePath) && !fs.existsSync(path.join(testDir, RESULTS_DIR, resultFileWithExt + DIFF_EXT)) && !force_update) { return; } - let expectedResult = readTestFile(path.join(testDir, testFileWithExt)); + let expectedResult = readTestFile(resultFilePath); const copyright = expectedResult?.copyright ?? DEFAULT_COPYRIGHT; - let actualResult = readTestFile(path.join(testDir, RESULTS_DIR, testFileWithExt)); + let actualResult = readTestFile(path.join(testDir, RESULTS_DIR, resultFileWithExt)); if (!actualResult || !actualResult.nodes) { - console.log(`Failed to update ${testFileWithExt}: couldn't read ACTUAL result file.`); + console.log(`Failed to update ${resultFileWithExt}: couldn't read ACTUAL result file.`); return; } // Write file with actual test results. let newResultJSON = JSON.stringify({ copyright, nodes: actualResult.nodes }, null, 4); - fs.writeFileSync(path.join(testDir, testFileWithExt), newResultJSON); + fs.writeFileSync(resultFilePath, newResultJSON); - console.log(`Updated ${testFileWithExt}`); + console.log(`Updated ${resultFileWithExt}`); } for (let testDir of testDirs) { diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 77cd2fa72..44bc9657e 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1602,9 +1602,7 @@ export class TypeScriptLinter { private handleElementAccessExpression(node: ts.Node) { const tsElementAccessExpr = node as ts.ElementAccessExpression; - const tsElemAccessBaseExprType = this.tsTypeChecker.getTypeAtLocation( - tsElementAccessExpr.expression - ); + const tsElemAccessBaseExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression); const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode( tsElemAccessBaseExprType, undefined, diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 360d36bb1..1414a71b9 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -1507,4 +1507,15 @@ export class TsUtils { visitNode(funcExpr); return found; } + + public getTypeOrTypeConstraintAtLocation(expr: ts.Expression): ts.Type { + let type = this.tsTypeChecker.getTypeAtLocation(expr); + if (type.isTypeParameter()) { + let constraint = type.getConstraint(); + if (constraint) { + return constraint; + } + } + return type; + } } diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts new file mode 100644 index 000000000..3911b881b --- /dev/null +++ b/linter-4.2/test/property_access_by_index.ts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +// #14071 +class A { + v: string = ''; +} +function SetProperty(oldObj: T, str: string, obj: Object): void { + oldObj[str] = obj; // Should report error +} +function GetProperty(oldObj: T, str: string): U { + return oldObj[str]; // Should report error +} +function test() { + let a: A = { v: 'abc' }; + SetProperty(a, 'u', 'def'); + return GetProperty(a, 'v') + GetProperty(a, 'u'); +} diff --git a/linter-4.2/test/property_access_by_index.ts.autofix.json b/linter-4.2/test/property_access_by_index.ts.autofix.json new file mode 100644 index 000000000..90d724616 --- /dev/null +++ b/linter-4.2/test/property_access_by_index.ts.autofix.json @@ -0,0 +1,34 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 21, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": false, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 24, + "column": 10, + "problem": "PropertyAccessByIndex", + "autofixable": false, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + } + ] +} \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.relax.json b/linter-4.2/test/property_access_by_index.ts.relax.json new file mode 100644 index 000000000..e7d2d6779 --- /dev/null +++ b/linter-4.2/test/property_access_by_index.ts.relax.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [] +} \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.strict.json b/linter-4.2/test/property_access_by_index.ts.strict.json new file mode 100644 index 000000000..816f247c7 --- /dev/null +++ b/linter-4.2/test/property_access_by_index.ts.strict.json @@ -0,0 +1,32 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 21, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 24, + "column": 10, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + } + ] +} \ No newline at end of file diff --git a/linter/scripts/update-test-results.mjs b/linter/scripts/update-test-results.mjs index dc579e424..45029c37e 100644 --- a/linter/scripts/update-test-results.mjs +++ b/linter/scripts/update-test-results.mjs @@ -37,7 +37,7 @@ const RESULTS_DIR = 'results' let testDirs = []; // forces to update all tests regardless of whether there was diff in a test result -const force_update = false; +let force_update = false; for (let arg of process.argv.slice(2)) { if (arg === '--force') @@ -72,33 +72,37 @@ function readTestFile(filePath) { function updateTest(testDir, testFile, mode) { let resultExt = RESULT_EXT[mode]; - let testFileWithExt = testFile + resultExt; + let resultFileWithExt = testFile + resultExt; + let resultFilePath = path.join(testDir, resultFileWithExt); // Do not update autofix result if test is skipped - if (mode === Mode.AUTOFIX && fs.existsSync(path.join(testDir, testFileWithExt + AUTOFIX_SKIP_EXT))) { + if (mode === Mode.AUTOFIX && fs.existsSync(path.join(testDir, testFile + AUTOFIX_SKIP_EXT))) { return; } - // Update test result when 'diff' exists or the 'force' option is enabled. - if (!fs.existsSync(path.join(testDir, RESULTS_DIR, testFileWithExt + DIFF_EXT)) && !force_update) { + // Update test result when: + // - '.diff' exists + // - expected '.json' doesn't exist + // - 'force' option is enabled + if (fs.existsSync(resultFilePath) && !fs.existsSync(path.join(testDir, RESULTS_DIR, resultFileWithExt + DIFF_EXT)) && !force_update) { return; } - let expectedResult = readTestFile(path.join(testDir, testFileWithExt)); + let expectedResult = readTestFile(resultFilePath); const copyright = expectedResult?.copyright ?? DEFAULT_COPYRIGHT; - let actualResult = readTestFile(path.join(testDir, RESULTS_DIR, testFileWithExt)); + let actualResult = readTestFile(path.join(testDir, RESULTS_DIR, resultFileWithExt)); if (!actualResult || !actualResult.nodes) { - console.log(`Failed to update ${testFileWithExt}: couldn't read ACTUAL result file.`); + console.log(`Failed to update ${resultFileWithExt}: couldn't read ACTUAL result file.`); return; } // Write file with actual test results. let newResultJSON = JSON.stringify({ copyright, nodes: actualResult.nodes }, null, 4); - fs.writeFileSync(path.join(testDir, testFileWithExt), newResultJSON); + fs.writeFileSync(resultFilePath, newResultJSON); - console.log(`Updated ${testFileWithExt}`); + console.log(`Updated ${resultFileWithExt}`); } for (let testDir of testDirs) { diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index a8910ce93..3b5ed579f 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1323,7 +1323,7 @@ export class TypeScriptLinter { private handleElementAccessExpression(node: ts.Node) { const tsElementAccessExpr = node as ts.ElementAccessExpression; - const tsElemAccessBaseExprType = this.tsTypeChecker.getTypeAtLocation(tsElementAccessExpr.expression); + const tsElemAccessBaseExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression); const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode(tsElemAccessBaseExprType, undefined, ts.NodeBuilderFlags.None); const checkClassOrInterface = tsElemAccessBaseExprType.isClassOrInterface() && diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index 17d2f6e7b..83e3683c1 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -1287,4 +1287,15 @@ export class TsUtils { visitNode(funcExpr); return found; } + + public getTypeOrTypeConstraintAtLocation(expr: ts.Expression): ts.Type { + let type = this.tsTypeChecker.getTypeAtLocation(expr); + if (type.isTypeParameter()) { + let constraint = type.getConstraint(); + if (constraint) { + return constraint; + } + } + return type; + } } diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts new file mode 100644 index 000000000..3911b881b --- /dev/null +++ b/linter/test/property_access_by_index.ts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +// #14071 +class A { + v: string = ''; +} +function SetProperty(oldObj: T, str: string, obj: Object): void { + oldObj[str] = obj; // Should report error +} +function GetProperty(oldObj: T, str: string): U { + return oldObj[str]; // Should report error +} +function test() { + let a: A = { v: 'abc' }; + SetProperty(a, 'u', 'def'); + return GetProperty(a, 'v') + GetProperty(a, 'u'); +} diff --git a/linter/test/property_access_by_index.ts.autofix.json b/linter/test/property_access_by_index.ts.autofix.json new file mode 100644 index 000000000..90d724616 --- /dev/null +++ b/linter/test/property_access_by_index.ts.autofix.json @@ -0,0 +1,34 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 21, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": false, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 24, + "column": 10, + "problem": "PropertyAccessByIndex", + "autofixable": false, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + } + ] +} \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.relax.json b/linter/test/property_access_by_index.ts.relax.json new file mode 100644 index 000000000..e7d2d6779 --- /dev/null +++ b/linter/test/property_access_by_index.ts.relax.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [] +} \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.strict.json b/linter/test/property_access_by_index.ts.strict.json new file mode 100644 index 000000000..816f247c7 --- /dev/null +++ b/linter/test/property_access_by_index.ts.strict.json @@ -0,0 +1,32 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 21, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 24, + "column": 10, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + } + ] +} \ No newline at end of file -- Gitee From 9e73ae10b69e9846fc6e1b86d638684af93947e0 Mon Sep 17 00:00:00 2001 From: Igor Rossinski Date: Wed, 18 Oct 2023 01:57:36 +0300 Subject: [PATCH 04/49] [ArkTS Linter] fix err#13851 Signed-off-by: Igor Rossinski --- linter-4.2/src/TypeScriptLinter.ts | 12 +++++++----- linter-4.2/test/ts_ignore.ts.relax.json | 7 ------- linter-4.2/test/ts_ignore.ts.strict.json | 7 ------- linter/src/TypeScriptLinter.ts | 21 ++++++++++++--------- linter/test/ts_ignore.ts.relax.json | 7 ------- linter/test/ts_ignore.ts.strict.json | 7 ------- 6 files changed, 19 insertions(+), 42 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 44bc9657e..250cec440 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -685,7 +685,7 @@ export class TypeScriptLinter { const baseExprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode.expression); const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); - if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { + if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { this.incrementCounters(propertyAccessNode.name, FaultID.Prototype); } if (!!exprSym && this.tsUtils.isSymbolAPI(exprSym) && !TsUtils.ALLOWED_STD_SYMBOL_API.includes(exprSym.getName())) { @@ -773,7 +773,7 @@ export class TypeScriptLinter { ts.isIdentifier(x.expression.expression) ) decoratorName = x.expression.expression.text; - + // special case for property of type CustomDialogController of the @CustomDialog-decorated class if (expectedDecorators.includes(TsUtils.NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS[0])) { return expectedDecorators.includes(decoratorName) && propType === 'CustomDialogController' @@ -1610,7 +1610,7 @@ export class TypeScriptLinter { ); const checkClassOrInterface = tsElemAccessBaseExprType.isClassOrInterface() && !this.tsUtils.isGenericArrayType(tsElemAccessBaseExprType) && - !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); + !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); const checkThisOrSuper = this.tsUtils.isThisOrSuperExpr(tsElementAccessExpr.expression) && !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); @@ -1728,7 +1728,7 @@ export class TypeScriptLinter { this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } this.handleLibraryTypeCall(tsCallExpr, calleeType); - + if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { this.incrementCounters(node, FaultID.EsObjectAccess); } @@ -2110,7 +2110,9 @@ export class TypeScriptLinter { comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? srcText.slice(comment.pos + 2, comment.end - 2) : srcText.slice(comment.pos + 2, comment.end); - + //if comment is multiline end closing '*/' is not at the same line as '@ts-xxx' - do nothing (see #13851) + if (commentContent.endsWith('\n')) + return; let trimmedContent = commentContent.trim(); if ( trimmedContent.startsWith("@ts-ignore") || diff --git a/linter-4.2/test/ts_ignore.ts.relax.json b/linter-4.2/test/ts_ignore.ts.relax.json index 8342e1744..8e4a16c18 100644 --- a/linter-4.2/test/ts_ignore.ts.relax.json +++ b/linter-4.2/test/ts_ignore.ts.relax.json @@ -42,13 +42,6 @@ "suggest": "", "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, - { - "line": 33, - "column": 2, - "problem": "ErrorSuppression", - "suggest": "", - "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" - }, { "line": 43, "column": 9, diff --git a/linter-4.2/test/ts_ignore.ts.strict.json b/linter-4.2/test/ts_ignore.ts.strict.json index 8342e1744..8e4a16c18 100644 --- a/linter-4.2/test/ts_ignore.ts.strict.json +++ b/linter-4.2/test/ts_ignore.ts.strict.json @@ -42,13 +42,6 @@ "suggest": "", "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, - { - "line": 33, - "column": 2, - "problem": "ErrorSuppression", - "suggest": "", - "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" - }, { "line": 43, "column": 9, diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 3b5ed579f..e5b475fe0 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -595,7 +595,7 @@ export class TypeScriptLinter { const baseExprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode.expression); const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); - if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { + if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { this.incrementCounters(propertyAccessNode.name, FaultID.Prototype); } if (!!exprSym && this.tsUtils.isSymbolAPI(exprSym) && !ALLOWED_STD_SYMBOL_API.includes(exprSym.getName())) { @@ -636,7 +636,7 @@ export class TypeScriptLinter { this.handleDecorators(decorators); this.filterOutDecoratorsDiagnostics(decorators, NON_INITIALIZABLE_PROPERTY_DECORATORS, {begin: propName.getStart(), end: propName.getStart()}, PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE); - + const classDecorators = ts.getDecorators(node.parent); const propType = (node as ts.PropertyDeclaration).type?.getText(); this.filterOutDecoratorsDiagnostics(classDecorators, NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS, @@ -1294,7 +1294,7 @@ export class TypeScriptLinter { private handleRestrictedValues(tsIdentifier: ts.Identifier, tsIdentSym: ts.Symbol) { const illegalValues = ts.SymbolFlags.ConstEnum | ts.SymbolFlags.RegularEnum | ts.SymbolFlags.ValueModule | (TypeScriptLinter.advancedClassChecks? 0 : ts.SymbolFlags.Class); - + // If module name is duplicated by another declaration, this increases the possibility // of finding a lot of false positives. Thus, do not check further in that case. if ((tsIdentSym.flags & ts.SymbolFlags.ValueModule) != 0) { @@ -1328,7 +1328,7 @@ export class TypeScriptLinter { const checkClassOrInterface = tsElemAccessBaseExprType.isClassOrInterface() && !this.tsUtils.isGenericArrayType(tsElemAccessBaseExprType) && - !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); + !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); const checkThisOrSuper = this.tsUtils.isThisOrSuperExpr(tsElementAccessExpr.expression) && !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); @@ -1427,7 +1427,7 @@ export class TypeScriptLinter { this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } this.handleLibraryTypeCall(tsCallExpr, calleeType); - + if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { this.incrementCounters(node, FaultID.EsObjectAccess); } @@ -1466,8 +1466,8 @@ export class TypeScriptLinter { private handleGenericCallWithNoTypeArgs(callLikeExpr: ts.CallExpression | ts.NewExpression, callSignature: ts.Signature) { // Note: The PR!716 has led to a significant performance degradation. // Since initial problem was fixed in a more general way, this change - // became redundant. Therefore, it was reverted. See #13721 comments - // for a detailed analysis. + // became redundant. Therefore, it was reverted. See #13721 comments + // for a detailed analysis. const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? ts.SyntaxKind.Constructor : ts.SyntaxKind.FunctionDeclaration; const signFlags = ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature | ts.NodeBuilderFlags.IgnoreErrors; @@ -1767,9 +1767,12 @@ export class TypeScriptLinter { const commentContent = comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? srcText.slice(comment.pos + 2, comment.end - 2) : srcText.slice(comment.pos + 2, comment.end); - const trimmedContent = commentContent.trim() + //if comment is multiline end closing '*/' is not at the same line as '@ts-xxx' - do nothing (see #13851) + if (commentContent.endsWith('\n')) + return; + const trimmedContent = commentContent.trim(); if (trimmedContent.startsWith('@ts-ignore') || - trimmedContent.startsWith('@ts-nocheck') || + trimmedContent.startsWith('@ts-nocheck') || trimmedContent.startsWith('@ts-expect-error')) this.incrementCounters(comment, FaultID.ErrorSuppression); } diff --git a/linter/test/ts_ignore.ts.relax.json b/linter/test/ts_ignore.ts.relax.json index 8342e1744..8e4a16c18 100644 --- a/linter/test/ts_ignore.ts.relax.json +++ b/linter/test/ts_ignore.ts.relax.json @@ -42,13 +42,6 @@ "suggest": "", "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, - { - "line": 33, - "column": 2, - "problem": "ErrorSuppression", - "suggest": "", - "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" - }, { "line": 43, "column": 9, diff --git a/linter/test/ts_ignore.ts.strict.json b/linter/test/ts_ignore.ts.strict.json index 8342e1744..8e4a16c18 100644 --- a/linter/test/ts_ignore.ts.strict.json +++ b/linter/test/ts_ignore.ts.strict.json @@ -42,13 +42,6 @@ "suggest": "", "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, - { - "line": 33, - "column": 2, - "problem": "ErrorSuppression", - "suggest": "", - "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" - }, { "line": 43, "column": 9, -- Gitee From b30e8f90e5fd4e4e7f94b4a01e62ad0fb8f88015 Mon Sep 17 00:00:00 2001 From: Denis Slynko Date: Tue, 24 Oct 2023 11:25:43 +0300 Subject: [PATCH 05/49] [ArkTS Linter] #14129 Specify semicolons as forbidden empty non-declaration statements in namespaces Signed-off-by: Denis Slynko --- linter-4.2/src/CookBookMsg.ts | 2 +- linter-4.2/test/ambient_module.ts.relax.json | 4 ++-- linter-4.2/test/ambient_module.ts.strict.json | 4 ++-- linter-4.2/test_rules/rule116.ts.autofix.json | 2 +- linter-4.2/test_rules/rule116.ts.relax.json | 2 +- linter-4.2/test_rules/rule116.ts.strict.json | 2 +- linter-4.2/test_rules/rule129.ts.autofix.json | 2 +- linter-4.2/test_rules/rule129.ts.relax.json | 2 +- linter-4.2/test_rules/rule129.ts.strict.json | 2 +- linter/src/CookBookMsg.ts | 2 +- linter/test/ambient_module.ts.relax.json | 4 ++-- linter/test/ambient_module.ts.strict.json | 4 ++-- linter/test_rules/rule116.ts.autofix.json | 2 +- linter/test_rules/rule116.ts.relax.json | 2 +- linter/test_rules/rule116.ts.strict.json | 2 +- linter/test_rules/rule129.ts.autofix.json | 2 +- linter/test_rules/rule129.ts.relax.json | 2 +- linter/test_rules/rule129.ts.strict.json | 2 +- 18 files changed, 22 insertions(+), 22 deletions(-) diff --git a/linter-4.2/src/CookBookMsg.ts b/linter-4.2/src/CookBookMsg.ts index 6f90d98ea..28b8b77f9 100644 --- a/linter-4.2/src/CookBookMsg.ts +++ b/linter-4.2/src/CookBookMsg.ts @@ -135,7 +135,7 @@ cookBookTag[112] = ''; cookBookTag[113] = '"enum" declaration merging is not supported (arkts-no-enum-merging)'; cookBookTag[114] = 'Namespaces cannot be used as objects (arkts-no-ns-as-obj)'; cookBookTag[115] = ''; -cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)'; +cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)'; cookBookTag[117] = ''; cookBookTag[118] = 'Special import type declarations are not supported (arkts-no-special-imports)'; cookBookTag[119] = 'Importing a module for side-effects only is not supported (arkts-no-side-effects-imports)'; diff --git a/linter-4.2/test/ambient_module.ts.relax.json b/linter-4.2/test/ambient_module.ts.relax.json index a02ca7fc8..543d0a12a 100644 --- a/linter-4.2/test/ambient_module.ts.relax.json +++ b/linter-4.2/test/ambient_module.ts.relax.json @@ -26,7 +26,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 20, @@ -47,7 +47,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 25, diff --git a/linter-4.2/test/ambient_module.ts.strict.json b/linter-4.2/test/ambient_module.ts.strict.json index a02ca7fc8..543d0a12a 100644 --- a/linter-4.2/test/ambient_module.ts.strict.json +++ b/linter-4.2/test/ambient_module.ts.strict.json @@ -26,7 +26,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 20, @@ -47,7 +47,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 25, diff --git a/linter-4.2/test_rules/rule116.ts.autofix.json b/linter-4.2/test_rules/rule116.ts.autofix.json index 8449964f6..f3a5f41b3 100644 --- a/linter-4.2/test_rules/rule116.ts.autofix.json +++ b/linter-4.2/test_rules/rule116.ts.autofix.json @@ -6,7 +6,7 @@ "problem": "NonDeclarationInNamespace", "autofixable": false, "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule116.ts.relax.json b/linter-4.2/test_rules/rule116.ts.relax.json index a5030d64e..3259498ae 100644 --- a/linter-4.2/test_rules/rule116.ts.relax.json +++ b/linter-4.2/test_rules/rule116.ts.relax.json @@ -5,7 +5,7 @@ "column": 5, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule116.ts.strict.json b/linter-4.2/test_rules/rule116.ts.strict.json index a5030d64e..3259498ae 100644 --- a/linter-4.2/test_rules/rule116.ts.strict.json +++ b/linter-4.2/test_rules/rule116.ts.strict.json @@ -5,7 +5,7 @@ "column": 5, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule129.ts.autofix.json b/linter-4.2/test_rules/rule129.ts.autofix.json index 6708658ae..80fc9c4b1 100644 --- a/linter-4.2/test_rules/rule129.ts.autofix.json +++ b/linter-4.2/test_rules/rule129.ts.autofix.json @@ -6,7 +6,7 @@ "problem": "NonDeclarationInNamespace", "autofixable": false, "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 2, diff --git a/linter-4.2/test_rules/rule129.ts.relax.json b/linter-4.2/test_rules/rule129.ts.relax.json index cc8823193..ab877e8e9 100644 --- a/linter-4.2/test_rules/rule129.ts.relax.json +++ b/linter-4.2/test_rules/rule129.ts.relax.json @@ -5,7 +5,7 @@ "column": 9, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 2, diff --git a/linter-4.2/test_rules/rule129.ts.strict.json b/linter-4.2/test_rules/rule129.ts.strict.json index cc8823193..ab877e8e9 100644 --- a/linter-4.2/test_rules/rule129.ts.strict.json +++ b/linter-4.2/test_rules/rule129.ts.strict.json @@ -5,7 +5,7 @@ "column": 9, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 2, diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index aba65028d..bf9f4b132 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -135,7 +135,7 @@ cookBookTag[112] = ''; cookBookTag[113] = '"enum" declaration merging is not supported (arkts-no-enum-merging)'; cookBookTag[114] = 'Namespaces cannot be used as objects (arkts-no-ns-as-obj)'; cookBookTag[115] = ''; -cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)'; +cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)'; cookBookTag[117] = ''; cookBookTag[118] = 'Special import type declarations are not supported (arkts-no-special-imports)'; cookBookTag[119] = 'Importing a module for side-effects only is not supported (arkts-no-side-effects-imports)'; diff --git a/linter/test/ambient_module.ts.relax.json b/linter/test/ambient_module.ts.relax.json index a02ca7fc8..543d0a12a 100755 --- a/linter/test/ambient_module.ts.relax.json +++ b/linter/test/ambient_module.ts.relax.json @@ -26,7 +26,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 20, @@ -47,7 +47,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 25, diff --git a/linter/test/ambient_module.ts.strict.json b/linter/test/ambient_module.ts.strict.json index a02ca7fc8..543d0a12a 100755 --- a/linter/test/ambient_module.ts.strict.json +++ b/linter/test/ambient_module.ts.strict.json @@ -26,7 +26,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 20, @@ -47,7 +47,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 25, diff --git a/linter/test_rules/rule116.ts.autofix.json b/linter/test_rules/rule116.ts.autofix.json index 8449964f6..f3a5f41b3 100644 --- a/linter/test_rules/rule116.ts.autofix.json +++ b/linter/test_rules/rule116.ts.autofix.json @@ -6,7 +6,7 @@ "problem": "NonDeclarationInNamespace", "autofixable": false, "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter/test_rules/rule116.ts.relax.json b/linter/test_rules/rule116.ts.relax.json index a5030d64e..3259498ae 100644 --- a/linter/test_rules/rule116.ts.relax.json +++ b/linter/test_rules/rule116.ts.relax.json @@ -5,7 +5,7 @@ "column": 5, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter/test_rules/rule116.ts.strict.json b/linter/test_rules/rule116.ts.strict.json index a5030d64e..3259498ae 100644 --- a/linter/test_rules/rule116.ts.strict.json +++ b/linter/test_rules/rule116.ts.strict.json @@ -5,7 +5,7 @@ "column": 5, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter/test_rules/rule129.ts.autofix.json b/linter/test_rules/rule129.ts.autofix.json index 6708658ae..80fc9c4b1 100644 --- a/linter/test_rules/rule129.ts.autofix.json +++ b/linter/test_rules/rule129.ts.autofix.json @@ -6,7 +6,7 @@ "problem": "NonDeclarationInNamespace", "autofixable": false, "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 2, diff --git a/linter/test_rules/rule129.ts.relax.json b/linter/test_rules/rule129.ts.relax.json index cc8823193..ab877e8e9 100644 --- a/linter/test_rules/rule129.ts.relax.json +++ b/linter/test_rules/rule129.ts.relax.json @@ -5,7 +5,7 @@ "column": 9, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 2, diff --git a/linter/test_rules/rule129.ts.strict.json b/linter/test_rules/rule129.ts.strict.json index cc8823193..ab877e8e9 100644 --- a/linter/test_rules/rule129.ts.strict.json +++ b/linter/test_rules/rule129.ts.strict.json @@ -5,7 +5,7 @@ "column": 9, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" }, { "line": 2, -- Gitee From ad1206aa1667a3ed2db267413872f08d270eaeb5 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Mon, 23 Oct 2023 12:20:44 +0300 Subject: [PATCH 06/49] [arkts-linter] allow use of ArrayBuffer.isView #14121 Signed-off-by: Nazarov Konstantin --- linter-4.2/docs/rules/recipe144.md | 2 -- linter-4.2/src/TypeScriptLinter.ts | 2 -- linter-4.2/src/Utils.ts | 1 - .../test/limited_stdlib_api.ts.autofix.json | 8 -------- linter-4.2/test/limited_stdlib_api.ts.relax.json | 7 ------- .../test/limited_stdlib_api.ts.strict.json | 7 ------- linter/docs/rules/recipe144.md | 2 -- linter/src/TypeScriptLinter.ts | 3 --- .../src/utils/consts/LimitedStdArrayBufferAPI.ts | 16 ---------------- linter/test/limited_stdlib_api.ts.autofix.json | 8 -------- linter/test/limited_stdlib_api.ts.relax.json | 7 ------- linter/test/limited_stdlib_api.ts.strict.json | 7 ------- 12 files changed, 70 deletions(-) delete mode 100644 linter/src/utils/consts/LimitedStdArrayBufferAPI.ts diff --git a/linter-4.2/docs/rules/recipe144.md b/linter-4.2/docs/rules/recipe144.md index 975ae2131..4d3585851 100644 --- a/linter-4.2/docs/rules/recipe144.md +++ b/linter-4.2/docs/rules/recipe144.md @@ -30,8 +30,6 @@ Properties and functions of the global object: ``eval``, ``handler.has()``, ``handler.isExtensible()``, ``handler.ownKeys()``, ``handler.preventExtensions()``, ``handler.set()``, ``handler.setPrototypeOf()`` -``ArrayBuffer``: ``isView`` - ## See also diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 250cec440..d284c3283 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1864,8 +1864,6 @@ export class TypeScriptLinter { ["ObjectConstructor", {arr: TsUtils.LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], ["Reflect", {arr: TsUtils.LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi}], ["ProxyHandler", {arr: TsUtils.LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi}], - ["ArrayBuffer", {arr: TsUtils.LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], - ["ArrayBufferConstructor", {arr: TsUtils.LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], ["Symbol", {arr: null, fault: FaultID.SymbolType}], ["SymbolConstructor", {arr: null, fault: FaultID.SymbolType}], ]) diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 1414a71b9..486c60842 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -124,7 +124,6 @@ export class TsUtils { 'apply', 'construct', 'defineProperty', 'deleteProperty', 'get', 'getOwnPropertyDescriptor', 'getPrototypeOf', 'has', 'isExtensible', 'ownKeys', 'preventExtensions', 'set', 'setPrototypeOf' ]; - static readonly LIMITED_STD_ARRAYBUFFER_API = ['isView']; static readonly NON_INITIALIZABLE_PROPERTY_DECORATORS = ['Link', 'Consume', 'ObjectLink', 'Prop', 'BuilderParam']; diff --git a/linter-4.2/test/limited_stdlib_api.ts.autofix.json b/linter-4.2/test/limited_stdlib_api.ts.autofix.json index 7c2eb1d35..d22507c45 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.autofix.json +++ b/linter-4.2/test/limited_stdlib_api.ts.autofix.json @@ -469,14 +469,6 @@ "autofixable": false, "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 93, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/limited_stdlib_api.ts.relax.json b/linter-4.2/test/limited_stdlib_api.ts.relax.json index 2cca52540..42695e72f 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.relax.json +++ b/linter-4.2/test/limited_stdlib_api.ts.relax.json @@ -412,13 +412,6 @@ "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 93, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/limited_stdlib_api.ts.strict.json b/linter-4.2/test/limited_stdlib_api.ts.strict.json index 2cca52540..42695e72f 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.strict.json +++ b/linter-4.2/test/limited_stdlib_api.ts.strict.json @@ -412,13 +412,6 @@ "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 93, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" } ] } \ No newline at end of file diff --git a/linter/docs/rules/recipe144.md b/linter/docs/rules/recipe144.md index b28c181c5..95dafd1dd 100644 --- a/linter/docs/rules/recipe144.md +++ b/linter/docs/rules/recipe144.md @@ -31,8 +31,6 @@ Properties and functions of the global object: ``eval``, ``handler.has()``, ``handler.isExtensible()``, ``handler.ownKeys()``, ``handler.preventExtensions()``, ``handler.set()``, ``handler.setPrototypeOf()`` -``ArrayBuffer``: ``isView`` - ## See also diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index e5b475fe0..8d4d17fc8 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -32,7 +32,6 @@ import { LIMITED_STD_GLOBAL_VAR } from './utils/consts/LimitedStdGlobalVar'; import { LIMITED_STD_OBJECT_API } from './utils/consts/LimitedStdObjectAPI'; import { LIMITED_STD_REFLECT_API } from './utils/consts/LimitedStdReflectAPI'; import { LIMITED_STD_PROXYHANDLER_API } from './utils/consts/LimitedStdProxyHandlerAPI'; -import { LIMITED_STD_ARRAYBUFFER_API } from './utils/consts/LimitedStdArrayBufferAPI'; import { ALLOWED_STD_SYMBOL_API } from './utils/consts/AllowedStdSymbolAPI'; import { NON_INITIALIZABLE_PROPERTY_DECORATORS, NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS } from './utils/consts/NonInitializablePropertyDecorators'; @@ -1543,8 +1542,6 @@ export class TypeScriptLinter { ['ObjectConstructor', {arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], ['Reflect', {arr: LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi}], ['ProxyHandler', {arr: LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi}], - ['ArrayBuffer', {arr: LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], - ['ArrayBufferConstructor', {arr: LIMITED_STD_ARRAYBUFFER_API, fault: FaultID.LimitedStdLibApi}], ['Symbol', {arr: null, fault: FaultID.SymbolType}], ['SymbolConstructor', {arr: null, fault: FaultID.SymbolType}], ]) diff --git a/linter/src/utils/consts/LimitedStdArrayBufferAPI.ts b/linter/src/utils/consts/LimitedStdArrayBufferAPI.ts deleted file mode 100644 index 39605128f..000000000 --- a/linter/src/utils/consts/LimitedStdArrayBufferAPI.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023-2023 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. - */ - -export const LIMITED_STD_ARRAYBUFFER_API = ['isView']; diff --git a/linter/test/limited_stdlib_api.ts.autofix.json b/linter/test/limited_stdlib_api.ts.autofix.json index e4aca6e3c..be0f7b9fb 100644 --- a/linter/test/limited_stdlib_api.ts.autofix.json +++ b/linter/test/limited_stdlib_api.ts.autofix.json @@ -469,14 +469,6 @@ "autofixable": false, "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 120, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" } ] } diff --git a/linter/test/limited_stdlib_api.ts.relax.json b/linter/test/limited_stdlib_api.ts.relax.json index 055ef99ee..12f323b61 100644 --- a/linter/test/limited_stdlib_api.ts.relax.json +++ b/linter/test/limited_stdlib_api.ts.relax.json @@ -412,13 +412,6 @@ "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 120, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" } ] } diff --git a/linter/test/limited_stdlib_api.ts.strict.json b/linter/test/limited_stdlib_api.ts.strict.json index 055ef99ee..12f323b61 100644 --- a/linter/test/limited_stdlib_api.ts.strict.json +++ b/linter/test/limited_stdlib_api.ts.strict.json @@ -412,13 +412,6 @@ "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 120, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" } ] } -- Gitee From 712a97b7c464b2a5c57179c4ec391e637abb7015 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Tue, 24 Oct 2023 14:09:46 +0300 Subject: [PATCH 07/49] [arkts-linter] #14155 allow computed property name in case of Symbol.iterator Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 14 +++++++-- linter-4.2/src/TypeScriptLinterConfig.ts | 1 - linter-4.2/src/Utils.ts | 31 +++++--------------- linter-4.2/test/symbol_api.ts | 6 ++++ linter/src/TypeScriptLinter.ts | 14 +++++++-- linter/src/TypeScriptLinterConfig.ts | 1 - linter/src/utils/TsUtils.ts | 36 +++++------------------- linter/test/symbol_api.ts | 6 ++++ 8 files changed, 50 insertions(+), 59 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index d284c3283..8eebb3614 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -150,6 +150,7 @@ export class TypeScriptLinter { [ts.SyntaxKind.SetAccessor, this.handleSetAccessor], [ts.SyntaxKind.ConstructSignature, this.handleConstructSignature], [ts.SyntaxKind.ExpressionWithTypeArguments, this.handleExpressionWithTypeArguments], + [ts.SyntaxKind.ComputedPropertyName, this.handleComputedPropertyName], ]); public incrementCounters( @@ -2093,13 +2094,22 @@ export class TypeScriptLinter { } private handleExpressionWithTypeArguments(node: ts.Node) { - let tsTypeExpr = node as ts.ExpressionWithTypeArguments; - let symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); + const tsTypeExpr = node as ts.ExpressionWithTypeArguments; + const symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); if (!!symbol && this.tsUtils.isEsObjectSymbol(symbol)) { this.incrementCounters(tsTypeExpr, FaultID.EsObjectType); } } + private handleComputedPropertyName(node: ts.Node) { + const computedProperty = node as ts.ComputedPropertyName; + const symbol = this.tsUtils.trueSymbolAtLocation(computedProperty.expression); + if (!!symbol && this.tsUtils.isSymbolIterator(symbol)) { + return + } + this.incrementCounters(node, FaultID.ComputedPropertyName); + } + private checkErrorSuppressingAnnotation( comment: ts.CommentRange, srcText: string diff --git a/linter-4.2/src/TypeScriptLinterConfig.ts b/linter-4.2/src/TypeScriptLinterConfig.ts index 423c18076..f91b02180 100644 --- a/linter-4.2/src/TypeScriptLinterConfig.ts +++ b/linter-4.2/src/TypeScriptLinterConfig.ts @@ -168,7 +168,6 @@ export class LinterConfig { static incrementOnlyTokens: Map = new Map([ [ts.SyntaxKind.AnyKeyword, FaultID.AnyType], [ts.SyntaxKind.SymbolKeyword, FaultID.SymbolType], [ts.SyntaxKind.ThisType, FaultID.ThisType], - [ts.SyntaxKind.ComputedPropertyName, FaultID.ComputedPropertyName], [ts.SyntaxKind.TypeQuery, FaultID.TypeQuery], [ts.SyntaxKind.DeleteExpression, FaultID.DeleteOperator], [ts.SyntaxKind.RegularExpressionLiteral, FaultID.RegexLiteral], diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 486c60842..2cb4369ea 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -1097,35 +1097,18 @@ export class TsUtils { return !parentName || parentName === 'global'; } - public isStdObjectAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Object' || parentName === 'ObjectConstructor'); - } - - public isStdReflectAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Reflect'); - } - - public isStdProxyHandlerAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'ProxyHandler'); - } - - public isStdArrayAPI(symbol: ts.Symbol): boolean { + public isSymbolAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Array' || parentName === 'ArrayConstructor'); + return !!parentName && (parentName === 'Symbol' || parentName === 'SymbolConstructor'); } - public isStdArrayBufferAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'ArrayBuffer' || parentName === 'ArrayBufferConstructor'); + public isStdSymbol(symbol: ts.Symbol): boolean { + const name = this.tsTypeChecker.getFullyQualifiedName(symbol) + return name === 'Symbol' && this.isGlobalSymbol(symbol); } - public isSymbolAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - let name = parentName ? parentName : symbol.escapedName; - return name === 'Symbol' || name === 'SymbolConstructor'; + public isSymbolIterator(symbol: ts.Symbol): boolean { + return this.isSymbolAPI(symbol) && symbol.name === 'iterator' } public isDefaultImport(importSpec: ts.ImportSpecifier): boolean { diff --git a/linter-4.2/test/symbol_api.ts b/linter-4.2/test/symbol_api.ts index 2d33c448f..8d7d25d3e 100644 --- a/linter-4.2/test/symbol_api.ts +++ b/linter-4.2/test/symbol_api.ts @@ -50,3 +50,9 @@ class TestClass { return Symbol(); } } + +class BIter { + [Symbol.iterator] = () => { + return 1; + }; +} diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 8d4d17fc8..31a922b5d 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -171,6 +171,7 @@ export class TypeScriptLinter { [ts.SyntaxKind.SetAccessor, this.handleSetAccessor], [ts.SyntaxKind.ConstructSignature, this.handleConstructSignature], [ts.SyntaxKind.ExpressionWithTypeArguments, this.handleExpressionWithTypeArguments], + [ts.SyntaxKind.ComputedPropertyName, this.handleComputedPropertyName], ]); public incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofixable: boolean = false, autofix?: Autofix[],) { @@ -1753,13 +1754,22 @@ export class TypeScriptLinter { } private handleExpressionWithTypeArguments(node: ts.Node) { - let tsTypeExpr = node as ts.ExpressionWithTypeArguments; - let symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); + const tsTypeExpr = node as ts.ExpressionWithTypeArguments; + const symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); if (!!symbol && this.tsUtils.isEsObjectSymbol(symbol)) { this.incrementCounters(tsTypeExpr, FaultID.EsObjectType); } } + private handleComputedPropertyName(node: ts.Node) { + const computedProperty = node as ts.ComputedPropertyName; + const symbol = this.tsUtils.trueSymbolAtLocation(computedProperty.expression); + if (!!symbol && this.tsUtils.isSymbolIterator(symbol)) { + return + } + this.incrementCounters(node, FaultID.ComputedPropertyName); + } + private checkErrorSuppressingAnnotation(comment: ts.CommentRange, srcText: string) { const commentContent = comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? srcText.slice(comment.pos + 2, comment.end - 2) diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/src/TypeScriptLinterConfig.ts index 03ebd743e..64c2c1126 100644 --- a/linter/src/TypeScriptLinterConfig.ts +++ b/linter/src/TypeScriptLinterConfig.ts @@ -74,7 +74,6 @@ export class LinterConfig { static incrementOnlyTokens: Map = new Map([ [ts.SyntaxKind.AnyKeyword, FaultID.AnyType], [ts.SyntaxKind.SymbolKeyword, FaultID.SymbolType], [ts.SyntaxKind.ThisType, FaultID.ThisType], - [ts.SyntaxKind.ComputedPropertyName, FaultID.ComputedPropertyName], [ts.SyntaxKind.TypeQuery, FaultID.TypeQuery], [ts.SyntaxKind.DeleteExpression, FaultID.DeleteOperator], [ts.SyntaxKind.RegularExpressionLiteral, FaultID.RegexLiteral], diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index 83e3683c1..fbe9f0452 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -900,35 +900,18 @@ export class TsUtils { return !parentName || parentName === 'global'; } - public isStdObjectAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Object' || parentName === 'ObjectConstructor'); - } - - public isStdReflectAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Reflect'); - } - - public isStdProxyHandlerAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'ProxyHandler'); - } - - public isStdArrayAPI(symbol: ts.Symbol): boolean { + public isSymbolAPI(symbol: ts.Symbol): boolean { let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'Array' || parentName === 'ArrayConstructor'); + return !!parentName && (parentName === 'Symbol' || parentName === 'SymbolConstructor'); } - public isStdArrayBufferAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - return !!parentName && (parentName === 'ArrayBuffer' || parentName === 'ArrayBufferConstructor'); + public isStdSymbol(symbol: ts.Symbol): boolean { + const name = this.tsTypeChecker.getFullyQualifiedName(symbol) + return name === 'Symbol' && this.isGlobalSymbol(symbol); } - public isSymbolAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); - let name = parentName ? parentName : symbol.escapedName; - return name === 'Symbol' || name === 'SymbolConstructor'; + public isSymbolIterator(symbol: ts.Symbol): boolean { + return this.isSymbolAPI(symbol) && symbol.name === 'iterator' } public isDefaultImport(importSpec: ts.ImportSpecifier): boolean { @@ -1020,11 +1003,6 @@ export class TsUtils { return false; } - public isStdFunctionType(type: ts.Type) { - const sym = type.getSymbol(); - return sym && sym.getName() === 'Function' && this.isGlobalSymbol(sym); - } - public isDynamicType(type: ts.Type | undefined): boolean | undefined { if (type === undefined) { return false; diff --git a/linter/test/symbol_api.ts b/linter/test/symbol_api.ts index 2d33c448f..8d7d25d3e 100644 --- a/linter/test/symbol_api.ts +++ b/linter/test/symbol_api.ts @@ -50,3 +50,9 @@ class TestClass { return Symbol(); } } + +class BIter { + [Symbol.iterator] = () => { + return 1; + }; +} -- Gitee From 023fe7331c533a4e70cb74332483d02b46accdc7 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Tue, 24 Oct 2023 20:32:45 +0300 Subject: [PATCH 08/49] [arkts-linter] fix 14031 Signed-off-by: Nazarov Konstantin --- linter/src/ts-diagnostics/TSCCompiledProgram.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/linter/src/ts-diagnostics/TSCCompiledProgram.ts b/linter/src/ts-diagnostics/TSCCompiledProgram.ts index 9ebcb1fab..d1ece2fc6 100644 --- a/linter/src/ts-diagnostics/TSCCompiledProgram.ts +++ b/linter/src/ts-diagnostics/TSCCompiledProgram.ts @@ -46,11 +46,13 @@ export class TSCCompiledProgramSimple implements TSCCompiledProgram { export class TSCCompiledProgramWithDiagnostics implements TSCCompiledProgram { private diagnosticsExtractor: TypeScriptDiagnosticsExtractor; private wasStrict: boolean; + private cachedDiagnostics: Map; constructor(program: ts.Program, options: LintOptions) { const { strict, nonStrict, wasStrict } = getTwoCompiledVersions(program, options); this.diagnosticsExtractor = new TypeScriptDiagnosticsExtractor(strict, nonStrict); this.wasStrict = wasStrict; + this.cachedDiagnostics = new Map(); } public getOriginalProgram(): ts.Program { @@ -58,7 +60,13 @@ export class TSCCompiledProgramWithDiagnostics implements TSCCompiledProgram { } public getStrictDiagnostics(fileName: string): ts.Diagnostic[] { - return this.diagnosticsExtractor.getStrictDiagnostics(fileName); + const cachedDiagnostic = this.cachedDiagnostics.get(fileName); + if (!!cachedDiagnostic) { + return cachedDiagnostic + } + const diagnostic = this.diagnosticsExtractor.getStrictDiagnostics(fileName); + this.cachedDiagnostics.set(fileName, diagnostic) + return diagnostic; } } -- Gitee From 0e99322c31f7f9b95005be21a61f07647abfa978 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Wed, 25 Oct 2023 11:41:56 +0300 Subject: [PATCH 09/49] [arkts-linter] fix 14124 - relax arkts-no-special-imports/exports Signed-off-by: Nazarov Konstantin --- linter-4.2/docs/rules/recipe118.md | 39 ---------- linter-4.2/docs/rules/recipe127.md | 48 ------------ linter-4.2/src/Problems.ts | 4 +- linter-4.2/src/TypeScriptLinter.ts | 18 ----- linter-4.2/src/TypeScriptLinterConfig.ts | 2 - linter-4.2/test/modules.ts.autofix.json | 39 ---------- linter-4.2/test/modules.ts.strict.json | 15 ---- linter-4.2/test_rules/rule118.ts.autofix.json | 18 +---- linter-4.2/test_rules/rule118.ts.strict.json | 10 +-- linter-4.2/test_rules/rule127.ts.autofix.json | 18 +---- linter-4.2/test_rules/rule127.ts.strict.json | 10 +-- linter/docs/rules/recipe118.md | 39 ---------- linter/docs/rules/recipe127.md | 48 ------------ linter/src/CookBookMsg.ts | 4 +- linter/src/FaultAttrs.ts | 2 - linter/src/FaultDesc.ts | 2 - linter/src/Problems.ts | 2 +- linter/src/TypeScriptLinter.ts | 38 --------- linter/test/default_imports.ts.autofix.json | 39 ---------- linter/test/default_imports.ts.strict.json | 25 ------ linter/test/modules.ts.autofix.json | 78 ------------------- linter/test/modules.ts.strict.json | 30 ------- linter/test_rules/rule118.ts.autofix.json | 18 +---- linter/test_rules/rule118.ts.strict.json | 10 +-- linter/test_rules/rule127.ts.autofix.json | 18 +---- linter/test_rules/rule127.ts.strict.json | 10 +-- 26 files changed, 12 insertions(+), 572 deletions(-) delete mode 100644 linter-4.2/docs/rules/recipe118.md delete mode 100644 linter-4.2/docs/rules/recipe127.md delete mode 100644 linter/docs/rules/recipe118.md delete mode 100644 linter/docs/rules/recipe127.md diff --git a/linter-4.2/docs/rules/recipe118.md b/linter-4.2/docs/rules/recipe118.md deleted file mode 100644 index f625bc3e9..000000000 --- a/linter-4.2/docs/rules/recipe118.md +++ /dev/null @@ -1,39 +0,0 @@ -# Special import type declarations are not supported - -Rule ``arkts-no-special-imports`` - -**Severity: error** - -ArkTS does not have a special notation for importing types. -Use ordinary import instead. - - -## TypeScript - - -``` - - // Re-using the same import - import { APIResponseType } from "api" - - // Explicitly use import type - import type { APIResponseType } from "api" - -``` - -## ArkTS - - -``` - - import { APIResponseType } from "api" - -``` - -## See also - -- Recipe 119: Importing a module for side-effects only is not supported (``arkts-no-side-effects-imports``) -- Recipe 120: ``import default as ...`` is not supported (``arkts-no-import-default-as``) -- Recipe 121: ``require`` and ``import`` assignment are not supported (``arkts-no-require``) - - diff --git a/linter-4.2/docs/rules/recipe127.md b/linter-4.2/docs/rules/recipe127.md deleted file mode 100644 index c89d24fba..000000000 --- a/linter-4.2/docs/rules/recipe127.md +++ /dev/null @@ -1,48 +0,0 @@ -# Special ``export type`` declarations are not supported - -Rule ``arkts-no-special-exports`` - -**Severity: error** - -ArkTS does not have a special notation for exporting types through -``export type ...``. Use ordinary export instead. - - -## TypeScript - - -``` - - // Explicitly exported class: - export class Class1 { - // ... - } - - // Declared class later exported through export type ... - class Class2 { - // ... - } - - // This is not supported: - export type { Class2 } - -``` - -## ArkTS - - -``` - - // Explicitly exported class: - export class Class1 { - // ... - } - - // Explicitly exported class: - export class Class2 { - // ... - } - -``` - - diff --git a/linter-4.2/src/Problems.ts b/linter-4.2/src/Problems.ts index 69dab34fb..df9623d67 100644 --- a/linter-4.2/src/Problems.ts +++ b/linter-4.2/src/Problems.ts @@ -27,7 +27,7 @@ export enum FaultID { ConditionalType, MappedType, NamespaceAsObject, ClassAsObject, NonDeclarationInNamespace, GeneratorFunction, FunctionContainsThis, PropertyAccessByIndex, JsxElement, EnumMemberNonConstInit, ImplementsClass, MethodReassignment, MultipleStaticBlocks, ThisType, - IntefaceExtendDifProps, StructuralIdentity, TypeOnlyImport, TypeOnlyExport, DefaultImport, + IntefaceExtendDifProps, StructuralIdentity, DefaultImport, ExportAssignment, ImportAssignment, GenericCallNoTypeArgs, ParameterProperties, InstanceofUnsupported, ShorthandAmbientModuleDecl, WildcardsInModuleName, UMDModuleDefinition, @@ -108,11 +108,9 @@ faultsAttrs[FaultID.EnumMerging] = {cookBookRef: '113',}; faultsAttrs[FaultID.NamespaceAsObject] = {cookBookRef: '114',}; faultsAttrs[FaultID.NonDeclarationInNamespace] = {cookBookRef: '116',}; faultsAttrs[FaultID.ImportFromPath] = {cookBookRef: '119',}; -faultsAttrs[FaultID.TypeOnlyImport] = {migratable: true, cookBookRef: '118',}; faultsAttrs[FaultID.DefaultImport] = {migratable: true, cookBookRef: '120',}; faultsAttrs[FaultID.ImportAssignment] = {cookBookRef: '121',}; faultsAttrs[FaultID.ExportAssignment] = {cookBookRef: '126',}; -faultsAttrs[FaultID.TypeOnlyExport] = {migratable: true, cookBookRef: '127',}; faultsAttrs[FaultID.ShorthandAmbientModuleDecl] = {cookBookRef: '128',}; faultsAttrs[FaultID.WildcardsInModuleName] = {cookBookRef: '129',}; faultsAttrs[FaultID.UMDModuleDefinition] = {cookBookRef: '130',}; diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 8eebb3614..0800b2c38 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -138,7 +138,6 @@ export class TypeScriptLinter { [ts.SyntaxKind.ElementAccessExpression, this.handleElementAccessExpression], [ts.SyntaxKind.EnumMember, this.handleEnumMember], [ts.SyntaxKind.TypeReference, this.handleTypeReference], - [ts.SyntaxKind.ExportDeclaration, this.handleExportDeclaration], [ts.SyntaxKind.ExportAssignment, this.handleExportAssignment], [ts.SyntaxKind.CallExpression, this.handleCallExpression], [ts.SyntaxKind.MetaProperty, this.handleMetaProperty], @@ -1428,13 +1427,6 @@ export class TypeScriptLinter { ); } } - - if (tsImportClause.isTypeOnly) { - let autofix: Autofix[] | undefined; - if (this.autofixesInfo.shouldAutofix(node, FaultID.TypeOnlyImport)) - autofix = [Autofixer.dropTypeOnlyFlag(tsImportClause)]; - this.incrementCounters(node, FaultID.TypeOnlyImport, true, autofix); - } } private handleImportSpecifier(node: ts.Node) { @@ -1688,16 +1680,6 @@ export class TypeScriptLinter { } } - private handleExportDeclaration(node: ts.Node) { - let tsExportDecl = node as ts.ExportDeclaration; - if (tsExportDecl.isTypeOnly) { - let autofix: Autofix[] | undefined; - if (this.autofixesInfo.shouldAutofix(node, FaultID.TypeOnlyExport)) - autofix = [Autofixer.dropTypeOnlyFlag(tsExportDecl)]; - this.incrementCounters(node, FaultID.TypeOnlyExport, true, autofix); - } - } - private handleExportAssignment(node: ts.Node) { const exportAssignment = node as ts.ExportAssignment; if (exportAssignment.isExportEquals) { diff --git a/linter-4.2/src/TypeScriptLinterConfig.ts b/linter-4.2/src/TypeScriptLinterConfig.ts index f91b02180..179738f65 100644 --- a/linter-4.2/src/TypeScriptLinterConfig.ts +++ b/linter-4.2/src/TypeScriptLinterConfig.ts @@ -92,8 +92,6 @@ export class LinterConfig { LinterConfig.nodeDesc[FaultID.ThisType] = '"this" type'; LinterConfig.nodeDesc[FaultID.IntefaceExtendDifProps] = 'Extends same properties with different types'; LinterConfig.nodeDesc[FaultID.StructuralIdentity] = 'Use of type structural identity'; - LinterConfig.nodeDesc[FaultID.TypeOnlyImport] = 'Type-only imports'; - LinterConfig.nodeDesc[FaultID.TypeOnlyExport] = 'Type-only exports'; LinterConfig.nodeDesc[FaultID.DefaultImport] = 'Default import declarations'; LinterConfig.nodeDesc[FaultID.ExportAssignment] = 'Export assignments (export = ..)'; LinterConfig.nodeDesc[FaultID.ImportAssignment] = 'Import assignments (import = ..)'; diff --git a/linter-4.2/test/modules.ts.autofix.json b/linter-4.2/test/modules.ts.autofix.json index 567b9a523..476aed0b6 100644 --- a/linter-4.2/test/modules.ts.autofix.json +++ b/linter-4.2/test/modules.ts.autofix.json @@ -111,51 +111,12 @@ "problem": "ImportAfterStatement", "autofixable": false }, - { - "line": 92, - "column": 8, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 1923, - "end": 1947, - "replacementText": "{ APIResponseType }" - } - ] - }, { "line": 93, "column": 1, "problem": "ImportAfterStatement", "autofixable": false }, - { - "line": 93, - "column": 8, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 1969, - "end": 1980, - "replacementText": "* as P" - } - ] - }, - { - "line": 96, - "column": 1, - "problem": "TypeOnlyExport", - "autofixable": true, - "autofix": [ - { - "start": 2014, - "end": 2045, - "replacementText": "export { TypeA as TypeB };" - } - ] - }, { "line": 104, "column": 1, diff --git a/linter-4.2/test/modules.ts.strict.json b/linter-4.2/test/modules.ts.strict.json index 9481d07d8..88de58388 100644 --- a/linter-4.2/test/modules.ts.strict.json +++ b/linter-4.2/test/modules.ts.strict.json @@ -89,26 +89,11 @@ "column": 1, "problem": "ImportAfterStatement" }, - { - "line": 92, - "column": 8, - "problem": "TypeOnlyImport" - }, { "line": 93, "column": 1, "problem": "ImportAfterStatement" }, - { - "line": 93, - "column": 8, - "problem": "TypeOnlyImport" - }, - { - "line": 96, - "column": 1, - "problem": "TypeOnlyExport" - }, { "line": 104, "column": 1, diff --git a/linter-4.2/test_rules/rule118.ts.autofix.json b/linter-4.2/test_rules/rule118.ts.autofix.json index 3ff68f6c7..13f13363f 100644 --- a/linter-4.2/test_rules/rule118.ts.autofix.json +++ b/linter-4.2/test_rules/rule118.ts.autofix.json @@ -1,19 +1,3 @@ { - "nodes": [ - { - "line": 5, - "column": 12, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 120, - "end": 144, - "replacementText": "{ APIResponseType }" - } - ], - "suggest": "", - "rule": "Special import type declarations are not supported (arkts-no-special-imports)" - } - ] + "nodes": [] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule118.ts.strict.json b/linter-4.2/test_rules/rule118.ts.strict.json index d30836a74..13f13363f 100644 --- a/linter-4.2/test_rules/rule118.ts.strict.json +++ b/linter-4.2/test_rules/rule118.ts.strict.json @@ -1,11 +1,3 @@ { - "nodes": [ - { - "line": 5, - "column": 12, - "problem": "TypeOnlyImport", - "suggest": "", - "rule": "Special import type declarations are not supported (arkts-no-special-imports)" - } - ] + "nodes": [] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule127.ts.autofix.json b/linter-4.2/test_rules/rule127.ts.autofix.json index c32c0f461..13f13363f 100644 --- a/linter-4.2/test_rules/rule127.ts.autofix.json +++ b/linter-4.2/test_rules/rule127.ts.autofix.json @@ -1,19 +1,3 @@ { - "nodes": [ - { - "line": 12, - "column": 5, - "problem": "TypeOnlyExport", - "autofixable": true, - "autofix": [ - { - "start": 218, - "end": 240, - "replacementText": "export { Class2 };" - } - ], - "suggest": "", - "rule": "Special \"export type\" declarations are not supported (arkts-no-special-exports)" - } - ] + "nodes": [] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule127.ts.strict.json b/linter-4.2/test_rules/rule127.ts.strict.json index 35f1a5889..13f13363f 100644 --- a/linter-4.2/test_rules/rule127.ts.strict.json +++ b/linter-4.2/test_rules/rule127.ts.strict.json @@ -1,11 +1,3 @@ { - "nodes": [ - { - "line": 12, - "column": 5, - "problem": "TypeOnlyExport", - "suggest": "", - "rule": "Special \"export type\" declarations are not supported (arkts-no-special-exports)" - } - ] + "nodes": [] } \ No newline at end of file diff --git a/linter/docs/rules/recipe118.md b/linter/docs/rules/recipe118.md deleted file mode 100644 index f625bc3e9..000000000 --- a/linter/docs/rules/recipe118.md +++ /dev/null @@ -1,39 +0,0 @@ -# Special import type declarations are not supported - -Rule ``arkts-no-special-imports`` - -**Severity: error** - -ArkTS does not have a special notation for importing types. -Use ordinary import instead. - - -## TypeScript - - -``` - - // Re-using the same import - import { APIResponseType } from "api" - - // Explicitly use import type - import type { APIResponseType } from "api" - -``` - -## ArkTS - - -``` - - import { APIResponseType } from "api" - -``` - -## See also - -- Recipe 119: Importing a module for side-effects only is not supported (``arkts-no-side-effects-imports``) -- Recipe 120: ``import default as ...`` is not supported (``arkts-no-import-default-as``) -- Recipe 121: ``require`` and ``import`` assignment are not supported (``arkts-no-require``) - - diff --git a/linter/docs/rules/recipe127.md b/linter/docs/rules/recipe127.md deleted file mode 100644 index c89d24fba..000000000 --- a/linter/docs/rules/recipe127.md +++ /dev/null @@ -1,48 +0,0 @@ -# Special ``export type`` declarations are not supported - -Rule ``arkts-no-special-exports`` - -**Severity: error** - -ArkTS does not have a special notation for exporting types through -``export type ...``. Use ordinary export instead. - - -## TypeScript - - -``` - - // Explicitly exported class: - export class Class1 { - // ... - } - - // Declared class later exported through export type ... - class Class2 { - // ... - } - - // This is not supported: - export type { Class2 } - -``` - -## ArkTS - - -``` - - // Explicitly exported class: - export class Class1 { - // ... - } - - // Explicitly exported class: - export class Class2 { - // ... - } - -``` - - diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index bf9f4b132..d71982547 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -137,7 +137,7 @@ cookBookTag[114] = 'Namespaces cannot be used as objects (arkts-no-ns-as-obj)'; cookBookTag[115] = ''; cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)'; cookBookTag[117] = ''; -cookBookTag[118] = 'Special import type declarations are not supported (arkts-no-special-imports)'; +cookBookTag[118] = ''; cookBookTag[119] = 'Importing a module for side-effects only is not supported (arkts-no-side-effects-imports)'; cookBookTag[120] = '"import default as ..." is not supported (arkts-no-import-default-as)'; cookBookTag[121] = '"require" and "import" assignment are not supported (arkts-no-require)'; @@ -146,7 +146,7 @@ cookBookTag[123] = ''; cookBookTag[124] = ''; cookBookTag[125] = ''; cookBookTag[126] = '"export = ..." assignment is not supported (arkts-no-export-assignment)'; -cookBookTag[127] = 'Special "export type" declarations are not supported (arkts-no-special-exports)'; +cookBookTag[127] = ''; cookBookTag[128] = 'Ambient module declaration is not supported (arkts-no-ambient-decls)'; cookBookTag[129] = 'Wildcards in module names are not supported (arkts-no-module-wildcards)'; cookBookTag[130] = 'Universal module definitions (UMD) are not supported (arkts-no-umd)'; diff --git a/linter/src/FaultAttrs.ts b/linter/src/FaultAttrs.ts index a40ad5b38..e567b1f60 100644 --- a/linter/src/FaultAttrs.ts +++ b/linter/src/FaultAttrs.ts @@ -85,11 +85,9 @@ faultsAttrs[FaultID.EnumMerging] = {cookBookRef: '113',}; faultsAttrs[FaultID.NamespaceAsObject] = {cookBookRef: '114',}; faultsAttrs[FaultID.NonDeclarationInNamespace] = {cookBookRef: '116',}; faultsAttrs[FaultID.ImportFromPath] = {cookBookRef: '119',}; -faultsAttrs[FaultID.TypeOnlyImport] = {migratable: true, cookBookRef: '118',}; faultsAttrs[FaultID.DefaultImport] = {migratable: true, cookBookRef: '120',}; faultsAttrs[FaultID.ImportAssignment] = {cookBookRef: '121',}; faultsAttrs[FaultID.ExportAssignment] = {cookBookRef: '126',}; -faultsAttrs[FaultID.TypeOnlyExport] = {migratable: true, cookBookRef: '127',}; faultsAttrs[FaultID.ShorthandAmbientModuleDecl] = {cookBookRef: '128',}; faultsAttrs[FaultID.WildcardsInModuleName] = {cookBookRef: '129',}; faultsAttrs[FaultID.UMDModuleDefinition] = {cookBookRef: '130',}; diff --git a/linter/src/FaultDesc.ts b/linter/src/FaultDesc.ts index c49b1f3bc..407fd7a05 100644 --- a/linter/src/FaultDesc.ts +++ b/linter/src/FaultDesc.ts @@ -76,8 +76,6 @@ faultDesc[FaultID.MultipleStaticBlocks] = 'Multiple static blocks'; faultDesc[FaultID.ThisType] = '"this" type'; faultDesc[FaultID.IntefaceExtendDifProps] = 'Extends same properties with different types'; faultDesc[FaultID.StructuralIdentity] = 'Use of type structural identity'; -faultDesc[FaultID.TypeOnlyImport] = 'Type-only imports'; -faultDesc[FaultID.TypeOnlyExport] = 'Type-only exports'; faultDesc[FaultID.DefaultImport] = 'Default import declarations'; faultDesc[FaultID.ExportAssignment] = 'Export assignments (export = ..)'; faultDesc[FaultID.ImportAssignment] = 'Import assignments (import = ..)'; diff --git a/linter/src/Problems.ts b/linter/src/Problems.ts index 245ea31e7..ea9407728 100644 --- a/linter/src/Problems.ts +++ b/linter/src/Problems.ts @@ -27,7 +27,7 @@ export enum FaultID { ConditionalType, MappedType, NamespaceAsObject, ClassAsObject, NonDeclarationInNamespace, GeneratorFunction, FunctionContainsThis, PropertyAccessByIndex, JsxElement, EnumMemberNonConstInit, ImplementsClass, MethodReassignment, MultipleStaticBlocks, ThisType, - IntefaceExtendDifProps, StructuralIdentity, TypeOnlyImport, TypeOnlyExport, DefaultImport, + IntefaceExtendDifProps, StructuralIdentity, DefaultImport, ExportAssignment, ImportAssignment, GenericCallNoTypeArgs, ParameterProperties, InstanceofUnsupported, ShorthandAmbientModuleDecl, WildcardsInModuleName, UMDModuleDefinition, diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 31a922b5d..9fc9e315b 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -159,7 +159,6 @@ export class TypeScriptLinter { [ts.SyntaxKind.ElementAccessExpression, this.handleElementAccessExpression], [ts.SyntaxKind.EnumMember, this.handleEnumMember], [ts.SyntaxKind.TypeReference, this.handleTypeReference], - [ts.SyntaxKind.ExportDeclaration, this.handleExportDeclaration], [ts.SyntaxKind.ExportAssignment, this.handleExportAssignment], [ts.SyntaxKind.CallExpression, this.handleCallExpression], [ts.SyntaxKind.MetaProperty, this.handleMetaProperty], @@ -1165,27 +1164,11 @@ export class TypeScriptLinter { this.incrementCounters(defaultSpec, FaultID.DefaultImport, true, autofix); } } - if (tsImportClause.isTypeOnly) { - let autofix: Autofix[] | undefined; - if (this.autofixesInfo.shouldAutofix(node, FaultID.TypeOnlyImport)) - autofix = [ Autofixer.dropTypeOnlyFlag(tsImportClause) ]; - this.incrementCounters(node, FaultID.TypeOnlyImport, true, autofix); - } } private handleImportSpecifier(node: ts.Node) { let importSpec = node as ts.ImportSpecifier; this.countDeclarationsWithDuplicateName(importSpec.name, importSpec); - // Don't report or autofix type-only flag on default import if the latter has been autofixed already. - if ( - importSpec.isTypeOnly && - (!this.tsUtils.isDefaultImport(importSpec) || !this.autofixesInfo.shouldAutofix(importSpec, FaultID.DefaultImport)) - ) { - let autofix: Autofix[] | undefined; - if (this.autofixesInfo.shouldAutofix(node, FaultID.TypeOnlyImport)) - autofix = [ Autofixer.dropTypeOnlyFlag(importSpec) ]; - this.incrementCounters(node, FaultID.TypeOnlyImport, true, autofix); - } } private handleNamespaceImport(node: ts.Node) { @@ -1375,27 +1358,6 @@ export class TypeScriptLinter { } } - private handleExportDeclaration(node: ts.Node) { - let tsExportDecl = node as ts.ExportDeclaration; - if (tsExportDecl.isTypeOnly) { - let autofix: Autofix[] | undefined; - if (this.autofixesInfo.shouldAutofix(node, FaultID.TypeOnlyExport)) - autofix = [ Autofixer.dropTypeOnlyFlag(tsExportDecl) ]; - this.incrementCounters(node, FaultID.TypeOnlyExport, true, autofix); - } - let exportClause = tsExportDecl.exportClause; - if (exportClause && ts.isNamedExports(exportClause)) { - for (const exportSpec of exportClause.elements) { - if (exportSpec.isTypeOnly) { - let autofix: Autofix[] | undefined; - if (this.autofixesInfo.shouldAutofix(exportSpec, FaultID.TypeOnlyExport)) - autofix = [ Autofixer.dropTypeOnlyFlag(exportSpec) ]; - this.incrementCounters(exportSpec, FaultID.TypeOnlyExport, true, autofix); - } - } - } - } - private handleExportAssignment(node: ts.Node) { const exportAssignment = node as ts.ExportAssignment; if (exportAssignment.isExportEquals) { diff --git a/linter/test/default_imports.ts.autofix.json b/linter/test/default_imports.ts.autofix.json index f666c003d..b083d587f 100755 --- a/linter/test/default_imports.ts.autofix.json +++ b/linter/test/default_imports.ts.autofix.json @@ -40,19 +40,6 @@ } ] }, - { - "line": 17, - "column": 8, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 655, - "end": 675, - "replacementText": "{ default as D2 }" - } - ] - }, { "line": 18, "column": 9, @@ -92,19 +79,6 @@ } ] }, - { - "line": 20, - "column": 8, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 785, - "end": 811, - "replacementText": "{ C, default as D5, D }" - } - ] - }, { "line": 21, "column": 17, @@ -117,19 +91,6 @@ "replacementText": "D5, { type E, F }" } ] - }, - { - "line": 21, - "column": 9, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 835, - "end": 841, - "replacementText": "E" - } - ] } ] } \ No newline at end of file diff --git a/linter/test/default_imports.ts.strict.json b/linter/test/default_imports.ts.strict.json index 07471ba2b..ffea8cd37 100755 --- a/linter/test/default_imports.ts.strict.json +++ b/linter/test/default_imports.ts.strict.json @@ -24,21 +24,11 @@ "column": 14, "problem": "DefaultImport" }, - { - "line": 17, - "column": 8, - "problem": "TypeOnlyImport" - }, { "line": 18, "column": 9, "problem": "DefaultImport" }, - { - "line": 18, - "column": 9, - "problem": "TypeOnlyImport" - }, { "line": 19, "column": 12, @@ -49,25 +39,10 @@ "column": 17, "problem": "DefaultImport" }, - { - "line": 20, - "column": 8, - "problem": "TypeOnlyImport" - }, { "line": 21, "column": 17, "problem": "DefaultImport" - }, - { - "line": 21, - "column": 9, - "problem": "TypeOnlyImport" - }, - { - "line": 21, - "column": 17, - "problem": "TypeOnlyImport" } ] } \ No newline at end of file diff --git a/linter/test/modules.ts.autofix.json b/linter/test/modules.ts.autofix.json index 3c5ec13d6..c78c78603 100755 --- a/linter/test/modules.ts.autofix.json +++ b/linter/test/modules.ts.autofix.json @@ -111,96 +111,18 @@ "problem": "ImportAfterStatement", "autofixable": false }, - { - "line": 92, - "column": 8, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 1923, - "end": 1947, - "replacementText": "{ APIResponseType }" - } - ] - }, { "line": 93, "column": 1, "problem": "ImportAfterStatement", "autofixable": false }, - { - "line": 93, - "column": 8, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 1969, - "end": 1980, - "replacementText": "* as P" - } - ] - }, { "line": 94, "column": 1, "problem": "ImportAfterStatement", "autofixable": false }, - { - "line": 94, - "column": 10, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 2002, - "end": 2009, - "replacementText": "T1" - } - ] - }, - { - "line": 94, - "column": 19, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 2011, - "end": 2024, - "replacementText": "T2 as T3" - } - ] - }, - { - "line": 97, - "column": 1, - "problem": "TypeOnlyExport", - "autofixable": true, - "autofix": [ - { - "start": 2063, - "end": 2094, - "replacementText": "export { TypeA as TypeB };" - } - ] - }, - { - "line": 98, - "column": 10, - "problem": "TypeOnlyExport", - "autofixable": true, - "autofix": [ - { - "start": 2104, - "end": 2127, - "replacementText": "TypeFoo as TypeBar" - } - ] - }, { "line": 106, "column": 1, diff --git a/linter/test/modules.ts.strict.json b/linter/test/modules.ts.strict.json index c13f8f250..273338ee9 100644 --- a/linter/test/modules.ts.strict.json +++ b/linter/test/modules.ts.strict.json @@ -89,46 +89,16 @@ "column": 1, "problem": "ImportAfterStatement" }, - { - "line": 92, - "column": 8, - "problem": "TypeOnlyImport" - }, { "line": 93, "column": 1, "problem": "ImportAfterStatement" }, - { - "line": 93, - "column": 8, - "problem": "TypeOnlyImport" - }, { "line": 94, "column": 1, "problem": "ImportAfterStatement" }, - { - "line": 94, - "column": 10, - "problem": "TypeOnlyImport" - }, - { - "line": 94, - "column": 19, - "problem": "TypeOnlyImport" - }, - { - "line": 97, - "column": 1, - "problem": "TypeOnlyExport" - }, - { - "line": 98, - "column": 10, - "problem": "TypeOnlyExport" - }, { "line": 106, "column": 1, diff --git a/linter/test_rules/rule118.ts.autofix.json b/linter/test_rules/rule118.ts.autofix.json index 3ff68f6c7..13f13363f 100644 --- a/linter/test_rules/rule118.ts.autofix.json +++ b/linter/test_rules/rule118.ts.autofix.json @@ -1,19 +1,3 @@ { - "nodes": [ - { - "line": 5, - "column": 12, - "problem": "TypeOnlyImport", - "autofixable": true, - "autofix": [ - { - "start": 120, - "end": 144, - "replacementText": "{ APIResponseType }" - } - ], - "suggest": "", - "rule": "Special import type declarations are not supported (arkts-no-special-imports)" - } - ] + "nodes": [] } \ No newline at end of file diff --git a/linter/test_rules/rule118.ts.strict.json b/linter/test_rules/rule118.ts.strict.json index d30836a74..13f13363f 100644 --- a/linter/test_rules/rule118.ts.strict.json +++ b/linter/test_rules/rule118.ts.strict.json @@ -1,11 +1,3 @@ { - "nodes": [ - { - "line": 5, - "column": 12, - "problem": "TypeOnlyImport", - "suggest": "", - "rule": "Special import type declarations are not supported (arkts-no-special-imports)" - } - ] + "nodes": [] } \ No newline at end of file diff --git a/linter/test_rules/rule127.ts.autofix.json b/linter/test_rules/rule127.ts.autofix.json index c32c0f461..13f13363f 100644 --- a/linter/test_rules/rule127.ts.autofix.json +++ b/linter/test_rules/rule127.ts.autofix.json @@ -1,19 +1,3 @@ { - "nodes": [ - { - "line": 12, - "column": 5, - "problem": "TypeOnlyExport", - "autofixable": true, - "autofix": [ - { - "start": 218, - "end": 240, - "replacementText": "export { Class2 };" - } - ], - "suggest": "", - "rule": "Special \"export type\" declarations are not supported (arkts-no-special-exports)" - } - ] + "nodes": [] } \ No newline at end of file diff --git a/linter/test_rules/rule127.ts.strict.json b/linter/test_rules/rule127.ts.strict.json index 35f1a5889..13f13363f 100644 --- a/linter/test_rules/rule127.ts.strict.json +++ b/linter/test_rules/rule127.ts.strict.json @@ -1,11 +1,3 @@ { - "nodes": [ - { - "line": 12, - "column": 5, - "problem": "TypeOnlyExport", - "suggest": "", - "rule": "Special \"export type\" declarations are not supported (arkts-no-special-exports)" - } - ] + "nodes": [] } \ No newline at end of file -- Gitee From 68e554311b9c17c04f0348a7f851f6938817658c Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Wed, 25 Oct 2023 16:58:41 +0300 Subject: [PATCH 10/49] [ArkTS Linter] Relax 'identifier-as-property-name' report for anonymous types from interop. Change-Id: I25b10f026bac0e585f2efbdbd890c952637463f3 Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 18 +++++++----------- linter-4.2/test/dynamic_lib.d.ts | 4 ++++ linter-4.2/test/dynamic_object_literals.ts | 14 ++++++++++++-- linter/src/TypeScriptLinter.ts | 10 ++++++---- linter/test/dynamic_lib.d.ts | 4 ++++ linter/test/dynamic_object_literals.ts | 14 ++++++++++++-- 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 0800b2c38..d9e35a7b5 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -707,20 +707,16 @@ export class TypeScriptLinter { ) { // We can use literals as property names only when creating Record or any interop instances. let isRecordObjectInitializer = false; - let isDynamicLiteralInitializer = false; + let isDynamic = false; if (ts.isPropertyAssignment(node)) { - let objectLiteralType = this.tsTypeChecker.getContextualType( - node.parent - ); - isRecordObjectInitializer = - !!objectLiteralType && - this.tsUtils.isStdRecordType(objectLiteralType); - isDynamicLiteralInitializer = this.tsUtils.isDynamicLiteralInitializer( - node.parent - ); + let objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); + if (objectLiteralType) { + isRecordObjectInitializer = this.tsUtils.isStdRecordType(objectLiteralType); + isDynamic = this.tsUtils.isLibraryType(objectLiteralType) || this.tsUtils.isDynamicLiteralInitializer(node.parent); + } } - if (!isRecordObjectInitializer && !isDynamicLiteralInitializer) { + if (!isRecordObjectInitializer && !isDynamic) { let autofix: Autofix[] | undefined = Autofixer.fixLiteralAsPropertyName(node); let autofixable = autofix != undefined; diff --git a/linter-4.2/test/dynamic_lib.d.ts b/linter-4.2/test/dynamic_lib.d.ts index e3da589b5..843931397 100644 --- a/linter-4.2/test/dynamic_lib.d.ts +++ b/linter-4.2/test/dynamic_lib.d.ts @@ -93,3 +93,7 @@ declare class B { } export declare function bad_func(): A & B; + +export type IndexedSignatureType = { + [key: string]: string; +} \ No newline at end of file diff --git a/linter-4.2/test/dynamic_object_literals.ts b/linter-4.2/test/dynamic_object_literals.ts index ea7f9759a..fae9413ea 100644 --- a/linter-4.2/test/dynamic_object_literals.ts +++ b/linter-4.2/test/dynamic_object_literals.ts @@ -24,7 +24,8 @@ import { dynamic_array, padding, margin, - position + position, + IndexedSignatureType } from "./dynamic_lib" function main(): void { @@ -84,4 +85,13 @@ dynamic_array.splice(2, 0, {a: 1, b: '2'}); // #13550 - allow literals as property names in dynamic context padding({'top': '0px', 'right': '5px', 'bottom': '10px', 'left': '15px'}); margin({'top': '10px', 'right': '20px', 'bottom': '30px', 'left': '40px'}); -position({'x': '20', 'y': '40'}); \ No newline at end of file +position({'x': '20', 'y': '40'}); + +// allow literal as property name for type aliases that come from interop +function typeAliasLitAsPropName(): IndexedSignatureType { + return { + 'a': '1', + 'b': '2', + 'c': '3' + } +} \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 9fc9e315b..eb88c473b 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -614,14 +614,16 @@ export class TypeScriptLinter { if (propName && (propName.kind === ts.SyntaxKind.NumericLiteral || propName.kind === ts.SyntaxKind.StringLiteral)) { // We can use literals as property names only when creating Record or any interop instances. let isRecordObjectInitializer = false; - let isDynamicLiteralInitializer = false; + let isDynamic = false; if (ts.isPropertyAssignment(node)) { let objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); - isRecordObjectInitializer = !!objectLiteralType && this.tsUtils.isStdRecordType(objectLiteralType); - isDynamicLiteralInitializer = this.tsUtils.isDynamicLiteralInitializer(node.parent); + if (objectLiteralType) { + isRecordObjectInitializer = this.tsUtils.isStdRecordType(objectLiteralType); + isDynamic = this.tsUtils.isLibraryType(objectLiteralType) || this.tsUtils.isDynamicLiteralInitializer(node.parent); + } } - if (!isRecordObjectInitializer && !isDynamicLiteralInitializer) { + if (!isRecordObjectInitializer && !isDynamic) { let autofix : Autofix[] | undefined = Autofixer.fixLiteralAsPropertyName(node); let autofixable = autofix != undefined; if (!this.autofixesInfo.shouldAutofix(node, FaultID.LiteralAsPropertyName)) { diff --git a/linter/test/dynamic_lib.d.ts b/linter/test/dynamic_lib.d.ts index e3da589b5..843931397 100644 --- a/linter/test/dynamic_lib.d.ts +++ b/linter/test/dynamic_lib.d.ts @@ -93,3 +93,7 @@ declare class B { } export declare function bad_func(): A & B; + +export type IndexedSignatureType = { + [key: string]: string; +} \ No newline at end of file diff --git a/linter/test/dynamic_object_literals.ts b/linter/test/dynamic_object_literals.ts index ea7f9759a..fae9413ea 100644 --- a/linter/test/dynamic_object_literals.ts +++ b/linter/test/dynamic_object_literals.ts @@ -24,7 +24,8 @@ import { dynamic_array, padding, margin, - position + position, + IndexedSignatureType } from "./dynamic_lib" function main(): void { @@ -84,4 +85,13 @@ dynamic_array.splice(2, 0, {a: 1, b: '2'}); // #13550 - allow literals as property names in dynamic context padding({'top': '0px', 'right': '5px', 'bottom': '10px', 'left': '15px'}); margin({'top': '10px', 'right': '20px', 'bottom': '30px', 'left': '40px'}); -position({'x': '20', 'y': '40'}); \ No newline at end of file +position({'x': '20', 'y': '40'}); + +// allow literal as property name for type aliases that come from interop +function typeAliasLitAsPropName(): IndexedSignatureType { + return { + 'a': '1', + 'b': '2', + 'c': '3' + } +} \ No newline at end of file -- Gitee From 6b8aff2770063cdd578bdb63ac41caa7741fde6d Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Thu, 26 Oct 2023 18:21:26 +0300 Subject: [PATCH 11/49] [arkts-linter] #14009 - remove stdlib functions restrictions Signed-off-by: Nazarov Konstantin --- linter-4.2/docs/rules/recipe144.md | 3 +- linter-4.2/src/TypeScriptLinter.ts | 7 ++- linter-4.2/src/Utils.ts | 3 +- .../test/limited_stdlib_api.ts.autofix.json | 48 ------------------- .../test/limited_stdlib_api.ts.relax.json | 42 ---------------- .../test/limited_stdlib_api.ts.strict.json | 42 ---------------- linter/docs/rules/recipe144.md | 3 +- linter/src/TypeScriptLinter.ts | 8 ++-- .../src/utils/consts/LimitedStdGlobalFunc.ts | 2 +- .../src/utils/consts/LimitedStdGlobalVar.ts | 16 ------- .../test/limited_stdlib_api.ts.autofix.json | 48 ------------------- linter/test/limited_stdlib_api.ts.relax.json | 42 ---------------- linter/test/limited_stdlib_api.ts.strict.json | 42 ---------------- 13 files changed, 10 insertions(+), 296 deletions(-) delete mode 100644 linter/src/utils/consts/LimitedStdGlobalVar.ts diff --git a/linter-4.2/docs/rules/recipe144.md b/linter-4.2/docs/rules/recipe144.md index 4d3585851..ec36a4ffb 100644 --- a/linter-4.2/docs/rules/recipe144.md +++ b/linter-4.2/docs/rules/recipe144.md @@ -9,8 +9,7 @@ The most part of the restricted APIs relates to manipulating objects in a dynamic manner, which is not compatible with static typing. The usage of the following APIs is prohibited: -Properties and functions of the global object: ``eval``, -``Infinity``, ``NaN``, ``isFinite``, ``isNaN``, ``parseFloat``, ``parseInt`` +Properties and functions of the global object: ``eval`` ``Object``: ``__proto__``, ``__defineGetter__``, ``__defineSetter__``, ``__lookupGetter__``, ``__lookupSetter__``, ``assign``, ``create``, diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index d9e35a7b5..7bc4b23e6 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1490,12 +1490,11 @@ export class TypeScriptLinter { (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && tsIdentifier.text === "globalThis" - ) + ) { this.incrementCounters(node, FaultID.GlobalThis); - else if (this.tsUtils.isGlobalSymbol(tsIdentSym) && TsUtils.LIMITED_STD_GLOBAL_VAR.includes(tsIdentSym.getName())) - this.incrementCounters(node, FaultID.LimitedStdLibApi); - else + } else { this.handleRestrictedValues(tsIdentifier, tsIdentSym); + } } } diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 2cb4369ea..ed6992f74 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -106,9 +106,8 @@ export class TsUtils { static readonly ES_OBJECT = 'ESObject' static readonly LIMITED_STD_GLOBAL_FUNC = [ - 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt' + 'eval' ]; - static readonly LIMITED_STD_GLOBAL_VAR = ['Infinity', 'NaN']; static readonly LIMITED_STD_OBJECT_API = [ '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'assign', 'create', 'defineProperties', 'defineProperty', 'freeze', 'fromEntries', 'getOwnPropertyDescriptor', diff --git a/linter-4.2/test/limited_stdlib_api.ts.autofix.json b/linter-4.2/test/limited_stdlib_api.ts.autofix.json index d22507c45..eb0a98815 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.autofix.json +++ b/linter-4.2/test/limited_stdlib_api.ts.autofix.json @@ -22,54 +22,6 @@ "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, - { - "line": 18, - "column": 11, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 19, - "column": 11, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 20, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 21, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 22, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 23, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, { "line": 31, "column": 1, diff --git a/linter-4.2/test/limited_stdlib_api.ts.relax.json b/linter-4.2/test/limited_stdlib_api.ts.relax.json index 42695e72f..2e0b7e736 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.relax.json +++ b/linter-4.2/test/limited_stdlib_api.ts.relax.json @@ -21,48 +21,6 @@ "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, - { - "line": 18, - "column": 11, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 19, - "column": 11, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 20, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 21, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 22, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 23, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, { "line": 31, "column": 1, diff --git a/linter-4.2/test/limited_stdlib_api.ts.strict.json b/linter-4.2/test/limited_stdlib_api.ts.strict.json index 42695e72f..2e0b7e736 100644 --- a/linter-4.2/test/limited_stdlib_api.ts.strict.json +++ b/linter-4.2/test/limited_stdlib_api.ts.strict.json @@ -21,48 +21,6 @@ "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, - { - "line": 18, - "column": 11, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 19, - "column": 11, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 20, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 21, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 22, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 23, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, { "line": 31, "column": 1, diff --git a/linter/docs/rules/recipe144.md b/linter/docs/rules/recipe144.md index 95dafd1dd..371513d07 100644 --- a/linter/docs/rules/recipe144.md +++ b/linter/docs/rules/recipe144.md @@ -9,8 +9,7 @@ The most part of the restricted APIs relates to manipulating objects in a dynamic manner, which is not compatible with static typing. The usage of the following APIs is prohibited: -Properties and functions of the global object: ``eval``, -``Infinity``, ``NaN``, ``isFinite``, ``isNaN``, ``parseFloat``, ``parseInt`` +Properties and functions of the global object: ``eval`` ``Object``: ``__proto__``, ``__defineGetter__``, ``__defineSetter__``, ``__lookupGetter__``, ``__lookupSetter__``, ``assign``, ``create``, diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index eb88c473b..c93553509 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -28,7 +28,6 @@ import { ProblemSeverity } from './ProblemSeverity'; import Logger from '../utils/logger'; import { ARKUI_DECORATORS } from './utils/consts/ArkUIDecorators'; import { LIMITED_STD_GLOBAL_FUNC } from './utils/consts/LimitedStdGlobalFunc'; -import { LIMITED_STD_GLOBAL_VAR } from './utils/consts/LimitedStdGlobalVar'; import { LIMITED_STD_OBJECT_API } from './utils/consts/LimitedStdObjectAPI'; import { LIMITED_STD_REFLECT_API } from './utils/consts/LimitedStdReflectAPI'; import { LIMITED_STD_PROXYHANDLER_API } from './utils/consts/LimitedStdProxyHandlerAPI'; @@ -1245,12 +1244,11 @@ export class TypeScriptLinter { (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && tsIdentifier.text === 'globalThis' - ) + ) { this.incrementCounters(node, FaultID.GlobalThis); - else if (this.tsUtils.isGlobalSymbol(tsIdentSym) && LIMITED_STD_GLOBAL_VAR.includes(tsIdentSym.getName())) - this.incrementCounters(node, FaultID.LimitedStdLibApi); - else + } else { this.handleRestrictedValues(tsIdentifier, tsIdentSym); + } } } diff --git a/linter/src/utils/consts/LimitedStdGlobalFunc.ts b/linter/src/utils/consts/LimitedStdGlobalFunc.ts index eec858299..841b81dda 100644 --- a/linter/src/utils/consts/LimitedStdGlobalFunc.ts +++ b/linter/src/utils/consts/LimitedStdGlobalFunc.ts @@ -14,5 +14,5 @@ */ export const LIMITED_STD_GLOBAL_FUNC = [ - 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt' + 'eval' ]; diff --git a/linter/src/utils/consts/LimitedStdGlobalVar.ts b/linter/src/utils/consts/LimitedStdGlobalVar.ts deleted file mode 100644 index fd0b48816..000000000 --- a/linter/src/utils/consts/LimitedStdGlobalVar.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023-2023 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. - */ - -export const LIMITED_STD_GLOBAL_VAR = ['Infinity', 'NaN']; diff --git a/linter/test/limited_stdlib_api.ts.autofix.json b/linter/test/limited_stdlib_api.ts.autofix.json index be0f7b9fb..5fa775012 100644 --- a/linter/test/limited_stdlib_api.ts.autofix.json +++ b/linter/test/limited_stdlib_api.ts.autofix.json @@ -22,54 +22,6 @@ "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, - { - "line": 18, - "column": 11, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 19, - "column": 11, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 20, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 21, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 22, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 23, - "column": 1, - "problem": "LimitedStdLibApi", - "autofixable": false, - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, { "line": 31, "column": 1, diff --git a/linter/test/limited_stdlib_api.ts.relax.json b/linter/test/limited_stdlib_api.ts.relax.json index 12f323b61..22ad3a0ad 100644 --- a/linter/test/limited_stdlib_api.ts.relax.json +++ b/linter/test/limited_stdlib_api.ts.relax.json @@ -21,48 +21,6 @@ "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, - { - "line": 18, - "column": 11, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 19, - "column": 11, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 20, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 21, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 22, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 23, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, { "line": 31, "column": 1, diff --git a/linter/test/limited_stdlib_api.ts.strict.json b/linter/test/limited_stdlib_api.ts.strict.json index 12f323b61..22ad3a0ad 100644 --- a/linter/test/limited_stdlib_api.ts.strict.json +++ b/linter/test/limited_stdlib_api.ts.strict.json @@ -21,48 +21,6 @@ "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" }, - { - "line": 18, - "column": 11, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 19, - "column": 11, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 20, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 21, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 22, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, - { - "line": 23, - "column": 1, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)" - }, { "line": 31, "column": 1, -- Gitee From 34ff05475e6b5a30dc91f317d9075555960d8ee2 Mon Sep 17 00:00:00 2001 From: Denis Slynko Date: Thu, 26 Oct 2023 18:25:32 +0300 Subject: [PATCH 12/49] [ArkTS Linter] Fix codestyle Signed-off-by: Denis Slynko --- linter-4.2/src/TypeScriptLinter.ts | 16 ++++++++-------- .../TypeScriptDiagnosticsExtractor.ts | 2 +- linter/src/TypeScriptLinter.ts | 16 ++++++++-------- linter/src/ts-diagnostics/TSCCompiledProgram.ts | 2 +- .../TypeScriptDiagnosticsExtractor.ts | 2 +- linter/src/utils/functions/ContainsThis.ts | 3 +-- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index d9e35a7b5..0ce94a063 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1901,14 +1901,14 @@ export class TypeScriptLinter { } this.filterStrictDiagnostics({ - [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { - return this.checkInRange(rangesToFilter, pos); - }, - [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { - return this.checkInRange(rangesToFilter, pos); - } + [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { + return this.checkInRange(rangesToFilter, pos); }, - this.libraryTypeCallDiagnosticChecker + [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { + return this.checkInRange(rangesToFilter, pos); + } + }, + this.libraryTypeCallDiagnosticChecker ); for (const msgChain of diagnosticMessages) { @@ -2096,7 +2096,7 @@ export class TypeScriptLinter { comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? srcText.slice(comment.pos + 2, comment.end - 2) : srcText.slice(comment.pos + 2, comment.end); - //if comment is multiline end closing '*/' is not at the same line as '@ts-xxx' - do nothing (see #13851) + // if comment is multiline end closing '*/' is not at the same line as '@ts-xxx' - do nothing (see #13851) if (commentContent.endsWith('\n')) return; let trimmedContent = commentContent.trim(); diff --git a/linter-4.2/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts b/linter-4.2/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts index 0d5106dd9..89380f130 100644 --- a/linter-4.2/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts +++ b/linter-4.2/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts @@ -25,7 +25,7 @@ export class TypeScriptDiagnosticsExtractor { public getStrictDiagnostics(fileName: string): ts.Diagnostic[] { // applying filter is a workaround for tsc bug const strict = getAllDiagnostics(this.strictProgram, fileName) - .filter(diag => !(diag.length === 0 && diag.start === 0)); + .filter(diag => !(diag.length === 0 && diag.start === 0)); const nonStrict = getAllDiagnostics(this.nonStrictProgram, fileName); // collect hashes for later easier comparison diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index eb88c473b..bfadb7fc9 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1565,14 +1565,14 @@ export class TypeScriptLinter { } this.filterStrictDiagnostics({ - [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { - return this.checkInRange(rangesToFilter, pos); - }, - [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { - return this.checkInRange(rangesToFilter, pos); - } + [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { + return this.checkInRange(rangesToFilter, pos); }, - this.libraryTypeCallDiagnosticChecker + [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { + return this.checkInRange(rangesToFilter, pos); + } + }, + this.libraryTypeCallDiagnosticChecker ); for (const msgChain of diagnosticMessages) { @@ -1738,7 +1738,7 @@ export class TypeScriptLinter { const commentContent = comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? srcText.slice(comment.pos + 2, comment.end - 2) : srcText.slice(comment.pos + 2, comment.end); - //if comment is multiline end closing '*/' is not at the same line as '@ts-xxx' - do nothing (see #13851) + // if comment is multiline end closing '*/' is not at the same line as '@ts-xxx' - do nothing (see #13851) if (commentContent.endsWith('\n')) return; const trimmedContent = commentContent.trim(); diff --git a/linter/src/ts-diagnostics/TSCCompiledProgram.ts b/linter/src/ts-diagnostics/TSCCompiledProgram.ts index d1ece2fc6..cee480fd8 100644 --- a/linter/src/ts-diagnostics/TSCCompiledProgram.ts +++ b/linter/src/ts-diagnostics/TSCCompiledProgram.ts @@ -61,7 +61,7 @@ export class TSCCompiledProgramWithDiagnostics implements TSCCompiledProgram { public getStrictDiagnostics(fileName: string): ts.Diagnostic[] { const cachedDiagnostic = this.cachedDiagnostics.get(fileName); - if (!!cachedDiagnostic) { + if (cachedDiagnostic) { return cachedDiagnostic } const diagnostic = this.diagnosticsExtractor.getStrictDiagnostics(fileName); diff --git a/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts b/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts index 0d5106dd9..89380f130 100644 --- a/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts +++ b/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts @@ -25,7 +25,7 @@ export class TypeScriptDiagnosticsExtractor { public getStrictDiagnostics(fileName: string): ts.Diagnostic[] { // applying filter is a workaround for tsc bug const strict = getAllDiagnostics(this.strictProgram, fileName) - .filter(diag => !(diag.length === 0 && diag.start === 0)); + .filter(diag => !(diag.length === 0 && diag.start === 0)); const nonStrict = getAllDiagnostics(this.nonStrictProgram, fileName); // collect hashes for later easier comparison diff --git a/linter/src/utils/functions/ContainsThis.ts b/linter/src/utils/functions/ContainsThis.ts index 958553f28..a0cccbb1c 100644 --- a/linter/src/utils/functions/ContainsThis.ts +++ b/linter/src/utils/functions/ContainsThis.ts @@ -39,5 +39,4 @@ export function scopeContainsThis(tsNode: ts.Node): boolean { } visitNode(tsNode); return found; -} - \ No newline at end of file +} \ No newline at end of file -- Gitee From 48a4c5f5a5ef53e9004279efc61553284c36e4a9 Mon Sep 17 00:00:00 2001 From: Ilya Trubachev Date: Thu, 26 Oct 2023 18:44:39 +0300 Subject: [PATCH 13/49] Fix strict error filtering Signed-off-by: Ilya Trubachev --- linter-4.2/src/TypeScriptLinter.ts | 6 ++--- linter-4.2/test/functions.ts | 21 ++++++++++++++- linter-4.2/test/functions.ts.autofix.json | 32 +++++++++++++++++++++++ linter-4.2/test/functions.ts.relax.json | 28 ++++++++++++++++++++ linter-4.2/test/functions.ts.strict.json | 28 ++++++++++++++++++++ linter/src/TypeScriptLinter.ts | 6 ++--- linter/test/functions.ts | 21 ++++++++++++++- linter/test/functions.ts.autofix.json | 32 +++++++++++++++++++++++ linter/test/functions.ts.relax.json | 28 ++++++++++++++++++++ linter/test/functions.ts.strict.json | 28 ++++++++++++++++++++ 10 files changed, 222 insertions(+), 8 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 27442da9f..dc4c76a9d 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1861,13 +1861,13 @@ export class TypeScriptLinter { let rangesToFilter: { begin: number, end: number }[] = []; if (nonFilteringRanges.length !== 0) { let rangesSize = nonFilteringRanges.length; - rangesToFilter.push({ begin: callExpr.pos, end: nonFilteringRanges[0].begin }) - rangesToFilter.push({ begin: nonFilteringRanges[rangesSize - 1].end, end: callExpr.end }) + rangesToFilter.push({ begin: callExpr.arguments.pos, end: nonFilteringRanges[0].begin }) + rangesToFilter.push({ begin: nonFilteringRanges[rangesSize - 1].end, end: callExpr.arguments.end }) for (let i = 0; i < rangesSize - 1; i++) { rangesToFilter.push({ begin: nonFilteringRanges[i].end, end: nonFilteringRanges[i + 1].begin }) } } else { - rangesToFilter.push({ begin: callExpr.pos, end: callExpr.end }) + rangesToFilter.push({ begin: callExpr.arguments.pos, end: callExpr.arguments.end }) } this.filterStrictDiagnostics({ diff --git a/linter-4.2/test/functions.ts b/linter-4.2/test/functions.ts index 8d67f99ff..fd8646324 100644 --- a/linter-4.2/test/functions.ts +++ b/linter-4.2/test/functions.ts @@ -105,4 +105,23 @@ bar(() => { bar(() => { f(null); }, null, f(null)); -}, null, foo(f(null))); \ No newline at end of file +}, null, foo(f(null))); + +type PropDecorator = () => void; +let Builder: PropDecorator; + +// this test is useless until we use custom tsc +@Builder +function buildSwiper() { + f(null) + foo(null) { + f(null) + foo(null) { + f(null) + foo(() => { + f(null) + }) + } + .foo(null) + } +} diff --git a/linter-4.2/test/functions.ts.autofix.json b/linter-4.2/test/functions.ts.autofix.json index bdec3c538..944c5bf6b 100644 --- a/linter-4.2/test/functions.ts.autofix.json +++ b/linter-4.2/test/functions.ts.autofix.json @@ -157,6 +157,38 @@ "autofixable": false, "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 116, + "column": 5, + "problem": "StrictDiagnostic", + "autofixable": false, + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 118, + "column": 7, + "problem": "StrictDiagnostic", + "autofixable": false, + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 120, + "column": 11, + "problem": "StrictDiagnostic", + "autofixable": false, + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 122, + "column": 11, + "problem": "StrictDiagnostic", + "autofixable": false, + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file diff --git a/linter-4.2/test/functions.ts.relax.json b/linter-4.2/test/functions.ts.relax.json index e11f7f9c4..1e86ab2f1 100644 --- a/linter-4.2/test/functions.ts.relax.json +++ b/linter-4.2/test/functions.ts.relax.json @@ -125,6 +125,34 @@ "problem": "StrictDiagnostic", "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 116, + "column": 5, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 118, + "column": 7, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 120, + "column": 11, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 122, + "column": 11, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file diff --git a/linter-4.2/test/functions.ts.strict.json b/linter-4.2/test/functions.ts.strict.json index d39199ff0..a1c2214e5 100644 --- a/linter-4.2/test/functions.ts.strict.json +++ b/linter-4.2/test/functions.ts.strict.json @@ -139,6 +139,34 @@ "problem": "StrictDiagnostic", "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 116, + "column": 5, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 118, + "column": 7, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 120, + "column": 11, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 122, + "column": 11, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 15d018ed5..caae84222 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1536,13 +1536,13 @@ export class TypeScriptLinter { let rangesToFilter: { begin: number, end: number }[] = []; if (nonFilteringRanges.length !== 0) { let rangesSize = nonFilteringRanges.length; - rangesToFilter.push({ begin: callExpr.pos, end: nonFilteringRanges[0].begin }) - rangesToFilter.push({ begin: nonFilteringRanges[rangesSize - 1].end, end: callExpr.end }) + rangesToFilter.push({ begin: callExpr.arguments.pos, end: nonFilteringRanges[0].begin }) + rangesToFilter.push({ begin: nonFilteringRanges[rangesSize - 1].end, end: callExpr.arguments.end }) for (let i = 0; i < rangesSize - 1; i++) { rangesToFilter.push({ begin: nonFilteringRanges[i].end, end: nonFilteringRanges[i + 1].begin }) } } else { - rangesToFilter.push({ begin: callExpr.pos, end: callExpr.end }) + rangesToFilter.push({ begin: callExpr.arguments.pos, end: callExpr.arguments.end }) } this.filterStrictDiagnostics({ diff --git a/linter/test/functions.ts b/linter/test/functions.ts index 8d67f99ff..fd8646324 100644 --- a/linter/test/functions.ts +++ b/linter/test/functions.ts @@ -105,4 +105,23 @@ bar(() => { bar(() => { f(null); }, null, f(null)); -}, null, foo(f(null))); \ No newline at end of file +}, null, foo(f(null))); + +type PropDecorator = () => void; +let Builder: PropDecorator; + +// this test is useless until we use custom tsc +@Builder +function buildSwiper() { + f(null) + foo(null) { + f(null) + foo(null) { + f(null) + foo(() => { + f(null) + }) + } + .foo(null) + } +} diff --git a/linter/test/functions.ts.autofix.json b/linter/test/functions.ts.autofix.json index bdec3c538..944c5bf6b 100755 --- a/linter/test/functions.ts.autofix.json +++ b/linter/test/functions.ts.autofix.json @@ -157,6 +157,38 @@ "autofixable": false, "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 116, + "column": 5, + "problem": "StrictDiagnostic", + "autofixable": false, + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 118, + "column": 7, + "problem": "StrictDiagnostic", + "autofixable": false, + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 120, + "column": 11, + "problem": "StrictDiagnostic", + "autofixable": false, + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 122, + "column": 11, + "problem": "StrictDiagnostic", + "autofixable": false, + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file diff --git a/linter/test/functions.ts.relax.json b/linter/test/functions.ts.relax.json index e11f7f9c4..1e86ab2f1 100644 --- a/linter/test/functions.ts.relax.json +++ b/linter/test/functions.ts.relax.json @@ -125,6 +125,34 @@ "problem": "StrictDiagnostic", "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 116, + "column": 5, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 118, + "column": 7, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 120, + "column": 11, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 122, + "column": 11, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file diff --git a/linter/test/functions.ts.strict.json b/linter/test/functions.ts.strict.json index d39199ff0..a1c2214e5 100644 --- a/linter/test/functions.ts.strict.json +++ b/linter/test/functions.ts.strict.json @@ -139,6 +139,34 @@ "problem": "StrictDiagnostic", "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 116, + "column": 5, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 118, + "column": 7, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 120, + "column": 11, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." + }, + { + "line": 122, + "column": 11, + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file -- Gitee From bbd8f8f17d2c97ded1ccfd00fbb4bd0f077b18a8 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Thu, 26 Oct 2023 19:24:24 +0300 Subject: [PATCH 14/49] [arkts-linter] fix 14033 14030 - double ESObject reporting Signed-off-by: Nazarov Konstantin --- linter-4.2/docs/rules/recipe151.md | 54 +++++ linter-4.2/src/CookBookMsg.ts | 1 + linter-4.2/src/Problems.ts | 6 +- linter-4.2/src/TypeScriptLinter.ts | 121 +++++----- linter-4.2/src/TypeScriptLinterConfig.ts | 4 +- linter-4.2/src/Utils.ts | 27 ++- linter-4.2/test/es_object.ts | 19 +- linter-4.2/test/es_object.ts.relax.json | 269 ++++++++++++++-------- linter-4.2/test/es_object.ts.strict.json | 271 +++++++++++++++-------- linter-4.2/test/oh_modules/ohos_lib.ts | 3 + linter/docs/rules/recipe151.md | 54 +++++ linter/src/CookBookMsg.ts | 1 + linter/src/FaultAttrs.ts | 4 +- linter/src/FaultDesc.ts | 4 +- linter/src/Problems.ts | 2 +- linter/src/TypeScriptLinter.ts | 114 +++++----- linter/src/utils/TsUtils.ts | 29 ++- linter/test/es_object.ts | 19 +- linter/test/es_object.ts.relax.json | 269 ++++++++++++++-------- linter/test/es_object.ts.strict.json | 271 +++++++++++++++-------- linter/test/oh_modules/ohos_lib.ts | 3 + 21 files changed, 1013 insertions(+), 532 deletions(-) create mode 100644 linter-4.2/docs/rules/recipe151.md create mode 100644 linter/docs/rules/recipe151.md diff --git a/linter-4.2/docs/rules/recipe151.md b/linter-4.2/docs/rules/recipe151.md new file mode 100644 index 000000000..bcc54e997 --- /dev/null +++ b/linter-4.2/docs/rules/recipe151.md @@ -0,0 +1,54 @@ + +# Usage of ``ESObject`` type is restricted + +Rule ``arkts-limited-esobject`` + +**Severity: warning** + +ArkTS does not allow using ``ESObject`` type in some cases. The most part of limitations +are put in place in order to prevent spread of dynamic objects in the static codebase. +The only scenario where it is permited to use ``ESObject`` as type specifier is in local +variable declaration. Initialization of variables with ``ESObject`` type is also limited. +Such variables can only be initialized with values that originate from interop: +other ``ESObject`` typed variables, any, unknown, variables with anonymous type, etc. +It is prohibited to initialize ``ESObject`` typed variable with statically typed value. +Varaible of type ``ESObject`` can only be passed to interop calls and assigned to other +variables of type ``ESObject``. + + +## ArkTS + + +``` + // lib.d.ts + declare function foo(): any; + declare function bar(a: any): number; + + // main.ets + let e0: ESObject = foo(); // CTE - ``ESObject`` typed variable can only be local + + function f() { + let e1 = foo(); // CTE - type of e1 is `any` + let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values + let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values + let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values + let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values + let e6: ESObject = foo(); // OK - explicitly annotaded as ESObject + let e7 = e6; // OK - initialize ESObject with ESObject + e6['prop'] // CTE - can't access dynamic properties of ESObject + e6[1] // CTE - can't access dynamic properties of ESObject + e6.prop // CTE - can't access dynamic properties of ESObject + bar(e6) // OK - ESObject is passed to interop call + } +``` + + +## See also + +- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) +- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) +- Recipe 029: Indexed access is not supported for fields (``arkts-no-props-by-index``) +- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) +- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) +- Recipe 137: ``globalThis`` is not supported (``arkts-no-globalthis``) + diff --git a/linter-4.2/src/CookBookMsg.ts b/linter-4.2/src/CookBookMsg.ts index 28b8b77f9..0f7b312b1 100644 --- a/linter-4.2/src/CookBookMsg.ts +++ b/linter-4.2/src/CookBookMsg.ts @@ -170,3 +170,4 @@ cookBookTag[147] = 'No dependencies on TypeScript code are currently allowed (ar cookBookTag[148] = 'No decorators except ArkUI decorators are currently allowed (arkts-no-decorators-except-arkui)'; cookBookTag[149] = 'Classes cannot be used as objects (arkts-no-classes-as-obj)'; cookBookTag[150] = '"import" statements after other statements are not allowed (arkts-no-misplaced-imports)'; +cookBookTag[151] = 'Usage of "ESObject" type is restricted (arkts-limited-esobject)'; diff --git a/linter-4.2/src/Problems.ts b/linter-4.2/src/Problems.ts index df9623d67..61d08d5cb 100644 --- a/linter-4.2/src/Problems.ts +++ b/linter-4.2/src/Problems.ts @@ -34,7 +34,7 @@ export enum FaultID { NewTarget, DefiniteAssignment, Prototype, GlobalThis, UtilityType, PropertyDeclOnFunction, FunctionApplyBindCall, ConstAssertion, ImportAssertion, SpreadOperator, LimitedStdLibApi, ErrorSuppression, StrictDiagnostic, UnsupportedDecorators, ImportAfterStatement, - EsObjectType, EsObjectAssignment, EsObjectAccess, + EsObjectType, LAST_ID, // this should always be last enum` } @@ -129,6 +129,4 @@ faultsAttrs[FaultID.ErrorSuppression] = {cookBookRef: '146',}; faultsAttrs[FaultID.UnsupportedDecorators] = {warning: true, cookBookRef: '148',}; faultsAttrs[FaultID.ClassAsObject] = {cookBookRef: '149',}; faultsAttrs[FaultID.ImportAfterStatement] = {cookBookRef: '150',}; -faultsAttrs[FaultID.EsObjectType] = {warning: true, cookBookRef: '8'}; -faultsAttrs[FaultID.EsObjectAssignment] = {warning: true, cookBookRef: '8'}; -faultsAttrs[FaultID.EsObjectAccess] = {warning: true, cookBookRef: '8'}; +faultsAttrs[FaultID.EsObjectType] = {warning: true, cookBookRef: '151'}; diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 39e52a88b..e3bfd0807 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -691,8 +691,8 @@ export class TypeScriptLinter { if (!!exprSym && this.tsUtils.isSymbolAPI(exprSym) && !TsUtils.ALLOWED_STD_SYMBOL_API.includes(exprSym.getName())) { this.incrementCounters(propertyAccessNode, FaultID.SymbolType); } - if (baseExprSym !== undefined && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { - this.incrementCounters(propertyAccessNode, FaultID.EsObjectAccess); + if (!!baseExprSym && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { + this.incrementCounters(propertyAccessNode, FaultID.EsObjectType); } } @@ -1199,9 +1199,7 @@ export class TypeScriptLinter { } const typeNode = this.tsUtils.getVariableDeclarationTypeNode(tsLhsExpr); - if (!!typeNode) { - this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); - } + this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); } } @@ -1244,39 +1242,42 @@ export class TypeScriptLinter { if (this.tsUtils.needToDeduceStructuralIdentity(tsVarType, tsInitType, tsVarInit)) { this.incrementCounters(tsVarDecl, FaultID.StructuralIdentity); } - - this.handleEsObjectAssignment(tsVarDecl, tsVarDecl.type, tsVarInit); } + this.handleEsObjectDelaration(tsVarDecl); this.handleDeclarationInferredType(tsVarDecl); this.handleDefiniteAssignmentAssertion(tsVarDecl); } - private handleEsObjectAssignment(node: ts.Node, type: ts.TypeNode, value: ts.Node) { - if (!this.tsUtils.isEsObjectType(type)) { - let valueTypeNode = this.tsUtils.getVariableDeclarationTypeNode(value); - if (!!valueTypeNode && this.tsUtils.isEsObjectType(valueTypeNode)) { - this.incrementCounters(node, FaultID.EsObjectAssignment); - } - - return - } - - if (ts.isArrayLiteralExpression(value) || ts.isObjectLiteralExpression(value)) { - this.incrementCounters(node, FaultID.EsObjectAssignment); + private handleEsObjectDelaration(node: ts.VariableDeclaration) { + const isDeclaredESObject = !!node.type && this.tsUtils.isEsObjectType(node.type); + const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); + const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); + const isLocal = this.tsUtils.isInsideBlock(node) + if ((isDeclaredESObject || isInitializedWithESObject) && !isLocal) { + this.incrementCounters(node, FaultID.EsObjectType); return; } - const valueType = this.tsTypeChecker.getTypeAtLocation(value); - if (this.tsUtils.isUnsupportedType(valueType)) { + if (node.initializer) { + this.handleEsObjectAssignment(node, node.type, node.initializer); return; } + } - if (this.tsUtils.isAnonymousType(valueType)) { + private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node) { + const isTypeAnnotated = !!nodeDeclType; + const isDeclaredESObject = !!nodeDeclType && this.tsUtils.isEsObjectType(nodeDeclType); + const initalizerTypeNode = this.tsUtils.getVariableDeclarationTypeNode(initializer); + const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); + if (isTypeAnnotated && !isDeclaredESObject && isInitializedWithESObject) { + this.incrementCounters(node, FaultID.EsObjectType); return; } - this.incrementCounters(node, FaultID.EsObjectAssignment); + if (isDeclaredESObject && !this.tsUtils.isValueAssignableToESObject(initializer)) { + this.incrementCounters(node, FaultID.EsObjectType); + } } private handleCatchClause(node: ts.Node) { @@ -1482,19 +1483,21 @@ export class TypeScriptLinter { } private handleIdentifier(node: ts.Node) { - let tsIdentifier = node as ts.Identifier; - let tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); + const tsIdentifier = node as ts.Identifier; + const tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); - if (tsIdentSym !== undefined) { - if ( - (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && - (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && - tsIdentifier.text === "globalThis" - ) { - this.incrementCounters(node, FaultID.GlobalThis); - } else { - this.handleRestrictedValues(tsIdentifier, tsIdentSym); - } + if (!tsIdentSym) { + return; + } + + if ( + (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && + (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && + tsIdentifier.text === "globalThis" + ) { + this.incrementCounters(node, FaultID.GlobalThis); + } else { + this.handleRestrictedValues(tsIdentifier, tsIdentSym); } } @@ -1633,7 +1636,7 @@ export class TypeScriptLinter { } if (this.tsUtils.hasEsObjectType(tsElementAccessExpr.expression)) { - this.incrementCounters(node, FaultID.EsObjectAccess); + this.incrementCounters(node, FaultID.EsObjectType); } } @@ -1696,7 +1699,7 @@ export class TypeScriptLinter { this.handleStdlibAPICall(tsCallExpr, calleeSym); this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); if (this.tsUtils.symbolHasEsObjectType(calleeSym)) { - this.incrementCounters(tsCallExpr, FaultID.EsObjectAccess); + this.incrementCounters(tsCallExpr, FaultID.EsObjectType); } } if (callSignature !== undefined) { @@ -1708,7 +1711,7 @@ export class TypeScriptLinter { this.handleLibraryTypeCall(tsCallExpr, calleeType); if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { - this.incrementCounters(node, FaultID.EsObjectAccess); + this.incrementCounters(node, FaultID.EsObjectType); } } @@ -1945,35 +1948,37 @@ export class TypeScriptLinter { } private handleTypeReference(node: ts.Node) { - let typeRef = node as ts.TypeReferenceNode; + const typeRef = node as ts.TypeReferenceNode; - if ( - ts.isIdentifier(typeRef.typeName) && - TsUtils.LIMITED_STANDARD_UTILITY_TYPES.includes(typeRef.typeName.text) - ) - this.incrementCounters(node, FaultID.UtilityType); - else if (this.tsUtils.isEsObjectType(typeRef) && !this.tsUtils.isEsObjectAllowed(typeRef)) { + const isESObject = this.tsUtils.isEsObjectType(typeRef); + const isPossiblyValidContext = this.tsUtils.isEsObjectPossiblyAllowed(typeRef); + if (isESObject && !isPossiblyValidContext) { this.incrementCounters(node, FaultID.EsObjectType); + return; } - else if ( - ts.isIdentifier(typeRef.typeName) && - typeRef.typeName.text === "Partial" && - typeRef.typeArguments && - typeRef.typeArguments.length === 1 - ) { - // Using Partial type is allowed only when its argument type is either Class or Interface. - let argType = this.tsTypeChecker.getTypeFromTypeNode( - typeRef.typeArguments[0] - ); - if (!argType || !argType.isClassOrInterface()) - this.incrementCounters(node, FaultID.UtilityType); + const typeName = this.tsUtils.entityNameToString(typeRef.typeName); + const isStdUtilityType = TsUtils.LIMITED_STANDARD_UTILITY_TYPES.includes(typeName); + if (isStdUtilityType) { + this.incrementCounters(node, FaultID.UtilityType); + return; + } + + // Using Partial type is allowed only when its argument type is either Class or Interface. + const isStdPartial = this.tsUtils.entityNameToString(typeRef.typeName) === 'Partial'; + const hasSingleTypeArgument = !!typeRef.typeArguments && typeRef.typeArguments.length === 1; + const firstTypeArg = !!typeRef.typeArguments && hasSingleTypeArgument && typeRef.typeArguments[0]; + const argType = firstTypeArg && this.tsTypeChecker.getTypeFromTypeNode(firstTypeArg); + if (isStdPartial && argType && !argType.isClassOrInterface()) { + this.incrementCounters(node, FaultID.UtilityType); + return; } } private handleMetaProperty(node: ts.Node) { let tsMetaProperty = node as ts.MetaProperty; - if (tsMetaProperty.name.text === "target") + if (tsMetaProperty.name.text === "target") { this.incrementCounters(node, FaultID.NewTarget); + } } private handleStructDeclaration(node: ts.Node) { diff --git a/linter-4.2/src/TypeScriptLinterConfig.ts b/linter-4.2/src/TypeScriptLinterConfig.ts index 179738f65..f549a8718 100644 --- a/linter-4.2/src/TypeScriptLinterConfig.ts +++ b/linter-4.2/src/TypeScriptLinterConfig.ts @@ -116,9 +116,7 @@ export class LinterConfig { LinterConfig.nodeDesc[FaultID.StrictDiagnostic] = 'Strict diagnostic'; LinterConfig.nodeDesc[FaultID.UnsupportedDecorators] = 'Unsupported decorators'; LinterConfig.nodeDesc[FaultID.ImportAfterStatement] = 'Import declaration after other declaration or statement'; - LinterConfig.nodeDesc[FaultID.EsObjectType] = '"ESObject" type'; - LinterConfig.nodeDesc[FaultID.EsObjectAssignment] = '"ESObject" type assignment'; - LinterConfig.nodeDesc[FaultID.EsObjectAccess] = '"ESObject" access'; + LinterConfig.nodeDesc[FaultID.EsObjectType] = 'Restricted "ESObject" type'; LinterConfig.initTsSyntaxKindNames(); } diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index ed6992f74..5f519cba0 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -1358,22 +1358,29 @@ export class TsUtils { typeNode.typeName.text == TsUtils.ES_OBJECT; } - public isEsObjectAllowed(typeRef: ts.TypeReferenceNode): boolean { - let node = typeRef.parent; - - if (!this.isVarDeclaration(node)) { - return false; - } - - while (node) { - if (ts.isBlock(node)) { + public isInsideBlock(node: ts.Node): boolean { + let par = node.parent + while (par) { + if (ts.isBlock(par)) { return true; } - node = node.parent; + par = par.parent; } return false; } + public isEsObjectPossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean { + return ts.isVariableDeclaration(typeRef.parent); + } + + public isValueAssignableToESObject(node: ts.Node): boolean { + if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) { + return false; + } + const valueType = this.tsTypeChecker.getTypeAtLocation(node); + return this.isUnsupportedType(valueType) || this.isAnonymousType(valueType) + } + public getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { let sym = this.trueSymbolAtLocation(node); if (sym === undefined) { diff --git a/linter-4.2/test/es_object.ts b/linter-4.2/test/es_object.ts index d9715b772..445b5c0c0 100644 --- a/linter-4.2/test/es_object.ts +++ b/linter-4.2/test/es_object.ts @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { fooOh, barOh } from './oh_modules/ohos_lib' type ESObject = any class A {} @@ -174,3 +174,20 @@ interface CL extends ESObject {} export interface CLS extends ESObject {} foo2({ k: 'k', h: {t: 1}}) // we can assign anything to the esobject, even untyped literal +let q1: ESObject = 1; // CTE - ``ESObject`` typed variable can only be local +let q2: ESObject = fooOh(); // CTE - ``ESObject`` typed variable can only be local +let q3: ESObject = q2; // CTE - ``ESObject`` typed variable can only be local +function f() { + let e1 = fooOh(); // CTE - type of e1 is `any` + let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values + let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values + let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values + let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values + let e6: ESObject = fooOh(); // OK - explicitly annotaded as ESObject + let e7: ESObject = e6; // OK - initialize ESObject with ESObject + e6['prop'] // CTE - can't access dynamic properties of ESObject + e6[1] // CTE - can't access dynamic properties of ESObject + e6.prop // CTE - can't access dynamic properties of ESObject + barOh(e6) // OK - ESObject is passed to interop call + e6 = e7 // OK - ESObject is assigned to ESObject +} diff --git a/linter-4.2/test/es_object.ts.relax.json b/linter-4.2/test/es_object.ts.relax.json index 10bd5f5bd..f3d5acdb4 100644 --- a/linter-4.2/test/es_object.ts.relax.json +++ b/linter-4.2/test/es_object.ts.relax.json @@ -23,234 +23,234 @@ }, { "line": 20, - "column": 9, + "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 77, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 78, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 79, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 80, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 82, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 83, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 85, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 86, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 87, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 88, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 90, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 91, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 93, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 94, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 95, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 96, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 98, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 99, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 114, @@ -486,37 +486,37 @@ { "line": 115, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 176, @@ -594,6 +594,83 @@ "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" + }, + { + "line": 177, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 178, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 179, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 181, + "column": 9, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 182, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 183, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 184, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 185, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 188, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 189, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 190, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/es_object.ts.strict.json b/linter-4.2/test/es_object.ts.strict.json index 10bd5f5bd..5c869e41f 100644 --- a/linter-4.2/test/es_object.ts.strict.json +++ b/linter-4.2/test/es_object.ts.strict.json @@ -23,234 +23,234 @@ }, { "line": 20, - "column": 9, + "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 77, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 78, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 79, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 80, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 82, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 83, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 85, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 86, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 87, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 88, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 90, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 91, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 93, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 94, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 95, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 96, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 98, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 99, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 114, @@ -486,37 +486,37 @@ { "line": 115, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 176, @@ -594,6 +594,83 @@ "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" + }, + { + "line": 177, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 178, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 179, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 181, + "column": 9, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 182, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 183, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 184, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 185, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 188, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 189, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 190, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" } - ] + ] } \ No newline at end of file diff --git a/linter-4.2/test/oh_modules/ohos_lib.ts b/linter-4.2/test/oh_modules/ohos_lib.ts index a0aa74c87..c69856185 100644 --- a/linter-4.2/test/oh_modules/ohos_lib.ts +++ b/linter-4.2/test/oh_modules/ohos_lib.ts @@ -20,3 +20,6 @@ export interface OhosI { export function ohFunction1({d: OhosI}): void {} // incorrect usage, but it was an issue, so we check it too export function ohFunction2(p: {d: OhosI}): void {} + +export function fooOh(): any {} +export function barOh(a: any) {} diff --git a/linter/docs/rules/recipe151.md b/linter/docs/rules/recipe151.md new file mode 100644 index 000000000..bcc54e997 --- /dev/null +++ b/linter/docs/rules/recipe151.md @@ -0,0 +1,54 @@ + +# Usage of ``ESObject`` type is restricted + +Rule ``arkts-limited-esobject`` + +**Severity: warning** + +ArkTS does not allow using ``ESObject`` type in some cases. The most part of limitations +are put in place in order to prevent spread of dynamic objects in the static codebase. +The only scenario where it is permited to use ``ESObject`` as type specifier is in local +variable declaration. Initialization of variables with ``ESObject`` type is also limited. +Such variables can only be initialized with values that originate from interop: +other ``ESObject`` typed variables, any, unknown, variables with anonymous type, etc. +It is prohibited to initialize ``ESObject`` typed variable with statically typed value. +Varaible of type ``ESObject`` can only be passed to interop calls and assigned to other +variables of type ``ESObject``. + + +## ArkTS + + +``` + // lib.d.ts + declare function foo(): any; + declare function bar(a: any): number; + + // main.ets + let e0: ESObject = foo(); // CTE - ``ESObject`` typed variable can only be local + + function f() { + let e1 = foo(); // CTE - type of e1 is `any` + let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values + let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values + let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values + let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values + let e6: ESObject = foo(); // OK - explicitly annotaded as ESObject + let e7 = e6; // OK - initialize ESObject with ESObject + e6['prop'] // CTE - can't access dynamic properties of ESObject + e6[1] // CTE - can't access dynamic properties of ESObject + e6.prop // CTE - can't access dynamic properties of ESObject + bar(e6) // OK - ESObject is passed to interop call + } +``` + + +## See also + +- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) +- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) +- Recipe 029: Indexed access is not supported for fields (``arkts-no-props-by-index``) +- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) +- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) +- Recipe 137: ``globalThis`` is not supported (``arkts-no-globalthis``) + diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index d71982547..80d6030bf 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -170,3 +170,4 @@ cookBookTag[147] = 'No dependencies on TypeScript code are currently allowed (ar cookBookTag[148] = 'No decorators except ArkUI decorators are currently allowed (arkts-no-decorators-except-arkui)'; cookBookTag[149] = 'Classes cannot be used as objects (arkts-no-classes-as-obj)'; cookBookTag[150] = '"import" statements after other statements are not allowed (arkts-no-misplaced-imports)'; +cookBookTag[151] = 'Usage of "ESObject" type is restricted (arkts-limited-esobject)'; diff --git a/linter/src/FaultAttrs.ts b/linter/src/FaultAttrs.ts index e567b1f60..1346c84b3 100644 --- a/linter/src/FaultAttrs.ts +++ b/linter/src/FaultAttrs.ts @@ -106,6 +106,4 @@ faultsAttrs[FaultID.ErrorSuppression] = {cookBookRef: '146',}; faultsAttrs[FaultID.UnsupportedDecorators] = {warning: true, cookBookRef: '148',}; faultsAttrs[FaultID.ClassAsObject] = {cookBookRef: '149',}; faultsAttrs[FaultID.ImportAfterStatement] = {cookBookRef: '150',}; -faultsAttrs[FaultID.EsObjectType] = {warning: true, cookBookRef: '8'}; -faultsAttrs[FaultID.EsObjectAssignment] = {warning: true, cookBookRef: '8'}; -faultsAttrs[FaultID.EsObjectAccess] = {warning: true, cookBookRef: '8'}; +faultsAttrs[FaultID.EsObjectType] = {warning: true, cookBookRef: '151'}; diff --git a/linter/src/FaultDesc.ts b/linter/src/FaultDesc.ts index 407fd7a05..d4555c10a 100644 --- a/linter/src/FaultDesc.ts +++ b/linter/src/FaultDesc.ts @@ -100,6 +100,4 @@ faultDesc[FaultID.ErrorSuppression] = 'Error suppression annotation'; faultDesc[FaultID.StrictDiagnostic] = 'Strict diagnostic'; faultDesc[FaultID.UnsupportedDecorators] = 'Unsupported decorators'; faultDesc[FaultID.ImportAfterStatement] = 'Import declaration after other declaration or statement'; -faultDesc[FaultID.EsObjectType] = '"ESObject" type'; -faultDesc[FaultID.EsObjectAssignment] = '"ESObject" type assignment'; -faultDesc[FaultID.EsObjectAccess] = '"ESObject" access'; +faultDesc[FaultID.EsObjectType] = 'Restricted "ESObject" type'; diff --git a/linter/src/Problems.ts b/linter/src/Problems.ts index ea9407728..4008210e4 100644 --- a/linter/src/Problems.ts +++ b/linter/src/Problems.ts @@ -34,6 +34,6 @@ export enum FaultID { NewTarget, DefiniteAssignment, Prototype, GlobalThis, UtilityType, PropertyDeclOnFunction, FunctionApplyBindCall, ConstAssertion, ImportAssertion, SpreadOperator, LimitedStdLibApi, ErrorSuppression, StrictDiagnostic, UnsupportedDecorators, ImportAfterStatement, - EsObjectType, EsObjectAssignment, EsObjectAccess, + EsObjectType, LAST_ID, // this should always be last enum` } diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index bfceb036c..d97a49cf2 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -603,8 +603,8 @@ export class TypeScriptLinter { // missing exact rule this.incrementCounters(propertyAccessNode.expression, FaultID.ClassAsObject); } - if (baseExprSym !== undefined && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { - this.incrementCounters(propertyAccessNode, FaultID.EsObjectAccess); + if (!!baseExprSym && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { + this.incrementCounters(propertyAccessNode, FaultID.EsObjectType); } } @@ -930,9 +930,7 @@ export class TypeScriptLinter { if (this.tsUtils.needToDeduceStructuralIdentity(leftOperandType, rightOperandType, tsRhsExpr)) { this.incrementCounters(tsBinaryExpr, FaultID.StructuralIdentity); } - if (typeNode) { - this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); - } + this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); break; default: return; @@ -1019,38 +1017,40 @@ export class TypeScriptLinter { if (this.tsUtils.needToDeduceStructuralIdentity(tsVarType, tsInitType, tsVarInit)) { this.incrementCounters(tsVarDecl, FaultID.StructuralIdentity); } - - this.handleEsObjectAssignment(tsVarDecl, tsVarDecl.type, tsVarInit); } + this.handleEsObjectDelaration(tsVarDecl); this.handleDeclarationInferredType(tsVarDecl); this.handleDefiniteAssignmentAssertion(tsVarDecl); } - private handleEsObjectAssignment(node: ts.Node, type: ts.TypeNode, value: ts.Node) { - if (!this.tsUtils.isEsObjectType(type)) { - let valueTypeNode = this.tsUtils.getVariableDeclarationTypeNode(value); - if (!!valueTypeNode && this.tsUtils.isEsObjectType(valueTypeNode)) { - this.incrementCounters(node, FaultID.EsObjectAssignment); - } - - return - } - - if (ts.isArrayLiteralExpression(value) || ts.isObjectLiteralExpression(value)) { - this.incrementCounters(node, FaultID.EsObjectAssignment); + private handleEsObjectDelaration(node: ts.VariableDeclaration) { + const isDeclaredESObject = !!node.type && this.tsUtils.isEsObjectType(node.type); + const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); + const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); + const isLocal = this.tsUtils.isInsideBlock(node) + if ((isDeclaredESObject || isInitializedWithESObject) && !isLocal) { + this.incrementCounters(node, FaultID.EsObjectType); return; } - const valueType = this.tsTypeChecker.getTypeAtLocation(value); - if (this.tsUtils.isUnsupportedType(valueType)) { - return; + if (node.initializer) { + this.handleEsObjectAssignment(node, node.type, node.initializer); } + } - if (this.tsUtils.isAnonymousType(valueType)) { + private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node) { + const isTypeAnnotated = !!nodeDeclType; + const isDeclaredESObject = isTypeAnnotated && this.tsUtils.isEsObjectType(nodeDeclType); + const initalizerTypeNode = this.tsUtils.getVariableDeclarationTypeNode(initializer); + const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); + if (isTypeAnnotated && !isDeclaredESObject && isInitializedWithESObject) { + this.incrementCounters(node, FaultID.EsObjectType); return; } - this.incrementCounters(node, FaultID.EsObjectAssignment); + if (isDeclaredESObject && !this.tsUtils.isValueAssignableToESObject(initializer)) { + this.incrementCounters(node, FaultID.EsObjectType); + } } private handleCatchClause(node: ts.Node) { @@ -1237,18 +1237,19 @@ export class TypeScriptLinter { } private handleIdentifier(node: ts.Node) { - let tsIdentifier = node as ts.Identifier; - let tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); - if (tsIdentSym !== undefined) { - if ( - (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && - (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && - tsIdentifier.text === 'globalThis' - ) { - this.incrementCounters(node, FaultID.GlobalThis); - } else { - this.handleRestrictedValues(tsIdentifier, tsIdentSym); - } + const tsIdentifier = node as ts.Identifier; + const tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); + if (!tsIdentSym) { + return + } + if ( + (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && + (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 && + tsIdentifier.text === 'globalThis' + ) { + this.incrementCounters(node, FaultID.GlobalThis); + } else { + this.handleRestrictedValues(tsIdentifier, tsIdentSym); } } @@ -1330,7 +1331,7 @@ export class TypeScriptLinter { } if (this.tsUtils.hasEsObjectType(tsElementAccessExpr.expression)) { - this.incrementCounters(node, FaultID.EsObjectAccess); + this.incrementCounters(node, FaultID.EsObjectType); } } @@ -1379,7 +1380,7 @@ export class TypeScriptLinter { this.handleStdlibAPICall(tsCallExpr, calleeSym); this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); if (this.tsUtils.symbolHasEsObjectType(calleeSym)) { - this.incrementCounters(tsCallExpr, FaultID.EsObjectAccess); + this.incrementCounters(tsCallExpr, FaultID.EsObjectType); } } if (callSignature !== undefined) { @@ -1391,7 +1392,7 @@ export class TypeScriptLinter { this.handleLibraryTypeCall(tsCallExpr, calleeType); if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { - this.incrementCounters(node, FaultID.EsObjectAccess); + this.incrementCounters(node, FaultID.EsObjectType); } } @@ -1617,26 +1618,37 @@ export class TypeScriptLinter { } private handleTypeReference(node: ts.Node) { - let typeRef = node as ts.TypeReferenceNode; - if (this.tsUtils.isEsObjectType(typeRef) && !this.tsUtils.isEsObjectAllowed(typeRef)) { + const typeRef = node as ts.TypeReferenceNode; + + const isESObject = this.tsUtils.isEsObjectType(typeRef); + const isPossiblyValidContext = this.tsUtils.isEsObjectPossiblyAllowed(typeRef); + if (isESObject && !isPossiblyValidContext) { this.incrementCounters(node, FaultID.EsObjectType); - } else if (ts.isIdentifier(typeRef.typeName) && LIMITED_STANDARD_UTILITY_TYPES.includes(typeRef.typeName.text)) + return; + } + + const typeName = this.tsUtils.entityNameToString(typeRef.typeName); + const isStdUtilityType = LIMITED_STANDARD_UTILITY_TYPES.includes(typeName); + if (isStdUtilityType) { this.incrementCounters(node, FaultID.UtilityType); - else if ( - ts.isIdentifier(typeRef.typeName) && typeRef.typeName.text === 'Partial' && - typeRef.typeArguments && typeRef.typeArguments.length === 1 - ) { - // Using Partial type is allowed only when its argument type is either Class or Interface. - let argType = this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[0]); - if (!argType || !argType.isClassOrInterface()) - this.incrementCounters(node, FaultID.UtilityType); + return; + } + + // Using Partial type is allowed only when its argument type is either Class or Interface. + const isStdPartial = this.tsUtils.entityNameToString(typeRef.typeName) === 'Partial'; + const hasSingleTypeArgument = !!typeRef.typeArguments && typeRef.typeArguments.length === 1; + const argType = hasSingleTypeArgument && this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[0]); + if (isStdPartial && argType && !argType.isClassOrInterface()) { + this.incrementCounters(node, FaultID.UtilityType); + return; } } private handleMetaProperty(node: ts.Node) { let tsMetaProperty = node as ts.MetaProperty; - if (tsMetaProperty.name.text === 'target') + if (tsMetaProperty.name.text === 'target') { this.incrementCounters(node, FaultID.NewTarget); + } } private handleStructDeclaration(node: ts.Node) { diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index fbe9f0452..39d31eed8 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -1115,22 +1115,29 @@ export class TsUtils { typeNode.typeName.text == ES_OBJECT; } - public isEsObjectAllowed(typeRef: ts.TypeReferenceNode): boolean { - let node = typeRef.parent; - - if (!this.isVarDeclaration(node)) { - return false; - } - - while (node) { - if (ts.isBlock(node)) { + public isInsideBlock(node: ts.Node): boolean { + let par = node.parent + while (par) { + if (ts.isBlock(par)) { return true; } - node = node.parent; + par = par.parent; } return false; } + public isEsObjectPossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean { + return ts.isVariableDeclaration(typeRef.parent); + } + + public isValueAssignableToESObject(node: ts.Node): boolean { + if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) { + return false; + } + const valueType = this.tsTypeChecker.getTypeAtLocation(node); + return this.isUnsupportedType(valueType) || this.isAnonymousType(valueType) + } + public getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { let sym = this.trueSymbolAtLocation(node); if (sym === undefined) { @@ -1160,7 +1167,7 @@ export class TsUtils { public isEsObjectSymbol(sym: ts.Symbol): boolean { let decl = this.getDeclaration(sym); return !!decl && ts.isTypeAliasDeclaration(decl) && decl.name.escapedText == ES_OBJECT && - decl.type.kind == ts.SyntaxKind.AnyKeyword; + decl.type.kind === ts.SyntaxKind.AnyKeyword; } public isAnonymousType(type: ts.Type): boolean { diff --git a/linter/test/es_object.ts b/linter/test/es_object.ts index d9715b772..445b5c0c0 100644 --- a/linter/test/es_object.ts +++ b/linter/test/es_object.ts @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { fooOh, barOh } from './oh_modules/ohos_lib' type ESObject = any class A {} @@ -174,3 +174,20 @@ interface CL extends ESObject {} export interface CLS extends ESObject {} foo2({ k: 'k', h: {t: 1}}) // we can assign anything to the esobject, even untyped literal +let q1: ESObject = 1; // CTE - ``ESObject`` typed variable can only be local +let q2: ESObject = fooOh(); // CTE - ``ESObject`` typed variable can only be local +let q3: ESObject = q2; // CTE - ``ESObject`` typed variable can only be local +function f() { + let e1 = fooOh(); // CTE - type of e1 is `any` + let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values + let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values + let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values + let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values + let e6: ESObject = fooOh(); // OK - explicitly annotaded as ESObject + let e7: ESObject = e6; // OK - initialize ESObject with ESObject + e6['prop'] // CTE - can't access dynamic properties of ESObject + e6[1] // CTE - can't access dynamic properties of ESObject + e6.prop // CTE - can't access dynamic properties of ESObject + barOh(e6) // OK - ESObject is passed to interop call + e6 = e7 // OK - ESObject is assigned to ESObject +} diff --git a/linter/test/es_object.ts.relax.json b/linter/test/es_object.ts.relax.json index 10bd5f5bd..f3d5acdb4 100644 --- a/linter/test/es_object.ts.relax.json +++ b/linter/test/es_object.ts.relax.json @@ -23,234 +23,234 @@ }, { "line": 20, - "column": 9, + "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 77, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 78, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 79, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 80, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 82, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 83, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 85, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 86, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 87, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 88, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 90, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 91, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 93, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 94, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 95, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 96, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 98, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 99, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 114, @@ -486,37 +486,37 @@ { "line": 115, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 176, @@ -594,6 +594,83 @@ "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" + }, + { + "line": 177, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 178, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 179, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 181, + "column": 9, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 182, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 183, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 184, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 185, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 188, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 189, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 190, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" } ] } \ No newline at end of file diff --git a/linter/test/es_object.ts.strict.json b/linter/test/es_object.ts.strict.json index 10bd5f5bd..5c869e41f 100644 --- a/linter/test/es_object.ts.strict.json +++ b/linter/test/es_object.ts.strict.json @@ -23,234 +23,234 @@ }, { "line": 20, - "column": 9, + "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 77, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 78, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 79, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 80, "column": 5, - "problem": "EsObjectAccess", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 82, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 83, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 85, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 86, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 87, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 88, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 90, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 91, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 93, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 94, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 95, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 96, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 98, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 99, "column": 5, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 114, @@ -486,37 +486,37 @@ { "line": 115, "column": 9, - "problem": "EsObjectAssignment", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" }, { "line": 176, @@ -594,6 +594,83 @@ "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" + }, + { + "line": 177, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 178, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 179, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 181, + "column": 9, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 182, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 183, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 184, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 185, + "column": 9, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 188, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 189, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + }, + { + "line": 190, + "column": 5, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" } - ] + ] } \ No newline at end of file diff --git a/linter/test/oh_modules/ohos_lib.ts b/linter/test/oh_modules/ohos_lib.ts index a0aa74c87..c69856185 100644 --- a/linter/test/oh_modules/ohos_lib.ts +++ b/linter/test/oh_modules/ohos_lib.ts @@ -20,3 +20,6 @@ export interface OhosI { export function ohFunction1({d: OhosI}): void {} // incorrect usage, but it was an issue, so we check it too export function ohFunction2(p: {d: OhosI}): void {} + +export function fooOh(): any {} +export function barOh(a: any) {} -- Gitee From 2b756ee2b90e1be8d45775dcc6c53178a5c9603e Mon Sep 17 00:00:00 2001 From: Denis Slynko Date: Mon, 30 Oct 2023 13:15:42 +0300 Subject: [PATCH 15/49] [ArkTS Linter] Fix possible type mismatch in validateDeclInferredType Signed-off-by: Denis Slynko --- linter-4.2/src/TypeScriptLinter.ts | 4 +--- linter/src/TypeScriptLinter.ts | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index e90316f2b..bc9dd25c4 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -2226,9 +2226,7 @@ export class TypeScriptLinter { if (type.aliasSymbol != undefined) { return; } - const isObject = type.flags & ts.TypeFlags.Object; - const isReference = (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference; - if (isObject && isReference) { + if (this.tsUtils.isObjectType(type) && !!(type.objectFlags & ts.ObjectFlags.Reference)) { this.handleInferredObjectreference(type, decl); return; } diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 135475594..a33d4740f 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1864,9 +1864,7 @@ export class TypeScriptLinter { if (type.aliasSymbol != undefined) { return; } - const isObject = type.flags & ts.TypeFlags.Object; - const isReference = (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference; - if (isObject && isReference) { + if (this.tsUtils.isObjectType(type) && !!(type.objectFlags & ts.ObjectFlags.Reference)) { this.handleInferredObjectreference(type, decl); return; } -- Gitee From 7762cb25bc0fa2edce6741fc535bc0eed57a8827 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Tue, 31 Oct 2023 16:50:34 +0300 Subject: [PATCH 16/49] [arkts-linter] update description for recipe 151 Signed-off-by: Nazarov Konstantin --- linter-4.2/docs/rules/recipe151.md | 29 ++-- linter-4.2/src/CookBookMsg.ts | 2 +- linter-4.2/test/es_object.ts.relax.json | 172 +++++++++++------------ linter-4.2/test/es_object.ts.strict.json | 172 +++++++++++------------ linter/docs/rules/recipe151.md | 29 ++-- linter/src/CookBookMsg.ts | 2 +- linter/test/es_object.ts.relax.json | 172 +++++++++++------------ linter/test/es_object.ts.strict.json | 172 +++++++++++------------ 8 files changed, 376 insertions(+), 374 deletions(-) diff --git a/linter-4.2/docs/rules/recipe151.md b/linter-4.2/docs/rules/recipe151.md index bcc54e997..2e7fd2d46 100644 --- a/linter-4.2/docs/rules/recipe151.md +++ b/linter-4.2/docs/rules/recipe151.md @@ -1,18 +1,18 @@ - # Usage of ``ESObject`` type is restricted -Rule ``arkts-limited-esobject`` +Rule ``arkts-limited-esobj`` **Severity: warning** -ArkTS does not allow using ``ESObject`` type in some cases. The most part of limitations -are put in place in order to prevent spread of dynamic objects in the static codebase. -The only scenario where it is permited to use ``ESObject`` as type specifier is in local -variable declaration. Initialization of variables with ``ESObject`` type is also limited. -Such variables can only be initialized with values that originate from interop: -other ``ESObject`` typed variables, any, unknown, variables with anonymous type, etc. -It is prohibited to initialize ``ESObject`` typed variable with statically typed value. -Varaible of type ``ESObject`` can only be passed to interop calls and assigned to other +ArkTS does not allow using ``ESObject`` type in some cases. The most part of +limitations are put in place in order to prevent spread of dynamic objects in +the static codebase. The only scenario where it is permited to use ``ESObject`` +as type specifier is in local variable declaration. Initialization of variables +with ``ESObject`` type is also limited. Such variables can only be initialized +with values that originate from interop: other ``ESObject`` typed variables, +any, unknown, variables with anonymous type, etc. It is prohibited to +initialize ``ESObject`` typed variable with statically typed value. Varaible +of type ``ESObject`` can only be passed to interop calls and assigned to other variables of type ``ESObject``. @@ -33,12 +33,13 @@ variables of type ``ESObject``. let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values + e5['prop'] // CTE - can't access dynamic properties of ESObject + e5[1] // CTE - can't access dynamic properties of ESObject + e5.prop // CTE - can't access dynamic properties of ESObject + let e6: ESObject = foo(); // OK - explicitly annotaded as ESObject let e7 = e6; // OK - initialize ESObject with ESObject - e6['prop'] // CTE - can't access dynamic properties of ESObject - e6[1] // CTE - can't access dynamic properties of ESObject - e6.prop // CTE - can't access dynamic properties of ESObject - bar(e6) // OK - ESObject is passed to interop call + bar(e7) // OK - ESObject is passed to interop call } ``` diff --git a/linter-4.2/src/CookBookMsg.ts b/linter-4.2/src/CookBookMsg.ts index 0f7b312b1..a5897f0e2 100644 --- a/linter-4.2/src/CookBookMsg.ts +++ b/linter-4.2/src/CookBookMsg.ts @@ -170,4 +170,4 @@ cookBookTag[147] = 'No dependencies on TypeScript code are currently allowed (ar cookBookTag[148] = 'No decorators except ArkUI decorators are currently allowed (arkts-no-decorators-except-arkui)'; cookBookTag[149] = 'Classes cannot be used as objects (arkts-no-classes-as-obj)'; cookBookTag[150] = '"import" statements after other statements are not allowed (arkts-no-misplaced-imports)'; -cookBookTag[151] = 'Usage of "ESObject" type is restricted (arkts-limited-esobject)'; +cookBookTag[151] = 'Usage of "ESObject" type is restricted (arkts-limited-esobj)'; diff --git a/linter-4.2/test/es_object.ts.relax.json b/linter-4.2/test/es_object.ts.relax.json index f3d5acdb4..7450fc30f 100644 --- a/linter-4.2/test/es_object.ts.relax.json +++ b/linter-4.2/test/es_object.ts.relax.json @@ -26,231 +26,231 @@ "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 77, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 78, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 79, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 80, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 82, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 83, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 85, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 86, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 87, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 88, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 90, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 91, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 93, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 94, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 95, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 96, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 98, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 99, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 114, @@ -488,35 +488,35 @@ "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 176, @@ -600,21 +600,21 @@ "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 178, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 179, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 181, @@ -628,49 +628,49 @@ "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 183, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 184, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 185, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 188, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 189, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 190, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/es_object.ts.strict.json b/linter-4.2/test/es_object.ts.strict.json index 5c869e41f..4909f595f 100644 --- a/linter-4.2/test/es_object.ts.strict.json +++ b/linter-4.2/test/es_object.ts.strict.json @@ -26,231 +26,231 @@ "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 77, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 78, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 79, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 80, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 82, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 83, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 85, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 86, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 87, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 88, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 90, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 91, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 93, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 94, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 95, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 96, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 98, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 99, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 114, @@ -488,35 +488,35 @@ "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 176, @@ -600,21 +600,21 @@ "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 178, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 179, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 181, @@ -628,49 +628,49 @@ "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 183, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 184, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 185, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 188, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 189, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 190, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" } ] } \ No newline at end of file diff --git a/linter/docs/rules/recipe151.md b/linter/docs/rules/recipe151.md index bcc54e997..2e7fd2d46 100644 --- a/linter/docs/rules/recipe151.md +++ b/linter/docs/rules/recipe151.md @@ -1,18 +1,18 @@ - # Usage of ``ESObject`` type is restricted -Rule ``arkts-limited-esobject`` +Rule ``arkts-limited-esobj`` **Severity: warning** -ArkTS does not allow using ``ESObject`` type in some cases. The most part of limitations -are put in place in order to prevent spread of dynamic objects in the static codebase. -The only scenario where it is permited to use ``ESObject`` as type specifier is in local -variable declaration. Initialization of variables with ``ESObject`` type is also limited. -Such variables can only be initialized with values that originate from interop: -other ``ESObject`` typed variables, any, unknown, variables with anonymous type, etc. -It is prohibited to initialize ``ESObject`` typed variable with statically typed value. -Varaible of type ``ESObject`` can only be passed to interop calls and assigned to other +ArkTS does not allow using ``ESObject`` type in some cases. The most part of +limitations are put in place in order to prevent spread of dynamic objects in +the static codebase. The only scenario where it is permited to use ``ESObject`` +as type specifier is in local variable declaration. Initialization of variables +with ``ESObject`` type is also limited. Such variables can only be initialized +with values that originate from interop: other ``ESObject`` typed variables, +any, unknown, variables with anonymous type, etc. It is prohibited to +initialize ``ESObject`` typed variable with statically typed value. Varaible +of type ``ESObject`` can only be passed to interop calls and assigned to other variables of type ``ESObject``. @@ -33,12 +33,13 @@ variables of type ``ESObject``. let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values + e5['prop'] // CTE - can't access dynamic properties of ESObject + e5[1] // CTE - can't access dynamic properties of ESObject + e5.prop // CTE - can't access dynamic properties of ESObject + let e6: ESObject = foo(); // OK - explicitly annotaded as ESObject let e7 = e6; // OK - initialize ESObject with ESObject - e6['prop'] // CTE - can't access dynamic properties of ESObject - e6[1] // CTE - can't access dynamic properties of ESObject - e6.prop // CTE - can't access dynamic properties of ESObject - bar(e6) // OK - ESObject is passed to interop call + bar(e7) // OK - ESObject is passed to interop call } ``` diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index 80d6030bf..c62bafe14 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -170,4 +170,4 @@ cookBookTag[147] = 'No dependencies on TypeScript code are currently allowed (ar cookBookTag[148] = 'No decorators except ArkUI decorators are currently allowed (arkts-no-decorators-except-arkui)'; cookBookTag[149] = 'Classes cannot be used as objects (arkts-no-classes-as-obj)'; cookBookTag[150] = '"import" statements after other statements are not allowed (arkts-no-misplaced-imports)'; -cookBookTag[151] = 'Usage of "ESObject" type is restricted (arkts-limited-esobject)'; +cookBookTag[151] = 'Usage of "ESObject" type is restricted (arkts-limited-esobj)'; diff --git a/linter/test/es_object.ts.relax.json b/linter/test/es_object.ts.relax.json index f3d5acdb4..7450fc30f 100644 --- a/linter/test/es_object.ts.relax.json +++ b/linter/test/es_object.ts.relax.json @@ -26,231 +26,231 @@ "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 77, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 78, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 79, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 80, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 82, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 83, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 85, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 86, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 87, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 88, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 90, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 91, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 93, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 94, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 95, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 96, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 98, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 99, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 114, @@ -488,35 +488,35 @@ "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 176, @@ -600,21 +600,21 @@ "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 178, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 179, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 181, @@ -628,49 +628,49 @@ "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 183, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 184, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 185, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 188, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 189, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 190, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" } ] } \ No newline at end of file diff --git a/linter/test/es_object.ts.strict.json b/linter/test/es_object.ts.strict.json index 5c869e41f..4909f595f 100644 --- a/linter/test/es_object.ts.strict.json +++ b/linter/test/es_object.ts.strict.json @@ -26,231 +26,231 @@ "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 21, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 22, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 25, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 26, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 27, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 21, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 35, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 29, "column": 53, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 35, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 39, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 14, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 46, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 43, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 48, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 52, "column": 63, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 19, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 33, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 51, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 56, "column": 65, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 60, @@ -271,175 +271,175 @@ "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 64, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 64, "column": 50, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 66, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 67, "column": 17, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 70, "column": 13, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 71, "column": 15, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 77, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 78, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 79, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 80, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 82, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 83, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 85, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 86, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 87, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 88, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 90, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 91, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 93, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 94, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 95, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 96, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 98, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 99, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 103, @@ -453,28 +453,28 @@ "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 106, "column": 11, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 108, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 109, "column": 18, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 114, @@ -488,35 +488,35 @@ "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 119, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 119, "column": 36, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 136, "column": 25, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 136, "column": 38, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 148, @@ -530,63 +530,63 @@ "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, "column": 45, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, "column": 58, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 32, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 47, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 162, "column": 60, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 170, "column": 28, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 172, "column": 22, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 174, "column": 30, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 176, @@ -600,21 +600,21 @@ "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 178, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 179, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 181, @@ -628,49 +628,49 @@ "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 183, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 184, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 185, "column": 9, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 188, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 189, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 190, "column": 5, "problem": "EsObjectType", "suggest": "", - "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobject)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" } ] } \ No newline at end of file -- Gitee From 3a20dff2875172938857b71af3147523b791a899 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Tue, 31 Oct 2023 21:47:07 +0300 Subject: [PATCH 17/49] [ArkTS Linter] Fix #14228: relax 'class-as-object' rule when passing class to method call of the object of 'any' type. Change-Id: Iaf7ef42da534b78af554bc4111cc37a4576a6d0d Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 3 +- linter-4.2/test/class_as_object.ts | 8 ++- linter-4.2/test/class_as_object.ts.relax.json | 70 +++++++++++++++---- .../test/class_as_object.ts.strict.json | 70 +++++++++++++++---- linter-4.2/test/oh_modules/ohos_factory.ts | 15 ++++ linter/src/TypeScriptLinter.ts | 3 +- linter/test/class_as_object.ts | 8 ++- linter/test/class_as_object.ts.relax.json | 70 +++++++++++++++---- linter/test/class_as_object.ts.strict.json | 70 +++++++++++++++---- linter/test/oh_modules/ohos_factory.ts | 15 ++++ 10 files changed, 272 insertions(+), 60 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index bc9dd25c4..2dd4ea42e 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1515,7 +1515,8 @@ export class TypeScriptLinter { if (ts.isCallExpression(ctx.parent) || ts.isNewExpression(ctx.parent)) { let callee = ctx.parent.expression; - if (callee != ctx && this.tsUtils.hasLibraryType(callee)) { + if (callee != ctx && (this.tsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)) || + this.tsUtils.hasLibraryType(callee))) { return true; } } diff --git a/linter-4.2/test/class_as_object.ts b/linter-4.2/test/class_as_object.ts index 302432975..0cdc57d50 100644 --- a/linter-4.2/test/class_as_object.ts +++ b/linter-4.2/test/class_as_object.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Something, SomethingFactory, SomethingBar, Bar } from "./oh_modules/ohos_factory"; +import { Something, SomethingFactory, SomethingBar, Bar, Select } from "./oh_modules/ohos_factory"; class C { static a = 5; @@ -91,3 +91,9 @@ for (let item = 0; item < Object.keys(Color).length; item++) { foo2(() => C); export { C as H }; + +// #14228 +let data = new Select().from(C).eq('key').query(C); // Ok +invalid_func(C); // Ok +let a: any; +a.foo(C); // Ok \ No newline at end of file diff --git a/linter-4.2/test/class_as_object.ts.relax.json b/linter-4.2/test/class_as_object.ts.relax.json index fbae23bf5..7032f676c 100644 --- a/linter-4.2/test/class_as_object.ts.relax.json +++ b/linter-4.2/test/class_as_object.ts.relax.json @@ -15,72 +15,114 @@ { "line": 27, "column": 9, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 28, "column": 5, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 29, "column": 11, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 30, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 38, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 39, "column": 6, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 42, "column": 10, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 45, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 46, "column": 8, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 49, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 58, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 60, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 87, "column": 39, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 91, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" + }, + { + "line": 96, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 98, + "column": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/class_as_object.ts.strict.json b/linter-4.2/test/class_as_object.ts.strict.json index fbae23bf5..7032f676c 100644 --- a/linter-4.2/test/class_as_object.ts.strict.json +++ b/linter-4.2/test/class_as_object.ts.strict.json @@ -15,72 +15,114 @@ { "line": 27, "column": 9, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 28, "column": 5, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 29, "column": 11, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 30, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 38, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 39, "column": 6, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 42, "column": 10, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 45, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 46, "column": 8, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 49, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 58, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 60, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 87, "column": 39, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 91, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" + }, + { + "line": 96, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 98, + "column": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/oh_modules/ohos_factory.ts b/linter-4.2/test/oh_modules/ohos_factory.ts index e26c4c911..b4fc3d2d2 100644 --- a/linter-4.2/test/oh_modules/ohos_factory.ts +++ b/linter-4.2/test/oh_modules/ohos_factory.ts @@ -16,3 +16,18 @@ export declare class SomethingBar extends Something { } export declare class Bar { constructor(arg: { new(): T }); } + +export class Select { + public from(cls: any) { + return this; + } + + // we intentionally omit generic argument of 'Select', see #14228 + public eq(name: string): Select { + return this; + } + + public query(cls: any): Promise { + return cls.foo(); + } +} \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index a33d4740f..9c27f9a69 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1268,7 +1268,8 @@ export class TypeScriptLinter { if (ts.isCallExpression(ctx.parent) || ts.isNewExpression(ctx.parent)) { let callee = ctx.parent.expression; - if (callee != ctx && this.tsUtils.hasLibraryType(callee)) { + if (callee != ctx && (this.tsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)) || + this.tsUtils.hasLibraryType(callee))) { return true; } } diff --git a/linter/test/class_as_object.ts b/linter/test/class_as_object.ts index e91d6c024..8a13dbfaa 100644 --- a/linter/test/class_as_object.ts +++ b/linter/test/class_as_object.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Something, SomethingFactory, SomethingBar, Bar } from "./oh_modules/ohos_factory"; +import { Something, SomethingFactory, SomethingBar, Bar, Select } from "./oh_modules/ohos_factory"; class C { static a = 5 @@ -91,3 +91,9 @@ for (let item = 0; item < Object.keys(Color).length; item++) { foo2(() => C); export { C as H }; + +// #14228 +let data = new Select().from(C).eq('key').query(C); // Ok +invalid_func(C); // Ok +let a: any; +a.foo(C); // Ok \ No newline at end of file diff --git a/linter/test/class_as_object.ts.relax.json b/linter/test/class_as_object.ts.relax.json index 0fdca9072..75576a35f 100644 --- a/linter/test/class_as_object.ts.relax.json +++ b/linter/test/class_as_object.ts.relax.json @@ -15,72 +15,114 @@ { "line": 27, "column": 9, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 28, "column": 5, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 29, "column": 11, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 30, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 38, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 39, "column": 6, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 42, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 45, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 46, "column": 8, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 49, "column": 14, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 58, "column": 22, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 60, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 87, "column": 39, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 91, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" + }, + { + "line": 96, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 98, + "column": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter/test/class_as_object.ts.strict.json b/linter/test/class_as_object.ts.strict.json index 0fdca9072..75576a35f 100644 --- a/linter/test/class_as_object.ts.strict.json +++ b/linter/test/class_as_object.ts.strict.json @@ -15,72 +15,114 @@ { "line": 27, "column": 9, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 28, "column": 5, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 29, "column": 11, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 30, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 38, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 39, "column": 6, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 42, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 45, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 46, "column": 8, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 49, "column": 14, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 58, "column": 22, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 60, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 87, "column": 39, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 91, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" + }, + { + "line": 96, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 98, + "column": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter/test/oh_modules/ohos_factory.ts b/linter/test/oh_modules/ohos_factory.ts index e26c4c911..b4fc3d2d2 100644 --- a/linter/test/oh_modules/ohos_factory.ts +++ b/linter/test/oh_modules/ohos_factory.ts @@ -16,3 +16,18 @@ export declare class SomethingBar extends Something { } export declare class Bar { constructor(arg: { new(): T }); } + +export class Select { + public from(cls: any) { + return this; + } + + // we intentionally omit generic argument of 'Select', see #14228 + public eq(name: string): Select { + return this; + } + + public query(cls: any): Promise { + return cls.foo(); + } +} \ No newline at end of file -- Gitee From 6123c08ced8a09761b7fd00a95dd1c86869435c2 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Fri, 27 Oct 2023 16:43:27 +0300 Subject: [PATCH 18/49] [arkts-linter] fix #14183 - fix reporting of indexed access Signed-off-by: Nazarov Konstantin --- linter-4.2/docs/rules/recipe29.md | 10 +- linter-4.2/src/TypeScriptLinter.ts | 49 +++------- linter-4.2/src/Utils.ts | 92 +++++++++++------- linter-4.2/test/es_object.ts | 2 +- linter-4.2/test/es_object.ts.relax.json | 11 ++- linter-4.2/test/es_object.ts.strict.json | 32 ++++++- .../test/function_expression.ts.autofix.json | 8 ++ .../test/function_expression.ts.strict.json | 7 ++ linter-4.2/test/property_access_by_index.ts | 72 ++++++++++++++ .../property_access_by_index.ts.autofix.json | 24 +++++ .../property_access_by_index.ts.relax.json | 10 +- .../property_access_by_index.ts.strict.json | 21 +++++ linter-4.2/test/types.ts.autofix.json | 8 ++ linter-4.2/test/types.ts.strict.json | 7 ++ linter/docs/rules/recipe29.md | 10 +- linter/src/TypeScriptLinter.ts | 30 +++--- linter/src/utils/TsUtils.ts | 93 ++++++++++++------- linter/test/array_literals.ts | 1 - linter/test/es_object.ts | 2 +- linter/test/es_object.ts.relax.json | 11 ++- linter/test/es_object.ts.strict.json | 32 ++++++- .../test/function_expression.ts.autofix.json | 8 ++ .../test/function_expression.ts.strict.json | 7 ++ linter/test/property_access_by_index.ts | 72 ++++++++++++++ .../property_access_by_index.ts.autofix.json | 24 +++++ .../property_access_by_index.ts.relax.json | 10 +- .../property_access_by_index.ts.strict.json | 21 +++++ linter/test/types.ts.autofix.json | 8 ++ linter/test/types.ts.strict.json | 7 ++ 29 files changed, 545 insertions(+), 144 deletions(-) diff --git a/linter-4.2/docs/rules/recipe29.md b/linter-4.2/docs/rules/recipe29.md index c7be978d6..7af61c43e 100644 --- a/linter-4.2/docs/rules/recipe29.md +++ b/linter-4.2/docs/rules/recipe29.md @@ -10,9 +10,13 @@ that are either declared in the class, or accessible via inheritance. Accessing any other fields is prohibited, and causes compile-time errors. To access a field, use ``obj.field`` syntax, indexed access (``obj["field"]``) -is not supported. An exception are all typed arrays from the standard library -(for example, ``Int32Array``), which support access to their elements through -``container[index]`` syntax. +is not supported. An exception are: + +- All typed arrays from the standard library (for example, ``Int32Array``), which +support access to their elements through ``container[index]`` syntax. +- Tuples. +- Records. +- Enums. ## TypeScript diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 2dd4ea42e..dbed0dc62 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -617,7 +617,7 @@ export class TypeScriptLinter { ); if ( !throwExprType.isClassOrInterface() || - !this.tsUtils.isDerivedFrom(throwExprType, CheckType.Error) + !this.tsUtils.isOrDerivedFrom(throwExprType, this.tsUtils.isStdErrorType) ) { this.incrementCounters(node, FaultID.ThrowStatement, false, undefined); } @@ -1600,34 +1600,20 @@ export class TypeScriptLinter { undefined, ts.NodeBuilderFlags.None ); - const checkClassOrInterface = tsElemAccessBaseExprType.isClassOrInterface() && - !this.tsUtils.isGenericArrayType(tsElemAccessBaseExprType) && - !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); - const checkThisOrSuper = this.tsUtils.isThisOrSuperExpr(tsElementAccessExpr.expression) && - !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); - - // if (this.tsUtils.isEnumType(tsElemAccessBaseExprType)) { - // implement argument expression type check - // let argType = this.tsTypeChecker.getTypeAtLocation(tsElementAccessExpr.argumentExpression); - // if (argType.aliasSymbol == this.tsUtils.trueSymbolAtLocation(tsElementAccessExpr.expression)) { - // return; - // } - // check if constant EnumMember inferred ... - // this.incrementCounters(node, FaultID.PropertyAccessByIndex, autofixable, autofix); - // } if ( !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && - !this.tsUtils.isTypedArray(tsElemAccessBaseExprTypeNode) && - ( checkClassOrInterface || - this.tsUtils.isObjectLiteralType(tsElemAccessBaseExprType) || checkThisOrSuper) + !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isArray) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isTuple) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStdRecordType) && + !this.tsUtils.isEnumType(tsElemAccessBaseExprType) && + !this.tsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) ) { let autofix = Autofixer.fixPropertyAccessByIndex(node); const autofixable = autofix != undefined; - if ( - !this.autofixesInfo.shouldAutofix(node, FaultID.PropertyAccessByIndex) - ) + if (!this.autofixesInfo.shouldAutofix(node, FaultID.PropertyAccessByIndex)) { autofix = undefined; - + } this.incrementCounters( node, FaultID.PropertyAccessByIndex, @@ -1998,21 +1984,8 @@ export class TypeScriptLinter { spreadElemNode.expression ); if (spreadExprType) { - const spreadExprTypeNode = this.tsTypeChecker.typeToTypeNode( - spreadExprType, - undefined, - ts.NodeBuilderFlags.None - ); - if ( - spreadExprTypeNode !== undefined && - (ts.isCallLikeExpression(node.parent) || - ts.isArrayLiteralExpression(node.parent)) - ) { - if ( - ts.isArrayTypeNode(spreadExprTypeNode) || - this.tsUtils.isTypedArray(spreadExprTypeNode) || - this.tsUtils.isDerivedFrom(spreadExprType, CheckType.Array) - ) { + if (ts.isCallLikeExpression(node.parent) || ts.isArrayLiteralExpression(node.parent)) { + if (this.tsUtils.isOrDerivedFrom(spreadExprType, this.tsUtils.isArray)) { return; } } diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 5f519cba0..c2f32b89a 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -94,13 +94,7 @@ export function isAssignmentOperator(tsBinOp: ts.BinaryOperatorToken): boolean { return tsBinOp.kind >= ts.SyntaxKind.FirstAssignment && tsBinOp.kind <= ts.SyntaxKind.LastAssignment; } -export enum CheckType { - Array, - String = "String", - Set = "Set", - Map = "Map", - Error = "Error", -}; +export type CheckType = ((t: ts.Type) => boolean); export class TsUtils { static readonly ES_OBJECT = 'ESObject' @@ -205,13 +199,6 @@ export class TsUtils { constructor(private tsTypeChecker: ts.TypeChecker, private testMode: boolean) { } - public isTypedArray(tsType: ts.TypeNode | undefined): boolean { - if (tsType === undefined || !ts.isTypeReferenceNode(tsType)) { - return false; - } - return TsUtils.TYPED_ARRAYS.includes(this.entityNameToString(tsType.typeName)); - } - public isType(tsType: ts.TypeNode | undefined, checkType: string): boolean { if (tsType === undefined || !ts.isTypeReferenceNode(tsType)) { return false; @@ -451,24 +438,48 @@ export class TsUtils { ); } + public isTypedArray(tsType: ts.Type): boolean { + const symbol = tsType.symbol; + if (!symbol) { + return false; + } + const name = this.tsTypeChecker.getFullyQualifiedName(symbol); + return this.isGlobalSymbol(symbol) && TsUtils.TYPED_ARRAYS.includes(name); + } + + public isArray(tsType: ts.Type): boolean { + return this.isGenericArrayType(tsType) || this.isTypedArray(tsType); + } + + public isTuple(tsType: ts.Type): boolean { + return this.isTypeReference(tsType) && !!(tsType.objectFlags & ts.ObjectFlags.Tuple); + } + // does something similar to relatedByInheritanceOrIdentical function - public isDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { - if (this.isTypeReference(tsType) && tsType.target !== tsType) tsType = tsType.target; + public isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { + if (this.isTypeReference(tsType) && tsType.target !== tsType) { + tsType = tsType.target; + } - const tsTypeNode = this.tsTypeChecker.typeToTypeNode(tsType, undefined, ts.NodeBuilderFlags.None); - if (checkType == CheckType.Array && (this.isGenericArrayType(tsType) || this.isTypedArray(tsTypeNode))) - return true; - if (checkType != CheckType.Array && this.isType(tsTypeNode, checkType.toString())) + if (checkType.call(this, tsType)) { return true; - if (!tsType.symbol || !tsType.symbol.declarations) return false; + } - for (let tsTypeDecl of tsType.symbol.declarations) { - if ( - (!ts.isClassDeclaration(tsTypeDecl) && !ts.isInterfaceDeclaration(tsTypeDecl)) || - !tsTypeDecl.heritageClauses - ) continue; + if (!tsType.symbol || !tsType.symbol.declarations) { + return false; + } + + for (const tsTypeDecl of tsType.symbol.declarations) { + if (!ts.isClassDeclaration(tsTypeDecl) && !ts.isInterfaceDeclaration(tsTypeDecl)) { + continue; + } + if (!tsTypeDecl.heritageClauses) { + continue; + } for (let heritageClause of tsTypeDecl.heritageClauses) { - if (this.processParentTypesCheck(heritageClause.types, checkType)) return true; + if (this.processParentTypesCheck(heritageClause.types, checkType)) { + return true; + } } } @@ -771,10 +782,14 @@ export class TsUtils { } private processParentTypesCheck(parentTypes: ts.NodeArray, checkType: CheckType): boolean { - for (let baseTypeExpr of parentTypes) { + for (const baseTypeExpr of parentTypes) { let baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeExpr); - if (this.isTypeReference(baseType) && baseType.target !== baseType) baseType = baseType.target; - if (baseType && this.isDerivedFrom(baseType, checkType)) return true; + if (this.isTypeReference(baseType) && baseType.target !== baseType) { + baseType = baseType.target; + } + if (baseType && this.isOrDerivedFrom(baseType, checkType)) { + return true; + } } return false; } @@ -1141,6 +1156,15 @@ export class TsUtils { return false; } + public isStdErrorType(type: ts.Type): boolean { + const symbol = type.symbol; + if (!symbol) { + return false; + } + const name = this.tsTypeChecker.getFullyQualifiedName(symbol); + return name === 'Error' && this.isGlobalSymbol(symbol); + } + public isStdPartialType(type: ts.Type): boolean { const sym = type.aliasSymbol; return !!sym && sym.getName() === 'Partial' && this.isGlobalSymbol(sym); @@ -1191,11 +1215,11 @@ export class TsUtils { const isEts = (ext === '.ets'); const isTs = (ext === '.ts' && !srcFile.isDeclarationFile); const isStatic = (isEts || (isTs && this.testMode)) && !isThirdPartyCode; + const isStdLib = TsUtils.STANDARD_LIBRARIES.includes(path.basename(fileName).toLowerCase()); // We still need to confirm support for certain API from the // TypeScript standard library in ArkTS. Thus, for now do not // count standard library modules. - return !isStatic && - !TsUtils.STANDARD_LIBRARIES.includes(path.basename(srcFile.fileName).toLowerCase()); + return !isStatic && !isStdLib; } return false; @@ -1353,8 +1377,8 @@ export class TsUtils { return false; } - public isEsObjectType(typeNode: ts.TypeNode): boolean { - return ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName) && + public isEsObjectType(typeNode: ts.TypeNode | undefined): boolean { + return !!typeNode && ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName) && typeNode.typeName.text == TsUtils.ES_OBJECT; } diff --git a/linter-4.2/test/es_object.ts b/linter-4.2/test/es_object.ts index 445b5c0c0..8b62f20f8 100644 --- a/linter-4.2/test/es_object.ts +++ b/linter-4.2/test/es_object.ts @@ -145,7 +145,7 @@ foo4([2, 3]) foo5([2, 3]) foo4(["str1", "str2"]) foo5(["str1", "str2"]) -let n = new ESObject[0] +let n: ESObject; n = null foo4(n) diff --git a/linter-4.2/test/es_object.ts.relax.json b/linter-4.2/test/es_object.ts.relax.json index 7450fc30f..5bab1a3ee 100644 --- a/linter-4.2/test/es_object.ts.relax.json +++ b/linter-4.2/test/es_object.ts.relax.json @@ -521,9 +521,16 @@ { "line": 148, "column": 5, - "problem": "AnyType", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" + }, + { + "line": 149, + "column": 1, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, diff --git a/linter-4.2/test/es_object.ts.strict.json b/linter-4.2/test/es_object.ts.strict.json index 4909f595f..c0ef7ba37 100644 --- a/linter-4.2/test/es_object.ts.strict.json +++ b/linter-4.2/test/es_object.ts.strict.json @@ -329,6 +329,13 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, + { + "line": 79, + "column": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 79, "column": 5, @@ -521,9 +528,16 @@ { "line": 148, "column": 5, - "problem": "AnyType", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" + }, + { + "line": 149, + "column": 1, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, @@ -651,6 +665,13 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, + { + "line": 188, + "column": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 188, "column": 5, @@ -658,6 +679,13 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, + { + "line": 189, + "column": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 189, "column": 5, diff --git a/linter-4.2/test/function_expression.ts.autofix.json b/linter-4.2/test/function_expression.ts.autofix.json index c571fa05a..e005781ad 100644 --- a/linter-4.2/test/function_expression.ts.autofix.json +++ b/linter-4.2/test/function_expression.ts.autofix.json @@ -267,6 +267,14 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, + { + "line": 82, + "column": 19, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 82, "column": 19, diff --git a/linter-4.2/test/function_expression.ts.strict.json b/linter-4.2/test/function_expression.ts.strict.json index fe4750449..48723e4cd 100644 --- a/linter-4.2/test/function_expression.ts.strict.json +++ b/linter-4.2/test/function_expression.ts.strict.json @@ -168,6 +168,13 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, + { + "line": 82, + "column": 19, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 82, "column": 19, diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index 3911b881b..407d70553 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -28,3 +28,75 @@ function test() { SetProperty(a, 'u', 'def'); return GetProperty(a, 'v') + GetProperty(a, 'u'); } + +let ar1 = [1, 2, 3, 4]; +let ar2 = [1, '2', 3, 4]; +let ar3: number[] = []; + +ar1[2]; +ar2[2]; +ar3[2]; + +const r0 = [1, 2, 3][1]; +let r1 = [1, 2, 3, 4][0] +let r2 = [1, '2', 3, 4][0] + +function fobject1(o: object) { + o['j'] +} + +function fobject2(o: Object) { + o['k'] +} + +let array1 = [0,1] +let array2 = [1,2,3,4,5] +let array3: number[] = [1,2,3,4,5] +let array4: Array = [1,2,3,4,5] +let array5 = new Array(10) +let array6 = new Int8Array(10) +let array7 = new Uint8Array(10) +let array8 = new Uint8ClampedArray(10) +let array9 = new Int16Array(10) +let array10 = new Uint16Array(10) +let array11 = new Int32Array(10) +let array12 = new Uint32Array(10) +let array13 = new Float32Array(10) +let array14 = new Float64Array(10) +let array15 = new BigInt64Array(10) +let array16 = new BigUint64Array(10) + +array1[0]; +array2[0]; +array3[0]; +array4[0]; +array5[0]; +array6[0]; +array7[0]; +array8[0]; +array9[0]; +array10[0]; +array11[0]; +array12[0]; +array13[0]; +array14[0]; +array15[0]; +array16[0]; + +function fff1(r: Record) { + r['bob'] +} + +enum CCCCCCCCC { + KATE, + BOB, + ROB, +} + +CCCCCCCCC['KATE'] +CCCCCCCCC['BOB'] +CCCCCCCCC['ROB'] + +CCCCCCCCC[CCCCCCCCC.KATE] +CCCCCCCCC[CCCCCCCCC.BOB] +CCCCCCCCC[CCCCCCCCC.ROB] diff --git a/linter-4.2/test/property_access_by_index.ts.autofix.json b/linter-4.2/test/property_access_by_index.ts.autofix.json index 90d724616..2c4552959 100644 --- a/linter-4.2/test/property_access_by_index.ts.autofix.json +++ b/linter-4.2/test/property_access_by_index.ts.autofix.json @@ -29,6 +29,30 @@ "autofixable": false, "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 45, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 49, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 56, + "column": 5, + "problem": "AnyType", + "autofixable": false, + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.relax.json b/linter-4.2/test/property_access_by_index.ts.relax.json index e7d2d6779..6cefe0230 100644 --- a/linter-4.2/test/property_access_by_index.ts.relax.json +++ b/linter-4.2/test/property_access_by_index.ts.relax.json @@ -13,5 +13,13 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "nodes": [] + "nodes": [ + { + "line": 56, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + } + ] } \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.strict.json b/linter-4.2/test/property_access_by_index.ts.strict.json index 816f247c7..6bb2b0400 100644 --- a/linter-4.2/test/property_access_by_index.ts.strict.json +++ b/linter-4.2/test/property_access_by_index.ts.strict.json @@ -27,6 +27,27 @@ "problem": "PropertyAccessByIndex", "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 45, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 49, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 56, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/types.ts.autofix.json b/linter-4.2/test/types.ts.autofix.json index 7833b9da0..3263fe492 100644 --- a/linter-4.2/test/types.ts.autofix.json +++ b/linter-4.2/test/types.ts.autofix.json @@ -214,6 +214,14 @@ "suggest": "", "rule": "\"in\" operator is not supported (arkts-no-in)" }, + { + "line": 78, + "column": 5, + "problem": "PropertyAccessByIndex", + "autofixable": false, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 92, "column": 22, diff --git a/linter-4.2/test/types.ts.strict.json b/linter-4.2/test/types.ts.strict.json index 12af0241f..509711199 100644 --- a/linter-4.2/test/types.ts.strict.json +++ b/linter-4.2/test/types.ts.strict.json @@ -189,6 +189,13 @@ "suggest": "", "rule": "\"in\" operator is not supported (arkts-no-in)" }, + { + "line": 78, + "column": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 92, "column": 22, diff --git a/linter/docs/rules/recipe29.md b/linter/docs/rules/recipe29.md index c7be978d6..7af61c43e 100644 --- a/linter/docs/rules/recipe29.md +++ b/linter/docs/rules/recipe29.md @@ -10,9 +10,13 @@ that are either declared in the class, or accessible via inheritance. Accessing any other fields is prohibited, and causes compile-time errors. To access a field, use ``obj.field`` syntax, indexed access (``obj["field"]``) -is not supported. An exception are all typed arrays from the standard library -(for example, ``Int32Array``), which support access to their elements through -``container[index]`` syntax. +is not supported. An exception are: + +- All typed arrays from the standard library (for example, ``Int32Array``), which +support access to their elements through ``container[index]`` syntax. +- Tuples. +- Records. +- Enums. ## TypeScript diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 9c27f9a69..2280f0e45 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -527,7 +527,7 @@ export class TypeScriptLinter { private handleThrowStatement(node: ts.Node) { let throwStmt = node as ts.ThrowStatement; let throwExprType = this.tsTypeChecker.getTypeAtLocation(throwStmt.expression); - if (!throwExprType.isClassOrInterface() || !this.tsUtils.isDerivedFrom(throwExprType, CheckType.Error)) { + if (!throwExprType.isClassOrInterface() || !this.tsUtils.isOrDerivedFrom(throwExprType, this.tsUtils.isStdErrorType)) { this.incrementCounters(node, FaultID.ThrowStatement, false, undefined); } } @@ -1310,24 +1310,20 @@ export class TypeScriptLinter { const tsElementAccessExpr = node as ts.ElementAccessExpression; const tsElemAccessBaseExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression); const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode(tsElemAccessBaseExprType, undefined, ts.NodeBuilderFlags.None); - - const checkClassOrInterface = tsElemAccessBaseExprType.isClassOrInterface() && - !this.tsUtils.isGenericArrayType(tsElemAccessBaseExprType) && - !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); - const checkThisOrSuper = this.tsUtils.isThisOrSuperExpr(tsElementAccessExpr.expression) && - !this.tsUtils.isDerivedFrom(tsElemAccessBaseExprType, CheckType.Array); - - // implement check for enum argument expression - if ( - !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && !this.tsUtils.isTypedArray(tsElemAccessBaseExprTypeNode) && - (checkClassOrInterface || this.tsUtils.isObjectLiteralType(tsElemAccessBaseExprType) || checkThisOrSuper) + !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && + !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isArray) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isTuple) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStdRecordType) && + !this.tsUtils.isEnumType(tsElemAccessBaseExprType) && + !this.tsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) ) { let autofix = Autofixer.fixPropertyAccessByIndex(node); const autofixable = autofix != undefined; - if (!this.autofixesInfo.shouldAutofix(node, FaultID.PropertyAccessByIndex)) + if (!this.autofixesInfo.shouldAutofix(node, FaultID.PropertyAccessByIndex)) { autofix = undefined; - + } this.incrementCounters(node, FaultID.PropertyAccessByIndex, autofixable, autofix); } @@ -1669,10 +1665,8 @@ export class TypeScriptLinter { let spreadElemNode = node as ts.SpreadElement; let spreadExprType = this.tsTypeChecker.getTypeAtLocation(spreadElemNode.expression); if (spreadExprType) { - const spreadExprTypeNode = this.tsTypeChecker.typeToTypeNode(spreadExprType, undefined, ts.NodeBuilderFlags.None); - if (spreadExprTypeNode !== undefined && (ts.isCallLikeExpression(node.parent) || ts.isArrayLiteralExpression(node.parent))) { - if (ts.isArrayTypeNode(spreadExprTypeNode) || this.tsUtils.isTypedArray(spreadExprTypeNode) || - this.tsUtils.isDerivedFrom(spreadExprType, CheckType.Array)) { + if (ts.isCallLikeExpression(node.parent) || ts.isArrayLiteralExpression(node.parent)) { + if (this.tsUtils.isOrDerivedFrom(spreadExprType, this.tsUtils.isArray)) { return } } diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index 39d31eed8..5bff6b0aa 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -25,24 +25,11 @@ import { pathContainsDirectory } from './functions/PathHelper'; import { ARKTS_IGNORE_DIRS, ARKTS_IGNORE_FILES } from './consts/ArktsIgnorePaths'; import { isAssignmentOperator } from './functions/isAssignmentOperator'; -export enum CheckType { - Array, - String = 'String', - Set = 'Set', - Map = 'Map', - Error = 'Error' -}; +export type CheckType = ((t: ts.Type) => boolean); export class TsUtils { constructor(private tsTypeChecker: ts.TypeChecker, private testMode: boolean, private advancedClassChecks: boolean) { } - public isTypedArray(tsType: ts.TypeNode | undefined): boolean { - if (tsType === undefined || !ts.isTypeReferenceNode(tsType)) { - return false; - } - return TYPED_ARRAYS.includes(this.entityNameToString(tsType.typeName)); - } - public isType(tsType: ts.TypeNode | undefined, checkType: string): boolean { if (tsType === undefined || !ts.isTypeReferenceNode(tsType)) { return false; @@ -282,24 +269,47 @@ export class TsUtils { ); } + public isTypedArray(tsType: ts.Type): boolean { + const symbol = tsType.symbol; + if (!symbol) { + return false; + } + const name = this.tsTypeChecker.getFullyQualifiedName(symbol); + return this.isGlobalSymbol(symbol) && TYPED_ARRAYS.includes(name); + } + + public isArray(tsType: ts.Type): boolean { + return this.isGenericArrayType(tsType) || this.isTypedArray(tsType); + } + + public isTuple(tsType: ts.Type): boolean { + return this.isTypeReference(tsType) && !!(tsType.objectFlags & ts.ObjectFlags.Tuple); + } + // does something similar to relatedByInheritanceOrIdentical function - public isDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { - if (this.isTypeReference(tsType) && tsType.target !== tsType) tsType = tsType.target; + public isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { + if (this.isTypeReference(tsType) && tsType.target !== tsType) { + tsType = tsType.target; + } - const tsTypeNode = this.tsTypeChecker.typeToTypeNode(tsType, undefined, ts.NodeBuilderFlags.None); - if (checkType == CheckType.Array && (this.isGenericArrayType(tsType) || this.isTypedArray(tsTypeNode))) - return true; - if (checkType != CheckType.Array && this.isType(tsTypeNode, checkType.toString())) + if (checkType.call(this, tsType)) { return true; - if (!tsType.symbol || !tsType.symbol.declarations) return false; + } - for (let tsTypeDecl of tsType.symbol.declarations) { - if ( - (!ts.isClassDeclaration(tsTypeDecl) && !ts.isInterfaceDeclaration(tsTypeDecl)) || - !tsTypeDecl.heritageClauses - ) continue; + if (!tsType.symbol || !tsType.symbol.declarations) { + return false; + } + + for (const tsTypeDecl of tsType.symbol.declarations) { + const isClassOrInterfaceDecl = ts.isClassDeclaration(tsTypeDecl) || ts.isInterfaceDeclaration(tsTypeDecl); + const isDerived = isClassOrInterfaceDecl && !!tsTypeDecl.heritageClauses; + if (!isDerived) { + continue; + } for (let heritageClause of tsTypeDecl.heritageClauses) { - if (this.processParentTypesCheck(heritageClause.types, checkType)) return true; + if (this.processParentTypesCheck(heritageClause.types, checkType)) { + return true; + } } } @@ -595,10 +605,14 @@ export class TsUtils { } private processParentTypesCheck(parentTypes: ts.NodeArray, checkType: CheckType): boolean { - for (let baseTypeExpr of parentTypes) { + for (const baseTypeExpr of parentTypes) { let baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeExpr); - if (this.isTypeReference(baseType) && baseType.target !== baseType) baseType = baseType.target; - if (baseType && this.isDerivedFrom(baseType, checkType)) return true; + if (this.isTypeReference(baseType) && baseType.target !== baseType) { + baseType = baseType.target; + } + if (baseType && this.isOrDerivedFrom(baseType, checkType)) { + return true; + } } return false; } @@ -945,6 +959,15 @@ export class TsUtils { return false; } + public isStdErrorType(type: ts.Type): boolean { + const symbol = type.symbol; + if (!symbol) { + return false; + } + const name = this.tsTypeChecker.getFullyQualifiedName(symbol); + return name === 'Error' && this.isGlobalSymbol(symbol); + } + public isStdPartialType(type: ts.Type): boolean { const sym = type.aliasSymbol; return !!sym && sym.getName() === 'Partial' && this.isGlobalSymbol(sym); @@ -994,11 +1017,11 @@ export class TsUtils { const isEts = (ext === '.ets'); const isTs = (ext === '.ts' && !srcFile.isDeclarationFile); const isStatic = (isEts || (isTs && this.testMode)) && !isThirdPartyCode; + const isStdLib = STANDARD_LIBRARIES.includes(path.basename(fileName).toLowerCase()); // We still need to confirm support for certain API from the // TypeScript standard library in ArkTS. Thus, for now do not - // count standard library modules. - return !isStatic && - !STANDARD_LIBRARIES.includes(path.basename(fileName).toLowerCase()); + // count standard library modules as dynamic. + return !isStatic && !isStdLib; } return false; } @@ -1110,8 +1133,8 @@ export class TsUtils { return false; } - public isEsObjectType(typeNode: ts.TypeNode): boolean { - return ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName) && + public isEsObjectType(typeNode: ts.TypeNode | undefined): boolean { + return !!typeNode && ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName) && typeNode.typeName.text == ES_OBJECT; } diff --git a/linter/test/array_literals.ts b/linter/test/array_literals.ts index 4c5e9de19..5889b08ba 100644 --- a/linter/test/array_literals.ts +++ b/linter/test/array_literals.ts @@ -124,4 +124,3 @@ class P { let a1 = [ { n:1, s:"1" } as P, { n:2, s:"2" } as P ]; // OK let a2: P[] = [ { n:3, s:"3" }, { n:4, s:"4" } ]; // OK let a3 = [ { n:1, s:"1" }, { n:2, s:"2" } ]; // NOT OK - \ No newline at end of file diff --git a/linter/test/es_object.ts b/linter/test/es_object.ts index 445b5c0c0..cd1e530ca 100644 --- a/linter/test/es_object.ts +++ b/linter/test/es_object.ts @@ -145,7 +145,7 @@ foo4([2, 3]) foo5([2, 3]) foo4(["str1", "str2"]) foo5(["str1", "str2"]) -let n = new ESObject[0] +let n: ESObject n = null foo4(n) diff --git a/linter/test/es_object.ts.relax.json b/linter/test/es_object.ts.relax.json index 7450fc30f..5bab1a3ee 100644 --- a/linter/test/es_object.ts.relax.json +++ b/linter/test/es_object.ts.relax.json @@ -521,9 +521,16 @@ { "line": 148, "column": 5, - "problem": "AnyType", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" + }, + { + "line": 149, + "column": 1, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, diff --git a/linter/test/es_object.ts.strict.json b/linter/test/es_object.ts.strict.json index 4909f595f..c0ef7ba37 100644 --- a/linter/test/es_object.ts.strict.json +++ b/linter/test/es_object.ts.strict.json @@ -329,6 +329,13 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, + { + "line": 79, + "column": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 79, "column": 5, @@ -521,9 +528,16 @@ { "line": 148, "column": 5, - "problem": "AnyType", + "problem": "EsObjectType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" + }, + { + "line": 149, + "column": 1, + "problem": "EsObjectType", + "suggest": "", + "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, { "line": 154, @@ -651,6 +665,13 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, + { + "line": 188, + "column": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 188, "column": 5, @@ -658,6 +679,13 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, + { + "line": 189, + "column": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 189, "column": 5, diff --git a/linter/test/function_expression.ts.autofix.json b/linter/test/function_expression.ts.autofix.json index c571fa05a..e005781ad 100644 --- a/linter/test/function_expression.ts.autofix.json +++ b/linter/test/function_expression.ts.autofix.json @@ -267,6 +267,14 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, + { + "line": 82, + "column": 19, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 82, "column": 19, diff --git a/linter/test/function_expression.ts.strict.json b/linter/test/function_expression.ts.strict.json index fe4750449..48723e4cd 100644 --- a/linter/test/function_expression.ts.strict.json +++ b/linter/test/function_expression.ts.strict.json @@ -168,6 +168,13 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, + { + "line": 82, + "column": 19, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 82, "column": 19, diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index 3911b881b..407d70553 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -28,3 +28,75 @@ function test() { SetProperty(a, 'u', 'def'); return GetProperty(a, 'v') + GetProperty(a, 'u'); } + +let ar1 = [1, 2, 3, 4]; +let ar2 = [1, '2', 3, 4]; +let ar3: number[] = []; + +ar1[2]; +ar2[2]; +ar3[2]; + +const r0 = [1, 2, 3][1]; +let r1 = [1, 2, 3, 4][0] +let r2 = [1, '2', 3, 4][0] + +function fobject1(o: object) { + o['j'] +} + +function fobject2(o: Object) { + o['k'] +} + +let array1 = [0,1] +let array2 = [1,2,3,4,5] +let array3: number[] = [1,2,3,4,5] +let array4: Array = [1,2,3,4,5] +let array5 = new Array(10) +let array6 = new Int8Array(10) +let array7 = new Uint8Array(10) +let array8 = new Uint8ClampedArray(10) +let array9 = new Int16Array(10) +let array10 = new Uint16Array(10) +let array11 = new Int32Array(10) +let array12 = new Uint32Array(10) +let array13 = new Float32Array(10) +let array14 = new Float64Array(10) +let array15 = new BigInt64Array(10) +let array16 = new BigUint64Array(10) + +array1[0]; +array2[0]; +array3[0]; +array4[0]; +array5[0]; +array6[0]; +array7[0]; +array8[0]; +array9[0]; +array10[0]; +array11[0]; +array12[0]; +array13[0]; +array14[0]; +array15[0]; +array16[0]; + +function fff1(r: Record) { + r['bob'] +} + +enum CCCCCCCCC { + KATE, + BOB, + ROB, +} + +CCCCCCCCC['KATE'] +CCCCCCCCC['BOB'] +CCCCCCCCC['ROB'] + +CCCCCCCCC[CCCCCCCCC.KATE] +CCCCCCCCC[CCCCCCCCC.BOB] +CCCCCCCCC[CCCCCCCCC.ROB] diff --git a/linter/test/property_access_by_index.ts.autofix.json b/linter/test/property_access_by_index.ts.autofix.json index 90d724616..2c4552959 100644 --- a/linter/test/property_access_by_index.ts.autofix.json +++ b/linter/test/property_access_by_index.ts.autofix.json @@ -29,6 +29,30 @@ "autofixable": false, "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 45, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 49, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 56, + "column": 5, + "problem": "AnyType", + "autofixable": false, + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.relax.json b/linter/test/property_access_by_index.ts.relax.json index e7d2d6779..6cefe0230 100644 --- a/linter/test/property_access_by_index.ts.relax.json +++ b/linter/test/property_access_by_index.ts.relax.json @@ -13,5 +13,13 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "nodes": [] + "nodes": [ + { + "line": 56, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + } + ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.strict.json b/linter/test/property_access_by_index.ts.strict.json index 816f247c7..6bb2b0400 100644 --- a/linter/test/property_access_by_index.ts.strict.json +++ b/linter/test/property_access_by_index.ts.strict.json @@ -27,6 +27,27 @@ "problem": "PropertyAccessByIndex", "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 45, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 49, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 56, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter/test/types.ts.autofix.json b/linter/test/types.ts.autofix.json index 7833b9da0..3263fe492 100644 --- a/linter/test/types.ts.autofix.json +++ b/linter/test/types.ts.autofix.json @@ -214,6 +214,14 @@ "suggest": "", "rule": "\"in\" operator is not supported (arkts-no-in)" }, + { + "line": 78, + "column": 5, + "problem": "PropertyAccessByIndex", + "autofixable": false, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 92, "column": 22, diff --git a/linter/test/types.ts.strict.json b/linter/test/types.ts.strict.json index 12af0241f..509711199 100644 --- a/linter/test/types.ts.strict.json +++ b/linter/test/types.ts.strict.json @@ -189,6 +189,13 @@ "suggest": "", "rule": "\"in\" operator is not supported (arkts-no-in)" }, + { + "line": 78, + "column": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, { "line": 92, "column": 22, -- Gitee From 214d1b1e0e87d8b259f85c7c905abe6f2f958fa1 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Fri, 27 Oct 2023 11:24:59 +0300 Subject: [PATCH 19/49] [ArkTS Linter] #14184: Do not report 'Class used as object' for 'property access' on enum in namespace. Change-Id: I098a6d0ece73add8c0f259aa62b9389e71b38adc Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 14 +++++++++---- linter-4.2/test/class_as_object.ts | 21 ++++++++++++++++++- linter-4.2/test/class_as_object.ts.relax.json | 7 +++++++ .../test/class_as_object.ts.strict.json | 7 +++++++ linter/src/TypeScriptLinter.ts | 5 +++-- .../functions/identiferUseInValueContext.ts | 7 +++---- linter/test/class_as_object.ts | 21 ++++++++++++++++++- linter/test/class_as_object.ts.relax.json | 7 +++++++ linter/test/class_as_object.ts.strict.json | 7 +++++++ 9 files changed, 84 insertions(+), 12 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index dbed0dc62..b83c5eba8 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1515,8 +1515,9 @@ export class TypeScriptLinter { if (ts.isCallExpression(ctx.parent) || ts.isNewExpression(ctx.parent)) { let callee = ctx.parent.expression; - if (callee != ctx && (this.tsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)) || - this.tsUtils.hasLibraryType(callee))) { + const isAny = this.tsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)); + const isDynamic = isAny || this.tsUtils.hasLibraryType(callee); + if (callee != ctx && isDynamic) { return true; } } @@ -1567,8 +1568,7 @@ export class TypeScriptLinter { // treat TypeQuery as valid because it's already forbidden (FaultID.TypeQuery) (ts.isTypeNode(parent) && !ts.isTypeOfExpression(parent)) || // ElementAccess is allowed for enum types - (ts.isElementAccessExpression(parent) - && (parent as ts.ElementAccessExpression).expression == ident && (tsSym.flags & ts.SymbolFlags.Enum)) || + this.isEnumPropAccess(ident, tsSym, parent) || ts.isExpressionWithTypeArguments(parent) || ts.isExportAssignment(parent) || ts.isExportSpecifier(parent) || @@ -1592,6 +1592,12 @@ export class TypeScriptLinter { ); } + private isEnumPropAccess(ident: ts.Identifier, tsSym: ts.Symbol, context: ts.Node): boolean { + return ts.isElementAccessExpression(context) && !!(tsSym.flags & ts.SymbolFlags.Enum) && + (context.expression == ident || + (ts.isPropertyAccessExpression(context.expression) && context.expression.name == ident)); + } + private handleElementAccessExpression(node: ts.Node) { const tsElementAccessExpr = node as ts.ElementAccessExpression; const tsElemAccessBaseExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression); diff --git a/linter-4.2/test/class_as_object.ts b/linter-4.2/test/class_as_object.ts index 0cdc57d50..195c076ec 100644 --- a/linter-4.2/test/class_as_object.ts +++ b/linter-4.2/test/class_as_object.ts @@ -96,4 +96,23 @@ export { C as H }; let data = new Select().from(C).eq('key').query(C); // Ok invalid_func(C); // Ok let a: any; -a.foo(C); // Ok \ No newline at end of file +a.foo(C); // Ok + +let col = 'WHITE'; +console.log(Color[col]) + +// #14184 +namespace NS { + export enum E { + A = 'A', + B = 'B', + C = 'C' + } +} + +let s: string = 'B'; +let s2: string = NS.E[s]; + +for (let item = 0; item < Object.keys(NS.E).length; item++) { + console.log(item); +} \ No newline at end of file diff --git a/linter-4.2/test/class_as_object.ts.relax.json b/linter-4.2/test/class_as_object.ts.relax.json index 7032f676c..87b0d7889 100644 --- a/linter-4.2/test/class_as_object.ts.relax.json +++ b/linter-4.2/test/class_as_object.ts.relax.json @@ -123,6 +123,13 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 116, + "column": 42, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/class_as_object.ts.strict.json b/linter-4.2/test/class_as_object.ts.strict.json index 7032f676c..87b0d7889 100644 --- a/linter-4.2/test/class_as_object.ts.strict.json +++ b/linter-4.2/test/class_as_object.ts.strict.json @@ -123,6 +123,13 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 116, + "column": 42, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" } ] } \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 2280f0e45..be639762e 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1268,8 +1268,9 @@ export class TypeScriptLinter { if (ts.isCallExpression(ctx.parent) || ts.isNewExpression(ctx.parent)) { let callee = ctx.parent.expression; - if (callee != ctx && (this.tsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)) || - this.tsUtils.hasLibraryType(callee))) { + const isAny = this.tsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)); + const isDynamic = isAny || this.tsUtils.hasLibraryType(callee); + if (callee != ctx && isDynamic) { return true; } } diff --git a/linter/src/utils/functions/identiferUseInValueContext.ts b/linter/src/utils/functions/identiferUseInValueContext.ts index 43c1389a9..96a762c2d 100644 --- a/linter/src/utils/functions/identiferUseInValueContext.ts +++ b/linter/src/utils/functions/identiferUseInValueContext.ts @@ -43,11 +43,10 @@ function getQualifiedStart(ident: ts.Node): ts.Node { } function isEnumPropAccess(ident: ts.Identifier, tsSym: ts.Symbol, context: ts.Node): boolean { - return ts.isElementAccessExpression(context) && - (context as ts.ElementAccessExpression).expression == ident && - !!(tsSym.flags & ts.SymbolFlags.Enum); + return ts.isElementAccessExpression(context) && !!(tsSym.flags & ts.SymbolFlags.Enum) && + (context.expression == ident || + (ts.isPropertyAccessExpression(context.expression) && context.expression.name == ident)); } - function isValidTypeNode(node: ts.TypeNode): boolean { return !ts.isTypeOfExpression(node); } diff --git a/linter/test/class_as_object.ts b/linter/test/class_as_object.ts index 8a13dbfaa..6fa062cdc 100644 --- a/linter/test/class_as_object.ts +++ b/linter/test/class_as_object.ts @@ -96,4 +96,23 @@ export { C as H }; let data = new Select().from(C).eq('key').query(C); // Ok invalid_func(C); // Ok let a: any; -a.foo(C); // Ok \ No newline at end of file +a.foo(C); // Ok + +let col = 'WHITE'; +console.log(Color[col]) + +// #14184 +namespace NS { + export enum E { + A = 'A', + B = 'B', + C = 'C' + } +} + +let s: string = 'B'; +let s2: string = NS.E[s]; + +for (let item = 0; item < Object.keys(NS.E).length; item++) { + console.log(item); +} \ No newline at end of file diff --git a/linter/test/class_as_object.ts.relax.json b/linter/test/class_as_object.ts.relax.json index 75576a35f..ebe30080e 100644 --- a/linter/test/class_as_object.ts.relax.json +++ b/linter/test/class_as_object.ts.relax.json @@ -123,6 +123,13 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 116, + "column": 42, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" } ] } \ No newline at end of file diff --git a/linter/test/class_as_object.ts.strict.json b/linter/test/class_as_object.ts.strict.json index 75576a35f..ebe30080e 100644 --- a/linter/test/class_as_object.ts.strict.json +++ b/linter/test/class_as_object.ts.strict.json @@ -123,6 +123,13 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 116, + "column": 42, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" } ] } \ No newline at end of file -- Gitee From f32f4eeae7c55aefc473cebe1e7f3ce5909680eb Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Wed, 1 Nov 2023 14:34:06 +0300 Subject: [PATCH 20/49] [arkts-linter] update error count in CookBookMessage.ts Signed-off-by: Nazarov Konstantin --- linter-4.2/src/CookBookMsg.ts | 2 +- linter/src/CookBookMsg.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linter-4.2/src/CookBookMsg.ts b/linter-4.2/src/CookBookMsg.ts index a5897f0e2..e505f59a8 100644 --- a/linter-4.2/src/CookBookMsg.ts +++ b/linter-4.2/src/CookBookMsg.ts @@ -16,7 +16,7 @@ export const cookBookMsg: string[] = []; export const cookBookTag: string[] = []; -for (let i = 0; i <= 150; i++) { +for (let i = 0; i <= 151; i++) { cookBookMsg[i] = ''; } diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index c62bafe14..d8f053a4e 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -16,7 +16,7 @@ export const cookBookMsg: string[] = []; export const cookBookTag: string[] = []; -for (let i = 0; i <= 150; i++) { +for (let i = 0; i <= 151; i++) { cookBookMsg[i] = ''; } -- Gitee From 09bd7137bbe760e77287696895bf91169234d9c3 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Thu, 2 Nov 2023 13:42:26 +0300 Subject: [PATCH 21/49] [arkts-linter] follow-up for #14183 - allow indexed access for any Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 1 + linter-4.2/test/es_object.ts.strict.json | 21 ------------------- linter-4.2/test/property_access_by_index.ts | 19 +++++++++++++++++ .../property_access_by_index.ts.autofix.json | 16 ++++++++++++++ .../property_access_by_index.ts.relax.json | 14 +++++++++++++ .../property_access_by_index.ts.strict.json | 14 +++++++++++++ linter/src/TypeScriptLinter.ts | 1 + linter/test/es_object.ts.strict.json | 21 ------------------- linter/test/property_access_by_index.ts | 19 +++++++++++++++++ .../property_access_by_index.ts.autofix.json | 16 ++++++++++++++ .../property_access_by_index.ts.relax.json | 14 +++++++++++++ .../property_access_by_index.ts.strict.json | 14 +++++++++++++ 12 files changed, 128 insertions(+), 42 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index b83c5eba8..7c90cb2d4 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1608,6 +1608,7 @@ export class TypeScriptLinter { ); if ( !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && + !this.tsUtils.isAnyType(tsElemAccessBaseExprType) && !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isArray) && !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isTuple) && diff --git a/linter-4.2/test/es_object.ts.strict.json b/linter-4.2/test/es_object.ts.strict.json index c0ef7ba37..86c0f49ac 100644 --- a/linter-4.2/test/es_object.ts.strict.json +++ b/linter-4.2/test/es_object.ts.strict.json @@ -329,13 +329,6 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, - { - "line": 79, - "column": 5, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 79, "column": 5, @@ -665,13 +658,6 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, - { - "line": 188, - "column": 5, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 188, "column": 5, @@ -679,13 +665,6 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, - { - "line": 189, - "column": 5, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 189, "column": 5, diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index 407d70553..03b2c8f71 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -100,3 +100,22 @@ CCCCCCCCC['ROB'] CCCCCCCCC[CCCCCCCCC.KATE] CCCCCCCCC[CCCCCCCCC.BOB] CCCCCCCCC[CCCCCCCCC.ROB] + +let arr32 = new Float32Array([1,2,3]) + +let iter_arr32 = arr32[Symbol.iterator]() +let tmp_arr32 = iter_arr32.next().value; +while (!!tmp_arr32) { + console.log(tmp_arr32[0]) + + tmp_arr32 = iter_arr32.next().value +} + +let arr = new Array() +arr = ['a','f','g'] +let iter_arr = arr[Symbol.iterator]() +let tmp_arr = iter_arr.next().value; +while (!!tmp_arr) { + console.log(tmp_arr[0]) + tmp_arr = iter_arr.next().value +} diff --git a/linter-4.2/test/property_access_by_index.ts.autofix.json b/linter-4.2/test/property_access_by_index.ts.autofix.json index 2c4552959..df5e23653 100644 --- a/linter-4.2/test/property_access_by_index.ts.autofix.json +++ b/linter-4.2/test/property_access_by_index.ts.autofix.json @@ -53,6 +53,22 @@ "autofixable": false, "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 107, + "column": 5, + "problem": "AnyType", + "autofixable": false, + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 117, + "column": 5, + "problem": "AnyType", + "autofixable": false, + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.relax.json b/linter-4.2/test/property_access_by_index.ts.relax.json index 6cefe0230..b492ed738 100644 --- a/linter-4.2/test/property_access_by_index.ts.relax.json +++ b/linter-4.2/test/property_access_by_index.ts.relax.json @@ -20,6 +20,20 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 107, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 117, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.strict.json b/linter-4.2/test/property_access_by_index.ts.strict.json index 6bb2b0400..daf068f0d 100644 --- a/linter-4.2/test/property_access_by_index.ts.strict.json +++ b/linter-4.2/test/property_access_by_index.ts.strict.json @@ -48,6 +48,20 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 107, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 117, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index be639762e..0877b7bda 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1313,6 +1313,7 @@ export class TypeScriptLinter { const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode(tsElemAccessBaseExprType, undefined, ts.NodeBuilderFlags.None); if ( !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && + !this.tsUtils.isAnyType(tsElemAccessBaseExprType) && !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isArray) && !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isTuple) && diff --git a/linter/test/es_object.ts.strict.json b/linter/test/es_object.ts.strict.json index c0ef7ba37..86c0f49ac 100644 --- a/linter/test/es_object.ts.strict.json +++ b/linter/test/es_object.ts.strict.json @@ -329,13 +329,6 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, - { - "line": 79, - "column": 5, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 79, "column": 5, @@ -665,13 +658,6 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, - { - "line": 188, - "column": 5, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 188, "column": 5, @@ -679,13 +665,6 @@ "suggest": "", "rule": "Usage of \"ESObject\" type is restricted (arkts-limited-esobj)" }, - { - "line": 189, - "column": 5, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 189, "column": 5, diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index 407d70553..d7cd6781f 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -100,3 +100,22 @@ CCCCCCCCC['ROB'] CCCCCCCCC[CCCCCCCCC.KATE] CCCCCCCCC[CCCCCCCCC.BOB] CCCCCCCCC[CCCCCCCCC.ROB] + +let arr32 = new Float32Array([1,2,3]) + +let iter_arr32 = arr32[Symbol.iterator]() +let tmp_arr32 = iter_arr32.next().value; +while (!!tmp_arr32) { + console.log(tmp_arr32[0]) + + tmp_arr32 = iter_arr32.next().value +} + +let arr = new Array() +arr = ['a','f','g'] +let iter_arr = arr[Symbol.iterator]() +let tmp_arr = iter_arr.next().value; +while (!!tmp_arr) { + console.log(tmp_arr[0]) + tmp_arr = iter_arr.next().value +} \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.autofix.json b/linter/test/property_access_by_index.ts.autofix.json index 2c4552959..df5e23653 100644 --- a/linter/test/property_access_by_index.ts.autofix.json +++ b/linter/test/property_access_by_index.ts.autofix.json @@ -53,6 +53,22 @@ "autofixable": false, "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 107, + "column": 5, + "problem": "AnyType", + "autofixable": false, + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 117, + "column": 5, + "problem": "AnyType", + "autofixable": false, + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.relax.json b/linter/test/property_access_by_index.ts.relax.json index 6cefe0230..b492ed738 100644 --- a/linter/test/property_access_by_index.ts.relax.json +++ b/linter/test/property_access_by_index.ts.relax.json @@ -20,6 +20,20 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 107, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 117, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.strict.json b/linter/test/property_access_by_index.ts.strict.json index 6bb2b0400..daf068f0d 100644 --- a/linter/test/property_access_by_index.ts.strict.json +++ b/linter/test/property_access_by_index.ts.strict.json @@ -48,6 +48,20 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 107, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 117, + "column": 5, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" } ] } \ No newline at end of file -- Gitee From 2fb32cb819968b3183ca11bff0bf98ba16365f6c Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Thu, 2 Nov 2023 14:32:07 +0300 Subject: [PATCH 22/49] [ArkTS Linter] Fix #14305: Retrieve list of unsupported comment directives from SourceFile node. Change-Id: Id390b41dea000f09bd36a7237a345db475f70d6b Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 40 ++++++++++++++++++++++-- linter-4.2/test/ts_ignore.ts | 15 +++++++-- linter-4.2/test/ts_ignore.ts.relax.json | 28 ++++++++--------- linter-4.2/test/ts_ignore.ts.strict.json | 28 ++++++++--------- linter/src/TypeScriptLinter.ts | 40 +++++++++++++++++++++++- linter/test/ts_ignore.ts | 15 +++++++-- linter/test/ts_ignore.ts.relax.json | 28 ++++++++--------- linter/test/ts_ignore.ts.strict.json | 28 ++++++++--------- 8 files changed, 159 insertions(+), 63 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index b83c5eba8..7f1e4bdbb 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -242,8 +242,6 @@ export class TypeScriptLinter { return; } - self.handleComments(node); - if (LinterConfig.terminalTokens.has(node.kind)) return; let incrementedType = LinterConfig.incrementOnlyTokens.get(node.kind); @@ -2226,9 +2224,47 @@ export class TypeScriptLinter { this.incrementCounters(decl, FaultID.UnknownType); } + private handleCommentDirectives(sourceFile: ts.SourceFile) { + // We use a dirty hack to retrieve list of parsed comment directives by accessing + // internal properties of SourceFile node. + + // Handle comment directive '@ts-nocheck' + let pragmas = (sourceFile as any)['pragmas']; + if (pragmas && pragmas instanceof Map) { + for (const pragma of pragmas) { + if (pragma[0] !== 'ts-nocheck' || !pragma[1]?.range.kind || !pragma[1]?.range.pos || !pragma[1]?.range.end) { + continue; + } + + this.incrementCounters(pragma[1].range as ts.CommentRange, FaultID.ErrorSuppression); + } + } + + // Handle comment directives '@ts-ignore' and '@ts-expect-error' + let commentDirectives = (sourceFile as any)['commentDirectives']; + if (commentDirectives && Array.isArray(commentDirectives)) { + for (const directive of commentDirectives) { + if (!directive.range?.pos || !directive.range?.end) continue; + + const range = directive.range as ts.TextRange; + const kind: ts.SyntaxKind = sourceFile.text.slice(range.pos, range.pos + 2) === '/*' + ? ts.SyntaxKind.MultiLineCommentTrivia + : ts.SyntaxKind.SingleLineCommentTrivia; + let commentRange: ts.CommentRange = { + pos: range.pos, + end: range.end, + kind + }; + + this.incrementCounters(commentRange, FaultID.ErrorSuppression); + } + } + } + public lint(sourceFile: ts.SourceFile) { this.walkedComments.clear(); this.sourceFile = sourceFile; this.visitTSNode(this.sourceFile); + this.handleCommentDirectives(this.sourceFile); } } diff --git a/linter-4.2/test/ts_ignore.ts b/linter-4.2/test/ts_ignore.ts index 3676a1550..5cee01903 100644 --- a/linter-4.2/test/ts_ignore.ts +++ b/linter-4.2/test/ts_ignore.ts @@ -31,11 +31,11 @@ let b: number = null; console.log("Hello" * 42); /* - @ts-expect-error + @ts-expect-error (shouldn't be reported) */ console.log("Hello" * 42); -// no @ts-expect-error +// no @ts-expect-error (shouldn't be reported) console.log("Hello" * 42); const l1 = (): void => { @@ -74,3 +74,14 @@ class ChainedCallsClass { let cc = new ChainedCallsClass() // @ts-ignore .methodOne().methodTwo(); + +// #14305 +/* +@ts-ignore (shouldn't be reported) + */ +let c: number = '1'; + +/* + @ts-ignore (shouldn't be reported) + */ +let d: number = '1'; \ No newline at end of file diff --git a/linter-4.2/test/ts_ignore.ts.relax.json b/linter-4.2/test/ts_ignore.ts.relax.json index 8e4a16c18..f802c561b 100644 --- a/linter-4.2/test/ts_ignore.ts.relax.json +++ b/linter-4.2/test/ts_ignore.ts.relax.json @@ -14,6 +14,20 @@ "limitations under the License." ], "nodes": [ + { + "line": 53, + "column": 3, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 55, + "column": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, { "line": 16, "column": 1, @@ -56,20 +70,6 @@ "suggest": "", "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, - { - "line": 53, - "column": 3, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 55, - "column": 22, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, { "line": 56, "column": 9, diff --git a/linter-4.2/test/ts_ignore.ts.strict.json b/linter-4.2/test/ts_ignore.ts.strict.json index 8e4a16c18..f802c561b 100644 --- a/linter-4.2/test/ts_ignore.ts.strict.json +++ b/linter-4.2/test/ts_ignore.ts.strict.json @@ -14,6 +14,20 @@ "limitations under the License." ], "nodes": [ + { + "line": 53, + "column": 3, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 55, + "column": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, { "line": 16, "column": 1, @@ -56,20 +70,6 @@ "suggest": "", "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, - { - "line": 53, - "column": 3, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 55, - "column": 22, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, { "line": 56, "column": 9, diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index be639762e..9b9569c1d 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -251,7 +251,7 @@ export class TypeScriptLinter { self.handleStructDeclaration(node); return; } - self.handleComments(node); + if (LinterConfig.terminalTokens.has(node.kind)) { return; } @@ -1880,9 +1880,47 @@ export class TypeScriptLinter { } } + private handleCommentDirectives(sourceFile: ts.SourceFile) { + // We use a dirty hack to retrieve list of parsed comment directives by accessing + // internal properties of SourceFile node. + + // Handle comment directive '@ts-nocheck' + let pragmas = (sourceFile as any)['pragmas']; + if (pragmas && pragmas instanceof Map) { + for (const pragma of pragmas) { + if (pragma[0] !== 'ts-nocheck' || !pragma[1]?.range.kind || !pragma[1]?.range.pos || !pragma[1]?.range.end) { + continue; + } + + this.incrementCounters(pragma[1].range as ts.CommentRange, FaultID.ErrorSuppression); + } + } + + // Handle comment directives '@ts-ignore' and '@ts-expect-error' + let commentDirectives = (sourceFile as any)['commentDirectives']; + if (commentDirectives && Array.isArray(commentDirectives)) { + for (const directive of commentDirectives) { + if (!directive.range?.pos || !directive.range?.end) continue; + + const range = directive.range as ts.TextRange; + const kind: ts.SyntaxKind = sourceFile.text.slice(range.pos, range.pos + 2) === '/*' + ? ts.SyntaxKind.MultiLineCommentTrivia + : ts.SyntaxKind.SingleLineCommentTrivia; + let commentRange: ts.CommentRange = { + pos: range.pos, + end: range.end, + kind + }; + + this.incrementCounters(commentRange, FaultID.ErrorSuppression); + } + } + } + public lint(sourceFile: ts.SourceFile) { this.walkedComments.clear(); this.sourceFile = sourceFile; this.visitTSNode(this.sourceFile); + this.handleCommentDirectives(this.sourceFile); } } diff --git a/linter/test/ts_ignore.ts b/linter/test/ts_ignore.ts index 3676a1550..5cee01903 100644 --- a/linter/test/ts_ignore.ts +++ b/linter/test/ts_ignore.ts @@ -31,11 +31,11 @@ let b: number = null; console.log("Hello" * 42); /* - @ts-expect-error + @ts-expect-error (shouldn't be reported) */ console.log("Hello" * 42); -// no @ts-expect-error +// no @ts-expect-error (shouldn't be reported) console.log("Hello" * 42); const l1 = (): void => { @@ -74,3 +74,14 @@ class ChainedCallsClass { let cc = new ChainedCallsClass() // @ts-ignore .methodOne().methodTwo(); + +// #14305 +/* +@ts-ignore (shouldn't be reported) + */ +let c: number = '1'; + +/* + @ts-ignore (shouldn't be reported) + */ +let d: number = '1'; \ No newline at end of file diff --git a/linter/test/ts_ignore.ts.relax.json b/linter/test/ts_ignore.ts.relax.json index 8e4a16c18..f802c561b 100644 --- a/linter/test/ts_ignore.ts.relax.json +++ b/linter/test/ts_ignore.ts.relax.json @@ -14,6 +14,20 @@ "limitations under the License." ], "nodes": [ + { + "line": 53, + "column": 3, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 55, + "column": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, { "line": 16, "column": 1, @@ -56,20 +70,6 @@ "suggest": "", "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, - { - "line": 53, - "column": 3, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 55, - "column": 22, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, { "line": 56, "column": 9, diff --git a/linter/test/ts_ignore.ts.strict.json b/linter/test/ts_ignore.ts.strict.json index 8e4a16c18..f802c561b 100644 --- a/linter/test/ts_ignore.ts.strict.json +++ b/linter/test/ts_ignore.ts.strict.json @@ -14,6 +14,20 @@ "limitations under the License." ], "nodes": [ + { + "line": 53, + "column": 3, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 55, + "column": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, { "line": 16, "column": 1, @@ -56,20 +70,6 @@ "suggest": "", "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, - { - "line": 53, - "column": 3, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 55, - "column": 22, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, { "line": 56, "column": 9, -- Gitee From 2eb651ab087e3f3be93ba9b34a150bda1055c936 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Fri, 3 Nov 2023 03:44:07 +0300 Subject: [PATCH 23/49] [arkts-linter] fix #14330 Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 229 +++++++++--------- linter-4.2/test/classB.ts.relax.json | 4 +- linter-4.2/test/classB.ts.strict.json | 4 +- .../function_object_methods.ts.relax.json | 16 +- .../function_object_methods.ts.strict.json | 16 +- linter-4.2/test/functions.ts.autofix.json | 4 +- linter-4.2/test/functions.ts.relax.json | 4 +- linter-4.2/test/functions.ts.strict.json | 4 +- .../test/prototype_assignment.ts.autofix.json | 12 +- .../test/prototype_assignment.ts.relax.json | 12 +- .../test/prototype_assignment.ts.strict.json | 12 +- linter-4.2/test/this_type.ts.relax.json | 16 +- linter-4.2/test/this_type.ts.strict.json | 16 +- linter-4.2/test/utility_types.ts.relax.json | 17 +- linter-4.2/test/utility_types.ts.strict.json | 17 +- linter-4.2/test_rules/rule136.ts.autofix.json | 8 +- linter-4.2/test_rules/rule136.ts.relax.json | 8 +- linter-4.2/test_rules/rule136.ts.strict.json | 8 +- linter-4.2/test_rules/rule93.ts.autofix.json | 4 +- linter-4.2/test_rules/rule93.ts.relax.json | 4 +- linter-4.2/test_rules/rule93.ts.strict.json | 4 +- linter/src/TypeScriptLinter.ts | 188 +++++++------- linter/src/utils/functions/ContainsThis.ts | 47 ++-- linter/test/classB.ts.relax.json | 4 +- linter/test/classB.ts.strict.json | 4 +- .../function_object_methods.ts.relax.json | 16 +- .../function_object_methods.ts.strict.json | 16 +- linter/test/functions.ts.autofix.json | 4 +- linter/test/functions.ts.relax.json | 4 +- linter/test/functions.ts.strict.json | 4 +- .../test/prototype_assignment.ts.autofix.json | 12 +- .../test/prototype_assignment.ts.relax.json | 12 +- .../test/prototype_assignment.ts.strict.json | 12 +- linter/test/this_type.ts.relax.json | 20 +- linter/test/this_type.ts.strict.json | 20 +- linter/test/utility_types.ts.relax.json | 17 +- linter/test/utility_types.ts.strict.json | 17 +- linter/test_rules/rule136.ts.autofix.json | 8 +- linter/test_rules/rule136.ts.relax.json | 8 +- linter/test_rules/rule136.ts.strict.json | 8 +- linter/test_rules/rule93.ts.autofix.json | 4 +- linter/test_rules/rule93.ts.relax.json | 4 +- linter/test_rules/rule93.ts.strict.json | 4 +- 43 files changed, 444 insertions(+), 408 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index cde04f232..efa0d583f 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -229,38 +229,45 @@ export class TypeScriptLinter { } } - private visitTSNode(node: ts.Node): void { - const self = this; - visitTSNodeImpl(node); - function visitTSNodeImpl(node: ts.Node): void { - if (node === null || node.kind === null) return; - - self.totalVisitedNodes++; - - if (self.tsUtils.isStructDeclaration(node)) { - self.handleStructDeclaration(node); - return; - } - - if (LinterConfig.terminalTokens.has(node.kind)) return; - - let incrementedType = LinterConfig.incrementOnlyTokens.get(node.kind); + private forEachNodeInSubtree(node: ts.Node, cb: (n: ts.Node) => void, stopCond?: (n: ts.Node) => boolean) { + cb.call(this, node); + if (stopCond?.call(this, node)) { + return; + } + // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. + // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. + // to traverse child nodes. + for (const child of node.getChildren()) { + this.forEachNodeInSubtree(child, cb, stopCond) + } + } + private visitSourceFile(sf: ts.SourceFile): void { + const callback = (node: ts.Node) => { + this.totalVisitedNodes++; + const incrementedType = LinterConfig.incrementOnlyTokens.get(node.kind); if (incrementedType !== undefined) { - self.incrementCounters(node, incrementedType); + this.incrementCounters(node, incrementedType); } else { - let handler = self.handlersMap.get(node.kind); + const handler = this.handlersMap.get(node.kind); if (handler !== undefined) { - handler.call(self, node); + handler.call(this, node); } } - - // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. - // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. - // to traverse child nodes. - for (const child of node.getChildren()) { - visitTSNodeImpl(child); + } + const stopCondition = (node: ts.Node) => { + if (node === null || node.kind === null) { + return true; + } + // Skip synthetic constructor in Struct declaration. + if (node.parent && this.tsUtils.isStructDeclaration(node.parent) && ts.isConstructorDeclaration(node)) { + return true; + } + if (LinterConfig.terminalTokens.has(node.kind)) { + return true; } + return false; } + this.forEachNodeInSubtree(sf, callback, stopCondition); } private countInterfaceExtendsDifferentPropertyTypes( @@ -342,33 +349,31 @@ export class TypeScriptLinter { } } - private scopeContainsThis(tsNode: ts.Node): boolean { - let found = false; - - function visitNode(tsNode: ts.Node) { - // Stop visiting child nodes if finished searching. - if (found) return; - + private static scopeContainsThis(tsNode: ts.Expression | ts.Block): boolean { + function scopeContainsThisVisitor(tsNode: ts.Node): boolean { if (tsNode.kind === ts.SyntaxKind.ThisKeyword) { - found = true; - return; + return true; } // Visit children nodes. Skip any local declaration that defines // its own scope as it needs to be checked separately. - if ( - !ts.isClassDeclaration(tsNode) && - !ts.isClassExpression(tsNode) && - !ts.isModuleDeclaration(tsNode) && - !ts.isFunctionDeclaration(tsNode) && - !ts.isFunctionExpression(tsNode) - ) - tsNode.forEachChild(visitNode); - } + const isClassLike = ts.isClassDeclaration(tsNode) || ts.isClassExpression(tsNode); + const isFunctionLike = ts.isFunctionDeclaration(tsNode) || ts.isFunctionExpression(tsNode); + const isModuleDecl = ts.isModuleDeclaration(tsNode); + if (isClassLike || isFunctionLike || isModuleDecl) { + return false; + } + + for (const child of tsNode.getChildren()) { + if (scopeContainsThisVisitor(child)) { + return true; + } + } - visitNode(tsNode); + return false; + } - return found; + return scopeContainsThisVisitor(tsNode); } private isPrototypePropertyAccess(tsPropertyAccess: ts.PropertyAccessExpression, propAccessSym: ts.Symbol | undefined, @@ -845,25 +850,23 @@ export class TypeScriptLinter { return true; } + private static isClassLikeOrIface(node: ts.Node): boolean { + return ts.isClassLike(node) || ts.isInterfaceDeclaration(node); + } + private handleFunctionExpression(node: ts.Node) { const funcExpr = node as ts.FunctionExpression; + const isGeneric = funcExpr.typeParameters !== undefined && funcExpr.typeParameters.length > 0; const isGenerator = funcExpr.asteriskToken !== undefined; - const containsThis = this.scopeContainsThis(funcExpr.body); - const hasValidContext = - this.tsUtils.hasPredecessor(funcExpr, ts.isClassLike) || - this.tsUtils.hasPredecessor(funcExpr, ts.isInterfaceDeclaration); - const isGeneric = - funcExpr.typeParameters !== undefined && - funcExpr.typeParameters.length > 0; + const hasThisKeyword = TypeScriptLinter.scopeContainsThis(funcExpr.body); const isCalledRecursively = this.tsUtils.isFunctionCalledRecursively(funcExpr); const [hasUnfixableReturnType, newRetTypeNode] = this.handleMissingReturnType(funcExpr); - const autofixable = !isGeneric && !isGenerator && !containsThis && !hasUnfixableReturnType && - !isCalledRecursively; + const autofixable = !isGeneric && !isGenerator && !hasThisKeyword && !isCalledRecursively && !hasUnfixableReturnType; let autofix: Autofix[] | undefined; if ( autofixable && - this.autofixesInfo.shouldAutofix(node, FaultID.FunctionExpression) + this.autofixesInfo.shouldAutofix(funcExpr, FaultID.FunctionExpression) ) { autofix = [ Autofixer.fixFunctionExpression( @@ -875,7 +878,7 @@ export class TypeScriptLinter { ]; } this.incrementCounters( - node, + funcExpr, FaultID.FunctionExpression, autofixable, autofix @@ -886,8 +889,8 @@ export class TypeScriptLinter { if (isGenerator) { this.incrementCounters(funcExpr, FaultID.GeneratorFunction); } - if (containsThis && !hasValidContext) { - this.incrementCounters(funcExpr, FaultID.FunctionContainsThis); + if (!TypeScriptLinter.hasPredecessor(funcExpr, TypeScriptLinter.isClassLikeOrIface)) { + this.reportThisKeywordsInScope(funcExpr.body); } if (hasUnfixableReturnType) { this.incrementCounters(funcExpr, FaultID.LimitedReturnTypeInference); @@ -896,12 +899,8 @@ export class TypeScriptLinter { private handleArrowFunction(node: ts.Node) { const arrowFunc = node as ts.ArrowFunction; - const containsThis = this.scopeContainsThis(arrowFunc.body); - const hasValidContext = - this.tsUtils.hasPredecessor(arrowFunc, ts.isClassLike) || - this.tsUtils.hasPredecessor(arrowFunc, ts.isInterfaceDeclaration); - if (containsThis && !hasValidContext) { - this.incrementCounters(arrowFunc, FaultID.FunctionContainsThis); + if (!TypeScriptLinter.hasPredecessor(arrowFunc, TypeScriptLinter.isClassLikeOrIface)) { + this.reportThisKeywordsInScope(arrowFunc.body); } const contextType = this.tsTypeChecker.getContextualType(arrowFunc); if (!(contextType && this.tsUtils.isLibraryType(contextType))) { @@ -921,26 +920,23 @@ export class TypeScriptLinter { } private handleFunctionDeclaration(node: ts.Node) { - let tsFunctionDeclaration = node as ts.FunctionDeclaration; - if (!tsFunctionDeclaration.type) + const tsFunctionDeclaration = node as ts.FunctionDeclaration; + if (!tsFunctionDeclaration.type) { this.handleMissingReturnType(tsFunctionDeclaration); - if (tsFunctionDeclaration.name) + } + if (tsFunctionDeclaration.name) { this.countDeclarationsWithDuplicateName(tsFunctionDeclaration.name, tsFunctionDeclaration); - - if ( - tsFunctionDeclaration.body && - this.scopeContainsThis(tsFunctionDeclaration.body) - ) - this.incrementCounters(node, FaultID.FunctionContainsThis); - - if ( - !ts.isSourceFile(tsFunctionDeclaration.parent) && - !ts.isModuleBlock(tsFunctionDeclaration.parent) - ) + } + if (tsFunctionDeclaration.body) { + this.reportThisKeywordsInScope(tsFunctionDeclaration.body); + } + const parent = tsFunctionDeclaration.parent; + if (!ts.isSourceFile(parent) && !ts.isModuleBlock(parent)) { this.incrementCounters(tsFunctionDeclaration, FaultID.LocalFunction); - - if (tsFunctionDeclaration.asteriskToken) + } + if (tsFunctionDeclaration.asteriskToken) { this.incrementCounters(node, FaultID.GeneratorFunction); + } } private handleMissingReturnType(funcLikeDecl: ts.FunctionLikeDeclaration | ts.MethodSignature): [boolean, ts.TypeNode | undefined] { @@ -1010,34 +1006,27 @@ export class TypeScriptLinter { funBody: ts.ConciseBody ): boolean { let hasLimitedTypeInference = false; - const self = this; - function visitNode(tsNode: ts.Node): void { + const callback = (node: ts.Node) => { if (hasLimitedTypeInference) return; if ( - ts.isReturnStatement(tsNode) && - tsNode.expression && - self.tsUtils.isCallToFunctionWithOmittedReturnType( - self.tsUtils.unwrapParenthesized(tsNode.expression) - ) + ts.isReturnStatement(node) && node.expression && + this.tsUtils.isCallToFunctionWithOmittedReturnType(this.tsUtils.unwrapParenthesized(node.expression)) ) { hasLimitedTypeInference = true; - return; } - - // Visit children nodes. Don't traverse other nested function-like declarations. - if ( - !ts.isFunctionDeclaration(tsNode) && - !ts.isFunctionExpression(tsNode) && - !ts.isMethodDeclaration(tsNode) && - !ts.isAccessor(tsNode) && - !ts.isArrowFunction(tsNode) - ) - tsNode.forEachChild(visitNode); + } + // Don't traverse other nested function-like declarations. + const stopCondition = (node: ts.Node) => { + return ts.isFunctionDeclaration(node) || + ts.isFunctionExpression(node) || + ts.isMethodDeclaration(node) || + ts.isAccessor(node) || + ts.isArrowFunction(node); } if (ts.isBlock(funBody)) { - visitNode(funBody); + this.forEachNodeInSubtree(funBody, callback, stopCondition); } else { const tsExpr = this.tsUtils.unwrapParenthesized(funBody); hasLimitedTypeInference = @@ -1446,10 +1435,9 @@ export class TypeScriptLinter { private handleMethodDeclaration(node: ts.Node) { const tsMethodDecl = node as ts.MethodDeclaration; - const hasThis = this.scopeContainsThis(tsMethodDecl); let isStatic = false; if (tsMethodDecl.modifiers) { - for (let mod of tsMethodDecl.modifiers) { + for (const mod of tsMethodDecl.modifiers) { if (mod.kind === ts.SyntaxKind.StaticKeyword) { isStatic = true; break; @@ -1457,8 +1445,8 @@ export class TypeScriptLinter { } } - if (isStatic && hasThis) { - this.incrementCounters(node, FaultID.FunctionContainsThis); + if (tsMethodDecl.body && isStatic) { + this.reportThisKeywordsInScope(tsMethodDecl.body); } if (!tsMethodDecl.type) this.handleMissingReturnType(tsMethodDecl); @@ -1973,13 +1961,6 @@ export class TypeScriptLinter { } } - private handleStructDeclaration(node: ts.Node) { - node.forEachChild((child) => { - // Skip synthetic constructor in Struct declaration. - if (!ts.isConstructorDeclaration(child)) this.visitTSNode(child); - }); - } - private handleSpreadOp(node: ts.Node) { // spread assignment is disabled // spread element is allowed only for arrays as rest parameter @@ -2262,10 +2243,36 @@ export class TypeScriptLinter { } } + private reportThisKeywordsInScope(scope: ts.Block | ts.Expression): void { + const callback = (node: ts.Node) => { + if (node.kind === ts.SyntaxKind.ThisKeyword) { + this.incrementCounters(node, FaultID.FunctionContainsThis); + } + } + const stopCondition = (node: ts.Node) => { + const isClassLike = ts.isClassDeclaration(node) || ts.isClassExpression(node); + const isFunctionLike = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node); + const isModuleDecl = ts.isModuleDeclaration(node); + return isClassLike || isFunctionLike || isModuleDecl; + } + this.forEachNodeInSubtree(scope, callback, stopCondition); + } + + private static hasPredecessor(node: ts.Node, predicate: (node: ts.Node) => boolean): boolean { + let parent = node.parent; + while (parent !== undefined) { + if (predicate(parent)) { + return true; + } + parent = parent.parent; + } + return false; + } + public lint(sourceFile: ts.SourceFile) { this.walkedComments.clear(); this.sourceFile = sourceFile; - this.visitTSNode(this.sourceFile); + this.visitSourceFile(this.sourceFile); this.handleCommentDirectives(this.sourceFile); } } diff --git a/linter-4.2/test/classB.ts.relax.json b/linter-4.2/test/classB.ts.relax.json index e44fd80c4..dc2b9ced4 100644 --- a/linter-4.2/test/classB.ts.relax.json +++ b/linter-4.2/test/classB.ts.relax.json @@ -15,8 +15,8 @@ ], "nodes": [ { - "line": 24, - "column": 5, + "line": 25, + "column": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test/classB.ts.strict.json b/linter-4.2/test/classB.ts.strict.json index e44fd80c4..dc2b9ced4 100644 --- a/linter-4.2/test/classB.ts.strict.json +++ b/linter-4.2/test/classB.ts.strict.json @@ -15,8 +15,8 @@ ], "nodes": [ { - "line": 24, - "column": 5, + "line": 25, + "column": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test/function_object_methods.ts.relax.json b/linter-4.2/test/function_object_methods.ts.relax.json index 96e3fcaf1..8b8fe68fe 100644 --- a/linter-4.2/test/function_object_methods.ts.relax.json +++ b/linter-4.2/test/function_object_methods.ts.relax.json @@ -190,29 +190,29 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" }, { - "line": 118, - "column": 7, + "line": 119, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 121, - "column": 7, + "line": 122, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 124, - "column": 7, + "line": 125, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 127, - "column": 7, + "line": 128, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test/function_object_methods.ts.strict.json b/linter-4.2/test/function_object_methods.ts.strict.json index e90572ea9..a73e4ace1 100644 --- a/linter-4.2/test/function_object_methods.ts.strict.json +++ b/linter-4.2/test/function_object_methods.ts.strict.json @@ -197,8 +197,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 118, - "column": 7, + "line": 119, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -218,15 +218,15 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 121, - "column": 7, + "line": 122, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 124, - "column": 7, + "line": 125, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -239,8 +239,8 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)" }, { - "line": 127, - "column": 7, + "line": 128, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test/functions.ts.autofix.json b/linter-4.2/test/functions.ts.autofix.json index 944c5bf6b..0b6af45e6 100644 --- a/linter-4.2/test/functions.ts.autofix.json +++ b/linter-4.2/test/functions.ts.autofix.json @@ -87,8 +87,8 @@ "rule": "Use generic functions instead of generic arrow functions (arkts-no-generic-lambdas)" }, { - "line": 63, - "column": 1, + "line": 64, + "column": 3, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", diff --git a/linter-4.2/test/functions.ts.relax.json b/linter-4.2/test/functions.ts.relax.json index 1e86ab2f1..6729c50d2 100644 --- a/linter-4.2/test/functions.ts.relax.json +++ b/linter-4.2/test/functions.ts.relax.json @@ -64,8 +64,8 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { - "line": 63, - "column": 1, + "line": 64, + "column": 3, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test/functions.ts.strict.json b/linter-4.2/test/functions.ts.strict.json index a1c2214e5..d57b74aa3 100644 --- a/linter-4.2/test/functions.ts.strict.json +++ b/linter-4.2/test/functions.ts.strict.json @@ -78,8 +78,8 @@ "rule": "Use generic functions instead of generic arrow functions (arkts-no-generic-lambdas)" }, { - "line": 63, - "column": 1, + "line": 64, + "column": 3, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test/prototype_assignment.ts.autofix.json b/linter-4.2/test/prototype_assignment.ts.autofix.json index 381cadf69..c1e3b5c63 100644 --- a/linter-4.2/test/prototype_assignment.ts.autofix.json +++ b/linter-4.2/test/prototype_assignment.ts.autofix.json @@ -15,8 +15,8 @@ ], "nodes": [ { - "line": 19, - "column": 1, + "line": 26, + "column": 19, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", @@ -31,8 +31,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 20, - "column": 20, + "line": 21, + "column": 5, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", @@ -71,8 +71,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 30, - "column": 26, + "line": 31, + "column": 12, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", diff --git a/linter-4.2/test/prototype_assignment.ts.relax.json b/linter-4.2/test/prototype_assignment.ts.relax.json index dc1c5be2c..79345f433 100644 --- a/linter-4.2/test/prototype_assignment.ts.relax.json +++ b/linter-4.2/test/prototype_assignment.ts.relax.json @@ -15,15 +15,15 @@ ], "nodes": [ { - "line": 19, - "column": 1, + "line": 26, + "column": 19, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 20, - "column": 20, + "line": 21, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -50,8 +50,8 @@ "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)" }, { - "line": 30, - "column": 26, + "line": 31, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test/prototype_assignment.ts.strict.json b/linter-4.2/test/prototype_assignment.ts.strict.json index ad3f54292..f1ebe772d 100644 --- a/linter-4.2/test/prototype_assignment.ts.strict.json +++ b/linter-4.2/test/prototype_assignment.ts.strict.json @@ -15,8 +15,8 @@ ], "nodes": [ { - "line": 19, - "column": 1, + "line": 26, + "column": 19, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -29,8 +29,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 20, - "column": 20, + "line": 21, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -64,8 +64,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 30, - "column": 26, + "line": 31, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test/this_type.ts.relax.json b/linter-4.2/test/this_type.ts.relax.json index 9d215c36e..21ba10e79 100644 --- a/linter-4.2/test/this_type.ts.relax.json +++ b/linter-4.2/test/this_type.ts.relax.json @@ -50,23 +50,23 @@ "problem": "ThisType" }, { - "line": 72, - "column": 3, + "line": 73, + "column": 5, "problem": "FunctionContainsThis" }, { - "line": 77, - "column": 9, + "line": 78, + "column": 3, "problem": "FunctionContainsThis" }, { - "line": 80, - "column": 10, + "line": 81, + "column": 3, "problem": "FunctionContainsThis" }, { - "line": 83, - "column": 1, + "line": 84, + "column": 3, "problem": "FunctionContainsThis" } ] diff --git a/linter-4.2/test/this_type.ts.strict.json b/linter-4.2/test/this_type.ts.strict.json index 673d4a501..274c793d5 100644 --- a/linter-4.2/test/this_type.ts.strict.json +++ b/linter-4.2/test/this_type.ts.strict.json @@ -50,13 +50,13 @@ "problem": "ThisType" }, { - "line": 72, - "column": 3, + "line": 73, + "column": 5, "problem": "FunctionContainsThis" }, { - "line": 77, - "column": 9, + "line": 78, + "column": 3, "problem": "FunctionContainsThis" }, { @@ -65,13 +65,13 @@ "problem": "FunctionExpression" }, { - "line": 80, - "column": 10, + "line": 81, + "column": 3, "problem": "FunctionContainsThis" }, { - "line": 83, - "column": 1, + "line": 84, + "column": 3, "problem": "FunctionContainsThis" } ] diff --git a/linter-4.2/test/utility_types.ts.relax.json b/linter-4.2/test/utility_types.ts.relax.json index 63a56e5cd..b274ba451 100644 --- a/linter-4.2/test/utility_types.ts.relax.json +++ b/linter-4.2/test/utility_types.ts.relax.json @@ -250,8 +250,8 @@ "problem": "UtilityType" }, { - "line": 173, - "column": 3, + "line": 174, + "column": 12, "problem": "FunctionContainsThis" }, { @@ -270,8 +270,8 @@ "problem": "FunctionApplyBindCall" }, { - "line": 183, - "column": 3, + "line": 184, + "column": 12, "problem": "FunctionContainsThis" }, { @@ -290,8 +290,13 @@ "problem": "FunctionApplyBindCall" }, { - "line": 192, - "column": 1, + "line": 208, + "column": 9, + "problem": "FunctionContainsThis" + }, + { + "line": 209, + "column": 9, "problem": "FunctionContainsThis" }, { diff --git a/linter-4.2/test/utility_types.ts.strict.json b/linter-4.2/test/utility_types.ts.strict.json index cb2916b9d..bbda8979a 100644 --- a/linter-4.2/test/utility_types.ts.strict.json +++ b/linter-4.2/test/utility_types.ts.strict.json @@ -260,8 +260,8 @@ "problem": "UtilityType" }, { - "line": 173, - "column": 3, + "line": 174, + "column": 12, "problem": "FunctionContainsThis" }, { @@ -295,8 +295,8 @@ "problem": "FunctionApplyBindCall" }, { - "line": 183, - "column": 3, + "line": 184, + "column": 12, "problem": "FunctionContainsThis" }, { @@ -320,8 +320,13 @@ "problem": "FunctionApplyBindCall" }, { - "line": 192, - "column": 1, + "line": 208, + "column": 9, + "problem": "FunctionContainsThis" + }, + { + "line": 209, + "column": 9, "problem": "FunctionContainsThis" }, { diff --git a/linter-4.2/test_rules/rule136.ts.autofix.json b/linter-4.2/test_rules/rule136.ts.autofix.json index fb3ab2780..2f60e039c 100644 --- a/linter-4.2/test_rules/rule136.ts.autofix.json +++ b/linter-4.2/test_rules/rule136.ts.autofix.json @@ -17,8 +17,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 1, - "column": 9, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", @@ -49,8 +49,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 11, - "column": 17, + "line": 12, + "column": 12, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", diff --git a/linter-4.2/test_rules/rule136.ts.relax.json b/linter-4.2/test_rules/rule136.ts.relax.json index d9d652719..ccffcfe55 100644 --- a/linter-4.2/test_rules/rule136.ts.relax.json +++ b/linter-4.2/test_rules/rule136.ts.relax.json @@ -1,8 +1,8 @@ { "nodes": [ { - "line": 1, - "column": 9, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -22,8 +22,8 @@ "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)" }, { - "line": 11, - "column": 17, + "line": 12, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test_rules/rule136.ts.strict.json b/linter-4.2/test_rules/rule136.ts.strict.json index 1df9367d3..03f0cbbe5 100644 --- a/linter-4.2/test_rules/rule136.ts.strict.json +++ b/linter-4.2/test_rules/rule136.ts.strict.json @@ -15,8 +15,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 1, - "column": 9, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -43,8 +43,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 11, - "column": 17, + "line": 12, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test_rules/rule93.ts.autofix.json b/linter-4.2/test_rules/rule93.ts.autofix.json index 872acd394..819c25194 100644 --- a/linter-4.2/test_rules/rule93.ts.autofix.json +++ b/linter-4.2/test_rules/rule93.ts.autofix.json @@ -1,8 +1,8 @@ { "nodes": [ { - "line": 1, - "column": 1, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", diff --git a/linter-4.2/test_rules/rule93.ts.relax.json b/linter-4.2/test_rules/rule93.ts.relax.json index a16283a18..772a1f628 100644 --- a/linter-4.2/test_rules/rule93.ts.relax.json +++ b/linter-4.2/test_rules/rule93.ts.relax.json @@ -1,8 +1,8 @@ { "nodes": [ { - "line": 1, - "column": 1, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter-4.2/test_rules/rule93.ts.strict.json b/linter-4.2/test_rules/rule93.ts.strict.json index a16283a18..772a1f628 100644 --- a/linter-4.2/test_rules/rule93.ts.strict.json +++ b/linter-4.2/test_rules/rule93.ts.strict.json @@ -1,8 +1,8 @@ { "nodes": [ { - "line": 1, - "column": 1, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 863cd0542..ff736aa8d 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -235,45 +235,55 @@ export class TypeScriptLinter { } } - private visitTSNode(node: ts.Node): void { - const self = this; - visitTSNodeImpl(node); - function visitTSNodeImpl(node: ts.Node): void { - if (node === null || node.kind === null) { - return; - } - if (self.incrementalLintInfo?.shouldSkipCheck(node)) { - return; - } + private forEachNodeInSubtree(node: ts.Node, cb: (n: ts.Node) => void, stopCond?: (n: ts.Node) => boolean) { + cb.call(this, node); + if (stopCond?.call(this, node)) { + return; + } + // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. + // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. + // to traverse child nodes. + for (const child of node.getChildren()) { + this.forEachNodeInSubtree(child, cb, stopCond) + } + } - self.totalVisitedNodes++; + private visitSourceFile(sf: ts.SourceFile): void { + const callback = (node: ts.Node) => { + this.totalVisitedNodes++; if (isStructDeclaration(node)) { - self.handleStructDeclaration(node); - return; - } - - if (LinterConfig.terminalTokens.has(node.kind)) { - return; + // early exit via exception if cancellation was requested + this.cancellationToken?.throwIfCancellationRequested(); } - let incrementedType = LinterConfig.incrementOnlyTokens.get(node.kind); + const incrementedType = LinterConfig.incrementOnlyTokens.get(node.kind); if (incrementedType !== undefined) { - self.incrementCounters(node, incrementedType); + this.incrementCounters(node, incrementedType); } else { - let handler = self.handlersMap.get(node.kind); + const handler = this.handlersMap.get(node.kind); if (handler !== undefined) { // possibly requested cancellation will be checked in a limited number of handlers // checked nodes are selected as construct nodes, similar to how TSC does - handler.call(self, node); + handler.call(this, node); } } - - // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. - // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. - // to traverse child nodes. - for (const child of node.getChildren()) { - visitTSNodeImpl(child); + } + const stopCondition = (node: ts.Node) => { + if (node === null || node.kind === null) { + return true; + } + if (this.incrementalLintInfo?.shouldSkipCheck(node)) { + return true; + } + // Skip synthetic constructor in Struct declaration. + if (node.parent && isStructDeclaration(node.parent) && ts.isConstructorDeclaration(node)) { + return true; + } + if (LinterConfig.terminalTokens.has(node.kind)) { + return true; } + return false; } + this.forEachNodeInSubtree(sf, callback, stopCondition); } private countInterfaceExtendsDifferentPropertyTypes( @@ -736,30 +746,31 @@ export class TypeScriptLinter { return true; } + private static isClassLikeOrIface(node: ts.Node): boolean { + return ts.isClassLike(node) || ts.isInterfaceDeclaration(node); + } + private handleFunctionExpression(node: ts.Node) { const funcExpr = node as ts.FunctionExpression; - const isGenerator = funcExpr.asteriskToken !== undefined; - const containsThis = scopeContainsThis(funcExpr.body); - const hasValidContext = hasPredecessor(funcExpr, ts.isClassLike) || - hasPredecessor(funcExpr, ts.isInterfaceDeclaration); const isGeneric = funcExpr.typeParameters !== undefined && funcExpr.typeParameters.length > 0; + const isGenerator = funcExpr.asteriskToken !== undefined; + const hasThisKeyword = scopeContainsThis(funcExpr.body); const isCalledRecursively = this.tsUtils.isFunctionCalledRecursively(funcExpr); const [hasUnfixableReturnType, newRetTypeNode] = this.handleMissingReturnType(funcExpr); - const autofixable = !isGeneric && !isGenerator && !containsThis && !hasUnfixableReturnType && - !isCalledRecursively; + const autofixable = !isGeneric && !isGenerator && !hasThisKeyword && !isCalledRecursively && !hasUnfixableReturnType; let autofix: Autofix[] | undefined; - if (autofixable && this.autofixesInfo.shouldAutofix(node, FaultID.FunctionExpression)) { - autofix = [ Autofixer.fixFunctionExpression(funcExpr, funcExpr.parameters, newRetTypeNode, ts.getModifiers(funcExpr)) ]; + if (autofixable && this.autofixesInfo.shouldAutofix(funcExpr, FaultID.FunctionExpression)) { + autofix = [Autofixer.fixFunctionExpression(funcExpr, funcExpr.parameters, newRetTypeNode, ts.getModifiers(funcExpr))]; } - this.incrementCounters(node, FaultID.FunctionExpression, autofixable, autofix); + this.incrementCounters(funcExpr, FaultID.FunctionExpression, autofixable, autofix); if (isGeneric) { this.incrementCounters(funcExpr, FaultID.LambdaWithTypeParameters); } if (isGenerator) { this.incrementCounters(funcExpr, FaultID.GeneratorFunction); } - if (containsThis && !hasValidContext) { - this.incrementCounters(funcExpr, FaultID.FunctionContainsThis); + if (!hasPredecessor(funcExpr, TypeScriptLinter.isClassLikeOrIface)) { + this.reportThisKeywordsInScope(funcExpr.body); } if (hasUnfixableReturnType) { this.incrementCounters(funcExpr, FaultID.LimitedReturnTypeInference); @@ -768,11 +779,8 @@ export class TypeScriptLinter { private handleArrowFunction(node: ts.Node) { const arrowFunc = node as ts.ArrowFunction; - const containsThis = scopeContainsThis(arrowFunc.body); - const hasValidContext = hasPredecessor(arrowFunc, ts.isClassLike) || - hasPredecessor(arrowFunc, ts.isInterfaceDeclaration); - if (containsThis && !hasValidContext) { - this.incrementCounters(arrowFunc, FaultID.FunctionContainsThis); + if (!hasPredecessor(arrowFunc, TypeScriptLinter.isClassLikeOrIface)) { + this.reportThisKeywordsInScope(arrowFunc.body); } const contextType = this.tsTypeChecker.getContextualType(arrowFunc); if (!(contextType && this.tsUtils.isLibraryType(contextType))) { @@ -795,17 +803,18 @@ export class TypeScriptLinter { // early exit via exception if cancellation was requested this.cancellationToken?.throwIfCancellationRequested(); - let tsFunctionDeclaration = node as ts.FunctionDeclaration; + const tsFunctionDeclaration = node as ts.FunctionDeclaration; if (!tsFunctionDeclaration.type) { this.handleMissingReturnType(tsFunctionDeclaration); } if (tsFunctionDeclaration.name) { this.countDeclarationsWithDuplicateName(tsFunctionDeclaration.name, tsFunctionDeclaration); } - if (tsFunctionDeclaration.body && scopeContainsThis(tsFunctionDeclaration.body)) { - this.incrementCounters(node, FaultID.FunctionContainsThis); + if (tsFunctionDeclaration.body) { + this.reportThisKeywordsInScope(tsFunctionDeclaration.body); } - if (!ts.isSourceFile(tsFunctionDeclaration.parent) && !ts.isModuleBlock(tsFunctionDeclaration.parent)) { + const funcDeclParent = tsFunctionDeclaration.parent; + if (!ts.isSourceFile(funcDeclParent) && !ts.isModuleBlock(funcDeclParent)) { this.incrementCounters(tsFunctionDeclaration, FaultID.LocalFunction); } if (tsFunctionDeclaration.asteriskToken) { @@ -857,30 +866,27 @@ export class TypeScriptLinter { private hasLimitedTypeInferenceFromReturnExpr(funBody: ts.ConciseBody): boolean { let hasLimitedTypeInference = false; - const self = this; - function visitNode(tsNode: ts.Node): void { + const callback = (node: ts.Node) => { if (hasLimitedTypeInference) { return; } if ( - ts.isReturnStatement(tsNode) && tsNode.expression && - self.tsUtils.isCallToFunctionWithOmittedReturnType(self.tsUtils.unwrapParenthesized(tsNode.expression)) + ts.isReturnStatement(node) && node.expression && + this.tsUtils.isCallToFunctionWithOmittedReturnType(this.tsUtils.unwrapParenthesized(node.expression)) ) { hasLimitedTypeInference = true; - return; } - // Visit children nodes. Don't traverse other nested function-like declarations. - if ( - !ts.isFunctionDeclaration(tsNode) && - !ts.isFunctionExpression(tsNode) && - !ts.isMethodDeclaration(tsNode) && - !ts.isAccessor(tsNode) && - !ts.isArrowFunction(tsNode) - ) - tsNode.forEachChild(visitNode); + } + // Don't traverse other nested function-like declarations. + const stopCondition = (node: ts.Node) => { + return ts.isFunctionDeclaration(node) || + ts.isFunctionExpression(node) || + ts.isMethodDeclaration(node) || + ts.isAccessor(node) || + ts.isArrowFunction(node); } if (ts.isBlock(funBody)) { - visitNode(funBody); + this.forEachNodeInSubtree(funBody, callback, stopCondition); } else { const tsExpr = this.tsUtils.unwrapParenthesized(funBody); hasLimitedTypeInference = this.tsUtils.isCallToFunctionWithOmittedReturnType(tsExpr); @@ -1187,18 +1193,17 @@ export class TypeScriptLinter { private handleMethodDeclaration(node: ts.Node) { const tsMethodDecl = node as ts.MethodDeclaration; - const hasThis = scopeContainsThis(tsMethodDecl); let isStatic = false if (tsMethodDecl.modifiers) { - for (let mod of tsMethodDecl.modifiers) { + for (const mod of tsMethodDecl.modifiers) { if (mod.kind === ts.SyntaxKind.StaticKeyword) { isStatic = true; break; } } } - if (isStatic && hasThis) { - this.incrementCounters(node, FaultID.FunctionContainsThis); + if (tsMethodDecl.body && isStatic) { + this.reportThisKeywordsInScope(tsMethodDecl.body); } if (!tsMethodDecl.type) { this.handleMissingReturnType(tsMethodDecl); @@ -1220,19 +1225,18 @@ export class TypeScriptLinter { } private handleClassStaticBlockDeclaration(node: ts.Node) { - if (ts.isClassDeclaration(node.parent)) { - const tsClassDecl = node.parent as ts.ClassDeclaration; - let className = ''; - if (tsClassDecl.name) - // May be undefined in `export default class { ... }`. - className = tsClassDecl.name.text; - if (scopeContainsThis(node)) { - this.incrementCounters(node, FaultID.FunctionContainsThis); - } - if (this.staticBlocks.has(className)) - this.incrementCounters(node, FaultID.MultipleStaticBlocks); - else - this.staticBlocks.add(className); + const classStaticBlockDecl = node as ts.ClassStaticBlockDeclaration; + const parent = classStaticBlockDecl.parent; + if (!ts.isClassDeclaration(parent)) { + return; + } + this.reportThisKeywordsInScope(classStaticBlockDecl.body); + // May be undefined in `export default class { ... }`. + const className = parent.name?.text ?? ''; + if (this.staticBlocks.has(className)) { + this.incrementCounters(classStaticBlockDecl, FaultID.MultipleStaticBlocks); + } else { + this.staticBlocks.add(className); } } @@ -1650,16 +1654,6 @@ export class TypeScriptLinter { } } - private handleStructDeclaration(node: ts.Node) { - // early exit via exception if cancellation was requested - this.cancellationToken?.throwIfCancellationRequested(); - - node.forEachChild(child => { - // Skip synthetic constructor in Struct declaration. - if (!ts.isConstructorDeclaration(child)) this.visitTSNode(child); - }); - } - private handleSpreadOp(node: ts.Node) { // spread assignment is disabled // spread element is allowed only for arrays as rest parameter @@ -1917,11 +1911,25 @@ export class TypeScriptLinter { } } } + private reportThisKeywordsInScope(scope: ts.Block | ts.Expression): void { + const callback = (node: ts.Node) => { + if (node.kind === ts.SyntaxKind.ThisKeyword) { + this.incrementCounters(node, FaultID.FunctionContainsThis); + } + } + const stopCondition = (node: ts.Node) => { + const isClassLike = ts.isClassDeclaration(node) || ts.isClassExpression(node); + const isFunctionLike = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node); + const isModuleDecl = ts.isModuleDeclaration(node); + return isClassLike || isFunctionLike || isModuleDecl; + } + this.forEachNodeInSubtree(scope, callback, stopCondition); + } public lint(sourceFile: ts.SourceFile) { this.walkedComments.clear(); this.sourceFile = sourceFile; - this.visitTSNode(this.sourceFile); + this.visitSourceFile(this.sourceFile); this.handleCommentDirectives(this.sourceFile); } } diff --git a/linter/src/utils/functions/ContainsThis.ts b/linter/src/utils/functions/ContainsThis.ts index a0cccbb1c..27018edf6 100644 --- a/linter/src/utils/functions/ContainsThis.ts +++ b/linter/src/utils/functions/ContainsThis.ts @@ -15,28 +15,29 @@ import * as ts from 'typescript'; -export function scopeContainsThis(tsNode: ts.Node): boolean { - let found = false; - function visitNode(tsNode: ts.Node) { - // Stop visiting child nodes if finished searching. - if (found) { - return; - } - if (tsNode.kind === ts.SyntaxKind.ThisKeyword) { - found = true; - return; +function scopeContainsThisVisitor(tsNode: ts.Node): boolean { + if (tsNode.kind === ts.SyntaxKind.ThisKeyword) { + return true; + } + + // Visit children nodes. Skip any local declaration that defines + // its own scope as it needs to be checked separately. + const isClassLike = ts.isClassDeclaration(tsNode) || ts.isClassExpression(tsNode); + const isFunctionLike = ts.isFunctionDeclaration(tsNode) || ts.isFunctionExpression(tsNode); + const isModuleDecl = ts.isModuleDeclaration(tsNode); + if (isClassLike || isFunctionLike || isModuleDecl) { + return false; + } + + for (const child of tsNode.getChildren()) { + if (scopeContainsThisVisitor(child)) { + return true; } - // Visit children nodes. Skip any local declaration that defines - // its own scope as it needs to be checked separately. - if ( - !ts.isClassDeclaration(tsNode) && - !ts.isClassExpression(tsNode) && - !ts.isModuleDeclaration(tsNode) && - !ts.isFunctionDeclaration(tsNode) && - !ts.isFunctionExpression(tsNode) - ) - tsNode.forEachChild(visitNode); } - visitNode(tsNode); - return found; -} \ No newline at end of file + + return false; +} + +export function scopeContainsThis(tsNode: ts.Expression | ts.Block): boolean { + return scopeContainsThisVisitor(tsNode); +} diff --git a/linter/test/classB.ts.relax.json b/linter/test/classB.ts.relax.json index e44fd80c4..dc2b9ced4 100644 --- a/linter/test/classB.ts.relax.json +++ b/linter/test/classB.ts.relax.json @@ -15,8 +15,8 @@ ], "nodes": [ { - "line": 24, - "column": 5, + "line": 25, + "column": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test/classB.ts.strict.json b/linter/test/classB.ts.strict.json index e44fd80c4..dc2b9ced4 100644 --- a/linter/test/classB.ts.strict.json +++ b/linter/test/classB.ts.strict.json @@ -15,8 +15,8 @@ ], "nodes": [ { - "line": 24, - "column": 5, + "line": 25, + "column": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test/function_object_methods.ts.relax.json b/linter/test/function_object_methods.ts.relax.json index 96e3fcaf1..8b8fe68fe 100644 --- a/linter/test/function_object_methods.ts.relax.json +++ b/linter/test/function_object_methods.ts.relax.json @@ -190,29 +190,29 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)" }, { - "line": 118, - "column": 7, + "line": 119, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 121, - "column": 7, + "line": 122, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 124, - "column": 7, + "line": 125, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 127, - "column": 7, + "line": 128, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test/function_object_methods.ts.strict.json b/linter/test/function_object_methods.ts.strict.json index e90572ea9..a73e4ace1 100644 --- a/linter/test/function_object_methods.ts.strict.json +++ b/linter/test/function_object_methods.ts.strict.json @@ -197,8 +197,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 118, - "column": 7, + "line": 119, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -218,15 +218,15 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 121, - "column": 7, + "line": 122, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 124, - "column": 7, + "line": 125, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -239,8 +239,8 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)" }, { - "line": 127, - "column": 7, + "line": 128, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test/functions.ts.autofix.json b/linter/test/functions.ts.autofix.json index 944c5bf6b..0b6af45e6 100755 --- a/linter/test/functions.ts.autofix.json +++ b/linter/test/functions.ts.autofix.json @@ -87,8 +87,8 @@ "rule": "Use generic functions instead of generic arrow functions (arkts-no-generic-lambdas)" }, { - "line": 63, - "column": 1, + "line": 64, + "column": 3, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", diff --git a/linter/test/functions.ts.relax.json b/linter/test/functions.ts.relax.json index 1e86ab2f1..6729c50d2 100644 --- a/linter/test/functions.ts.relax.json +++ b/linter/test/functions.ts.relax.json @@ -64,8 +64,8 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { - "line": 63, - "column": 1, + "line": 64, + "column": 3, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test/functions.ts.strict.json b/linter/test/functions.ts.strict.json index a1c2214e5..d57b74aa3 100644 --- a/linter/test/functions.ts.strict.json +++ b/linter/test/functions.ts.strict.json @@ -78,8 +78,8 @@ "rule": "Use generic functions instead of generic arrow functions (arkts-no-generic-lambdas)" }, { - "line": 63, - "column": 1, + "line": 64, + "column": 3, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test/prototype_assignment.ts.autofix.json b/linter/test/prototype_assignment.ts.autofix.json index 381cadf69..c1e3b5c63 100755 --- a/linter/test/prototype_assignment.ts.autofix.json +++ b/linter/test/prototype_assignment.ts.autofix.json @@ -15,8 +15,8 @@ ], "nodes": [ { - "line": 19, - "column": 1, + "line": 26, + "column": 19, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", @@ -31,8 +31,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 20, - "column": 20, + "line": 21, + "column": 5, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", @@ -71,8 +71,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 30, - "column": 26, + "line": 31, + "column": 12, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", diff --git a/linter/test/prototype_assignment.ts.relax.json b/linter/test/prototype_assignment.ts.relax.json index dc1c5be2c..79345f433 100644 --- a/linter/test/prototype_assignment.ts.relax.json +++ b/linter/test/prototype_assignment.ts.relax.json @@ -15,15 +15,15 @@ ], "nodes": [ { - "line": 19, - "column": 1, + "line": 26, + "column": 19, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" }, { - "line": 20, - "column": 20, + "line": 21, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -50,8 +50,8 @@ "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)" }, { - "line": 30, - "column": 26, + "line": 31, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test/prototype_assignment.ts.strict.json b/linter/test/prototype_assignment.ts.strict.json index ad3f54292..f1ebe772d 100644 --- a/linter/test/prototype_assignment.ts.strict.json +++ b/linter/test/prototype_assignment.ts.strict.json @@ -15,8 +15,8 @@ ], "nodes": [ { - "line": 19, - "column": 1, + "line": 26, + "column": 19, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -29,8 +29,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 20, - "column": 20, + "line": 21, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -64,8 +64,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 30, - "column": 26, + "line": 31, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test/this_type.ts.relax.json b/linter/test/this_type.ts.relax.json index 1508e5c96..7afe8f170 100644 --- a/linter/test/this_type.ts.relax.json +++ b/linter/test/this_type.ts.relax.json @@ -50,28 +50,28 @@ "problem": "ThisType" }, { - "line": 72, - "column": 3, + "line": 73, + "column": 5, "problem": "FunctionContainsThis" }, { - "line": 77, - "column": 9, + "line": 78, + "column": 3, "problem": "FunctionContainsThis" }, { - "line": 80, - "column": 10, + "line": 81, + "column": 3, "problem": "FunctionContainsThis" }, { - "line": 83, - "column": 1, + "line": 84, + "column": 3, "problem": "FunctionContainsThis" }, { - "line": 88, - "column": 3, + "line": 89, + "column": 5, "problem": "FunctionContainsThis" } ] diff --git a/linter/test/this_type.ts.strict.json b/linter/test/this_type.ts.strict.json index 1631a08e6..1e2f8ec86 100644 --- a/linter/test/this_type.ts.strict.json +++ b/linter/test/this_type.ts.strict.json @@ -50,13 +50,13 @@ "problem": "ThisType" }, { - "line": 72, - "column": 3, + "line": 73, + "column": 5, "problem": "FunctionContainsThis" }, { - "line": 77, - "column": 9, + "line": 78, + "column": 3, "problem": "FunctionContainsThis" }, { @@ -65,18 +65,18 @@ "problem": "FunctionExpression" }, { - "line": 80, - "column": 10, + "line": 81, + "column": 3, "problem": "FunctionContainsThis" }, { - "line": 83, - "column": 1, + "line": 84, + "column": 3, "problem": "FunctionContainsThis" }, { - "line": 88, - "column": 3, + "line": 89, + "column": 5, "problem": "FunctionContainsThis" } ] diff --git a/linter/test/utility_types.ts.relax.json b/linter/test/utility_types.ts.relax.json index 63a56e5cd..b274ba451 100644 --- a/linter/test/utility_types.ts.relax.json +++ b/linter/test/utility_types.ts.relax.json @@ -250,8 +250,8 @@ "problem": "UtilityType" }, { - "line": 173, - "column": 3, + "line": 174, + "column": 12, "problem": "FunctionContainsThis" }, { @@ -270,8 +270,8 @@ "problem": "FunctionApplyBindCall" }, { - "line": 183, - "column": 3, + "line": 184, + "column": 12, "problem": "FunctionContainsThis" }, { @@ -290,8 +290,13 @@ "problem": "FunctionApplyBindCall" }, { - "line": 192, - "column": 1, + "line": 208, + "column": 9, + "problem": "FunctionContainsThis" + }, + { + "line": 209, + "column": 9, "problem": "FunctionContainsThis" }, { diff --git a/linter/test/utility_types.ts.strict.json b/linter/test/utility_types.ts.strict.json index cb2916b9d..bbda8979a 100644 --- a/linter/test/utility_types.ts.strict.json +++ b/linter/test/utility_types.ts.strict.json @@ -260,8 +260,8 @@ "problem": "UtilityType" }, { - "line": 173, - "column": 3, + "line": 174, + "column": 12, "problem": "FunctionContainsThis" }, { @@ -295,8 +295,8 @@ "problem": "FunctionApplyBindCall" }, { - "line": 183, - "column": 3, + "line": 184, + "column": 12, "problem": "FunctionContainsThis" }, { @@ -320,8 +320,13 @@ "problem": "FunctionApplyBindCall" }, { - "line": 192, - "column": 1, + "line": 208, + "column": 9, + "problem": "FunctionContainsThis" + }, + { + "line": 209, + "column": 9, "problem": "FunctionContainsThis" }, { diff --git a/linter/test_rules/rule136.ts.autofix.json b/linter/test_rules/rule136.ts.autofix.json index fb3ab2780..2f60e039c 100644 --- a/linter/test_rules/rule136.ts.autofix.json +++ b/linter/test_rules/rule136.ts.autofix.json @@ -17,8 +17,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 1, - "column": 9, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", @@ -49,8 +49,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 11, - "column": 17, + "line": 12, + "column": 12, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", diff --git a/linter/test_rules/rule136.ts.relax.json b/linter/test_rules/rule136.ts.relax.json index d9d652719..ccffcfe55 100644 --- a/linter/test_rules/rule136.ts.relax.json +++ b/linter/test_rules/rule136.ts.relax.json @@ -1,8 +1,8 @@ { "nodes": [ { - "line": 1, - "column": 9, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -22,8 +22,8 @@ "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)" }, { - "line": 11, - "column": 17, + "line": 12, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test_rules/rule136.ts.strict.json b/linter/test_rules/rule136.ts.strict.json index 1df9367d3..03f0cbbe5 100644 --- a/linter/test_rules/rule136.ts.strict.json +++ b/linter/test_rules/rule136.ts.strict.json @@ -15,8 +15,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 1, - "column": 9, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" @@ -43,8 +43,8 @@ "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)" }, { - "line": 11, - "column": 17, + "line": 12, + "column": 12, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test_rules/rule93.ts.autofix.json b/linter/test_rules/rule93.ts.autofix.json index 872acd394..819c25194 100644 --- a/linter/test_rules/rule93.ts.autofix.json +++ b/linter/test_rules/rule93.ts.autofix.json @@ -1,8 +1,8 @@ { "nodes": [ { - "line": 1, - "column": 1, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "autofixable": false, "suggest": "", diff --git a/linter/test_rules/rule93.ts.relax.json b/linter/test_rules/rule93.ts.relax.json index a16283a18..772a1f628 100644 --- a/linter/test_rules/rule93.ts.relax.json +++ b/linter/test_rules/rule93.ts.relax.json @@ -1,8 +1,8 @@ { "nodes": [ { - "line": 1, - "column": 1, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" diff --git a/linter/test_rules/rule93.ts.strict.json b/linter/test_rules/rule93.ts.strict.json index a16283a18..772a1f628 100644 --- a/linter/test_rules/rule93.ts.strict.json +++ b/linter/test_rules/rule93.ts.strict.json @@ -1,8 +1,8 @@ { "nodes": [ { - "line": 1, - "column": 1, + "line": 2, + "column": 5, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)" -- Gitee From 21a620d312a3ea0cd5816331f047722d934485d1 Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Fri, 3 Nov 2023 13:31:59 +0300 Subject: [PATCH 24/49] [ArkTS][Linter] Fix suppression of strict diagnostics for overloaded functions (#14328) --- linter/src/TypeScriptLinter.ts | 4 +++ .../LibraryTypeCallDiagnosticChecker.ts | 9 +++++++ linter/test/null_check_calls.ts.relax.json | 21 +++++++++------- linter/test/null_check_calls.ts.strict.json | 25 +++++++++++-------- .../test/undefined_check_calls.ts.relax.json | 7 ------ .../test/undefined_check_calls.ts.strict.json | 7 ------ 6 files changed, 40 insertions(+), 33 deletions(-) diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 863cd0542..f9d81f931 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -50,6 +50,7 @@ import { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; import { DiagnosticChecker } from './utils/functions/DiagnosticChecker'; import { ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE, + NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE, TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE, LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; @@ -1566,6 +1567,9 @@ export class TypeScriptLinter { [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { return this.checkInRange(rangesToFilter, pos); }, + [NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE]: (pos: number) => { + return this.checkInRange([{begin: callExpr.pos, end: callExpr.end}], pos); + }, [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { return this.checkInRange(rangesToFilter, pos); } diff --git a/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts b/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts index 72778922b..3adf03b3e 100644 --- a/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts +++ b/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts @@ -24,6 +24,7 @@ export const TYPE_NULL_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE = /^Type 'null' is not ass export const TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE = /^Type 'undefined' is not assignable to type '.*'\.$/; export const ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE = 2345; +export const NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE = 2769; export const ARGUMENT_OF_TYPE_NULL_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE = /^Argument of type 'null' is not assignable to parameter of type '.*'\.$/; export const ARGUMENT_OF_TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE = /^Argument of type 'undefined' is not assignable to parameter of type '.*'\.$/; @@ -64,6 +65,14 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { return false; } } + if (chain.code == ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE) { + if (this.inLibCall && chain.messageText.match(ARGUMENT_OF_TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE)) { + return false; + } + if (this.inLibCall && chain.messageText.match(ARGUMENT_OF_TYPE_NULL_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE)) { + return false; + } + } return chain.next == undefined ? true : this.checkMessageChain(chain.next[0]); }; diff --git a/linter/test/null_check_calls.ts.relax.json b/linter/test/null_check_calls.ts.relax.json index 8d879ca42..dda25acbf 100644 --- a/linter/test/null_check_calls.ts.relax.json +++ b/linter/test/null_check_calls.ts.relax.json @@ -14,30 +14,33 @@ "limitations under the License." ], "nodes": [ - { - "line": 33, - "column": 12, - "problem": "StrictDiagnostic" - }, { "line": 37, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'number[]'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'number[]'." }, { "line": 42, "column": 20, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'number'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'number'." }, { "line": 43, "column": 42, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'number | null' is not assignable to parameter of type 'number'.\n Type 'null' is not assignable to type 'number'.", + "rule": "Argument of type 'number | null' is not assignable to parameter of type 'number'.\n Type 'null' is not assignable to type 'number'." }, { "line": 47, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'number | null' is not assignable to parameter of type 'number'.\n Type 'null' is not assignable to type 'number'.", + "rule": "Argument of type 'number | null' is not assignable to parameter of type 'number'.\n Type 'null' is not assignable to type 'number'." }, { "line": 52, diff --git a/linter/test/null_check_calls.ts.strict.json b/linter/test/null_check_calls.ts.strict.json index fef4e06af..6ae1263ea 100644 --- a/linter/test/null_check_calls.ts.strict.json +++ b/linter/test/null_check_calls.ts.strict.json @@ -17,32 +17,37 @@ { "line": 43, "column": 1, - "problem": "LimitedReturnTypeInference" - }, - { - "line": 33, - "column": 12, - "problem": "StrictDiagnostic" + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)" }, { "line": 37, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'number[]'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'number[]'." }, { "line": 42, "column": 20, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'null' is not assignable to parameter of type 'number'.", + "rule": "Argument of type 'null' is not assignable to parameter of type 'number'." }, { "line": 43, "column": 42, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'number | null' is not assignable to parameter of type 'number'.\n Type 'null' is not assignable to type 'number'.", + "rule": "Argument of type 'number | null' is not assignable to parameter of type 'number'.\n Type 'null' is not assignable to type 'number'." }, { "line": 47, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Argument of type 'number | null' is not assignable to parameter of type 'number'.\n Type 'null' is not assignable to type 'number'.", + "rule": "Argument of type 'number | null' is not assignable to parameter of type 'number'.\n Type 'null' is not assignable to type 'number'." }, { "line": 52, diff --git a/linter/test/undefined_check_calls.ts.relax.json b/linter/test/undefined_check_calls.ts.relax.json index 33bf02fda..21f9e8691 100644 --- a/linter/test/undefined_check_calls.ts.relax.json +++ b/linter/test/undefined_check_calls.ts.relax.json @@ -14,13 +14,6 @@ "limitations under the License." ], "nodes": [ - { - "line": 33, - "column": 12, - "problem": "StrictDiagnostic", - "suggest": "No overload matches this call.\n Overload 1 of 2, '(func: Function, ...args: unknown[]): Promise', gave the following error.\n Argument of type 'undefined' is not assignable to parameter of type 'Function'.\n Overload 2 of 2, '(group: TaskGroup, priority?: Priority | undefined): Promise', gave the following error.\n Argument of type 'undefined' is not assignable to parameter of type 'TaskGroup'.", - "rule": "No overload matches this call.\n Overload 1 of 2, '(func: Function, ...args: unknown[]): Promise', gave the following error.\n Argument of type 'undefined' is not assignable to parameter of type 'Function'.\n Overload 2 of 2, '(group: TaskGroup, priority?: Priority | undefined): Promise', gave the following error.\n Argument of type 'undefined' is not assignable to parameter of type 'TaskGroup'." - }, { "line": 37, "column": 5, diff --git a/linter/test/undefined_check_calls.ts.strict.json b/linter/test/undefined_check_calls.ts.strict.json index 33bf02fda..21f9e8691 100644 --- a/linter/test/undefined_check_calls.ts.strict.json +++ b/linter/test/undefined_check_calls.ts.strict.json @@ -14,13 +14,6 @@ "limitations under the License." ], "nodes": [ - { - "line": 33, - "column": 12, - "problem": "StrictDiagnostic", - "suggest": "No overload matches this call.\n Overload 1 of 2, '(func: Function, ...args: unknown[]): Promise', gave the following error.\n Argument of type 'undefined' is not assignable to parameter of type 'Function'.\n Overload 2 of 2, '(group: TaskGroup, priority?: Priority | undefined): Promise', gave the following error.\n Argument of type 'undefined' is not assignable to parameter of type 'TaskGroup'.", - "rule": "No overload matches this call.\n Overload 1 of 2, '(func: Function, ...args: unknown[]): Promise', gave the following error.\n Argument of type 'undefined' is not assignable to parameter of type 'Function'.\n Overload 2 of 2, '(group: TaskGroup, priority?: Priority | undefined): Promise', gave the following error.\n Argument of type 'undefined' is not assignable to parameter of type 'TaskGroup'." - }, { "line": 37, "column": 5, -- Gitee From 5b6e3499a02d99c3781309da762a2ad6775e4fc1 Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Thu, 9 Nov 2023 11:48:46 +0300 Subject: [PATCH 25/49] [ArkTS][Linter] Allow processing of modules `oh_modules Signed-off-by: Urakov Alexandr --- linter-4.2/src/IsFileFromModuleCallback.ts | 16 ++++++++++++++ linter-4.2/src/LintOptions.ts | 2 ++ linter-4.2/src/LinterRunner.ts | 17 ++++++++++++--- linter-4.2/src/Utils.ts | 4 +++- linter/src/IsFileFromModuleCallback.ts | 16 ++++++++++++++ linter/src/LintOptions.ts | 2 ++ linter/src/LinterRunner.ts | 23 +++++++++++++++++---- linter/src/utils/consts/ArktsIgnorePaths.ts | 7 ++++++- 8 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 linter-4.2/src/IsFileFromModuleCallback.ts create mode 100644 linter/src/IsFileFromModuleCallback.ts diff --git a/linter-4.2/src/IsFileFromModuleCallback.ts b/linter-4.2/src/IsFileFromModuleCallback.ts new file mode 100644 index 000000000..57be93846 --- /dev/null +++ b/linter-4.2/src/IsFileFromModuleCallback.ts @@ -0,0 +1,16 @@ +2/* + * Copyright (c) 2023-2023 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. + */ + +export type IsFileFromModuleCallback = (fileFsPath: string) => boolean; diff --git a/linter-4.2/src/LintOptions.ts b/linter-4.2/src/LintOptions.ts index a2d1184f5..6e3011c9e 100644 --- a/linter-4.2/src/LintOptions.ts +++ b/linter-4.2/src/LintOptions.ts @@ -15,10 +15,12 @@ import * as ts from 'typescript'; import { CommandLineOptions } from './CommandLineOptions'; +import { IsFileFromModuleCallback } from './IsFileFromModuleCallback'; // common options interface, additional fields may be used by plugins export interface LintOptions { cmdOptions: CommandLineOptions; tsProgram?: ts.Program; + isFileFromModuleCb?: IsFileFromModuleCallback; [key: string]: any; } diff --git a/linter-4.2/src/LinterRunner.ts b/linter-4.2/src/LinterRunner.ts index dca4d3dfd..d266f285d 100644 --- a/linter-4.2/src/LinterRunner.ts +++ b/linter-4.2/src/LinterRunner.ts @@ -57,9 +57,7 @@ export function lint(options: LintOptions): LintRunResult { } // #13436: ignore-list for ArkTS projects. - inputFiles = inputFiles.filter(input => - !TsUtils.ARKTS_IGNORE_FILES.some(ignore => path.basename(input) === ignore) && - !TsUtils.ARKTS_IGNORE_DIRS.some(ignore => pathContainsDirectory(path.resolve(input), ignore))); + inputFiles = inputFiles.filter(input => shouldProcessFile(options, input)); const srcFiles: ts.SourceFile[] = []; for (const inputFile of inputFiles) { @@ -289,3 +287,16 @@ function runIDEMode(cmdOptions: CommandLineOptions) { fs.unlinkSync(tmpFileName); }); } + +function shouldProcessFile(options: LintOptions, fileFsPath: string) { + if (TsUtils.ARKTS_IGNORE_FILES.some(ignore => path.basename(fileFsPath) === ignore)) { + return false; + } + + if (TsUtils.ARKTS_IGNORE_DIRS_NO_OH_MODULES.some(ignore => pathContainsDirectory(path.resolve(fileFsPath), ignore))) { + return false; + } + + return !pathContainsDirectory(path.resolve(fileFsPath), TsUtils.ARKTS_IGNORE_DIRS_OH_MODULES) || + (options.isFileFromModuleCb !== undefined && options.isFileFromModuleCb(fileFsPath)); +} diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index c2f32b89a..9c6531412 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -193,7 +193,9 @@ export class TsUtils { 'BigUint64Array', ] - static readonly ARKTS_IGNORE_DIRS = ['node_modules', 'oh_modules', 'build', '.preview']; + static readonly ARKTS_IGNORE_DIRS_NO_OH_MODULES = ['node_modules', 'build', '.preview']; + static readonly ARKTS_IGNORE_DIRS_OH_MODULES = 'oh_modules'; + static readonly ARKTS_IGNORE_DIRS = [...TsUtils.ARKTS_IGNORE_DIRS_NO_OH_MODULES, TsUtils.ARKTS_IGNORE_DIRS_OH_MODULES]; static readonly ARKTS_IGNORE_FILES = ['hvigorfile.ts']; constructor(private tsTypeChecker: ts.TypeChecker, private testMode: boolean) { diff --git a/linter/src/IsFileFromModuleCallback.ts b/linter/src/IsFileFromModuleCallback.ts new file mode 100644 index 000000000..57be93846 --- /dev/null +++ b/linter/src/IsFileFromModuleCallback.ts @@ -0,0 +1,16 @@ +2/* + * Copyright (c) 2023-2023 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. + */ + +export type IsFileFromModuleCallback = (fileFsPath: string) => boolean; diff --git a/linter/src/LintOptions.ts b/linter/src/LintOptions.ts index 621b43dc2..3a8758143 100644 --- a/linter/src/LintOptions.ts +++ b/linter/src/LintOptions.ts @@ -17,6 +17,7 @@ import * as ts from 'typescript'; import { CommandLineOptions } from './CommandLineOptions'; import { IncrementalLintInfo } from './IncrementalLintInfo'; import { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; +import { IsFileFromModuleCallback } from "./IsFileFromModuleCallback"; // common options interface, additional fields may be used by plugins export interface LintOptions { @@ -26,5 +27,6 @@ export interface LintOptions { incrementalLintInfo?: IncrementalLintInfo; tsProgram?: ts.Program; reportAutofixCb?: ReportAutofixCallback; + isFileFromModuleCb?: IsFileFromModuleCallback; [key: string]: any; } diff --git a/linter/src/LinterRunner.ts b/linter/src/LinterRunner.ts index 1494b65fd..4a5a147fd 100644 --- a/linter/src/LinterRunner.ts +++ b/linter/src/LinterRunner.ts @@ -28,7 +28,11 @@ import { TSCCompiledProgram, TSCCompiledProgramSimple, TSCCompiledProgramWithDia import { mergeArrayMaps } from './utils/functions/MergeArrayMaps'; import { getTscDiagnostics } from './ts-diagnostics/GetTscDiagnostics'; import { transformTscDiagnostics } from './ts-diagnostics/TransformTscDiagnostics'; -import { ARKTS_IGNORE_DIRS, ARKTS_IGNORE_FILES } from './utils/consts/ArktsIgnorePaths'; +import { + ARKTS_IGNORE_DIRS_NO_OH_MODULES, + ARKTS_IGNORE_DIRS_OH_MODULES, + ARKTS_IGNORE_FILES +} from './utils/consts/ArktsIgnorePaths'; import { pathContainsDirectory } from './utils/functions/PathHelper'; export function lint(options: LintOptions): LintRunResult { @@ -52,9 +56,7 @@ export function lint(options: LintOptions): LintRunResult { } // #13436: ignore-list for ArkTS projects. - inputFiles = inputFiles.filter(input => - !ARKTS_IGNORE_FILES.some(ignore => path.basename(input) === ignore) && - !ARKTS_IGNORE_DIRS.some(ignore => pathContainsDirectory(path.resolve(input), ignore))); + inputFiles = inputFiles.filter(input => shouldProcessFile(options, input)); const srcFiles: ts.SourceFile[] = []; for (const inputFile of inputFiles) { @@ -190,3 +192,16 @@ function logProblemsPercentageByFeatures(linter: TypeScriptLinter) { consoleLog(faultDesc[i].padEnd(55, ' '), pecentage, '[', nodes, ' constructs / ', lines, ' lines]'); } } + +function shouldProcessFile(options: LintOptions, fileFsPath: string) { + if (ARKTS_IGNORE_FILES.some(ignore => path.basename(fileFsPath) === ignore)) { + return false; + } + + if (ARKTS_IGNORE_DIRS_NO_OH_MODULES.some(ignore => pathContainsDirectory(path.resolve(fileFsPath), ignore))) { + return false; + } + + return !pathContainsDirectory(path.resolve(fileFsPath), ARKTS_IGNORE_DIRS_OH_MODULES) || + (options.isFileFromModuleCb !== undefined && options.isFileFromModuleCb(fileFsPath)); +} diff --git a/linter/src/utils/consts/ArktsIgnorePaths.ts b/linter/src/utils/consts/ArktsIgnorePaths.ts index ca29111ac..73e063e4b 100644 --- a/linter/src/utils/consts/ArktsIgnorePaths.ts +++ b/linter/src/utils/consts/ArktsIgnorePaths.ts @@ -13,5 +13,10 @@ * limitations under the License. */ -export const ARKTS_IGNORE_DIRS = ['node_modules', 'oh_modules', 'build', '.preview']; +export const ARKTS_IGNORE_DIRS_NO_OH_MODULES = ['node_modules', 'build', '.preview']; + +export const ARKTS_IGNORE_DIRS_OH_MODULES = 'oh_modules'; + +export const ARKTS_IGNORE_DIRS = [...ARKTS_IGNORE_DIRS_NO_OH_MODULES, ARKTS_IGNORE_DIRS_OH_MODULES]; + export const ARKTS_IGNORE_FILES = ['hvigorfile.ts']; -- Gitee From 7d952e46ac0117a2133ef25b373f20217332d66c Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Thu, 9 Nov 2023 11:49:37 +0300 Subject: [PATCH 26/49] [ArkTS][Linter] Fix typo in rule #116 Signed-off-by: Urakov Alexandr --- linter-4.2/src/CookBookMsg.ts | 2 +- linter-4.2/test/ambient_module.ts.relax.json | 4 ++-- linter-4.2/test/ambient_module.ts.strict.json | 4 ++-- linter-4.2/test_rules/rule116.ts.autofix.json | 16 +++++++++++++++- linter-4.2/test_rules/rule116.ts.relax.json | 16 +++++++++++++++- linter-4.2/test_rules/rule116.ts.strict.json | 16 +++++++++++++++- linter-4.2/test_rules/rule129.ts.autofix.json | 17 ++++++++++++++++- linter-4.2/test_rules/rule129.ts.relax.json | 17 ++++++++++++++++- linter-4.2/test_rules/rule129.ts.strict.json | 17 ++++++++++++++++- linter/src/CookBookMsg.ts | 2 +- linter/src/LintOptions.ts | 2 +- linter/test/ambient_module.ts.relax.json | 4 ++-- linter/test/ambient_module.ts.strict.json | 4 ++-- linter/test_rules/rule116.ts.autofix.json | 16 +++++++++++++++- linter/test_rules/rule116.ts.relax.json | 16 +++++++++++++++- linter/test_rules/rule116.ts.strict.json | 16 +++++++++++++++- linter/test_rules/rule129.ts.autofix.json | 17 ++++++++++++++++- linter/test_rules/rule129.ts.relax.json | 17 ++++++++++++++++- linter/test_rules/rule129.ts.strict.json | 17 ++++++++++++++++- 19 files changed, 197 insertions(+), 23 deletions(-) mode change 100644 => 100755 linter-4.2/test/ambient_module.ts.relax.json mode change 100644 => 100755 linter-4.2/test/ambient_module.ts.strict.json diff --git a/linter-4.2/src/CookBookMsg.ts b/linter-4.2/src/CookBookMsg.ts index e505f59a8..2bb270627 100644 --- a/linter-4.2/src/CookBookMsg.ts +++ b/linter-4.2/src/CookBookMsg.ts @@ -135,7 +135,7 @@ cookBookTag[112] = ''; cookBookTag[113] = '"enum" declaration merging is not supported (arkts-no-enum-merging)'; cookBookTag[114] = 'Namespaces cannot be used as objects (arkts-no-ns-as-obj)'; cookBookTag[115] = ''; -cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)'; +cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)'; cookBookTag[117] = ''; cookBookTag[118] = 'Special import type declarations are not supported (arkts-no-special-imports)'; cookBookTag[119] = 'Importing a module for side-effects only is not supported (arkts-no-side-effects-imports)'; diff --git a/linter-4.2/test/ambient_module.ts.relax.json b/linter-4.2/test/ambient_module.ts.relax.json old mode 100644 new mode 100755 index 543d0a12a..81f9bd90b --- a/linter-4.2/test/ambient_module.ts.relax.json +++ b/linter-4.2/test/ambient_module.ts.relax.json @@ -26,7 +26,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 20, @@ -47,7 +47,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 25, diff --git a/linter-4.2/test/ambient_module.ts.strict.json b/linter-4.2/test/ambient_module.ts.strict.json old mode 100644 new mode 100755 index 543d0a12a..81f9bd90b --- a/linter-4.2/test/ambient_module.ts.strict.json +++ b/linter-4.2/test/ambient_module.ts.strict.json @@ -26,7 +26,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 20, @@ -47,7 +47,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 25, diff --git a/linter-4.2/test_rules/rule116.ts.autofix.json b/linter-4.2/test_rules/rule116.ts.autofix.json index f3a5f41b3..d623882bd 100644 --- a/linter-4.2/test_rules/rule116.ts.autofix.json +++ b/linter-4.2/test_rules/rule116.ts.autofix.json @@ -1,4 +1,18 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 3, @@ -6,7 +20,7 @@ "problem": "NonDeclarationInNamespace", "autofixable": false, "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule116.ts.relax.json b/linter-4.2/test_rules/rule116.ts.relax.json index 3259498ae..a13f450c7 100644 --- a/linter-4.2/test_rules/rule116.ts.relax.json +++ b/linter-4.2/test_rules/rule116.ts.relax.json @@ -1,11 +1,25 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 3, "column": 5, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule116.ts.strict.json b/linter-4.2/test_rules/rule116.ts.strict.json index 3259498ae..a13f450c7 100644 --- a/linter-4.2/test_rules/rule116.ts.strict.json +++ b/linter-4.2/test_rules/rule116.ts.strict.json @@ -1,11 +1,25 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 3, "column": 5, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter-4.2/test_rules/rule129.ts.autofix.json b/linter-4.2/test_rules/rule129.ts.autofix.json index 80fc9c4b1..897f1d325 100644 --- a/linter-4.2/test_rules/rule129.ts.autofix.json +++ b/linter-4.2/test_rules/rule129.ts.autofix.json @@ -1,4 +1,18 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 4, @@ -6,7 +20,7 @@ "problem": "NonDeclarationInNamespace", "autofixable": false, "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 2, @@ -29,6 +43,7 @@ "column": 5, "problem": "ImportAfterStatement", "autofixable": false, + "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)" } ] diff --git a/linter-4.2/test_rules/rule129.ts.relax.json b/linter-4.2/test_rules/rule129.ts.relax.json index ab877e8e9..0cb1a6d72 100644 --- a/linter-4.2/test_rules/rule129.ts.relax.json +++ b/linter-4.2/test_rules/rule129.ts.relax.json @@ -1,11 +1,25 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 4, "column": 9, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 2, @@ -25,6 +39,7 @@ "line": 8, "column": 5, "problem": "ImportAfterStatement", + "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)" } ] diff --git a/linter-4.2/test_rules/rule129.ts.strict.json b/linter-4.2/test_rules/rule129.ts.strict.json index ab877e8e9..0cb1a6d72 100644 --- a/linter-4.2/test_rules/rule129.ts.strict.json +++ b/linter-4.2/test_rules/rule129.ts.strict.json @@ -1,11 +1,25 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 4, "column": 9, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 2, @@ -25,6 +39,7 @@ "line": 8, "column": 5, "problem": "ImportAfterStatement", + "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)" } ] diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index d8f053a4e..dc0116777 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -135,7 +135,7 @@ cookBookTag[112] = ''; cookBookTag[113] = '"enum" declaration merging is not supported (arkts-no-enum-merging)'; cookBookTag[114] = 'Namespaces cannot be used as objects (arkts-no-ns-as-obj)'; cookBookTag[115] = ''; -cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)'; +cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)'; cookBookTag[117] = ''; cookBookTag[118] = ''; cookBookTag[119] = 'Importing a module for side-effects only is not supported (arkts-no-side-effects-imports)'; diff --git a/linter/src/LintOptions.ts b/linter/src/LintOptions.ts index 3a8758143..ce7a7a50e 100644 --- a/linter/src/LintOptions.ts +++ b/linter/src/LintOptions.ts @@ -17,7 +17,7 @@ import * as ts from 'typescript'; import { CommandLineOptions } from './CommandLineOptions'; import { IncrementalLintInfo } from './IncrementalLintInfo'; import { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; -import { IsFileFromModuleCallback } from "./IsFileFromModuleCallback"; +import { IsFileFromModuleCallback } from './IsFileFromModuleCallback'; // common options interface, additional fields may be used by plugins export interface LintOptions { diff --git a/linter/test/ambient_module.ts.relax.json b/linter/test/ambient_module.ts.relax.json index 543d0a12a..81f9bd90b 100755 --- a/linter/test/ambient_module.ts.relax.json +++ b/linter/test/ambient_module.ts.relax.json @@ -26,7 +26,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 20, @@ -47,7 +47,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 25, diff --git a/linter/test/ambient_module.ts.strict.json b/linter/test/ambient_module.ts.strict.json index 543d0a12a..81f9bd90b 100755 --- a/linter/test/ambient_module.ts.strict.json +++ b/linter/test/ambient_module.ts.strict.json @@ -26,7 +26,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 20, @@ -47,7 +47,7 @@ "column": 3, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 25, diff --git a/linter/test_rules/rule116.ts.autofix.json b/linter/test_rules/rule116.ts.autofix.json index f3a5f41b3..d623882bd 100644 --- a/linter/test_rules/rule116.ts.autofix.json +++ b/linter/test_rules/rule116.ts.autofix.json @@ -1,4 +1,18 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 3, @@ -6,7 +20,7 @@ "problem": "NonDeclarationInNamespace", "autofixable": false, "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter/test_rules/rule116.ts.relax.json b/linter/test_rules/rule116.ts.relax.json index 3259498ae..a13f450c7 100644 --- a/linter/test_rules/rule116.ts.relax.json +++ b/linter/test_rules/rule116.ts.relax.json @@ -1,11 +1,25 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 3, "column": 5, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter/test_rules/rule116.ts.strict.json b/linter/test_rules/rule116.ts.strict.json index 3259498ae..a13f450c7 100644 --- a/linter/test_rules/rule116.ts.strict.json +++ b/linter/test_rules/rule116.ts.strict.json @@ -1,11 +1,25 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 3, "column": 5, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" } ] } \ No newline at end of file diff --git a/linter/test_rules/rule129.ts.autofix.json b/linter/test_rules/rule129.ts.autofix.json index 80fc9c4b1..897f1d325 100644 --- a/linter/test_rules/rule129.ts.autofix.json +++ b/linter/test_rules/rule129.ts.autofix.json @@ -1,4 +1,18 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 4, @@ -6,7 +20,7 @@ "problem": "NonDeclarationInNamespace", "autofixable": false, "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 2, @@ -29,6 +43,7 @@ "column": 5, "problem": "ImportAfterStatement", "autofixable": false, + "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)" } ] diff --git a/linter/test_rules/rule129.ts.relax.json b/linter/test_rules/rule129.ts.relax.json index ab877e8e9..0cb1a6d72 100644 --- a/linter/test_rules/rule129.ts.relax.json +++ b/linter/test_rules/rule129.ts.relax.json @@ -1,11 +1,25 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 4, "column": 9, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 2, @@ -25,6 +39,7 @@ "line": 8, "column": 5, "problem": "ImportAfterStatement", + "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)" } ] diff --git a/linter/test_rules/rule129.ts.strict.json b/linter/test_rules/rule129.ts.strict.json index ab877e8e9..0cb1a6d72 100644 --- a/linter/test_rules/rule129.ts.strict.json +++ b/linter/test_rules/rule129.ts.strict.json @@ -1,11 +1,25 @@ { + "copyright": [ + "Copyright (c) 2023-2023 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." + ], "nodes": [ { "line": 4, "column": 9, "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statement) (arkts-no-ns-statements)" + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)" }, { "line": 2, @@ -25,6 +39,7 @@ "line": 8, "column": 5, "problem": "ImportAfterStatement", + "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)" } ] -- Gitee From 9d2215d775f342623af94f9d2ffd2de06c85ae71 Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Thu, 9 Nov 2023 13:31:18 +0300 Subject: [PATCH 27/49] [ArkTS][Linter] Fix typo from !31 Signed-off-by: Urakov Alexandr --- linter-4.2/src/IsFileFromModuleCallback.ts | 2 +- linter/src/IsFileFromModuleCallback.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linter-4.2/src/IsFileFromModuleCallback.ts b/linter-4.2/src/IsFileFromModuleCallback.ts index 57be93846..46ed92b86 100644 --- a/linter-4.2/src/IsFileFromModuleCallback.ts +++ b/linter-4.2/src/IsFileFromModuleCallback.ts @@ -1,4 +1,4 @@ -2/* +/* * Copyright (c) 2023-2023 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. diff --git a/linter/src/IsFileFromModuleCallback.ts b/linter/src/IsFileFromModuleCallback.ts index 57be93846..46ed92b86 100644 --- a/linter/src/IsFileFromModuleCallback.ts +++ b/linter/src/IsFileFromModuleCallback.ts @@ -1,4 +1,4 @@ -2/* +/* * Copyright (c) 2023-2023 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. -- Gitee From 7462825935c087f29ded06b69be9954a6631a84b Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Thu, 9 Nov 2023 21:20:43 +0300 Subject: [PATCH 28/49] [ArkTS Linter] Fix #14399 Change-Id: I8bdc67e7abef3cd8e565e0a7112b12cc634e19b6 Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 4 +++- linter-4.2/test/dynamic_lib.d.ts | 4 +++- linter-4.2/test/dynamic_object_literals.ts | 14 ++++++++++++-- linter/src/TypeScriptLinter.ts | 4 +++- linter/test/dynamic_lib.d.ts | 4 +++- linter/test/dynamic_object_literals.ts | 14 ++++++++++++-- 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index efa0d583f..91aae8d38 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -710,13 +710,15 @@ export class TypeScriptLinter { ) { // We can use literals as property names only when creating Record or any interop instances. let isRecordObjectInitializer = false; + let isLibraryType = false; let isDynamic = false; if (ts.isPropertyAssignment(node)) { let objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); if (objectLiteralType) { isRecordObjectInitializer = this.tsUtils.isStdRecordType(objectLiteralType); - isDynamic = this.tsUtils.isLibraryType(objectLiteralType) || this.tsUtils.isDynamicLiteralInitializer(node.parent); + isLibraryType = this.tsUtils.isLibraryType(objectLiteralType); } + isDynamic = isLibraryType || this.tsUtils.isDynamicLiteralInitializer(node.parent); } if (!isRecordObjectInitializer && !isDynamic) { diff --git a/linter-4.2/test/dynamic_lib.d.ts b/linter-4.2/test/dynamic_lib.d.ts index 843931397..85dddff2c 100644 --- a/linter-4.2/test/dynamic_lib.d.ts +++ b/linter-4.2/test/dynamic_lib.d.ts @@ -96,4 +96,6 @@ export declare function bad_func(): A & B; export type IndexedSignatureType = { [key: string]: string; -} \ No newline at end of file +} + +export declare function postCardAction(comp: Object, action: Object): void; \ No newline at end of file diff --git a/linter-4.2/test/dynamic_object_literals.ts b/linter-4.2/test/dynamic_object_literals.ts index fae9413ea..dc4de64df 100644 --- a/linter-4.2/test/dynamic_object_literals.ts +++ b/linter-4.2/test/dynamic_object_literals.ts @@ -25,7 +25,8 @@ import { padding, margin, position, - IndexedSignatureType + IndexedSignatureType, + postCardAction } from "./dynamic_lib" function main(): void { @@ -94,4 +95,13 @@ function typeAliasLitAsPropName(): IndexedSignatureType { 'b': '2', 'c': '3' } -} \ No newline at end of file +} + +// #14399 +postCardAction({}, { + "action": 'router', + "abilityName": 'SomeAbility', + "params": { + "message": 'add detail' + } +}); \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 73b403007..309d2c142 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -624,13 +624,15 @@ export class TypeScriptLinter { if (propName && (propName.kind === ts.SyntaxKind.NumericLiteral || propName.kind === ts.SyntaxKind.StringLiteral)) { // We can use literals as property names only when creating Record or any interop instances. let isRecordObjectInitializer = false; + let isLibraryType = false; let isDynamic = false; if (ts.isPropertyAssignment(node)) { let objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); if (objectLiteralType) { isRecordObjectInitializer = this.tsUtils.isStdRecordType(objectLiteralType); - isDynamic = this.tsUtils.isLibraryType(objectLiteralType) || this.tsUtils.isDynamicLiteralInitializer(node.parent); + isLibraryType = this.tsUtils.isLibraryType(objectLiteralType); } + isDynamic = isLibraryType || this.tsUtils.isDynamicLiteralInitializer(node.parent); } if (!isRecordObjectInitializer && !isDynamic) { diff --git a/linter/test/dynamic_lib.d.ts b/linter/test/dynamic_lib.d.ts index 843931397..85dddff2c 100644 --- a/linter/test/dynamic_lib.d.ts +++ b/linter/test/dynamic_lib.d.ts @@ -96,4 +96,6 @@ export declare function bad_func(): A & B; export type IndexedSignatureType = { [key: string]: string; -} \ No newline at end of file +} + +export declare function postCardAction(comp: Object, action: Object): void; \ No newline at end of file diff --git a/linter/test/dynamic_object_literals.ts b/linter/test/dynamic_object_literals.ts index fae9413ea..dc4de64df 100644 --- a/linter/test/dynamic_object_literals.ts +++ b/linter/test/dynamic_object_literals.ts @@ -25,7 +25,8 @@ import { padding, margin, position, - IndexedSignatureType + IndexedSignatureType, + postCardAction } from "./dynamic_lib" function main(): void { @@ -94,4 +95,13 @@ function typeAliasLitAsPropName(): IndexedSignatureType { 'b': '2', 'c': '3' } -} \ No newline at end of file +} + +// #14399 +postCardAction({}, { + "action": 'router', + "abilityName": 'SomeAbility', + "params": { + "message": 'add detail' + } +}); \ No newline at end of file -- Gitee From 943ba43f1a81badd658540bfdfcd1caa5aec516b Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Fri, 3 Nov 2023 16:13:28 +0300 Subject: [PATCH 29/49] [arkts-linter] add pretest codecheck target. add eslint + prettier pipeline for autofixes Signed-off-by: Nazarov Konstantin --- linter/.editorconfig | 6 + linter/.eslintignore | 15 + linter/.eslintrc.json | 193 +++ linter/.prettierrc.json | 10 + linter/README.md | 10 +- linter/package.json | 24 +- linter/src/Autofixer.ts | 205 ++- linter/src/CommandLineOptions.ts | 4 +- linter/src/CommandLineParser.ts | 152 +- linter/src/CompilerWrapper.ts | 4 +- linter/src/CookBookMsg.ts | 44 +- linter/src/FaultAttrs.ts | 168 +-- linter/src/IncrementalLintInfo.ts | 4 +- linter/src/LintOptions.ts | 10 +- linter/src/LintRunResult.ts | 2 +- linter/src/LinterCLI.ts | 40 +- linter/src/LinterRunner.ts | 202 ++- linter/src/ProblemInfo.ts | 2 +- linter/src/ProblemSeverity.ts | 5 +- linter/src/Problems.ts | 106 +- linter/src/TestRunner.ts | 193 ++- linter/src/TypeScriptLinter.ts | 1313 ++++++++++------- linter/src/TypeScriptLinterConfig.ts | 129 +- linter/src/autofixes/AutofixTitles.ts | 30 +- linter/src/autofixes/ReportAutofixCallback.ts | 30 +- linter/src/ts-compiler/FormTscOptions.ts | 14 +- .../src/ts-diagnostics/GetTscDiagnostics.ts | 10 +- .../src/ts-diagnostics/TSCCompiledProgram.ts | 62 +- .../ts-diagnostics/TransformTscDiagnostics.ts | 17 +- .../TypeScriptDiagnosticsExtractor.ts | 28 +- linter/src/utils/TsUtils.ts | 320 ++-- .../src/utils/consts/AllowedStdSymbolAPI.ts | 2 +- linter/src/utils/consts/ArkUIDecorators.ts | 2 +- linter/src/utils/consts/ESObject.ts | 2 +- .../consts/LimitedStandardUtilityTypes.ts | 20 +- .../src/utils/consts/LimitedStdGlobalFunc.ts | 4 +- .../src/utils/consts/LimitedStdObjectAPI.ts | 30 +- .../utils/consts/LimitedStdProxyHandlerAPI.ts | 15 +- .../src/utils/consts/LimitedStdReflectAPI.ts | 11 +- .../NonInitializablePropertyDecorators.ts | 2 +- linter/src/utils/consts/StandardLibraries.ts | 68 +- linter/src/utils/consts/TypedArrays.ts | 4 +- .../src/utils/functions/DiagnosticChecker.ts | 2 +- linter/src/utils/functions/GetScriptKind.ts | 6 +- linter/src/utils/functions/IsStdLibrary.ts | 2 +- .../LibraryTypeCallDiagnosticChecker.ts | 32 +- linter/src/utils/functions/LinterInfo.ts | 8 +- linter/src/utils/functions/MergeArrayMaps.ts | 5 +- linter/src/utils/functions/PathHelper.ts | 2 +- .../functions/identiferUseInValueContext.ts | 63 +- .../utils/functions/isAssignmentOperator.ts | 2 +- 51 files changed, 2265 insertions(+), 1369 deletions(-) create mode 100644 linter/.editorconfig create mode 100644 linter/.eslintignore create mode 100644 linter/.eslintrc.json create mode 100644 linter/.prettierrc.json diff --git a/linter/.editorconfig b/linter/.editorconfig new file mode 100644 index 000000000..dfacac798 --- /dev/null +++ b/linter/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[**] +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/linter/.eslintignore b/linter/.eslintignore new file mode 100644 index 000000000..b633cbdd8 --- /dev/null +++ b/linter/.eslintignore @@ -0,0 +1,15 @@ +bin +build +bundle +cookbook_convertor +dist +docs +node_modules +scripts +stats_calculator +test +test_extended_features +test_rules +utils +*.json +*.js diff --git a/linter/.eslintrc.json b/linter/.eslintrc.json new file mode 100644 index 000000000..62716178e --- /dev/null +++ b/linter/.eslintrc.json @@ -0,0 +1,193 @@ +{ + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "project": true + }, + "plugins": ["@typescript-eslint", "@stylistic"], + "rules": { + // suggestions + "arrow-body-style": ["error", "always"], + "camelcase": "off", // we use naming-convention rule to enforce naming scheme + "class-methods-use-this": ["error", { "exceptMethods": [], "enforceForClassFields": true }], + "complexity": ["error", { "max": 15 }], + "consistent-return": ["error", { "treatUndefinedAsUnspecified": false }], + "curly": ["error", "all"], + "dot-notation": "error", + "eqeqeq": ["error", "smart"], + "max-depth": ["error", { "max": 4 }], + "multiline-comment-style": ["error", "starred-block"], + "@stylistic/no-confusing-arrow": "error", + "no-else-return": ["error", { "allowElseIf": true }], + "no-extra-bind": "error", + "@stylistic/no-floating-decimal": "error", + "no-lonely-if": "error", + "no-unneeded-ternary": "error", + "no-useless-return": "error", + "no-var": "error", + "prefer-const": "error", + "spaced-comment": ["error", "always"], + "one-var": ["error", "never"], + "max-lines-per-function": ["error", { "max": 50 }], + + // style + "@stylistic/array-bracket-newline": ["error", "consistent"], + "@stylistic/array-bracket-spacing": ["error", "never"], + "@stylistic/array-element-newline": ["error", "consistent"], + "@stylistic/arrow-parens": ["error", "always"], + "@stylistic/arrow-spacing": ["error", { "before": true, "after": true }], + "@stylistic/block-spacing": ["error", "always"], + "@stylistic/brace-style": ["error", "1tbs", { "allowSingleLine": true }], + "@stylistic/comma-dangle": [ + "error", + { + "arrays": "never", + "objects": "never", + "imports": "never", + "exports": "never", + "functions": "never" + } + ], + "@stylistic/comma-spacing": ["error", { "before": false, "after": true }], + "@stylistic/comma-style": ["error", "last"], + "@stylistic/computed-property-spacing": ["error", "never", { "enforceForClassMembers": true }], + "@stylistic/dot-location": ["error", "object"], + "@stylistic/eol-last": ["error", "always"], + "@stylistic/func-call-spacing": ["error", "never"], + "@stylistic/function-call-argument-newline": ["error", "consistent"], + "@stylistic/function-paren-newline": ["error", "consistent"], + "@stylistic/generator-star-spacing": ["error", { "before": true, "after": false }], + "@stylistic/implicit-arrow-linebreak": ["error", "beside"], + "@stylistic/indent": [ + "error", + 2, + { + "ignoredNodes": [], + "SwitchCase": 1, + "VariableDeclarator": 1, + "outerIIFEBody": 1, + "MemberExpression": 1, + "FunctionDeclaration": { + "parameters": 1, + "body": 1 + }, + "FunctionExpression": { + "parameters": 1, + "body": 1 + }, + "CallExpression": { + "arguments": 1 + }, + "ArrayExpression": 1, + "ObjectExpression": 1, + "ImportDeclaration": 1, + "flatTernaryExpressions": true, + "offsetTernaryExpressions": false, + "ignoreComments": false + } + ], + "@stylistic/jsx-quotes": ["error", "prefer-double"], + "@stylistic/keyword-spacing": ["error", { "before": true, "after": true }], + "line-comment-position": ["error", { "position": "above" }], + "@stylistic/linebreak-style": ["error", "unix"], + "@stylistic/lines-around-comment": ["error", { "beforeBlockComment": true }], + "@stylistic/lines-between-class-members": [ + "error", + { + "enforce": [ + { "blankLine": "always", "prev": "*", "next": "method" }, + { "blankLine": "always", "prev": "method", "next": "*" } + ] + } + ], + "@stylistic/max-len": ["error", { "code": 120, "tabWidth": 2, "ignoreComments": true, "ignoreStrings": true }], + "@stylistic/max-statements-per-line": ["error", { "max": 1 }], + "@stylistic/multiline-ternary": ["error", "always-multiline"], + "@stylistic/new-parens": ["error", "always"], + "@stylistic/newline-per-chained-call": ["error", { "ignoreChainWithDepth": 2 }], + "@stylistic/no-extra-parens": ["error", "all"], + "@stylistic/no-mixed-spaces-and-tabs": "error", + "@stylistic/no-multi-spaces": "error", + "@stylistic/no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1 }], + "@stylistic/no-tabs": "error", + "@stylistic/no-trailing-spaces": ["error", { "skipBlankLines": false, "ignoreComments": false }], + "@stylistic/no-whitespace-before-property": "error", + "@stylistic/nonblock-statement-body-position": ["error", "beside"], + "@stylistic/object-curly-newline": ["error", { "consistent": true }], + "@stylistic/object-curly-spacing": ["error", "always"], + "@stylistic/operator-linebreak": ["error", "after"], + // disable due to conflict with required rule 'lines-around-comment' + "@stylistic/padded-blocks": "off", + "@stylistic/quotes": ["error", "single"], + "@stylistic/rest-spread-spacing": ["error", "never"], + "@stylistic/semi": ["error", "always"], + "@stylistic/semi-spacing": ["error", { "before": false, "after": true }], + "@stylistic/semi-style": ["error", "last"], + "@stylistic/space-before-blocks": ["error", "always"], + "@stylistic/space-before-function-paren": ["error", "never"], + "@stylistic/space-in-parens": ["error", "never"], + "@stylistic/space-infix-ops": ["error"], + "@stylistic/space-unary-ops": ["error", { "words": true, "nonwords": false, "overrides": {} }], + "@stylistic/switch-colon-spacing": ["error", { "after": true, "before": false }], + "@stylistic/template-curly-spacing": ["error", "never"], + "@stylistic/template-tag-spacing": ["error", "never"], + "unicode-bom": ["error", "never"], + "@stylistic/wrap-iife": ["error", "outside"], + "@stylistic/wrap-regex": "error", + "@stylistic/yield-star-spacing": ["error", { "before": true, "after": false }], + + // typescript + "@typescript-eslint/explicit-function-return-type": "error", + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/explicit-member-accessibility": [ + "error", + { + "accessibility": "no-public" + } + ], + "@typescript-eslint/method-signature-style": "error", + "@typescript-eslint/no-confusing-non-null-assertion": "error", + "@typescript-eslint/no-confusing-void-expression": "error", + // FIXME(knazarov) + // need to do something about this + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-meaningless-void-operator": "error", + "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error", + // FIXME(knazarov) + // disabled due to many cases, where typescript deduces non-undefined value, but we can recieve one from the api + "@typescript-eslint/no-unnecessary-condition": "off", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/prefer-as-const": "error", + "@typescript-eslint/prefer-optional-chain": "error", + "@typescript-eslint/prefer-readonly": "error", + "@typescript-eslint/consistent-type-imports": "error", + // FIXME(knazarov) + // need to change metadata in cookbook accordingle. so do it later + "@typescript-eslint/naming-convention": [ + "off", + { + "selector": "default", + "format": ["camelCase"] + }, + { + "selector": "enumMember", + "format": ["UPPER_CASE"] + }, + { + "selector": "variable", + "format": ["camelCase", "UPPER_CASE"] + }, + { + "selector": "typeLike", + "format": ["PascalCase"] + }, + { + "selector": "memberLike", + "format": ["camelCase"] + } + ] + } +} diff --git a/linter/.prettierrc.json b/linter/.prettierrc.json new file mode 100644 index 000000000..813963a82 --- /dev/null +++ b/linter/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "singleQuote": true, + "jsxSingleQuote": true, + "arrowParens": "always", + "printWidth": 120, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "trailingComma": "none" +} diff --git a/linter/README.md b/linter/README.md index 3983b1f55..9c637a534 100644 --- a/linter/README.md +++ b/linter/README.md @@ -1,14 +1,17 @@ # TypeScript linter -Typescript linter ( further mentioned as 'linter' ) is a tool to check typescript sources and find language elements -and constructions which are deprecated to use in a purpose to migrate sources to STS. + +Typescript linter ( further mentioned as 'linter' ) is a tool to check typescript sources and find language elements +and constructions which are deprecated to use in a purpose to migrate sources to STS. The linter is currently under development. ## Prerequisits ### Visual Studio Code + For development, it's recommended to use `VS Code`, as it has a full built-in support for TypeScript language. ### NodeJS and NPM + Install the latest stable version of `NodeJS` and `NPM`. It is recommended using a `Node version manager` to install Node and NPM ([nvm](https://github.com/nvm-sh/nvm) for Linux; [nvm-windows](https://github.com/coreybutler/nvm-windows) for windows - v1.1.9 is the most stable). You can also follow the [official guide](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm). ## Building @@ -26,7 +29,9 @@ npm run build ``` ## Running + Run the following command from the same directory: + ```bash node dist/tslinter.js [options] [input files] ``` @@ -56,6 +61,7 @@ To prevent command line buffer overflow, response file may be used. It is specif ## Running tests Run the following command: + ```bash npm test ``` diff --git a/linter/package.json b/linter/package.json index b9f16d7bf..6acb1be18 100644 --- a/linter/package.json +++ b/linter/package.json @@ -16,27 +16,31 @@ "build": "npm run clean && npm run compile && npm run webpack && npm run pack:linter", "postinstall": "npm run build", "pack:linter": "rimraf bundle && mkdir bundle && npm pack --pack-destination bundle", + "pretest": "npm run eslint-check", "test": "npm run compile && rimraf test/results test_rules/results && node build/src/TestRunner.js test test_rules", "test_main": "npm run compile && rimraf test/results && node build/src/TestRunner.js test", "test_rules": "npm run compile && rimraf test_rules/results && node build/src/TestRunner.js test_rules", - "update-tests": "node scripts/update-test-results.mjs test test_rules" + "update-tests": "node scripts/update-test-results.mjs test test_rules", + "eslint-check": "npx eslint --ext .ts src", + "eslint-fix": "npm run eslint-check -- --fix", + "prettier-fix": "prettier src --write", + "fix": "npm run prettier-fix && npm run eslint-fix" }, "dependencies": { - "typescript": "4.8.4", + "commander": "9.4.0", "log4js": "6.4.0", - "commander": "9.4.0" + "typescript": "4.8.4" }, "devDependencies": { + "@stylistic/eslint-plugin": "latest", "@types/node": "18.11.7", + "@typescript-eslint/eslint-plugin": "latest", + "@typescript-eslint/parser": "latest", + "eslint": "latest", + "prettier": "latest", "rimraf": "^3.0.2", "webpack": "^5.75.0", - "webpack-cli": "^5.0.1", - "@typescript-eslint/eslint-plugin": "5.51.0", - "@typescript-eslint/parser": "5.51.0", - "eslint": "7.32.0", - "eslint-config-prettier": "^6.15.0", - "eslint-plugin-prettier": "^3.1.4", - "prettier": "^2.0.5" + "webpack-cli": "^5.0.1" }, "bundledDependencies": [ "typescript", diff --git a/linter/src/Autofixer.ts b/linter/src/Autofixer.ts index f6dc5129d..58f6cec9a 100644 --- a/linter/src/Autofixer.ts +++ b/linter/src/Autofixer.ts @@ -14,20 +14,24 @@ */ import * as ts from 'typescript'; -import { AutofixInfo } from './autofixes/AutofixInfo'; +import type { AutofixInfo } from './autofixes/AutofixInfo'; import { FaultID } from './Problems'; import { isAssignmentOperator } from './utils/functions/isAssignmentOperator'; export const AUTOFIX_ALL: AutofixInfo = { - problemID: '', start: -1, end: -1 -} + problemID: '', + start: -1, + end: -1 +}; -// Some fixes are potentially risky and may break source code if fixes -// are applied separately. -// Temporary solution is to disable all risky autofixes, until the -// algorithm is improved to guarantee that fixes can be applied -// safely and won't break program code. -const UNSAFE_FIXES: FaultID[] = [ FaultID.LiteralAsPropertyName, FaultID.PropertyAccessByIndex ]; +/* + * Some fixes are potentially risky and may break source code if fixes + * are applied separately. + * Temporary solution is to disable all risky autofixes, until the + * algorithm is improved to guarantee that fixes can be applied + * safely and won't break program code. + */ +const UNSAFE_FIXES: FaultID[] = [FaultID.LiteralAsPropertyName, FaultID.PropertyAccessByIndex]; export interface Autofix { replacementText: string; @@ -36,70 +40,89 @@ export interface Autofix { } export class AutofixInfoSet { - private autofixInfo: AutofixInfo[]; + private readonly autofixInfo: AutofixInfo[]; constructor(autofixInfo: AutofixInfo[] | undefined) { this.autofixInfo = autofixInfo ? autofixInfo : []; } - public shouldAutofix(node: ts.Node, faultID: FaultID): boolean { - if (UNSAFE_FIXES.includes(faultID)) return false; - if (this.autofixInfo.length === 0) return false; - if (this.autofixInfo.length === 1 && this.autofixInfo[0] == AUTOFIX_ALL) return true; - return this.autofixInfo.findIndex( - value => value.start === node.getStart() && value.end === node.getEnd() && value.problemID === FaultID[faultID] - ) !== -1; + shouldAutofix(node: ts.Node, faultID: FaultID): boolean { + if (UNSAFE_FIXES.includes(faultID)) { + return false; + } + if (this.autofixInfo.length === 0) { + return false; + } + if (this.autofixInfo.length === 1 && this.autofixInfo[0] === AUTOFIX_ALL) { + return true; + } + return ( + this.autofixInfo.findIndex((value) => { + return value.start === node.getStart() && value.end === node.getEnd() && value.problemID === FaultID[faultID]; + }) !== -1 + ); } } export function fixLiteralAsPropertyName(node: ts.Node): Autofix[] | undefined { if (ts.isPropertyDeclaration(node) || ts.isPropertyAssignment(node)) { - let propName = (node as (ts.PropertyDeclaration | ts.PropertyAssignment)).name; - let identName = propertyName2IdentifierName(propName); - if (identName) + const propName = node.name; + const identName = propertyName2IdentifierName(propName); + if (identName) { return [{ replacementText: identName, start: propName.getStart(), end: propName.getEnd() }]; + } } return undefined; } export function fixPropertyAccessByIndex(node: ts.Node): Autofix[] | undefined { if (ts.isElementAccessExpression(node)) { - let elemAccess = node as ts.ElementAccessExpression; - let identifierName = indexExpr2IdentifierName(elemAccess.argumentExpression); - if (identifierName) - return [{ - replacementText: elemAccess.expression.getText() + '.' + identifierName, - start: elemAccess.getStart(), end: elemAccess.getEnd() - }]; + const elemAccess = node; + const identifierName = indexExpr2IdentifierName(elemAccess.argumentExpression); + if (identifierName) { + return [ + { + replacementText: elemAccess.expression.getText() + '.' + identifierName, + start: elemAccess.getStart(), + end: elemAccess.getEnd() + } + ]; + } } return undefined; } -export function fixFunctionExpression(funcExpr: ts.FunctionExpression, - params: ts.NodeArray = funcExpr.parameters, +export function fixFunctionExpression( + funcExpr: ts.FunctionExpression, + params: ts.NodeArray = funcExpr.parameters, retType: ts.TypeNode | undefined = funcExpr.type, - modifiers: readonly ts.Modifier[] | undefined): Autofix { + modifiers: readonly ts.Modifier[] | undefined +): Autofix { let arrowFunc: ts.Expression = ts.factory.createArrowFunction( - modifiers, undefined, params, retType, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + modifiers, + undefined, + params, + retType, + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), funcExpr.body ); if (needsParentheses(funcExpr)) { arrowFunc = ts.factory.createParenthesizedExpression(arrowFunc); } - let text = printer.printNode(ts.EmitHint.Unspecified, arrowFunc, funcExpr.getSourceFile()); + const text = printer.printNode(ts.EmitHint.Unspecified, arrowFunc, funcExpr.getSourceFile()); return { start: funcExpr.getStart(), end: funcExpr.getEnd(), replacementText: text }; } export function fixReturnType(funcLikeDecl: ts.FunctionLikeDeclaration, typeNode: ts.TypeNode): Autofix { - let text = ': ' + printer.printNode(ts.EmitHint.Unspecified, typeNode, funcLikeDecl.getSourceFile()); - let pos = getReturnTypePosition(funcLikeDecl); + const text = ': ' + printer.printNode(ts.EmitHint.Unspecified, typeNode, funcLikeDecl.getSourceFile()); + const pos = getReturnTypePosition(funcLikeDecl); return { start: pos, end: pos, replacementText: text }; } export function dropTypeOnVarDecl(varDecl: ts.VariableDeclaration): Autofix { - let newVarDecl = ts.factory.createVariableDeclaration(varDecl.name, undefined, undefined, undefined); - let text = printer.printNode(ts.EmitHint.Unspecified, newVarDecl, varDecl.getSourceFile()); - return { start: varDecl.getStart(), end: varDecl.getEnd(), replacementText: text}; + const newVarDecl = ts.factory.createVariableDeclaration(varDecl.name, undefined, undefined, undefined); + const text = printer.printNode(ts.EmitHint.Unspecified, newVarDecl, varDecl.getSourceFile()); + return { start: varDecl.getStart(), end: varDecl.getEnd(), replacementText: text }; } export function dropTypeOnlyFlag( @@ -107,84 +130,98 @@ export function dropTypeOnlyFlag( ): Autofix { let text: string; if (ts.isImportClause(impExpNode)) { - let newImportClause = ts.factory.createImportClause(false, impExpNode.name, impExpNode.namedBindings); + const newImportClause = ts.factory.createImportClause(false, impExpNode.name, impExpNode.namedBindings); text = printer.printNode(ts.EmitHint.Unspecified, newImportClause, impExpNode.getSourceFile()); - } - else if (ts.isImportSpecifier(impExpNode)) { - let newImportSpec = ts.factory.createImportSpecifier(false, impExpNode.propertyName, impExpNode.name); + } else if (ts.isImportSpecifier(impExpNode)) { + const newImportSpec = ts.factory.createImportSpecifier(false, impExpNode.propertyName, impExpNode.name); text = printer.printNode(ts.EmitHint.Unspecified, newImportSpec, impExpNode.getSourceFile()); - } - else if (ts.isExportDeclaration(impExpNode)) { - let newExportDecl = ts.factory.createExportDeclaration(impExpNode.modifiers, false, impExpNode.exportClause, - impExpNode.moduleSpecifier, impExpNode.assertClause); + } else if (ts.isExportDeclaration(impExpNode)) { + const newExportDecl = ts.factory.createExportDeclaration( + impExpNode.modifiers, + false, + impExpNode.exportClause, + impExpNode.moduleSpecifier, + impExpNode.assertClause + ); text = printer.printNode(ts.EmitHint.Unspecified, newExportDecl, impExpNode.getSourceFile()); - } - else { - let newExportSpec = ts.factory.createExportSpecifier(false, impExpNode.propertyName, impExpNode.name); + } else { + const newExportSpec = ts.factory.createExportSpecifier(false, impExpNode.propertyName, impExpNode.name); text = printer.printNode(ts.EmitHint.Unspecified, newExportSpec, impExpNode.getSourceFile()); } return { start: impExpNode.getStart(), end: impExpNode.getEnd(), replacementText: text }; } -export function fixDefaultImport(importClause: ts.ImportClause, - defaultSpec: ts.ImportSpecifier, nonDefaultSpecs: ts.ImportSpecifier[]): Autofix { - let nameBindings = nonDefaultSpecs.length > 0 ? ts.factory.createNamedImports(nonDefaultSpecs) : undefined; - let newImportClause = ts.factory.createImportClause(importClause.isTypeOnly, defaultSpec.name, nameBindings); - let text = printer.printNode(ts.EmitHint.Unspecified, newImportClause, importClause.getSourceFile()); +export function fixDefaultImport( + importClause: ts.ImportClause, + defaultSpec: ts.ImportSpecifier, + nonDefaultSpecs: ts.ImportSpecifier[] +): Autofix { + const nameBindings = nonDefaultSpecs.length > 0 ? ts.factory.createNamedImports(nonDefaultSpecs) : undefined; + const newImportClause = ts.factory.createImportClause(importClause.isTypeOnly, defaultSpec.name, nameBindings); + const text = printer.printNode(ts.EmitHint.Unspecified, newImportClause, importClause.getSourceFile()); return { start: importClause.getStart(), end: importClause.getEnd(), replacementText: text }; } export function fixTypeAssertion(typeAssertion: ts.TypeAssertion): Autofix { const asExpr = ts.factory.createAsExpression(typeAssertion.expression, typeAssertion.type); - let text = printer.printNode(ts.EmitHint.Unspecified, asExpr, typeAssertion.getSourceFile()); + const text = printer.printNode(ts.EmitHint.Unspecified, asExpr, typeAssertion.getSourceFile()); return { start: typeAssertion.getStart(), end: typeAssertion.getEnd(), replacementText: text }; } const printer: ts.Printer = ts.createPrinter(); -function numericLiteral2IdentifierName(numeric: ts.NumericLiteral) { +function numericLiteral2IdentifierName(numeric: ts.NumericLiteral): string { return '__' + numeric.getText(); } -function stringLiteral2IdentifierName(str: ts.StringLiteral) { - let text = (str as ts.StringLiteral).getText(); - return text.substring(1, text.length-1); // cut out starting and ending quoters. +function stringLiteral2IdentifierName(str: ts.StringLiteral): string { + const text = str.getText(); + // cut out starting and ending quoters. + return text.substring(1, text.length - 1); } function propertyName2IdentifierName(name: ts.PropertyName): string { - if (name.kind === ts.SyntaxKind.NumericLiteral) - return numericLiteral2IdentifierName(name as ts.NumericLiteral); + if (name.kind === ts.SyntaxKind.NumericLiteral) { + return numericLiteral2IdentifierName(name); + } + + if (name.kind === ts.SyntaxKind.StringLiteral) { + return stringLiteral2IdentifierName(name); + } - if (name.kind === ts.SyntaxKind.StringLiteral) - return stringLiteral2IdentifierName(name as ts.StringLiteral); - return ''; } -function indexExpr2IdentifierName(index: ts.Expression) { - if (index.kind === ts.SyntaxKind.NumericLiteral) +function indexExpr2IdentifierName(index: ts.Expression): string { + if (index.kind === ts.SyntaxKind.NumericLiteral) { return numericLiteral2IdentifierName(index as ts.NumericLiteral); + } - if (index.kind === ts.SyntaxKind.StringLiteral) + if (index.kind === ts.SyntaxKind.StringLiteral) { return stringLiteral2IdentifierName(index as ts.StringLiteral); - + } + return ''; } function getReturnTypePosition(funcLikeDecl: ts.FunctionLikeDeclaration): number { if (funcLikeDecl.body) { - // Find position of the first node or token that follows parameters. - // After that, iterate over child nodes in reverse order, until found - // first closing parenthesis. - let postParametersPosition = ts.isArrowFunction(funcLikeDecl) - ? funcLikeDecl.equalsGreaterThanToken.getStart() - : funcLikeDecl.body.getStart(); - + + /* + * Find position of the first node or token that follows parameters. + * After that, iterate over child nodes in reverse order, until found + * first closing parenthesis. + */ + const postParametersPosition = ts.isArrowFunction(funcLikeDecl) ? + funcLikeDecl.equalsGreaterThanToken.getStart() : + funcLikeDecl.body.getStart(); + const children = funcLikeDecl.getChildren(); for (let i = children.length - 1; i >= 0; i--) { const child = children[i]; - if (child.kind === ts.SyntaxKind.CloseParenToken && child.getEnd() <= postParametersPosition) + if (child.kind === ts.SyntaxKind.CloseParenToken && child.getEnd() <= postParametersPosition) { return child.getEnd(); + } } } @@ -194,9 +231,15 @@ function getReturnTypePosition(funcLikeDecl: ts.FunctionLikeDeclaration): number function needsParentheses(node: ts.FunctionExpression): boolean { const parent = node.parent; - return ts.isPrefixUnaryExpression(parent) || ts.isPostfixUnaryExpression(parent) || - ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent) || - ts.isTypeOfExpression(parent) || ts.isVoidExpression(parent) || ts.isAwaitExpression(parent) || - (ts.isCallExpression(parent) && node === parent.expression) || - (ts.isBinaryExpression(parent) && !isAssignmentOperator(parent.operatorToken)); -} \ No newline at end of file + return ( + ts.isPrefixUnaryExpression(parent) || + ts.isPostfixUnaryExpression(parent) || + ts.isPropertyAccessExpression(parent) || + ts.isElementAccessExpression(parent) || + ts.isTypeOfExpression(parent) || + ts.isVoidExpression(parent) || + ts.isAwaitExpression(parent) || + ts.isCallExpression(parent) && node === parent.expression || + ts.isBinaryExpression(parent) && !isAssignmentOperator(parent.operatorToken) + ); +} diff --git a/linter/src/CommandLineOptions.ts b/linter/src/CommandLineOptions.ts index fab0ed372..7e174d625 100644 --- a/linter/src/CommandLineOptions.ts +++ b/linter/src/CommandLineOptions.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import * as ts from 'typescript'; -import { AutofixInfo } from './autofixes/AutofixInfo'; +import type * as ts from 'typescript'; +import type { AutofixInfo } from './autofixes/AutofixInfo'; export interface CommandLineOptions { testMode?: boolean; diff --git a/linter/src/CommandLineParser.ts b/linter/src/CommandLineParser.ts index 284ef5c8e..77c4116c1 100644 --- a/linter/src/CommandLineParser.ts +++ b/linter/src/CommandLineParser.ts @@ -16,7 +16,7 @@ import Logger from '../utils/logger'; import { logTscDiagnostic } from './utils/functions/LogTscDiagnostic'; import { decodeAutofixInfo } from './utils/functions/LinterInfo'; -import { CommandLineOptions } from './CommandLineOptions'; +import type { CommandLineOptions } from './CommandLineOptions'; import { AUTOFIX_ALL } from './Autofixer'; import { Command, Option } from 'commander'; import * as ts from 'typescript'; @@ -32,11 +32,12 @@ const logger = Logger.getLogger(); let inputFiles: string[]; let responseFile = ''; -function addSrcFile(value: string, dummy: string) { - if(value.startsWith('@')) +function addSrcFile(value: string): void { + if (value.startsWith('@')) { responseFile = value; - else + } else { inputFiles.push(value); + } } const getFiles = (dir: string): string[] => { @@ -44,87 +45,114 @@ const getFiles = (dir: string): string[] => { const files = fs.readdirSync(dir); for (let i = 0; i < files.length; ++i) { - let name = path.join(dir, files[i]); + const name = path.join(dir, files[i]); if (fs.statSync(name).isDirectory()) { resultFiles.push(...getFiles(name)); } else { - let extension = path.extname(name); - if (extension === TS_EXT || extension === TSX_EXT || extension === ETS_EXT) + const extension = path.extname(name); + if (extension === TS_EXT || extension === TSX_EXT || extension === ETS_EXT) { resultFiles.push(name); + } } } return resultFiles; }; -function addProjectFolder(projectFolder: string, previous: any ) { +function addProjectFolder(projectFolder: string, previous: string[]): string[] { return previous.concat([projectFolder]); } -export function parseCommandLine(commandLineArgs: string[]): CommandLineOptions { +function formCommandLineOptions(program: Command): CommandLineOptions { const opts: CommandLineOptions = { inputFiles: [], warningsAsErrors: false }; + // Default mode of the linter. + opts.strictMode = true; + opts.inputFiles = inputFiles; + + const options = program.opts(); + if (options.relax) { + opts.strictMode = false; + } + if (options.TSC_Errors) { + opts.logTscErrors = true; + } + if (options.devecoPluginMode) { + opts.ideMode = true; + } + if (options.testMode) { + opts.testMode = true; + } + if (options.projectFolder) { + doProjectFolderArg(options.projectFolder, opts); + } + if (options.project) { + doProjectArg(options.project, opts); + } + if (options.autofix) { + doAutofixArg(options.autofix, opts); + } + if (options.warningsAsErrors) { + opts.warningsAsErrors = true; + } + return opts; +} +export function parseCommandLine(commandLineArgs: string[]): CommandLineOptions { const program = new Command(); - program - .name('tslinter') - .description('Linter for TypeScript sources') - .version('0.0.1'); - program - .option('-E, --TSC_Errors', 'show error messages from Tsc') - .option('--relax', 'relax mode On') - .option('--test-mode', 'run linter as if running TS test files') - .option('--deveco-plugin-mode', 'run as IDE plugin') - .option('-p, --project ', 'path to TS project config file') - .option('--project-folder ', 'path to folder containig TS files to verify', addProjectFolder, []) - .option('--autofix [autofix.json]', 'fix errors specified by JSON file (all if file is omitted)', - (val: string, prev: string|boolean) => { return val.endsWith(JSON_EXT) ? val : true; }) - .addOption(new Option('--warnings-as-errors', 'treat warnings as errors').hideHelp(true)); - program - .argument('[srcFile...]', 'files to be verified', addSrcFile); - - opts.strictMode = true; // Default mode of the linter. + program.name('tslinter').description('Linter for TypeScript sources'). + version('0.0.1'); + program. + option('-E, --TSC_Errors', 'show error messages from Tsc'). + option('--relax', 'relax mode On'). + option('--test-mode', 'run linter as if running TS test files'). + option('--deveco-plugin-mode', 'run as IDE plugin'). + option('-p, --project ', 'path to TS project config file'). + option('--project-folder ', 'path to folder containig TS files to verify', addProjectFolder, []). + option('--autofix [autofix.json]', 'fix errors specified by JSON file (all if file is omitted)', (val: string) => { + return val.endsWith(JSON_EXT) ? val : true; + }). + addOption(new Option('--warnings-as-errors', 'treat warnings as errors').hideHelp(true)); + program.argument('[srcFile...]', 'files to be verified', addSrcFile); + inputFiles = []; - let cmdArgs: string[] = ['dummy', 'dummy']; // method parse() eats two first args, so make them dummy + // method parse() eats two first args, so make them dummy + let cmdArgs: string[] = ['dummy', 'dummy']; cmdArgs.push(...commandLineArgs); program.parse(cmdArgs); if (responseFile !== '') { try { - commandLineArgs = fs.readFileSync(responseFile.slice(1)).toString().split('\n').filter((e) => e.trimEnd()); + commandLineArgs = fs. + readFileSync(responseFile.slice(1)). + toString(). + split('\n'). + filter((e) => { + return e.trimEnd(); + }); cmdArgs = ['dummy', 'dummy']; cmdArgs.push(...commandLineArgs); - program.parse( cmdArgs); - } catch (error: any) { - logger.error('Failed to read response file: ' + (error.message ?? error)); - process.exit(-1) + program.parse(cmdArgs); + } catch (error) { + logger.error('Failed to read response file: ', error); + process.exit(-1); } } - opts.inputFiles = inputFiles; - const options = program.opts(); - if (options.relax) opts.strictMode = false; - if (options.TSC_Errors) opts.logTscErrors = true; - if (options.devecoPluginMode) opts.ideMode = true; - if (options.testMode) opts.testMode = true; - if (options.projectFolder) doProjectFolderArg(options.projectFolder, opts); - if (options.project) doProjectArg(options.project, opts); - if (options.autofix) doAutofixArg(options.autofix, opts); - if (options.warningsAsErrors) opts.warningsAsErrors = true; - return opts; + return formCommandLineOptions(program); } -function doProjectFolderArg(prjFolders: string[], opts: CommandLineOptions) { - for( let i = 0; i < prjFolders.length; i++ ) { - var prjFolderPath = prjFolders[ i ]; +function doProjectFolderArg(prjFolders: string[], opts: CommandLineOptions): void { + for (let i = 0; i < prjFolders.length; i++) { + const prjFolderPath = prjFolders[i]; try { opts.inputFiles.push(...getFiles(prjFolderPath)); - } catch (error: any) { - logger.error('Failed to read folder: ' + (error.message ?? error)); + } catch (error) { + logger.error('Failed to read folder: ', error); process.exit(-1); } } } -function doProjectArg(cfgPath: string, opts: CommandLineOptions) { +function doProjectArg(cfgPath: string, opts: CommandLineOptions): void { // Process project file (tsconfig.json) and retrieve config arguments. const configFile = cfgPath; @@ -134,12 +162,15 @@ function doProjectArg(cfgPath: string, opts: CommandLineOptions) { try { const oldUnrecoverableDiagnostic = host.onUnRecoverableConfigFileDiagnostic; - host.onUnRecoverableConfigFileDiagnostic = (diagnostic: ts.Diagnostic) => { diagnostics.push(diagnostic); }; + host.onUnRecoverableConfigFileDiagnostic = (diagnostic: ts.Diagnostic): void => { + diagnostics.push(diagnostic); + }; opts.parsedConfigFile = ts.getParsedCommandLineOfConfigFile(configFile, {}, host); host.onUnRecoverableConfigFileDiagnostic = oldUnrecoverableDiagnostic; - if (opts.parsedConfigFile) + if (opts.parsedConfigFile) { diagnostics.push(...ts.getConfigFileParsingDiagnostics(opts.parsedConfigFile)); + } if (diagnostics.length > 0) { // Log all diagnostic messages and exit program. @@ -147,17 +178,20 @@ function doProjectArg(cfgPath: string, opts: CommandLineOptions) { logTscDiagnostic(diagnostics, logger.info); process.exit(-1); } - } catch (error: any) { - logger.error('Failed to read config file: ' + (error.message ?? error)); + } catch (error) { + logger.error('Failed to read config file: ', error); process.exit(-1); } } -function doAutofixArg(autofixOptVal: string|boolean, opts: CommandLineOptions) { +function doAutofixArg(autofixOptVal: string | boolean, opts: CommandLineOptions): void { if (typeof autofixOptVal === 'string') { - let autofixInfoStr = fs.readFileSync(autofixOptVal).toString(); - let autofixInfos = JSON.parse(autofixInfoStr); - opts.autofixInfo = autofixInfos.autofixInfo.map((x: string) => decodeAutofixInfo(x)); + const autofixInfoStr = fs.readFileSync(autofixOptVal).toString(); + const autofixInfos = JSON.parse(autofixInfoStr); + opts.autofixInfo = autofixInfos.autofixInfo.map((x: string) => { + return decodeAutofixInfo(x); + }); + } else { + opts.autofixInfo = [AUTOFIX_ALL]; } - else opts.autofixInfo = [AUTOFIX_ALL]; } diff --git a/linter/src/CompilerWrapper.ts b/linter/src/CompilerWrapper.ts index 50172a72c..7bbd53274 100644 --- a/linter/src/CompilerWrapper.ts +++ b/linter/src/CompilerWrapper.ts @@ -17,9 +17,9 @@ import * as ts from 'typescript'; import { logTscDiagnostic } from './utils/functions/LogTscDiagnostic'; import { consoleLog } from './TypeScriptLinter'; import { formTscOptions } from './ts-compiler/FormTscOptions'; -import { LintOptions } from './LintOptions'; +import type { LintOptions } from './LintOptions'; -export function compile(options: LintOptions, extraOptions?: any): ts.Program { +export function compile(options: LintOptions, extraOptions?: unknown): ts.Program { const createProgramOptions = formTscOptions(options.cmdOptions, extraOptions); const program = ts.createProgram(createProgramOptions); // Log Tsc errors if needed diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index dc0116777..3e7025ca3 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -1,16 +1,16 @@ -/* - * Copyright (c) 2022-2023 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. +/* + * Copyright (c) 2022-2023 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. */ export const cookBookMsg: string[] = []; @@ -20,7 +20,8 @@ for (let i = 0; i <= 151; i++) { cookBookMsg[i] = ''; } -cookBookTag[1] = 'Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)'; +cookBookTag[1] = + 'Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)'; cookBookTag[2] = '"Symbol()" API is not supported (arkts-no-symbol)'; cookBookTag[3] = 'Private \'#\' identifiers are not supported (arkts-no-private-identifiers)'; cookBookTag[4] = 'Use unique names for types and namespaces. (arkts-unique-names)'; @@ -57,7 +58,8 @@ cookBookTag[34] = 'Type inference in case of generic function calls is limited ( cookBookTag[35] = ''; cookBookTag[36] = ''; cookBookTag[37] = 'RegExp literals are not supported (arkts-no-regexp-literals)'; -cookBookTag[38] = 'Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)'; +cookBookTag[38] = + 'Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)'; cookBookTag[39] = ''; cookBookTag[40] = 'Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)'; cookBookTag[41] = ''; @@ -118,7 +120,8 @@ cookBookTag[95] = ''; cookBookTag[96] = 'Type guarding is supported with "instanceof" and "as" (arkts-no-is)'; cookBookTag[97] = ''; cookBookTag[98] = ''; -cookBookTag[99] = 'It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)'; +cookBookTag[99] = + 'It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)'; cookBookTag[100] = ''; cookBookTag[101] = ''; cookBookTag[102] = 'Interface can not extend interfaces with the same method (arkts-no-extend-same-prop)'; @@ -130,12 +133,14 @@ cookBookTag[107] = ''; cookBookTag[108] = ''; cookBookTag[109] = ''; cookBookTag[110] = ''; -cookBookTag[111] = 'Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)'; +cookBookTag[111] = + 'Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)'; cookBookTag[112] = ''; cookBookTag[113] = '"enum" declaration merging is not supported (arkts-no-enum-merging)'; cookBookTag[114] = 'Namespaces cannot be used as objects (arkts-no-ns-as-obj)'; cookBookTag[115] = ''; -cookBookTag[116] = 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)'; +cookBookTag[116] = + 'Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)'; cookBookTag[117] = ''; cookBookTag[118] = ''; cookBookTag[119] = 'Importing a module for side-effects only is not supported (arkts-no-side-effects-imports)'; @@ -159,7 +164,8 @@ cookBookTag[136] = 'Prototype assignment is not supported (arkts-no-prototype-as cookBookTag[137] = '"globalThis" is not supported (arkts-no-globalthis)'; cookBookTag[138] = 'Some of utility types are not supported (arkts-no-utility-types)'; cookBookTag[139] = 'Declaring properties on functions is not supported (arkts-no-func-props)'; -cookBookTag[140] = '"Function.apply", "Function.bind", "Function.call" are not supported (arkts-no-func-apply-bind-call)'; +cookBookTag[140] = + '"Function.apply", "Function.bind", "Function.call" are not supported (arkts-no-func-apply-bind-call)'; cookBookTag[141] = ''; cookBookTag[142] = '"as const" assertions are not supported (arkts-no-as-const)'; cookBookTag[143] = 'Import assertions are not supported (arkts-no-import-assertions)'; diff --git a/linter/src/FaultAttrs.ts b/linter/src/FaultAttrs.ts index 1346c84b3..c5bbe02ff 100644 --- a/linter/src/FaultAttrs.ts +++ b/linter/src/FaultAttrs.ts @@ -23,87 +23,87 @@ export class FaultAttributs { export const faultsAttrs: FaultAttributs[] = []; -faultsAttrs[FaultID.LiteralAsPropertyName] = {migratable: true, cookBookRef: '1',}; -faultsAttrs[FaultID.ComputedPropertyName] = {cookBookRef: '1',}; -faultsAttrs[FaultID.SymbolType] = {cookBookRef: '2',}; -faultsAttrs[FaultID.PrivateIdentifier] = {migratable: true, cookBookRef: '3',}; -faultsAttrs[FaultID.DeclWithDuplicateName] = {migratable: true, cookBookRef: '4',}; -faultsAttrs[FaultID.VarDeclaration] = {migratable: true, cookBookRef: '5',}; -faultsAttrs[FaultID.AnyType] = {cookBookRef: '8'}; -faultsAttrs[FaultID.UnknownType] = {cookBookRef: '8',}; -faultsAttrs[FaultID.CallSignature] = {cookBookRef: '14',}; -faultsAttrs[FaultID.ConstructorType] = {cookBookRef: '15',}; -faultsAttrs[FaultID.MultipleStaticBlocks] = {cookBookRef: '16',}; -faultsAttrs[FaultID.IndexMember] = {cookBookRef: '17',}; -faultsAttrs[FaultID.IntersectionType] = {cookBookRef: '19',}; -faultsAttrs[FaultID.ThisType] = {cookBookRef: '21',}; -faultsAttrs[FaultID.ConditionalType] = {cookBookRef: '22',}; -faultsAttrs[FaultID.ParameterProperties] = {migratable: true, cookBookRef: '25',}; -faultsAttrs[FaultID.ConstructorIface] = {cookBookRef: '27',}; -faultsAttrs[FaultID.IndexedAccessType] = {cookBookRef: '28',}; -faultsAttrs[FaultID.PropertyAccessByIndex] = {migratable: true, cookBookRef: '29',}; -faultsAttrs[FaultID.StructuralIdentity] = {cookBookRef: '30',}; -faultsAttrs[FaultID.GenericCallNoTypeArgs] = {cookBookRef: '34',}; -faultsAttrs[FaultID.RegexLiteral] = {cookBookRef: '37',}; -faultsAttrs[FaultID.ObjectLiteralNoContextType] = {cookBookRef: '38',}; -faultsAttrs[FaultID.ObjectTypeLiteral] = {cookBookRef: '40',}; -faultsAttrs[FaultID.ArrayLiteralNoContextType] = {cookBookRef: '43',}; -faultsAttrs[FaultID.FunctionExpression] = {migratable: true, cookBookRef: '46',}; -faultsAttrs[FaultID.LambdaWithTypeParameters] = {migratable: true, cookBookRef: '49',}; -faultsAttrs[FaultID.ClassExpression] = {migratable: true, cookBookRef: '50',}; -faultsAttrs[FaultID.ImplementsClass] = {cookBookRef: '51',}; -faultsAttrs[FaultID.MethodReassignment] = {cookBookRef: '52',}; -faultsAttrs[FaultID.TypeAssertion] = {migratable: true, cookBookRef: '53',}; -faultsAttrs[FaultID.JsxElement] = {cookBookRef: '54',}; -faultsAttrs[FaultID.UnaryArithmNotNumber] = {cookBookRef: '55',}; -faultsAttrs[FaultID.DeleteOperator] = {cookBookRef: '59',}; -faultsAttrs[FaultID.TypeQuery] = {cookBookRef: '60',}; -faultsAttrs[FaultID.InstanceofUnsupported] = {cookBookRef: '65',}; -faultsAttrs[FaultID.InOperator] = {cookBookRef: '66',}; -faultsAttrs[FaultID.DestructuringAssignment] = {migratable: true, cookBookRef: '69',}; -faultsAttrs[FaultID.CommaOperator] = {cookBookRef: '71',}; -faultsAttrs[FaultID.DestructuringDeclaration] = {migratable: true, cookBookRef: '74',}; -faultsAttrs[FaultID.CatchWithUnsupportedType] = {migratable: true, cookBookRef: '79',}; -faultsAttrs[FaultID.ForInStatement] = {cookBookRef: '80',}; -faultsAttrs[FaultID.MappedType] = {cookBookRef: '83',}; -faultsAttrs[FaultID.WithStatement] = {cookBookRef: '84',}; -faultsAttrs[FaultID.ThrowStatement] = {migratable: true, cookBookRef: '87',}; -faultsAttrs[FaultID.LimitedReturnTypeInference] = {migratable: true, cookBookRef: '90',}; -faultsAttrs[FaultID.DestructuringParameter] = {cookBookRef: '91',}; -faultsAttrs[FaultID.LocalFunction] = {migratable: true, cookBookRef: '92',}; -faultsAttrs[FaultID.FunctionContainsThis] = {cookBookRef: '93',}; -faultsAttrs[FaultID.GeneratorFunction] = {cookBookRef: '94',}; -faultsAttrs[FaultID.YieldExpression] = {cookBookRef: '94',}; -faultsAttrs[FaultID.IsOperator] = {cookBookRef: '96',}; -faultsAttrs[FaultID.SpreadOperator] = {cookBookRef: '99',}; -faultsAttrs[FaultID.IntefaceExtendDifProps] = {cookBookRef: '102',}; -faultsAttrs[FaultID.InterfaceMerging] = {cookBookRef: '103',}; -faultsAttrs[FaultID.InterfaceExtendsClass] = {cookBookRef: '104',}; -faultsAttrs[FaultID.ConstructorFuncs] = {cookBookRef: '106',}; -faultsAttrs[FaultID.EnumMemberNonConstInit] = {cookBookRef: '111',}; -faultsAttrs[FaultID.EnumMerging] = {cookBookRef: '113',}; -faultsAttrs[FaultID.NamespaceAsObject] = {cookBookRef: '114',}; -faultsAttrs[FaultID.NonDeclarationInNamespace] = {cookBookRef: '116',}; -faultsAttrs[FaultID.ImportFromPath] = {cookBookRef: '119',}; -faultsAttrs[FaultID.DefaultImport] = {migratable: true, cookBookRef: '120',}; -faultsAttrs[FaultID.ImportAssignment] = {cookBookRef: '121',}; -faultsAttrs[FaultID.ExportAssignment] = {cookBookRef: '126',}; -faultsAttrs[FaultID.ShorthandAmbientModuleDecl] = {cookBookRef: '128',}; -faultsAttrs[FaultID.WildcardsInModuleName] = {cookBookRef: '129',}; -faultsAttrs[FaultID.UMDModuleDefinition] = {cookBookRef: '130',}; -faultsAttrs[FaultID.NewTarget] = {cookBookRef: '132',}; -faultsAttrs[FaultID.DefiniteAssignment] = {warning: true, cookBookRef: '134',}; -faultsAttrs[FaultID.Prototype] = {cookBookRef: '136',}; -faultsAttrs[FaultID.GlobalThis] = {cookBookRef: '137',}; -faultsAttrs[FaultID.UtilityType] = {cookBookRef: '138',}; -faultsAttrs[FaultID.PropertyDeclOnFunction] = {cookBookRef: '139',}; -faultsAttrs[FaultID.FunctionApplyBindCall] = {cookBookRef: '140',}; -faultsAttrs[FaultID.ConstAssertion] = {cookBookRef: '142',}; -faultsAttrs[FaultID.ImportAssertion] = {cookBookRef: '143',}; -faultsAttrs[FaultID.LimitedStdLibApi] = {cookBookRef: '144',}; -faultsAttrs[FaultID.StrictDiagnostic] = {cookBookRef: '145',}; -faultsAttrs[FaultID.ErrorSuppression] = {cookBookRef: '146',}; -faultsAttrs[FaultID.UnsupportedDecorators] = {warning: true, cookBookRef: '148',}; -faultsAttrs[FaultID.ClassAsObject] = {cookBookRef: '149',}; -faultsAttrs[FaultID.ImportAfterStatement] = {cookBookRef: '150',}; -faultsAttrs[FaultID.EsObjectType] = {warning: true, cookBookRef: '151'}; +faultsAttrs[FaultID.LiteralAsPropertyName] = { migratable: true, cookBookRef: '1' }; +faultsAttrs[FaultID.ComputedPropertyName] = { cookBookRef: '1' }; +faultsAttrs[FaultID.SymbolType] = { cookBookRef: '2' }; +faultsAttrs[FaultID.PrivateIdentifier] = { migratable: true, cookBookRef: '3' }; +faultsAttrs[FaultID.DeclWithDuplicateName] = { migratable: true, cookBookRef: '4' }; +faultsAttrs[FaultID.VarDeclaration] = { migratable: true, cookBookRef: '5' }; +faultsAttrs[FaultID.AnyType] = { cookBookRef: '8' }; +faultsAttrs[FaultID.UnknownType] = { cookBookRef: '8' }; +faultsAttrs[FaultID.CallSignature] = { cookBookRef: '14' }; +faultsAttrs[FaultID.ConstructorType] = { cookBookRef: '15' }; +faultsAttrs[FaultID.MultipleStaticBlocks] = { cookBookRef: '16' }; +faultsAttrs[FaultID.IndexMember] = { cookBookRef: '17' }; +faultsAttrs[FaultID.IntersectionType] = { cookBookRef: '19' }; +faultsAttrs[FaultID.ThisType] = { cookBookRef: '21' }; +faultsAttrs[FaultID.ConditionalType] = { cookBookRef: '22' }; +faultsAttrs[FaultID.ParameterProperties] = { migratable: true, cookBookRef: '25' }; +faultsAttrs[FaultID.ConstructorIface] = { cookBookRef: '27' }; +faultsAttrs[FaultID.IndexedAccessType] = { cookBookRef: '28' }; +faultsAttrs[FaultID.PropertyAccessByIndex] = { migratable: true, cookBookRef: '29' }; +faultsAttrs[FaultID.StructuralIdentity] = { cookBookRef: '30' }; +faultsAttrs[FaultID.GenericCallNoTypeArgs] = { cookBookRef: '34' }; +faultsAttrs[FaultID.RegexLiteral] = { cookBookRef: '37' }; +faultsAttrs[FaultID.ObjectLiteralNoContextType] = { cookBookRef: '38' }; +faultsAttrs[FaultID.ObjectTypeLiteral] = { cookBookRef: '40' }; +faultsAttrs[FaultID.ArrayLiteralNoContextType] = { cookBookRef: '43' }; +faultsAttrs[FaultID.FunctionExpression] = { migratable: true, cookBookRef: '46' }; +faultsAttrs[FaultID.LambdaWithTypeParameters] = { migratable: true, cookBookRef: '49' }; +faultsAttrs[FaultID.ClassExpression] = { migratable: true, cookBookRef: '50' }; +faultsAttrs[FaultID.ImplementsClass] = { cookBookRef: '51' }; +faultsAttrs[FaultID.MethodReassignment] = { cookBookRef: '52' }; +faultsAttrs[FaultID.TypeAssertion] = { migratable: true, cookBookRef: '53' }; +faultsAttrs[FaultID.JsxElement] = { cookBookRef: '54' }; +faultsAttrs[FaultID.UnaryArithmNotNumber] = { cookBookRef: '55' }; +faultsAttrs[FaultID.DeleteOperator] = { cookBookRef: '59' }; +faultsAttrs[FaultID.TypeQuery] = { cookBookRef: '60' }; +faultsAttrs[FaultID.InstanceofUnsupported] = { cookBookRef: '65' }; +faultsAttrs[FaultID.InOperator] = { cookBookRef: '66' }; +faultsAttrs[FaultID.DestructuringAssignment] = { migratable: true, cookBookRef: '69' }; +faultsAttrs[FaultID.CommaOperator] = { cookBookRef: '71' }; +faultsAttrs[FaultID.DestructuringDeclaration] = { migratable: true, cookBookRef: '74' }; +faultsAttrs[FaultID.CatchWithUnsupportedType] = { migratable: true, cookBookRef: '79' }; +faultsAttrs[FaultID.ForInStatement] = { cookBookRef: '80' }; +faultsAttrs[FaultID.MappedType] = { cookBookRef: '83' }; +faultsAttrs[FaultID.WithStatement] = { cookBookRef: '84' }; +faultsAttrs[FaultID.ThrowStatement] = { migratable: true, cookBookRef: '87' }; +faultsAttrs[FaultID.LimitedReturnTypeInference] = { migratable: true, cookBookRef: '90' }; +faultsAttrs[FaultID.DestructuringParameter] = { cookBookRef: '91' }; +faultsAttrs[FaultID.LocalFunction] = { migratable: true, cookBookRef: '92' }; +faultsAttrs[FaultID.FunctionContainsThis] = { cookBookRef: '93' }; +faultsAttrs[FaultID.GeneratorFunction] = { cookBookRef: '94' }; +faultsAttrs[FaultID.YieldExpression] = { cookBookRef: '94' }; +faultsAttrs[FaultID.IsOperator] = { cookBookRef: '96' }; +faultsAttrs[FaultID.SpreadOperator] = { cookBookRef: '99' }; +faultsAttrs[FaultID.IntefaceExtendDifProps] = { cookBookRef: '102' }; +faultsAttrs[FaultID.InterfaceMerging] = { cookBookRef: '103' }; +faultsAttrs[FaultID.InterfaceExtendsClass] = { cookBookRef: '104' }; +faultsAttrs[FaultID.ConstructorFuncs] = { cookBookRef: '106' }; +faultsAttrs[FaultID.EnumMemberNonConstInit] = { cookBookRef: '111' }; +faultsAttrs[FaultID.EnumMerging] = { cookBookRef: '113' }; +faultsAttrs[FaultID.NamespaceAsObject] = { cookBookRef: '114' }; +faultsAttrs[FaultID.NonDeclarationInNamespace] = { cookBookRef: '116' }; +faultsAttrs[FaultID.ImportFromPath] = { cookBookRef: '119' }; +faultsAttrs[FaultID.DefaultImport] = { migratable: true, cookBookRef: '120' }; +faultsAttrs[FaultID.ImportAssignment] = { cookBookRef: '121' }; +faultsAttrs[FaultID.ExportAssignment] = { cookBookRef: '126' }; +faultsAttrs[FaultID.ShorthandAmbientModuleDecl] = { cookBookRef: '128' }; +faultsAttrs[FaultID.WildcardsInModuleName] = { cookBookRef: '129' }; +faultsAttrs[FaultID.UMDModuleDefinition] = { cookBookRef: '130' }; +faultsAttrs[FaultID.NewTarget] = { cookBookRef: '132' }; +faultsAttrs[FaultID.DefiniteAssignment] = { warning: true, cookBookRef: '134' }; +faultsAttrs[FaultID.Prototype] = { cookBookRef: '136' }; +faultsAttrs[FaultID.GlobalThis] = { cookBookRef: '137' }; +faultsAttrs[FaultID.UtilityType] = { cookBookRef: '138' }; +faultsAttrs[FaultID.PropertyDeclOnFunction] = { cookBookRef: '139' }; +faultsAttrs[FaultID.FunctionApplyBindCall] = { cookBookRef: '140' }; +faultsAttrs[FaultID.ConstAssertion] = { cookBookRef: '142' }; +faultsAttrs[FaultID.ImportAssertion] = { cookBookRef: '143' }; +faultsAttrs[FaultID.LimitedStdLibApi] = { cookBookRef: '144' }; +faultsAttrs[FaultID.StrictDiagnostic] = { cookBookRef: '145' }; +faultsAttrs[FaultID.ErrorSuppression] = { cookBookRef: '146' }; +faultsAttrs[FaultID.UnsupportedDecorators] = { warning: true, cookBookRef: '148' }; +faultsAttrs[FaultID.ClassAsObject] = { cookBookRef: '149' }; +faultsAttrs[FaultID.ImportAfterStatement] = { cookBookRef: '150' }; +faultsAttrs[FaultID.EsObjectType] = { warning: true, cookBookRef: '151' }; diff --git a/linter/src/IncrementalLintInfo.ts b/linter/src/IncrementalLintInfo.ts index f1039696b..610b78409 100644 --- a/linter/src/IncrementalLintInfo.ts +++ b/linter/src/IncrementalLintInfo.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import * as ts from 'typescript'; +import type * as ts from 'typescript'; export interface IncrementalLintInfo { - shouldSkipCheck(node: ts.Node): boolean; + shouldSkipCheck: (node: ts.Node) => boolean; } diff --git a/linter/src/LintOptions.ts b/linter/src/LintOptions.ts index ce7a7a50e..af388cec5 100644 --- a/linter/src/LintOptions.ts +++ b/linter/src/LintOptions.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import * as ts from 'typescript'; -import { CommandLineOptions } from './CommandLineOptions'; -import { IncrementalLintInfo } from './IncrementalLintInfo'; -import { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; -import { IsFileFromModuleCallback } from './IsFileFromModuleCallback'; +import type * as ts from 'typescript'; +import type { CommandLineOptions } from './CommandLineOptions'; +import type { IncrementalLintInfo } from './IncrementalLintInfo'; +import type { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; +import type { IsFileFromModuleCallback } from './IsFileFromModuleCallback'; // common options interface, additional fields may be used by plugins export interface LintOptions { diff --git a/linter/src/LintRunResult.ts b/linter/src/LintRunResult.ts index 0b2821949..751cc8d6e 100644 --- a/linter/src/LintRunResult.ts +++ b/linter/src/LintRunResult.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ProblemInfo } from './ProblemInfo'; +import type { ProblemInfo } from './ProblemInfo'; export interface LintRunResult { errorNodes: number; diff --git a/linter/src/LinterCLI.ts b/linter/src/LinterCLI.ts index 7fd5063d9..ae6ad55a2 100644 --- a/linter/src/LinterCLI.ts +++ b/linter/src/LinterCLI.ts @@ -20,12 +20,12 @@ import * as fs from 'node:fs'; import * as os from 'node:os'; import * as readline from 'node:readline'; import * as path from 'node:path'; -import { CommandLineOptions } from './CommandLineOptions'; +import type { CommandLineOptions } from './CommandLineOptions'; import { lint } from './LinterRunner'; const logger = Logger.getLogger(); -export function run() { +export function run(): void { const commandLineArgs = process.argv.slice(2); if (commandLineArgs.length === 0) { logger.info('Command line error: no arguments'); @@ -48,11 +48,11 @@ export function run() { } } -function getTempFileName() { +function getTempFileName(): string { return path.join(os.tmpdir(), Math.floor(Math.random() * 10000000).toString() + '_linter_tmp_file.ts'); } -function runIDEMode(cmdOptions: CommandLineOptions) { +function runIDEMode(cmdOptions: CommandLineOptions): void { TypeScriptLinter.ideMode = true; const tmpFileName = getTempFileName(); // read data from stdin @@ -60,10 +60,12 @@ function runIDEMode(cmdOptions: CommandLineOptions) { const rl = readline.createInterface({ input: process.stdin, output: writeStream, - terminal: false, + terminal: false }); - rl.on('line', (line: string) => { fs.appendFileSync(tmpFileName, line + '\n'); }); + rl.on('line', (line: string) => { + fs.appendFileSync(tmpFileName, line + '\n'); + }); rl.once('close', () => { // end of input writeStream.close(); @@ -74,18 +76,20 @@ function runIDEMode(cmdOptions: CommandLineOptions) { const result = lint({ cmdOptions: cmdOptions, realtimeLint: false }); const problems = Array.from(result.problemsInfos.values()); if (problems.length === 1) { - const jsonMessage = problems[0].map((x) => ({ - line: x.line, - column: x.column, - start: x.start, - end: x.end, - type: x.type, - suggest: x.suggest, - rule: x.rule, - severity: x.severity, - autofixable: x.autofixable, - autofix: x.autofix - })); + const jsonMessage = problems[0].map((x) => { + return { + line: x.line, + column: x.column, + start: x.start, + end: x.end, + type: x.type, + suggest: x.suggest, + rule: x.rule, + severity: x.severity, + autofixable: x.autofixable, + autofix: x.autofix + }; + }); logger.info(`{"linter messages":${JSON.stringify(jsonMessage)}}`); } else { logger.error('Unexpected error: could not lint file'); diff --git a/linter/src/LinterRunner.ts b/linter/src/LinterRunner.ts index 4a5a147fd..2737bdb76 100644 --- a/linter/src/LinterRunner.ts +++ b/linter/src/LinterRunner.ts @@ -13,18 +13,24 @@ * limitations under the License. */ -import * as ts from 'typescript'; -import { ProblemInfo } from './ProblemInfo'; +import type * as ts from 'typescript'; +import type { ProblemInfo } from './ProblemInfo'; import { TypeScriptLinter, consoleLog } from './TypeScriptLinter'; import { FaultID } from './Problems'; import { faultDesc } from './FaultDesc'; import { faultsAttrs } from './FaultAttrs'; -import { LintRunResult } from './LintRunResult'; +import type { LintRunResult } from './LintRunResult'; import * as path from 'node:path'; import { compile } from './CompilerWrapper'; -import { LintOptions } from './LintOptions'; +import type { LintOptions } from './LintOptions'; +import type { CommandLineOptions } from './CommandLineOptions'; import { AutofixInfoSet } from './Autofixer'; -import { TSCCompiledProgram, TSCCompiledProgramSimple, TSCCompiledProgramWithDiagnostics, getStrictOptions } from './ts-diagnostics/TSCCompiledProgram'; +import type { TSCCompiledProgram } from './ts-diagnostics/TSCCompiledProgram'; +import { + TSCCompiledProgramSimple, + TSCCompiledProgramWithDiagnostics, + getStrictOptions +} from './ts-diagnostics/TSCCompiledProgram'; import { mergeArrayMaps } from './utils/functions/MergeArrayMaps'; import { getTscDiagnostics } from './ts-diagnostics/GetTscDiagnostics'; import { transformTscDiagnostics } from './ts-diagnostics/TransformTscDiagnostics'; @@ -35,37 +41,72 @@ import { } from './utils/consts/ArktsIgnorePaths'; import { pathContainsDirectory } from './utils/functions/PathHelper'; -export function lint(options: LintOptions): LintRunResult { - const cmdOptions = options.cmdOptions; - const cancellationToken = options.cancellationToken; - - const tscDiagnosticsLinter = createLinter(options); - const tsProgram = tscDiagnosticsLinter.getOriginalProgram(); - - // Prepare list of input files for linter and retrieve AST for those files. - let inputFiles: string[] = cmdOptions.inputFiles; +function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { + let inputFiles = cmdOptions.inputFiles; if (cmdOptions.parsedConfigFile) { inputFiles = cmdOptions.parsedConfigFile.fileNames; if (cmdOptions.inputFiles.length > 0) { - // Apply linter only to the project source files that are specified - // as a command-line arguments. Other source files will be discarded. - const cmdInputsResolvedPaths = cmdOptions.inputFiles.map((x) => path.resolve(x)); - const configInputsResolvedPaths = inputFiles.map((x) => path.resolve(x)); - inputFiles = configInputsResolvedPaths.filter((x) => cmdInputsResolvedPaths.some((y) => x === y)); + + /* + * Apply linter only to the project source files that are specified + * as a command-line arguments. Other source files will be discarded. + */ + const cmdInputsResolvedPaths = cmdOptions.inputFiles.map((x) => { + return path.resolve(x); + }); + const configInputsResolvedPaths = inputFiles.map((x) => { + return path.resolve(x); + }); + inputFiles = configInputsResolvedPaths.filter((x) => { + return cmdInputsResolvedPaths.some((y) => { + return x === y; + }); + }); } } - // #13436: ignore-list for ArkTS projects. - inputFiles = inputFiles.filter(input => shouldProcessFile(options, input)); + return inputFiles; +} +function countProblems(linter: TypeScriptLinter): [number, number] { + let errorNodesTotal = 0; + let warningNodes = 0; + for (let i = 0; i < FaultID.LAST_ID; i++) { + // if Strict mode - count all cases + if (!linter.strictMode && faultsAttrs[i].migratable) { + // In relax mode skip migratable + continue; + } + if (faultsAttrs[i].warning) { + warningNodes += linter.nodeCounters[i]; + } else { + errorNodesTotal += linter.nodeCounters[i]; + } + } + + return [errorNodesTotal, warningNodes]; +} + +export function lint(options: LintOptions): LintRunResult { + const cmdOptions = options.cmdOptions; + const cancellationToken = options.cancellationToken; + const tscDiagnosticsLinter = createLinter(options); + const tsProgram = tscDiagnosticsLinter.getOriginalProgram(); + + // Prepare list of input files for linter and retrieve AST for those files. + let inputFiles = prepareInputFilesList(cmdOptions); + inputFiles = inputFiles.filter((input) => { + return shouldProcessFile(options, input); + }); const srcFiles: ts.SourceFile[] = []; for (const inputFile of inputFiles) { const srcFile = tsProgram.getSourceFile(inputFile); - if (srcFile) srcFiles.push(srcFile); + if (srcFile) { + srcFiles.push(srcFile); + } } const tscStrictDiagnostics = getTscDiagnostics(tscDiagnosticsLinter, srcFiles); - const linter = new TypeScriptLinter( tsProgram.getTypeChecker(), new AutofixInfoSet(cmdOptions.autofixInfo), @@ -81,20 +122,14 @@ export function lint(options: LintOptions): LintRunResult { consoleLog('\n\n\nFiles scanned: ', srcFiles.length); consoleLog('\nFiles with problems: ', errorNodes); - let errorNodesTotal = 0, warningNodes = 0; - for (let i = 0; i < FaultID.LAST_ID; i++) { - // if Strict mode - count all cases - if (!linter.strictMode && faultsAttrs[i].migratable) // In relax mode skip migratable - continue; + const [errorNodesTotal, warningNodes] = countProblems(linter); - if (faultsAttrs[i].warning) warningNodes += linter.nodeCounters[i]; - else errorNodesTotal += linter.nodeCounters[i]; - } logTotalProblemsInfo(errorNodesTotal, warningNodes, linter); logProblemsPercentageByFeatures(linter); + return { errorNodes: errorNodesTotal, - problemsInfos: mergeArrayMaps(problemsInfos, transformTscDiagnostics(tscStrictDiagnostics)), + problemsInfos: mergeArrayMaps(problemsInfos, transformTscDiagnostics(tscStrictDiagnostics)) }; } @@ -111,7 +146,7 @@ export function createLinter(options: LintOptions): TSCCompiledProgram { function lintFiles(srcFiles: ts.SourceFile[], linter: TypeScriptLinter): LintRunResult { let problemFiles = 0; - let problemsInfos: Map = new Map(); + const problemsInfos: Map = new Map(); for (const srcFile of srcFiles) { const prevVisitedNodes = linter.totalVisitedNodes; @@ -121,12 +156,13 @@ function lintFiles(srcFiles: ts.SourceFile[], linter: TypeScriptLinter): LintRun linter.warningLineNumbersString = ''; const nodeCounters: number[] = []; - for (let i = 0; i < FaultID.LAST_ID; i++) + for (let i = 0; i < FaultID.LAST_ID; i++) { nodeCounters[i] = linter.nodeCounters[i]; + } linter.lint(srcFile); // save results and clear problems array - problemsInfos.set( path.normalize(srcFile.fileName), [...linter.problemsInfos]); + problemsInfos.set(path.normalize(srcFile.fileName), [...linter.problemsInfos]); linter.problemsInfos.length = 0; // print results for current file @@ -135,73 +171,115 @@ function lintFiles(srcFiles: ts.SourceFile[], linter: TypeScriptLinter): LintRun const fileWarningLines = linter.totalWarningLines - prevWarningLines; problemFiles = countProblemFiles( - nodeCounters, problemFiles, srcFile, fileVisitedNodes, fileErrorLines, fileWarningLines, linter + nodeCounters, + problemFiles, + srcFile, + fileVisitedNodes, + fileErrorLines, + fileWarningLines, + linter ); } return { errorNodes: problemFiles, - problemsInfos: problemsInfos, + problemsInfos: problemsInfos }; } function countProblemFiles( - nodeCounters: number[], filesNumber: number, tsSrcFile: ts.SourceFile, - fileNodes: number, fileErrorLines: number, fileWarningLines: number, linter: TypeScriptLinter, -) { - let errorNodes = 0, warningNodes = 0; + nodeCounters: number[], + filesNumber: number, + tsSrcFile: ts.SourceFile, + fileNodes: number, + fileErrorLines: number, + fileWarningLines: number, + linter: TypeScriptLinter +): number { + let errorNodes = 0; + let warningNodes = 0; for (let i = 0; i < FaultID.LAST_ID; i++) { - let nodeCounterDiff = linter.nodeCounters[i] - nodeCounters[i]; - if (faultsAttrs[i].warning) warningNodes += nodeCounterDiff; - else errorNodes += nodeCounterDiff; + const nodeCounterDiff = linter.nodeCounters[i] - nodeCounters[i]; + if (faultsAttrs[i].warning) { + warningNodes += nodeCounterDiff; + } else { + errorNodes += nodeCounterDiff; + } } if (errorNodes > 0) { filesNumber++; - let errorRate = ((errorNodes / fileNodes) * 100).toFixed(2); - let warningRate = ((warningNodes / fileNodes) * 100).toFixed(2); + const errorRate = (errorNodes / fileNodes * 100).toFixed(2); + const warningRate = (warningNodes / fileNodes * 100).toFixed(2); consoleLog(tsSrcFile.fileName, ': ', '\n\tError lines: ', linter.errorLineNumbersString); consoleLog(tsSrcFile.fileName, ': ', '\n\tWarning lines: ', linter.warningLineNumbersString); - consoleLog('\n\tError constructs (%): ', errorRate, '\t[ of ', fileNodes, ' constructs ], \t', fileErrorLines, ' lines'); - consoleLog('\n\tWarning constructs (%): ', warningRate, '\t[ of ', fileNodes, ' constructs ], \t', fileWarningLines, ' lines'); + consoleLog( + '\n\tError constructs (%): ', + errorRate, + '\t[ of ', + fileNodes, + ' constructs ], \t', + fileErrorLines, + ' lines' + ); + consoleLog( + '\n\tWarning constructs (%): ', + warningRate, + '\t[ of ', + fileNodes, + ' constructs ], \t', + fileWarningLines, + ' lines' + ); } return filesNumber; } -function logTotalProblemsInfo(errorNodes: number, warningNodes: number, linter: TypeScriptLinter) { - let errorRate = ((errorNodes / linter.totalVisitedNodes) * 100).toFixed(2); - let warningRate = ((warningNodes / linter.totalVisitedNodes) * 100).toFixed(2); +function logTotalProblemsInfo(errorNodes: number, warningNodes: number, linter: TypeScriptLinter): void { + const errorRate = (errorNodes / linter.totalVisitedNodes * 100).toFixed(2); + const warningRate = (warningNodes / linter.totalVisitedNodes * 100).toFixed(2); consoleLog('\nTotal error constructs (%): ', errorRate); consoleLog('\nTotal warning constructs (%): ', warningRate); consoleLog('\nTotal error lines:', linter.totalErrorLines, ' lines\n'); consoleLog('\nTotal warning lines:', linter.totalWarningLines, ' lines\n'); } -function logProblemsPercentageByFeatures(linter: TypeScriptLinter) { +function logProblemsPercentageByFeatures(linter: TypeScriptLinter): void { consoleLog('\nPercent by features: '); for (let i = 0; i < FaultID.LAST_ID; i++) { // if Strict mode - count all cases - if (!linter.strictMode && faultsAttrs[i].migratable) + if (!linter.strictMode && faultsAttrs[i].migratable) { continue; - - let nodes = linter.nodeCounters[i]; - let lines = linter.lineCounters[i]; - let pecentage = ((nodes / linter.totalVisitedNodes) * 100).toFixed(2).padEnd(7, ' '); + } + + const nodes = linter.nodeCounters[i]; + const lines = linter.lineCounters[i]; + const pecentage = (nodes / linter.totalVisitedNodes * 100).toFixed(2).padEnd(7, ' '); consoleLog(faultDesc[i].padEnd(55, ' '), pecentage, '[', nodes, ' constructs / ', lines, ' lines]'); } } -function shouldProcessFile(options: LintOptions, fileFsPath: string) { - if (ARKTS_IGNORE_FILES.some(ignore => path.basename(fileFsPath) === ignore)) { +function shouldProcessFile(options: LintOptions, fileFsPath: string): boolean { + if ( + ARKTS_IGNORE_FILES.some((ignore) => { + return path.basename(fileFsPath) === ignore; + }) + ) { return false; } - if (ARKTS_IGNORE_DIRS_NO_OH_MODULES.some(ignore => pathContainsDirectory(path.resolve(fileFsPath), ignore))) { + if ( + ARKTS_IGNORE_DIRS_NO_OH_MODULES.some((ignore) => { + return pathContainsDirectory(path.resolve(fileFsPath), ignore); + }) + ) { return false; } - return !pathContainsDirectory(path.resolve(fileFsPath), ARKTS_IGNORE_DIRS_OH_MODULES) || - (options.isFileFromModuleCb !== undefined && options.isFileFromModuleCb(fileFsPath)); + return ( + !pathContainsDirectory(path.resolve(fileFsPath), ARKTS_IGNORE_DIRS_OH_MODULES) || + options.isFileFromModuleCb !== undefined && options.isFileFromModuleCb(fileFsPath) + ); } diff --git a/linter/src/ProblemInfo.ts b/linter/src/ProblemInfo.ts index ff4543a32..97e82432e 100644 --- a/linter/src/ProblemInfo.ts +++ b/linter/src/ProblemInfo.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Autofix } from './Autofixer'; +import type { Autofix } from './Autofixer'; export interface ProblemInfo { line: number; diff --git a/linter/src/ProblemSeverity.ts b/linter/src/ProblemSeverity.ts index 3736c692e..e89dc4a78 100644 --- a/linter/src/ProblemSeverity.ts +++ b/linter/src/ProblemSeverity.ts @@ -13,4 +13,7 @@ * limitations under the License. */ -export enum ProblemSeverity { WARNING = 1, ERROR = 2 } +export enum ProblemSeverity { + WARNING = 1, + ERROR = 2 +} diff --git a/linter/src/Problems.ts b/linter/src/Problems.ts index 4008210e4..9a46fcc49 100644 --- a/linter/src/Problems.ts +++ b/linter/src/Problems.ts @@ -14,26 +14,90 @@ */ export enum FaultID { - AnyType, SymbolType, ObjectLiteralNoContextType, ArrayLiteralNoContextType, - ComputedPropertyName, LiteralAsPropertyName, TypeQuery, RegexLiteral, IsOperator, - DestructuringParameter, YieldExpression, InterfaceMerging, EnumMerging, InterfaceExtendsClass, IndexMember, WithStatement, - ThrowStatement, IndexedAccessType, UnknownType, ForInStatement, InOperator, - ImportFromPath, FunctionExpression, IntersectionType, - ObjectTypeLiteral, CommaOperator, LimitedReturnTypeInference, - LambdaWithTypeParameters, ClassExpression, DestructuringAssignment, - DestructuringDeclaration, VarDeclaration, CatchWithUnsupportedType, DeleteOperator, - DeclWithDuplicateName, UnaryArithmNotNumber, ConstructorType, ConstructorIface, ConstructorFuncs, CallSignature, - TypeAssertion, PrivateIdentifier, LocalFunction, - ConditionalType, MappedType, NamespaceAsObject, ClassAsObject, - NonDeclarationInNamespace, GeneratorFunction, FunctionContainsThis, PropertyAccessByIndex, JsxElement, - EnumMemberNonConstInit, ImplementsClass, MethodReassignment, MultipleStaticBlocks, ThisType, - IntefaceExtendDifProps, StructuralIdentity, DefaultImport, - ExportAssignment, ImportAssignment, - GenericCallNoTypeArgs, ParameterProperties, - InstanceofUnsupported, ShorthandAmbientModuleDecl, WildcardsInModuleName, UMDModuleDefinition, - NewTarget, DefiniteAssignment, Prototype, GlobalThis, - UtilityType, PropertyDeclOnFunction, FunctionApplyBindCall, ConstAssertion, ImportAssertion, - SpreadOperator, LimitedStdLibApi, ErrorSuppression, StrictDiagnostic, UnsupportedDecorators, ImportAfterStatement, + AnyType, + SymbolType, + ObjectLiteralNoContextType, + ArrayLiteralNoContextType, + ComputedPropertyName, + LiteralAsPropertyName, + TypeQuery, + RegexLiteral, + IsOperator, + DestructuringParameter, + YieldExpression, + InterfaceMerging, + EnumMerging, + InterfaceExtendsClass, + IndexMember, + WithStatement, + ThrowStatement, + IndexedAccessType, + UnknownType, + ForInStatement, + InOperator, + ImportFromPath, + FunctionExpression, + IntersectionType, + ObjectTypeLiteral, + CommaOperator, + LimitedReturnTypeInference, + LambdaWithTypeParameters, + ClassExpression, + DestructuringAssignment, + DestructuringDeclaration, + VarDeclaration, + CatchWithUnsupportedType, + DeleteOperator, + DeclWithDuplicateName, + UnaryArithmNotNumber, + ConstructorType, + ConstructorIface, + ConstructorFuncs, + CallSignature, + TypeAssertion, + PrivateIdentifier, + LocalFunction, + ConditionalType, + MappedType, + NamespaceAsObject, + ClassAsObject, + NonDeclarationInNamespace, + GeneratorFunction, + FunctionContainsThis, + PropertyAccessByIndex, + JsxElement, + EnumMemberNonConstInit, + ImplementsClass, + MethodReassignment, + MultipleStaticBlocks, + ThisType, + IntefaceExtendDifProps, + StructuralIdentity, + DefaultImport, + ExportAssignment, + ImportAssignment, + GenericCallNoTypeArgs, + ParameterProperties, + InstanceofUnsupported, + ShorthandAmbientModuleDecl, + WildcardsInModuleName, + UMDModuleDefinition, + NewTarget, + DefiniteAssignment, + Prototype, + GlobalThis, + UtilityType, + PropertyDeclOnFunction, + FunctionApplyBindCall, + ConstAssertion, + ImportAssertion, + SpreadOperator, + LimitedStdLibApi, + ErrorSuppression, + StrictDiagnostic, + UnsupportedDecorators, + ImportAfterStatement, EsObjectType, - LAST_ID, // this should always be last enum` + // this should always be last enum + LAST_ID } diff --git a/linter/src/TestRunner.ts b/linter/src/TestRunner.ts index 99fa92958..d2fbb0ca8 100644 --- a/linter/src/TestRunner.ts +++ b/linter/src/TestRunner.ts @@ -16,11 +16,12 @@ import { TypeScriptLinter } from './TypeScriptLinter'; import { lint } from './LinterRunner'; import { parseCommandLine } from './CommandLineParser'; -import { Autofix } from './Autofixer'; +import type { Autofix } from './Autofixer'; import Logger from '../utils/logger'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as ts from 'typescript'; +import type { CommandLineOptions } from './CommandLineOptions'; const TEST_DIR = 'test'; const TAB = ' '; @@ -49,69 +50,64 @@ RESULT_EXT[Mode.RELAX] = '.relax.json'; RESULT_EXT[Mode.AUTOFIX] = '.autofix.json'; const AUTOFIX_CONFIG_EXT = '.autofix.cfg.json'; const AUTOFIX_SKIP_EXT = '.autofix.skip'; -const ARGS_CONFIG_EXT = '.args.json' +const ARGS_CONFIG_EXT = '.args.json'; const DIFF_EXT = '.diff'; function runTests(testDirs: string[]): number { - let hasComparisonFailures = false; - // Set the IDE mode manually to enable storing information - // about found bad nodes and also disable the log output. + /* + * Set the IDE mode manually to enable storing information + * about found bad nodes and also disable the log output. + */ TypeScriptLinter.ideMode = true; TypeScriptLinter.testMode = true; - let passed = 0, failed = 0; - + let hasComparisonFailures = false; + let passed = 0; + let failed = 0; // Get tests from test directory - if (!testDirs?.length) testDirs = [ TEST_DIR ]; + if (!testDirs?.length) { + testDirs = [TEST_DIR]; + } for (const testDir of testDirs) { - let testFiles: string[] = fs.readdirSync(testDir) - .filter((x) => (x.trimEnd().endsWith(ts.Extension.Ts) && !x.trimEnd().endsWith(ts.Extension.Dts)) || x.trimEnd().endsWith(ts.Extension.Tsx)); - + const testFiles: string[] = fs.readdirSync(testDir).filter((x) => { + return ( + x.trimEnd().endsWith(ts.Extension.Ts) && !x.trimEnd().endsWith(ts.Extension.Dts) || + x.trimEnd().endsWith(ts.Extension.Tsx) + ); + }); logger.info(`\nProcessing "${testDir}" directory:\n`); - // Run each test in Strict, Autofix, and Relax mode: for (const testFile of testFiles) { if (runTest(testDir, testFile, Mode.STRICT)) { failed++; hasComparisonFailures = true; + } else { + passed++; } - else passed++; - if (runTest(testDir, testFile, Mode.AUTOFIX)) { failed++; hasComparisonFailures = true; + } else { + passed++; } - else passed++; - if (runTest(testDir, testFile, Mode.RELAX)) { failed++; hasComparisonFailures = true; + } else { + passed++; } - else passed++; } } - logger.info(`\nSUMMARY: ${passed + failed} total, ${passed} passed or skipped, ${failed} failed.`); - logger.info((failed > 0) ? '\nTEST FAILED' : '\nTEST SUCCESSFUL'); - + logger.info(failed > 0 ? '\nTEST FAILED' : '\nTEST SUCCESSFUL'); process.exit(hasComparisonFailures ? -1 : 0); } -function runTest(testDir: string, testFile: string, mode: Mode): boolean { - let testFailed = false; - if (mode === Mode.AUTOFIX && fs.existsSync(path.join(testDir, testFile + AUTOFIX_SKIP_EXT))) { - logger.info(`Skipping test ${testFile} (${Mode[mode]} mode)`); - return false; - } - logger.info(`Running test ${testFile} (${Mode[mode]} mode)`); - - TypeScriptLinter.initGlobals(); - +function parseArgs(testDir: string, testFile: string, mode: Mode): CommandLineOptions { // Configure test parameters and run linter. const args: string[] = [path.join(testDir, testFile)]; - let argsFileName = path.join(testDir, testFile + ARGS_CONFIG_EXT); - let currentTestMode = TypeScriptLinter.testMode; + const argsFileName = path.join(testDir, testFile + ARGS_CONFIG_EXT); if (fs.existsSync(argsFileName)) { const data = fs.readFileSync(argsFileName).toString(); @@ -121,72 +117,94 @@ function runTest(testDir: string, testFile: string, mode: Mode): boolean { } } - if (mode === Mode.RELAX) args.push('--relax'); - else if (mode === Mode.AUTOFIX) { + if (mode === Mode.RELAX) { + args.push('--relax'); + } else if (mode === Mode.AUTOFIX) { args.push('--autofix'); - let autofixCfg = path.join(testDir, testFile + AUTOFIX_CONFIG_EXT); - if (fs.existsSync(autofixCfg)) args.push(autofixCfg); - } - const cmdOptions = parseCommandLine(args); - const result = lint({ cmdOptions: cmdOptions, realtimeLint: false }); - const fileProblems = result.problemsInfos.get( path.normalize(cmdOptions.inputFiles[0]) ); - if (fileProblems === undefined) { - return true; + const autofixCfg = path.join(testDir, testFile + AUTOFIX_CONFIG_EXT); + if (fs.existsSync(autofixCfg)) { + args.push(autofixCfg); + } } - TypeScriptLinter.testMode = currentTestMode; - - const resultExt = RESULT_EXT[mode]; - const testResultFileName = testFile + resultExt; - - // Get list of bad nodes from the current run. - const resultNodes: TestNodeInfo[] = - fileProblems.map( - (x) => ({ - line: x.line, column: x.column, problem: x.problem, - autofixable: mode === Mode.AUTOFIX ? x.autofixable : undefined, - autofix: mode === Mode.AUTOFIX ? x.autofix : undefined, - suggest: x.suggest, - rule: x.rule - }) - ); + return parseCommandLine(args); +} +function compareExpectedAndActual(testDir: string, testFile: string, mode: Mode, resultNodes: TestNodeInfo[]): string { // Read file with expected test result. let expectedResult: { nodes: TestNodeInfo[] }; let diff: string = ''; + const resultExt = RESULT_EXT[mode]; + const testResultFileName = testFile + resultExt; try { const expectedResultFile = fs.readFileSync(path.join(testDir, testResultFileName)).toString(); expectedResult = JSON.parse(expectedResultFile); - if (!expectedResult || !expectedResult.nodes || expectedResult.nodes.length !== resultNodes.length) { - testFailed = true; - let expectedResultCount = expectedResult && expectedResult.nodes ? expectedResult.nodes.length : 0; + if (!expectedResult?.nodes || expectedResult.nodes.length !== resultNodes.length) { + const expectedResultCount = expectedResult?.nodes ? expectedResult.nodes.length : 0; diff = `Expected count: ${expectedResultCount} vs actual count: ${resultNodes.length}`; logger.info(`${TAB}${diff}`); } else { diff = expectedAndActualMatch(expectedResult.nodes, resultNodes); - testFailed = !!diff; } - if (testFailed) { + if (diff) { logger.info(`${TAB}Test failed. Expected and actual results differ.`); } - } catch (error: any) { - testFailed = true; - logger.info(`${TAB}Test failed. ${error.message ?? error}`); + } catch (error) { + logger.info(`${TAB}Test failed. `, error); + } + + return diff; +} + +function runTest(testDir: string, testFile: string, mode: Mode): boolean { + if (mode === Mode.AUTOFIX && fs.existsSync(path.join(testDir, testFile + AUTOFIX_SKIP_EXT))) { + logger.info(`Skipping test ${testFile} (${Mode[mode]} mode)`); + return false; + } + logger.info(`Running test ${testFile} (${Mode[mode]} mode)`); + + TypeScriptLinter.initGlobals(); + + const currentTestMode = TypeScriptLinter.testMode; + + const cmdOptions = parseArgs(testDir, testFile, mode); + const result = lint({ cmdOptions: cmdOptions, realtimeLint: false }); + const fileProblems = result.problemsInfos.get(path.normalize(cmdOptions.inputFiles[0])); + if (fileProblems === undefined) { + return true; } + TypeScriptLinter.testMode = currentTestMode; + + // Get list of bad nodes from the current run. + const resultNodes: TestNodeInfo[] = fileProblems.map((x) => { + return { + line: x.line, + column: x.column, + problem: x.problem, + autofixable: mode === Mode.AUTOFIX ? x.autofixable : undefined, + autofix: mode === Mode.AUTOFIX ? x.autofix : undefined, + suggest: x.suggest, + rule: x.rule + }; + }); + + // Read file with expected test result. + const testResult = compareExpectedAndActual(testDir, testFile, mode, resultNodes); + // Write file with actual test results. - writeActualResultFile(testDir, testFile, resultExt, resultNodes, diff); + writeActualResultFile(testDir, testFile, mode, resultNodes, testResult); - return testFailed; + return !!testResult; } function expectedAndActualMatch(expectedNodes: TestNodeInfo[], actualNodes: TestNodeInfo[]): string { // Compare expected and actual results. for (let i = 0; i < actualNodes.length; i++) { - let actual = actualNodes[i]; - let expect = expectedNodes[i]; + const actual = actualNodes[i]; + const expect = expectedNodes[i]; if (actual.line !== expect.line || actual.column !== expect.column || actual.problem !== expect.problem) { return reportDiff(expect, actual); } @@ -205,20 +223,36 @@ function expectedAndActualMatch(expectedNodes: TestNodeInfo[], actualNodes: Test } function autofixArraysMatch(expected: Autofix[] | undefined, actual: Autofix[] | undefined): boolean { - if (!expected && !actual) return true; - if (!(expected && actual) || expected.length !== actual.length) return false; + if (!expected && !actual) { + return true; + } + if (!(expected && actual) || expected.length !== actual.length) { + return false; + } for (let i = 0; i < actual.length; ++i) { if ( - actual[i].start !== expected[i].start || actual[i].end !== expected[i].end || + actual[i].start !== expected[i].start || + actual[i].end !== expected[i].end || actual[i].replacementText.replace(/\r\n/g, '\n') !== expected[i].replacementText.replace(/\r\n/g, '\n') - ) return false; + ) { + return false; + } } return true; } -function writeActualResultFile(testDir: string, testFile: string, resultExt: string, resultNodes: TestNodeInfo[], diff: string) { +function writeActualResultFile( + testDir: string, + testFile: string, + mode: Mode, + resultNodes: TestNodeInfo[], + diff: string +): void { const actualResultsDir = path.join(testDir, 'results'); - if (!fs.existsSync(actualResultsDir)) fs.mkdirSync(actualResultsDir); + const resultExt = RESULT_EXT[mode]; + if (!fs.existsSync(actualResultsDir)) { + fs.mkdirSync(actualResultsDir); + } const actualResultJSON = JSON.stringify({ nodes: resultNodes }, null, 4); fs.writeFileSync(path.join(actualResultsDir, testFile + resultExt), actualResultJSON); @@ -229,11 +263,10 @@ function writeActualResultFile(testDir: string, testFile: string, resultExt: str } function reportDiff(expected: TestNodeInfo, actual: TestNodeInfo): string { - let expectedNode = JSON.stringify({ nodes: [expected] }, null, 4); - let actualNode = JSON.stringify({ nodes: [actual] }, null, 4); + const expectedNode = JSON.stringify({ nodes: [expected] }, null, 4); + const actualNode = JSON.stringify({ nodes: [actual] }, null, 4); - let diff = -`Expected: + const diff = `Expected: ${expectedNode} Actual: ${actualNode}`; diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 309d2c142..c2cb4cb59 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -15,15 +15,15 @@ import * as ts from 'typescript'; import * as path from 'node:path'; -import { TsUtils, CheckType } from './utils/TsUtils'; +import { TsUtils } from './utils/TsUtils'; import { FaultID } from './Problems'; import { faultsAttrs } from './FaultAttrs'; import { faultDesc } from './FaultDesc'; import { cookBookMsg, cookBookTag } from './CookBookMsg'; import { LinterConfig } from './TypeScriptLinterConfig'; -import { Autofix, AutofixInfoSet } from './Autofixer'; +import type { Autofix, AutofixInfoSet } from './Autofixer'; import * as Autofixer from './Autofixer'; -import { ProblemInfo } from './ProblemInfo'; +import type { ProblemInfo } from './ProblemInfo'; import { ProblemSeverity } from './ProblemSeverity'; import Logger from '../utils/logger'; import { ARKUI_DECORATORS } from './utils/consts/ArkUIDecorators'; @@ -32,22 +32,24 @@ import { LIMITED_STD_OBJECT_API } from './utils/consts/LimitedStdObjectAPI'; import { LIMITED_STD_REFLECT_API } from './utils/consts/LimitedStdReflectAPI'; import { LIMITED_STD_PROXYHANDLER_API } from './utils/consts/LimitedStdProxyHandlerAPI'; import { ALLOWED_STD_SYMBOL_API } from './utils/consts/AllowedStdSymbolAPI'; -import { NON_INITIALIZABLE_PROPERTY_DECORATORS, - NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS } from './utils/consts/NonInitializablePropertyDecorators'; +import { + NON_INITIALIZABLE_PROPERTY_DECORATORS, + NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS +} from './utils/consts/NonInitializablePropertyDecorators'; import { NON_RETURN_FUNCTION_DECORATORS } from './utils/consts/NonReturnFunctionDecorators'; import { LIMITED_STANDARD_UTILITY_TYPES } from './utils/consts/LimitedStandardUtilityTypes'; import { PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE } from './utils/consts/PropertyHasNoInitializerErrorCode'; import { FUNCTION_HAS_NO_RETURN_ERROR_CODE } from './utils/consts/FunctionHasNoReturnErrorCode'; -import { identiferUseInValueContext } from './utils/functions/identiferUseInValueContext' -import { hasPredecessor } from './utils/functions/HasPredecessor' +import { identiferUseInValueContext } from './utils/functions/identiferUseInValueContext'; +import { hasPredecessor } from './utils/functions/HasPredecessor'; import { scopeContainsThis } from './utils/functions/ContainsThis'; import { isStructDeclaration, isStruct } from './utils/functions/IsStruct'; import { isAssignmentOperator } from './utils/functions/isAssignmentOperator'; -import { IncrementalLintInfo } from './IncrementalLintInfo'; +import type { IncrementalLintInfo } from './IncrementalLintInfo'; import { cookBookRefToFixTitle } from './autofixes/AutofixTitles'; import { isStdLibraryType } from './utils/functions/IsStdLibrary'; -import { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; -import { DiagnosticChecker } from './utils/functions/DiagnosticChecker'; +import type { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; +import type { DiagnosticChecker } from './utils/functions/DiagnosticChecker'; import { ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE, NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE, @@ -57,7 +59,7 @@ import { const logger = Logger.getLogger(); -export function consoleLog(...args: any[]): void { +export function consoleLog(...args: unknown[]): void { if (TypeScriptLinter.ideMode) { return; } @@ -100,21 +102,23 @@ export class TypeScriptLinter { } constructor( - private tsTypeChecker: ts.TypeChecker, - private autofixesInfo: AutofixInfoSet, + private readonly tsTypeChecker: ts.TypeChecker, + private readonly autofixesInfo: AutofixInfoSet, public strictMode: boolean, public warningsAsErrors: boolean, - private cancellationToken?: ts.CancellationToken, - private incrementalLintInfo?: IncrementalLintInfo, - private tscStrictDiagnostics?: Map, - private reportAutofixCb?: ReportAutofixCallback + private readonly cancellationToken?: ts.CancellationToken, + private readonly incrementalLintInfo?: IncrementalLintInfo, + private readonly tscStrictDiagnostics?: Map, + private readonly reportAutofixCb?: ReportAutofixCallback ) { this.tsUtils = new TsUtils(this.tsTypeChecker, TypeScriptLinter.testMode, TypeScriptLinter.advancedClassChecks); this.currentErrorLine = 0; this.currentWarningLine = 0; this.staticBlocks = new Set(); this.walkedComments = new Set(); - this.libraryTypeCallDiagnosticChecker = new LibraryTypeCallDiagnosticChecker(TypeScriptLinter.filteredDiagnosticMessages); + this.libraryTypeCallDiagnosticChecker = new LibraryTypeCallDiagnosticChecker( + TypeScriptLinter.filteredDiagnosticMessages + ); for (let i = 0; i < FaultID.LAST_ID; i++) { this.nodeCounters[i] = 0; @@ -170,87 +174,118 @@ export class TypeScriptLinter { [ts.SyntaxKind.SetAccessor, this.handleSetAccessor], [ts.SyntaxKind.ConstructSignature, this.handleConstructSignature], [ts.SyntaxKind.ExpressionWithTypeArguments, this.handleExpressionWithTypeArguments], - [ts.SyntaxKind.ComputedPropertyName, this.handleComputedPropertyName], + [ts.SyntaxKind.ComputedPropertyName, this.handleComputedPropertyName] ]); - public incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofixable: boolean = false, autofix?: Autofix[],) { - if (!this.strictMode && faultsAttrs[faultId].migratable) { // In relax mode skip migratable + private getLineAndCharacterOfNode(node: ts.Node | ts.CommentRange): ts.LineAndCharacter { + const startPos = this.tsUtils.getStartPos(node); + const { line, character } = this.sourceFile!.getLineAndCharacterOfPosition(startPos); + // TSC counts lines and columns from zero + return { line: line + 1, character: character + 1 }; + } + + incrementCounters( + node: ts.Node | ts.CommentRange, + faultId: number, + autofixable: boolean = false, + autofix?: Autofix[] + ): void { + if (!this.strictMode && faultsAttrs[faultId].migratable) { + // In relax mode skip migratable return; } - const startPos = this.tsUtils.getStartPos(node); - const endPos = this.tsUtils.getEndPos(node); - const pos = this.sourceFile!.getLineAndCharacterOfPosition(endPos); this.nodeCounters[faultId]++; - // TSC counts lines and columns from zero - let { line, character } = this.sourceFile!.getLineAndCharacterOfPosition(startPos); - ++line; - ++character; - let faultDescr = faultDesc[faultId]; - let faultType = LinterConfig.tsSyntaxKindNames[node.kind]; + const { line, character } = this.getLineAndCharacterOfNode(node); if (TypeScriptLinter.ideMode) { - const cookBookMsgNum = faultsAttrs[faultId] ? Number(faultsAttrs[faultId].cookBookRef) : 0; - const cookBookTg = cookBookTag[cookBookMsgNum]; - let severity = ProblemSeverity.ERROR; - if (faultsAttrs[faultId] && faultsAttrs[faultId].warning) { - severity = ProblemSeverity.WARNING; - } - const isMsgNumValid = cookBookMsgNum > 0; - const badNodeInfo: ProblemInfo = { - line: line, - column: character, - endLine: pos.line + 1, - endColumn: pos.character + 1, - start: startPos, - end: endPos, - type: faultType, - severity: severity, - problem: FaultID[faultId], - suggest: isMsgNumValid ? cookBookMsg[cookBookMsgNum] : '', - rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, - ruleTag: cookBookMsgNum, - autofixable: autofixable, - autofix: autofix, - autofixTitle: isMsgNumValid && autofixable ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined, - }; - this.problemsInfos.push(badNodeInfo); - // problems with autofixes might be collected separately - if (this.reportAutofixCb && badNodeInfo.autofix) { - this.reportAutofixCb(badNodeInfo); - } + this.incrementCountersIdeMode(node, faultId, line, character, autofixable, autofix); } else { + const faultDescr = faultDesc[faultId]; + const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; logger.info( `Warning: ${this.sourceFile!.fileName} (${line}, ${character}): ${faultDescr ? faultDescr : faultType}` ); } this.lineCounters[faultId]++; if (faultsAttrs[faultId].warning) { - if (line != this.currentWarningLine) { + if (line !== this.currentWarningLine) { this.currentWarningLine = line; ++this.totalWarningLines; - this.warningLineNumbersString += line + ', ' + this.warningLineNumbersString += line + ', '; } - } else if (line != this.currentErrorLine) { + } else if (line !== this.currentErrorLine) { this.currentErrorLine = line; ++this.totalErrorLines; this.errorLineNumbersString += line + ', '; } } - private forEachNodeInSubtree(node: ts.Node, cb: (n: ts.Node) => void, stopCond?: (n: ts.Node) => boolean) { + private incrementCountersIdeMode( + node: ts.Node | ts.CommentRange, + faultId: number, + line: number, + character: number, + autofixable: boolean, + autofix?: Autofix[] + ): void { + if (!TypeScriptLinter.ideMode) { + return; + } + const startPos = this.tsUtils.getStartPos(node); + const endPos = this.tsUtils.getEndPos(node); + const pos = this.sourceFile!.getLineAndCharacterOfPosition(endPos); + + const faultDescr = faultDesc[faultId]; + const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; + + const cookBookMsgNum = faultsAttrs[faultId] ? Number(faultsAttrs[faultId].cookBookRef) : 0; + const cookBookTg = cookBookTag[cookBookMsgNum]; + let severity = ProblemSeverity.ERROR; + if (faultsAttrs[faultId] && faultsAttrs[faultId].warning) { + severity = ProblemSeverity.WARNING; + } + const isMsgNumValid = cookBookMsgNum > 0; + const badNodeInfo: ProblemInfo = { + line: line, + column: character, + endLine: pos.line + 1, + endColumn: pos.character + 1, + start: startPos, + end: endPos, + type: faultType, + severity: severity, + problem: FaultID[faultId], + suggest: isMsgNumValid ? cookBookMsg[cookBookMsgNum] : '', + rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, + ruleTag: cookBookMsgNum, + autofixable: autofixable, + autofix: autofix, + autofixTitle: isMsgNumValid && autofixable ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined + }; + this.problemsInfos.push(badNodeInfo); + // problems with autofixes might be collected separately + if (this.reportAutofixCb && badNodeInfo.autofix) { + this.reportAutofixCb(badNodeInfo); + } + } + + private forEachNodeInSubtree(node: ts.Node, cb: (n: ts.Node) => void, stopCond?: (n: ts.Node) => boolean): void { cb.call(this, node); if (stopCond?.call(this, node)) { return; } - // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. - // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. - // to traverse child nodes. + + /* + * #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. + * As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. + * to traverse child nodes. + */ for (const child of node.getChildren()) { - this.forEachNodeInSubtree(child, cb, stopCond) + this.forEachNodeInSubtree(child, cb, stopCond); } } private visitSourceFile(sf: ts.SourceFile): void { - const callback = (node: ts.Node) => { + const callback = (node: ts.Node): void => { this.totalVisitedNodes++; if (isStructDeclaration(node)) { // early exit via exception if cancellation was requested @@ -262,14 +297,17 @@ export class TypeScriptLinter { } else { const handler = this.handlersMap.get(node.kind); if (handler !== undefined) { - // possibly requested cancellation will be checked in a limited number of handlers - // checked nodes are selected as construct nodes, similar to how TSC does + + /* + * possibly requested cancellation will be checked in a limited number of handlers + * checked nodes are selected as construct nodes, similar to how TSC does + */ handler.call(this, node); } } - } - const stopCondition = (node: ts.Node) => { - if (node === null || node.kind === null) { + }; + const stopCondition = (node: ts.Node): boolean => { + if (!node) { return true; } if (this.incrementalLintInfo?.shouldSkipCheck(node)) { @@ -283,7 +321,7 @@ export class TypeScriptLinter { return true; } return false; - } + }; this.forEachNodeInSubtree(sf, callback, stopCondition); } @@ -292,7 +330,7 @@ export class TypeScriptLinter { prop2type: Map, propName: string, type: ts.TypeNode | undefined - ) { + ): void { if (type) { const methodType = type.getText(); const propType = prop2type.get(propName); @@ -304,56 +342,70 @@ export class TypeScriptLinter { } } - private countDeclarationsWithDuplicateName(tsNode: ts.Node, tsDeclNode: ts.Node, tsDeclKind?: ts.SyntaxKind - ): void { - let symbol = this.tsTypeChecker.getSymbolAtLocation(tsNode); - // If specific declaration kind is provided, check against it. - // Otherwise, use syntax kind of corresponding declaration node. + private countDeclarationsWithDuplicateName(tsNode: ts.Node, tsDeclNode: ts.Node, tsDeclKind?: ts.SyntaxKind): void { + const symbol = this.tsTypeChecker.getSymbolAtLocation(tsNode); + + /* + * If specific declaration kind is provided, check against it. + * Otherwise, use syntax kind of corresponding declaration node. + */ if (!!symbol && this.tsUtils.symbolHasDuplicateName(symbol, tsDeclKind ?? tsDeclNode.kind)) { this.incrementCounters(tsDeclNode, FaultID.DeclWithDuplicateName); } } + private static isPrivateIdentifierDuplicateOfIdentifier( + ident1: ts.Identifier | ts.PrivateIdentifier, + ident2: ts.Identifier | ts.PrivateIdentifier + ): boolean { + if (ts.isIdentifier(ident1) && ts.isPrivateIdentifier(ident2)) { + return ident1.text === ident2.text.substring(1); + } + if (ts.isIdentifier(ident2) && ts.isPrivateIdentifier(ident1)) { + return ident2.text === ident1.text.substring(1); + } + return false; + } + + private static isIdentifierOrPrivateIdentifier(node?: ts.PropertyName): node is ts.Identifier | ts.PrivateIdentifier { + if (!node) { + return false; + } + return ts.isIdentifier(node) || ts.isPrivateIdentifier(node); + } + private countClassMembersWithDuplicateName(tsClassDecl: ts.ClassDeclaration): void { - for (const tsCurrentMember of tsClassDecl.members) { - if ( - !tsCurrentMember.name || - !(ts.isIdentifier(tsCurrentMember.name) || ts.isPrivateIdentifier(tsCurrentMember.name)) - ) { + const nClassMembers = tsClassDecl.members.length; + const isNodeReported = new Array(nClassMembers); + for (let curIdx = 0; curIdx < nClassMembers; ++curIdx) { + const tsCurrentMember = tsClassDecl.members[curIdx]; + if (!TypeScriptLinter.isIdentifierOrPrivateIdentifier(tsCurrentMember.name)) { continue; } - for (const tsClassMember of tsClassDecl.members) { - if (tsCurrentMember === tsClassMember) { - continue; - } - if ( - !tsClassMember.name || - !(ts.isIdentifier(tsClassMember.name) || ts.isPrivateIdentifier(tsClassMember.name)) - ) { + if (isNodeReported[curIdx]) { + continue; + } + for (let idx = curIdx + 1; idx < nClassMembers; ++idx) { + const tsClassMember = tsClassDecl.members[idx]; + if (!TypeScriptLinter.isIdentifierOrPrivateIdentifier(tsClassMember.name)) { continue; } - if ( - ts.isIdentifier(tsCurrentMember.name) && - ts.isPrivateIdentifier(tsClassMember.name) && - tsCurrentMember.name.text === tsClassMember.name.text.substring(1) - ) { - this.incrementCounters(tsCurrentMember, FaultID.DeclWithDuplicateName); - break; - } - if ( - ts.isPrivateIdentifier(tsCurrentMember.name) && - ts.isIdentifier(tsClassMember.name) && - tsCurrentMember.name.text.substring(1) === tsClassMember.name.text - ) { + if (TypeScriptLinter.isPrivateIdentifierDuplicateOfIdentifier(tsCurrentMember.name, tsClassMember.name)) { this.incrementCounters(tsCurrentMember, FaultID.DeclWithDuplicateName); + this.incrementCounters(tsClassMember, FaultID.DeclWithDuplicateName); + isNodeReported[idx] = true; break; } } } } - private isPrototypePropertyAccess(tsPropertyAccess: ts.PropertyAccessExpression, propAccessSym: ts.Symbol | undefined, - baseExprSym: ts.Symbol | undefined, baseExprType: ts.Type): boolean { + private isPrototypePropertyAccess( + tsPropertyAccess: ts.PropertyAccessExpression, + propAccessSym: ts.Symbol | undefined, + baseExprSym: ts.Symbol | undefined, + baseExprType: ts.Type + ): boolean { if (!(ts.isIdentifier(tsPropertyAccess.name) && tsPropertyAccess.name.text === 'prototype')) { return false; } @@ -383,12 +435,15 @@ export class TypeScriptLinter { if (this.tsUtils.isTypeSymbol(baseExprSym) || this.tsUtils.isFunctionSymbol(baseExprSym)) { return true; } - // Check if type of LHS expression Function type or Any type. - // The latter check is to cover cases with multiple prototype - // chain (as the 'Prototype' property should be 'Any' type): - // X.prototype.prototype.prototype = ... + + /* + * Check if type of LHS expression Function type or Any type. + * The latter check is to cover cases with multiple prototype + * chain (as the 'Prototype' property should be 'Any' type): + * X.prototype.prototype.prototype = ... + */ const baseExprTypeNode = this.tsTypeChecker.typeToTypeNode(baseExprType, undefined, ts.NodeBuilderFlags.None); - return ((baseExprTypeNode && ts.isFunctionTypeNode(baseExprTypeNode)) || this.tsUtils.isAnyType(baseExprType)); + return baseExprTypeNode && ts.isFunctionTypeNode(baseExprTypeNode) || this.tsUtils.isAnyType(baseExprType); } private interfaceInheritanceLint(node: ts.Node, heritageClauses: ts.NodeArray): void { @@ -409,7 +464,9 @@ export class TypeScriptLinter { } private lintForInterfaceExtendsDifferentPorpertyTypes( - node: ts.Node, tsExprType: ts.Type, prop2type: Map + node: ts.Node, + tsExprType: ts.Type, + prop2type: Map ): void { const props = tsExprType.getProperties(); for (const p of props) { @@ -425,37 +482,47 @@ export class TypeScriptLinter { } } - private handleObjectLiteralExpression(node: ts.Node) { - let objectLiteralExpr = node as ts.ObjectLiteralExpression; + private handleObjectLiteralExpression(node: ts.Node): void { + const objectLiteralExpr = node as ts.ObjectLiteralExpression; // If object literal is a part of destructuring assignment, then don't process it further. if (this.tsUtils.isDestructuringAssignmentLHS(objectLiteralExpr)) { return; } // issue 13082: Allow initializing struct instances with object literal. - let objectLiteralType = this.tsTypeChecker.getContextualType(objectLiteralExpr); - if (!this.tsUtils.isStructObjectInitializer(objectLiteralExpr) && - !this.tsUtils.isDynamicLiteralInitializer(objectLiteralExpr) && - !this.tsUtils.isObjectLiteralAssignable(objectLiteralType, objectLiteralExpr)) { + const objectLiteralType = this.tsTypeChecker.getContextualType(objectLiteralExpr); + if ( + !this.tsUtils.isStructObjectInitializer(objectLiteralExpr) && + !this.tsUtils.isDynamicLiteralInitializer(objectLiteralExpr) && + !this.tsUtils.isObjectLiteralAssignable(objectLiteralType, objectLiteralExpr) + ) { this.incrementCounters(node, FaultID.ObjectLiteralNoContextType); } } - private handleArrayLiteralExpression(node: ts.Node) { - // If array literal is a part of destructuring assignment, then - // don't process it further. + private handleArrayLiteralExpression(node: ts.Node): void { + + /* + * If array literal is a part of destructuring assignment, then + * don't process it further. + */ if (this.tsUtils.isDestructuringAssignmentLHS(node as ts.ArrayLiteralExpression)) { return; } - let arrayLitNode = node as ts.ArrayLiteralExpression; + const arrayLitNode = node as ts.ArrayLiteralExpression; let noContextTypeForArrayLiteral = false; - // check that array literal consists of inferrable types - // e.g. there is no element which is untyped object literals - let arrayLitElements = arrayLitNode.elements; - for(let element of arrayLitElements ) { - if(ts.isObjectLiteralExpression(element)) { - let objectLiteralType = this.tsTypeChecker.getContextualType(element); - if (!this.tsUtils.isDynamicLiteralInitializer(arrayLitNode) && - !this.tsUtils.isObjectLiteralAssignable(objectLiteralType, element)) { + + /* + * check that array literal consists of inferrable types + * e.g. there is no element which is untyped object literals + */ + const arrayLitElements = arrayLitNode.elements; + for (const element of arrayLitElements) { + if (ts.isObjectLiteralExpression(element)) { + const objectLiteralType = this.tsTypeChecker.getContextualType(element); + if ( + !this.tsUtils.isDynamicLiteralInitializer(arrayLitNode) && + !this.tsUtils.isObjectLiteralAssignable(objectLiteralType, element) + ) { noContextTypeForArrayLiteral = true; break; } @@ -466,12 +533,12 @@ export class TypeScriptLinter { } } - private handleParameter(node: ts.Node) { - let tsParam = node as ts.ParameterDeclaration; + private handleParameter(node: ts.Node): void { + const tsParam = node as ts.ParameterDeclaration; if (ts.isArrayBindingPattern(tsParam.name) || ts.isObjectBindingPattern(tsParam.name)) { this.incrementCounters(node, FaultID.DestructuringParameter); } - let tsParamMods = ts.getModifiers(tsParam); + const tsParamMods = ts.getModifiers(tsParam); if ( tsParamMods && (this.tsUtils.hasModifier(tsParamMods, ts.SyntaxKind.PublicKeyword) || @@ -485,45 +552,55 @@ export class TypeScriptLinter { this.handleDeclarationInferredType(tsParam); } - private handleEnumDeclaration(node: ts.Node) { - let enumNode = node as ts.EnumDeclaration; + private handleEnumDeclaration(node: ts.Node): void { + const enumNode = node as ts.EnumDeclaration; this.countDeclarationsWithDuplicateName(enumNode.name, enumNode); - let enumSymbol = this.tsUtils.trueSymbolAtLocation(enumNode.name); + const enumSymbol = this.tsUtils.trueSymbolAtLocation(enumNode.name); if (!enumSymbol) { return; } - let enumDecls = enumSymbol.getDeclarations(); + const enumDecls = enumSymbol.getDeclarations(); if (!enumDecls) { return; } - // Since type checker merges all declarations with the same name - // into one symbol, we need to check that there's more than one - // enum declaration related to that specific symbol. - // See 'countDeclarationsWithDuplicateName' method for details. + + /* + * Since type checker merges all declarations with the same name + * into one symbol, we need to check that there's more than one + * enum declaration related to that specific symbol. + * See 'countDeclarationsWithDuplicateName' method for details. + */ let enumDeclCount = 0; for (const decl of enumDecls) { - if (decl.kind === ts.SyntaxKind.EnumDeclaration) enumDeclCount++; + if (decl.kind === ts.SyntaxKind.EnumDeclaration) { + enumDeclCount++; + } } if (enumDeclCount > 1) { this.incrementCounters(node, FaultID.EnumMerging); } } - private handleInterfaceDeclaration(node: ts.Node) { + private handleInterfaceDeclaration(node: ts.Node): void { // early exit via exception if cancellation was requested this.cancellationToken?.throwIfCancellationRequested(); - let interfaceNode = node as ts.InterfaceDeclaration; - let iSymbol = this.tsUtils.trueSymbolAtLocation(interfaceNode.name); - let iDecls = iSymbol ? iSymbol.getDeclarations() : null; + const interfaceNode = node as ts.InterfaceDeclaration; + const iSymbol = this.tsUtils.trueSymbolAtLocation(interfaceNode.name); + const iDecls = iSymbol ? iSymbol.getDeclarations() : null; if (iDecls) { - // Since type checker merges all declarations with the same name - // into one symbol, we need to check that there's more than one - // interface declaration related to that specific symbol. - // See 'countDeclarationsWithDuplicateName' method for details. + + /* + * Since type checker merges all declarations with the same name + * into one symbol, we need to check that there's more than one + * interface declaration related to that specific symbol. + * See 'countDeclarationsWithDuplicateName' method for details. + */ let iDeclCount = 0; for (const decl of iDecls) { - if (decl.kind === ts.SyntaxKind.InterfaceDeclaration) iDeclCount++; + if (decl.kind === ts.SyntaxKind.InterfaceDeclaration) { + iDeclCount++; + } } if (iDeclCount > 1) { this.incrementCounters(node, FaultID.InterfaceMerging); @@ -535,44 +612,47 @@ export class TypeScriptLinter { this.countDeclarationsWithDuplicateName(interfaceNode.name, interfaceNode); } - private handleThrowStatement(node: ts.Node) { - let throwStmt = node as ts.ThrowStatement; - let throwExprType = this.tsTypeChecker.getTypeAtLocation(throwStmt.expression); - if (!throwExprType.isClassOrInterface() || !this.tsUtils.isOrDerivedFrom(throwExprType, this.tsUtils.isStdErrorType)) { + private handleThrowStatement(node: ts.Node): void { + const throwStmt = node as ts.ThrowStatement; + const throwExprType = this.tsTypeChecker.getTypeAtLocation(throwStmt.expression); + if ( + !throwExprType.isClassOrInterface() || + !this.tsUtils.isOrDerivedFrom(throwExprType, this.tsUtils.isStdErrorType) + ) { this.incrementCounters(node, FaultID.ThrowStatement, false, undefined); } } - private handleForStatement(node: ts.Node) { - let tsForStmt = node as ts.ForStatement; - let tsForInit = tsForStmt.initializer; + private handleForStatement(node: ts.Node): void { + const tsForStmt = node as ts.ForStatement; + const tsForInit = tsForStmt.initializer; if (tsForInit && (ts.isArrayLiteralExpression(tsForInit) || ts.isObjectLiteralExpression(tsForInit))) { this.incrementCounters(tsForInit, FaultID.DestructuringAssignment); } } - private handleForInStatement(node: ts.Node) { - let tsForInStmt = node as ts.ForInStatement; - let tsForInInit = tsForInStmt.initializer; + private handleForInStatement(node: ts.Node): void { + const tsForInStmt = node as ts.ForInStatement; + const tsForInInit = tsForInStmt.initializer; if (ts.isArrayLiteralExpression(tsForInInit) || ts.isObjectLiteralExpression(tsForInInit)) { this.incrementCounters(tsForInInit, FaultID.DestructuringAssignment); } this.incrementCounters(node, FaultID.ForInStatement); } - private handleForOfStatement(node: ts.Node) { - let tsForOfStmt = node as ts.ForOfStatement; - let tsForOfInit = tsForOfStmt.initializer; + private handleForOfStatement(node: ts.Node): void { + const tsForOfStmt = node as ts.ForOfStatement; + const tsForOfInit = tsForOfStmt.initializer; if (ts.isArrayLiteralExpression(tsForOfInit) || ts.isObjectLiteralExpression(tsForOfInit)) { this.incrementCounters(tsForOfInit, FaultID.DestructuringAssignment); } } - private handleImportDeclaration(node: ts.Node) { + private handleImportDeclaration(node: ts.Node): void { // early exit via exception if cancellation was requested this.cancellationToken?.throwIfCancellationRequested(); - let importDeclNode = node as ts.ImportDeclaration; + const importDeclNode = node as ts.ImportDeclaration; for (const stmt of importDeclNode.parent.statements) { if (stmt === importDeclNode) { break; @@ -582,7 +662,7 @@ export class TypeScriptLinter { break; } } - let expr1 = importDeclNode.moduleSpecifier; + const expr1 = importDeclNode.moduleSpecifier; if (expr1.kind === ts.SyntaxKind.StringLiteral) { if (!importDeclNode.importClause) { this.incrementCounters(node, FaultID.ImportFromPath); @@ -593,12 +673,12 @@ export class TypeScriptLinter { } } - private handlePropertyAccessExpression(node: ts.Node) { - if (ts.isCallExpression(node.parent) && node == node.parent.expression) { + private handlePropertyAccessExpression(node: ts.Node): void { + if (ts.isCallExpression(node.parent) && node === node.parent.expression) { return; } - let propertyAccessNode = node as ts.PropertyAccessExpression; + const propertyAccessNode = node as ts.PropertyAccessExpression; const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode); const baseExprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode.expression); @@ -619,15 +699,15 @@ export class TypeScriptLinter { } } - private handlePropertyAssignmentOrDeclaration(node: ts.Node) { - let propName = (node as ts.PropertyAssignment | ts.PropertyDeclaration).name; + private handlePropertyAssignmentOrDeclaration(node: ts.Node): void { + const propName = (node as ts.PropertyAssignment | ts.PropertyDeclaration).name; if (propName && (propName.kind === ts.SyntaxKind.NumericLiteral || propName.kind === ts.SyntaxKind.StringLiteral)) { // We can use literals as property names only when creating Record or any interop instances. let isRecordObjectInitializer = false; let isLibraryType = false; let isDynamic = false; if (ts.isPropertyAssignment(node)) { - let objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); + const objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); if (objectLiteralType) { isRecordObjectInitializer = this.tsUtils.isStdRecordType(objectLiteralType); isLibraryType = this.tsUtils.isLibraryType(objectLiteralType); @@ -636,8 +716,8 @@ export class TypeScriptLinter { } if (!isRecordObjectInitializer && !isDynamic) { - let autofix : Autofix[] | undefined = Autofixer.fixLiteralAsPropertyName(node); - let autofixable = autofix != undefined; + let autofix: Autofix[] | undefined = Autofixer.fixLiteralAsPropertyName(node); + const autofixable = autofix !== undefined; if (!this.autofixesInfo.shouldAutofix(node, FaultID.LiteralAsPropertyName)) { autofix = undefined; } @@ -647,13 +727,22 @@ export class TypeScriptLinter { if (ts.isPropertyDeclaration(node)) { const decorators = ts.getDecorators(node); this.handleDecorators(decorators); - this.filterOutDecoratorsDiagnostics(decorators, NON_INITIALIZABLE_PROPERTY_DECORATORS, - {begin: propName.getStart(), end: propName.getStart()}, PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE); + this.filterOutDecoratorsDiagnostics( + decorators, + NON_INITIALIZABLE_PROPERTY_DECORATORS, + { begin: propName.getStart(), end: propName.getStart() }, + PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE + ); const classDecorators = ts.getDecorators(node.parent); - const propType = (node as ts.PropertyDeclaration).type?.getText(); - this.filterOutDecoratorsDiagnostics(classDecorators, NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS, - {begin: propName.getStart(), end: propName.getStart()}, PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE, propType); + const propType = node.type?.getText(); + this.filterOutDecoratorsDiagnostics( + classDecorators, + NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS, + { begin: propName.getStart(), end: propName.getStart() }, + PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE, + propType + ); this.handleDeclarationInferredType(node); this.handleDefiniteAssignmentAssertion(node); } @@ -662,56 +751,52 @@ export class TypeScriptLinter { private filterOutDecoratorsDiagnostics( decorators: readonly ts.Decorator[] | undefined, expectedDecorators: readonly string[], - range: {begin: number, end: number}, + range: { begin: number; end: number }, code: number, propType?: string - ) { + ): void { // Filter out non-initializable property decorators from strict diagnostics. if (this.tscStrictDiagnostics && this.sourceFile) { - if (decorators?.some(x => { - let decoratorName = ''; - if (ts.isIdentifier(x.expression)) { - decoratorName = x.expression.text; - } else if (ts.isCallExpression(x.expression) && ts.isIdentifier(x.expression.expression)) { - decoratorName = x.expression.expression.text; - } - // special case for property of type CustomDialogController of the @CustomDialog-decorated class - if (expectedDecorators.includes(NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS[0])) { - return expectedDecorators.includes(decoratorName) && propType === 'CustomDialogController' - } - return expectedDecorators.includes(decoratorName); - })) { - let file = path.normalize(this.sourceFile.fileName); - let tscDiagnostics = this.tscStrictDiagnostics.get(file) + if ( + decorators?.some((x) => { + let decoratorName = ''; + if (ts.isIdentifier(x.expression)) { + decoratorName = x.expression.text; + } else if (ts.isCallExpression(x.expression) && ts.isIdentifier(x.expression.expression)) { + decoratorName = x.expression.expression.text; + } + // special case for property of type CustomDialogController of the @CustomDialog-decorated class + if (expectedDecorators.includes(NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS[0])) { + return expectedDecorators.includes(decoratorName) && propType === 'CustomDialogController'; + } + return expectedDecorators.includes(decoratorName); + }) + ) { + const file = path.normalize(this.sourceFile.fileName); + const tscDiagnostics = this.tscStrictDiagnostics.get(file); if (tscDiagnostics) { - let filteredDiagnostics = tscDiagnostics.filter( - (val, idx, array) => { - if (val.code !== code) { - return true; - } - - if (val.start === undefined) { - return true; - } - - if (val.start < range.begin) { - return true; - } - - if (val.start > range.end) { - return true; - } - - return false; + const filteredDiagnostics = tscDiagnostics.filter((val) => { + if (val.code !== code) { + return true; + } + if (val.start === undefined) { + return true; + } + if (val.start < range.begin) { + return true; } - ); + if (val.start > range.end) { + return true; + } + return false; + }); this.tscStrictDiagnostics.set(file, filteredDiagnostics); } } } } - private checkInRange(rangesToFilter: { begin: number, end: number }[], pos: number): boolean { + private static checkInRange(rangesToFilter: { begin: number; end: number }[], pos: number): boolean { for (let i = 0; i < rangesToFilter.length; i++) { if (pos >= rangesToFilter[i].begin && pos < rangesToFilter[i].end) { return false; @@ -720,18 +805,20 @@ export class TypeScriptLinter { return true; } - private filterStrictDiagnostics(filters: { [code: number]: (pos: number) => boolean }, - diagnosticChecker: DiagnosticChecker): boolean { + private filterStrictDiagnostics( + filters: { [code: number]: (pos: number) => boolean }, + diagnosticChecker: DiagnosticChecker + ): boolean { if (!this.tscStrictDiagnostics || !this.sourceFile) { return false; } - let file = path.normalize(this.sourceFile.fileName); - let tscDiagnostics = this.tscStrictDiagnostics.get(file) + const file = path.normalize(this.sourceFile.fileName); + const tscDiagnostics = this.tscStrictDiagnostics.get(file); if (!tscDiagnostics) { return false; } - const checkDiagnostic = (val: ts.Diagnostic) => { + const checkDiagnostic = (val: ts.Diagnostic): boolean => { const checkInRange = filters[val.code]; if (!checkInRange) { return true; @@ -753,17 +840,20 @@ export class TypeScriptLinter { return ts.isClassLike(node) || ts.isInterfaceDeclaration(node); } - private handleFunctionExpression(node: ts.Node) { + private handleFunctionExpression(node: ts.Node): void { const funcExpr = node as ts.FunctionExpression; const isGeneric = funcExpr.typeParameters !== undefined && funcExpr.typeParameters.length > 0; const isGenerator = funcExpr.asteriskToken !== undefined; const hasThisKeyword = scopeContainsThis(funcExpr.body); const isCalledRecursively = this.tsUtils.isFunctionCalledRecursively(funcExpr); const [hasUnfixableReturnType, newRetTypeNode] = this.handleMissingReturnType(funcExpr); - const autofixable = !isGeneric && !isGenerator && !hasThisKeyword && !isCalledRecursively && !hasUnfixableReturnType; + const autofixable = + !isGeneric && !isGenerator && !hasThisKeyword && !isCalledRecursively && !hasUnfixableReturnType; let autofix: Autofix[] | undefined; if (autofixable && this.autofixesInfo.shouldAutofix(funcExpr, FaultID.FunctionExpression)) { - autofix = [Autofixer.fixFunctionExpression(funcExpr, funcExpr.parameters, newRetTypeNode, ts.getModifiers(funcExpr))]; + autofix = [ + Autofixer.fixFunctionExpression(funcExpr, funcExpr.parameters, newRetTypeNode, ts.getModifiers(funcExpr)) + ]; } this.incrementCounters(funcExpr, FaultID.FunctionExpression, autofixable, autofix); if (isGeneric) { @@ -780,7 +870,7 @@ export class TypeScriptLinter { } } - private handleArrowFunction(node: ts.Node) { + private handleArrowFunction(node: ts.Node): void { const arrowFunc = node as ts.ArrowFunction; if (!hasPredecessor(arrowFunc, TypeScriptLinter.isClassLikeOrIface)) { this.reportThisKeywordsInScope(arrowFunc.body); @@ -796,13 +886,13 @@ export class TypeScriptLinter { } } - private handleClassExpression(node: ts.Node) { - let tsClassExpr = node as ts.ClassExpression; + private handleClassExpression(node: ts.Node): void { + const tsClassExpr = node as ts.ClassExpression; this.incrementCounters(node, FaultID.ClassExpression); this.handleDecorators(ts.getDecorators(tsClassExpr)); } - private handleFunctionDeclaration(node: ts.Node) { + private handleFunctionDeclaration(node: ts.Node): void { // early exit via exception if cancellation was requested this.cancellationToken?.throwIfCancellationRequested(); @@ -825,28 +915,42 @@ export class TypeScriptLinter { } } - private handleMissingReturnType(funcLikeDecl: ts.FunctionLikeDeclaration | ts.MethodSignature): [boolean, ts.TypeNode | undefined] { + private handleMissingReturnType( + funcLikeDecl: ts.FunctionLikeDeclaration | ts.MethodSignature + ): [boolean, ts.TypeNode | undefined] { // Note: Return type can't be inferred for function without body. const isSignature = ts.isMethodSignature(funcLikeDecl); if (isSignature || !funcLikeDecl.body) { // Ambient flag is not exposed, so we apply dirty hack to make it visible - const isAmbientDeclaration = !!(funcLikeDecl.flags & (ts.NodeFlags as any)['Ambient']); + const isAmbientDeclaration = !!(funcLikeDecl.flags & (ts.NodeFlags as any).Ambient); if ((isSignature || isAmbientDeclaration) && !funcLikeDecl.type) { this.incrementCounters(funcLikeDecl, FaultID.LimitedReturnTypeInference); } return [false, undefined]; } + + return this.tryAutofixMissingReturnType(funcLikeDecl); + } + + private tryAutofixMissingReturnType(funcLikeDecl: ts.FunctionLikeDeclaration): [boolean, ts.TypeNode | undefined] { + if (!funcLikeDecl.body) { + return [false, undefined]; + } + let autofixable = false; - let autofix : Autofix[] | undefined; + let autofix: Autofix[] | undefined; let newRetTypeNode: ts.TypeNode | undefined; - let isFuncExpr = ts.isFunctionExpression(funcLikeDecl); - // Currently, ArkTS can't infer return type of function, when expression - // in the return statement is a call to a function or method whose return - // value type is omitted. In that case, we attempt to prepare an autofix. + const isFuncExpr = ts.isFunctionExpression(funcLikeDecl); + + /* + * Currently, ArkTS can't infer return type of function, when expression + * in the return statement is a call to a function or method whose return + * value type is omitted. In that case, we attempt to prepare an autofix. + */ let hasLimitedRetTypeInference = this.hasLimitedTypeInferenceFromReturnExpr(funcLikeDecl.body); - let tsSignature = this.tsTypeChecker.getSignatureFromDeclaration(funcLikeDecl); + const tsSignature = this.tsTypeChecker.getSignatureFromDeclaration(funcLikeDecl); if (tsSignature) { - let tsRetType = this.tsTypeChecker.getReturnTypeOfSignature(tsSignature); + const tsRetType = this.tsTypeChecker.getReturnTypeOfSignature(tsSignature); if (!tsRetType || this.tsUtils.isUnsupportedType(tsRetType)) { hasLimitedRetTypeInference = true; } else if (hasLimitedRetTypeInference) { @@ -859,35 +963,42 @@ export class TypeScriptLinter { } } } - // Don't report here if in function expression context. - // See handleFunctionExpression for details. + + /* + * Don't report here if in function expression context. + * See handleFunctionExpression for details. + */ if (hasLimitedRetTypeInference && !isFuncExpr) { this.incrementCounters(funcLikeDecl, FaultID.LimitedReturnTypeInference, autofixable, autofix); } + return [hasLimitedRetTypeInference && !newRetTypeNode, newRetTypeNode]; } private hasLimitedTypeInferenceFromReturnExpr(funBody: ts.ConciseBody): boolean { let hasLimitedTypeInference = false; - const callback = (node: ts.Node) => { + const callback = (node: ts.Node): void => { if (hasLimitedTypeInference) { return; } if ( - ts.isReturnStatement(node) && node.expression && + ts.isReturnStatement(node) && + node.expression && this.tsUtils.isCallToFunctionWithOmittedReturnType(this.tsUtils.unwrapParenthesized(node.expression)) ) { hasLimitedTypeInference = true; } - } + }; // Don't traverse other nested function-like declarations. - const stopCondition = (node: ts.Node) => { - return ts.isFunctionDeclaration(node) || + const stopCondition = (node: ts.Node): boolean => { + return ( + ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isMethodDeclaration(node) || ts.isAccessor(node) || - ts.isArrowFunction(node); - } + ts.isArrowFunction(node) + ); + }; if (ts.isBlock(funBody)) { this.forEachNodeInSubtree(funBody, callback, stopCondition); } else { @@ -897,24 +1008,27 @@ export class TypeScriptLinter { return hasLimitedTypeInference; } - private handlePrefixUnaryExpression(node: ts.Node) { - let tsUnaryArithm = node as ts.PrefixUnaryExpression; - let tsUnaryOp = tsUnaryArithm.operator; + private handlePrefixUnaryExpression(node: ts.Node): void { + const tsUnaryArithm = node as ts.PrefixUnaryExpression; + const tsUnaryOp = tsUnaryArithm.operator; if ( tsUnaryOp === ts.SyntaxKind.PlusToken || tsUnaryOp === ts.SyntaxKind.MinusToken || tsUnaryOp === ts.SyntaxKind.TildeToken ) { const tsOperatndType = this.tsTypeChecker.getTypeAtLocation(tsUnaryArithm.operand); - if (!(tsOperatndType.getFlags() & (ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLiteral)) || - ( tsUnaryOp === ts.SyntaxKind.TildeToken && tsUnaryArithm.operand.kind === ts.SyntaxKind.NumericLiteral && - !this.tsUtils.isIntegerConstantValue(tsUnaryArithm.operand as ts.NumericLiteral) ) - ) + if ( + !(tsOperatndType.getFlags() & (ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLiteral)) || + tsUnaryOp === ts.SyntaxKind.TildeToken && + tsUnaryArithm.operand.kind === ts.SyntaxKind.NumericLiteral && + !this.tsUtils.isIntegerConstantValue(tsUnaryArithm.operand as ts.NumericLiteral) + ) { this.incrementCounters(node, FaultID.UnaryArithmNotNumber); + } } } - private handleBinaryExpression(node: ts.Node) { + private handleBinaryExpression(node: ts.Node): void { const tsBinaryExpr = node as ts.BinaryExpression; const tsLhsExpr = tsBinaryExpr.left; const tsRhsExpr = tsBinaryExpr.right; @@ -942,29 +1056,30 @@ export class TypeScriptLinter { this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); break; default: - return; } } - private processBinaryAssignment(node: ts.Node, tsLhsExpr: ts.Expression) { + private processBinaryAssignment(node: ts.Node, tsLhsExpr: ts.Expression): void { if (ts.isObjectLiteralExpression(tsLhsExpr) || ts.isArrayLiteralExpression(tsLhsExpr)) { this.incrementCounters(node, FaultID.DestructuringAssignment); } if (ts.isPropertyAccessExpression(tsLhsExpr)) { const tsLhsSymbol = this.tsUtils.trueSymbolAtLocation(tsLhsExpr); const tsLhsBaseSymbol = this.tsUtils.trueSymbolAtLocation(tsLhsExpr.expression); - if (tsLhsSymbol && (tsLhsSymbol.flags & ts.SymbolFlags.Method)) { + if (tsLhsSymbol && tsLhsSymbol.flags & ts.SymbolFlags.Method) { this.incrementCounters(tsLhsExpr, FaultID.MethodReassignment); } if ( - this.tsUtils.isMethodAssignment(tsLhsSymbol) && tsLhsBaseSymbol && + this.tsUtils.isMethodAssignment(tsLhsSymbol) && + tsLhsBaseSymbol && (tsLhsBaseSymbol.flags & ts.SymbolFlags.Function) !== 0 - ) + ) { this.incrementCounters(tsLhsExpr, FaultID.PropertyDeclOnFunction); + } } } - private processBinaryComma(tsBinaryExpr: ts.BinaryExpression) { + private processBinaryComma(tsBinaryExpr: ts.BinaryExpression): void { // CommaOpertor is allowed in 'for' statement initalizer and incrementor let tsExprNode: ts.Node = tsBinaryExpr; let tsParentNode = tsExprNode.parent; @@ -974,45 +1089,58 @@ export class TypeScriptLinter { } if (tsParentNode && tsParentNode.kind === ts.SyntaxKind.ForStatement) { const tsForNode = tsParentNode as ts.ForStatement; - if (tsExprNode === tsForNode.initializer || tsExprNode === tsForNode.incrementor) return; + if (tsExprNode === tsForNode.initializer || tsExprNode === tsForNode.incrementor) { + return; + } } this.incrementCounters(tsBinaryExpr as ts.Node, FaultID.CommaOperator); } - private processBinaryInstanceOf(node: ts.Node, tsLhsExpr: ts.Expression, leftOperandType: ts.Type) { + private processBinaryInstanceOf(node: ts.Node, tsLhsExpr: ts.Expression, leftOperandType: ts.Type): void { const leftExpr = this.tsUtils.unwrapParenthesized(tsLhsExpr); const leftSymbol = this.tsUtils.trueSymbolAtLocation(leftExpr); - // In STS, the left-hand side expression may be of any reference type, otherwise - // a compile-time error occurs. In addition, the left operand in STS cannot be a type. + + /* + * In STS, the left-hand side expression may be of any reference type, otherwise + * a compile-time error occurs. In addition, the left operand in STS cannot be a type. + */ if (tsLhsExpr.kind === ts.SyntaxKind.ThisKeyword) { return; } - if (this.tsUtils.isPrimitiveType(leftOperandType) || ts.isTypeNode(leftExpr) || this.tsUtils.isTypeSymbol(leftSymbol)) { + if ( + this.tsUtils.isPrimitiveType(leftOperandType) || + ts.isTypeNode(leftExpr) || + this.tsUtils.isTypeSymbol(leftSymbol) + ) { this.incrementCounters(node, FaultID.InstanceofUnsupported); } } - private handleVariableDeclarationList(node: ts.Node) { - let varDeclFlags = ts.getCombinedNodeFlags(node); - if (!(varDeclFlags & (ts.NodeFlags.Let | ts.NodeFlags.Const))) + private handleVariableDeclarationList(node: ts.Node): void { + const varDeclFlags = ts.getCombinedNodeFlags(node); + if (!(varDeclFlags & (ts.NodeFlags.Let | ts.NodeFlags.Const))) { this.incrementCounters(node, FaultID.VarDeclaration); + } } - private handleVariableDeclaration(node: ts.Node) { - let tsVarDecl = node as ts.VariableDeclaration; - if (ts.isArrayBindingPattern(tsVarDecl.name) || ts.isObjectBindingPattern(tsVarDecl.name)) + private handleVariableDeclaration(node: ts.Node): void { + const tsVarDecl = node as ts.VariableDeclaration; + if (ts.isArrayBindingPattern(tsVarDecl.name) || ts.isObjectBindingPattern(tsVarDecl.name)) { this.incrementCounters(node, FaultID.DestructuringDeclaration); + } { // Check variable declaration for duplicate name. - const visitBindingPatternNames = (tsBindingName: ts.BindingName) => { + const visitBindingPatternNames = (tsBindingName: ts.BindingName): void => { if (ts.isIdentifier(tsBindingName)) { // The syntax kind of the declaration is defined here by the parent of 'BindingName' node. this.countDeclarationsWithDuplicateName(tsBindingName, tsBindingName, tsBindingName.parent.kind); return; } for (const tsBindingElem of tsBindingName.elements) { - if (ts.isOmittedExpression(tsBindingElem)) continue; + if (ts.isOmittedExpression(tsBindingElem)) { + continue; + } visitBindingPatternNames(tsBindingElem.name); } @@ -1020,9 +1148,9 @@ export class TypeScriptLinter { visitBindingPatternNames(tsVarDecl.name); } if (tsVarDecl.type && tsVarDecl.initializer) { - let tsVarInit = tsVarDecl.initializer; - let tsVarType = this.tsTypeChecker.getTypeAtLocation(tsVarDecl.type); - let tsInitType = this.tsTypeChecker.getTypeAtLocation(tsVarInit); + const tsVarInit = tsVarDecl.initializer; + const tsVarType = this.tsTypeChecker.getTypeAtLocation(tsVarDecl.type); + const tsInitType = this.tsTypeChecker.getTypeAtLocation(tsVarInit); if (this.tsUtils.needToDeduceStructuralIdentity(tsVarType, tsInitType, tsVarInit)) { this.incrementCounters(tsVarDecl, FaultID.StructuralIdentity); } @@ -1032,11 +1160,11 @@ export class TypeScriptLinter { this.handleDefiniteAssignmentAssertion(tsVarDecl); } - private handleEsObjectDelaration(node: ts.VariableDeclaration) { + private handleEsObjectDelaration(node: ts.VariableDeclaration): void { const isDeclaredESObject = !!node.type && this.tsUtils.isEsObjectType(node.type); const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); - const isLocal = this.tsUtils.isInsideBlock(node) + const isLocal = this.tsUtils.isInsideBlock(node); if ((isDeclaredESObject || isInitializedWithESObject) && !isLocal) { this.incrementCounters(node, FaultID.EsObjectType); return; @@ -1047,7 +1175,7 @@ export class TypeScriptLinter { } } - private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node) { + private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node): void { const isTypeAnnotated = !!nodeDeclType; const isDeclaredESObject = isTypeAnnotated && this.tsUtils.isEsObjectType(nodeDeclType); const initalizerTypeNode = this.tsUtils.getVariableDeclarationTypeNode(initializer); @@ -1062,35 +1190,39 @@ export class TypeScriptLinter { } } - private handleCatchClause(node: ts.Node) { - let tsCatch = node as ts.CatchClause; - // In TS catch clause doesn't permit specification of the exception varible type except 'any' or 'unknown'. - // It is not compatible with STS 'catch' where the exception variable has to be of type - // Error or derived from it. - // So each 'catch' which has explicit type for the exception object goes to problems in strict mode. - if (tsCatch.variableDeclaration && tsCatch.variableDeclaration.type) { + private handleCatchClause(node: ts.Node): void { + const tsCatch = node as ts.CatchClause; + + /* + * In TS catch clause doesn't permit specification of the exception varible type except 'any' or 'unknown'. + * It is not compatible with STS 'catch' where the exception variable has to be of type + * Error or derived from it. + * So each 'catch' which has explicit type for the exception object goes to problems in strict mode. + */ + if (tsCatch.variableDeclaration?.type) { let autofix: Autofix[] | undefined; - if (this.autofixesInfo.shouldAutofix(tsCatch, FaultID.CatchWithUnsupportedType)) - autofix = [ Autofixer.dropTypeOnVarDecl(tsCatch.variableDeclaration) ]; + if (this.autofixesInfo.shouldAutofix(tsCatch, FaultID.CatchWithUnsupportedType)) { + autofix = [Autofixer.dropTypeOnVarDecl(tsCatch.variableDeclaration)]; + } this.incrementCounters(node, FaultID.CatchWithUnsupportedType, true, autofix); } } - private handleClassDeclaration(node: ts.Node) { + private handleClassDeclaration(node: ts.Node): void { // early exit via exception if cancellation was requested this.cancellationToken?.throwIfCancellationRequested(); - let tsClassDecl = node as ts.ClassDeclaration; + const tsClassDecl = node as ts.ClassDeclaration; this.staticBlocks.clear(); if (tsClassDecl.name) { this.countDeclarationsWithDuplicateName(tsClassDecl.name, tsClassDecl); } this.countClassMembersWithDuplicateName(tsClassDecl); - const visitHClause = (hClause: ts.HeritageClause) => { + const visitHClause = (hClause: ts.HeritageClause): void => { for (const tsTypeExpr of hClause.types) { const tsExprType = this.tsTypeChecker.getTypeAtLocation(tsTypeExpr.expression); - if (tsExprType.isClass() && hClause.token == ts.SyntaxKind.ImplementsKeyword) { + if (tsExprType.isClass() && hClause.token === ts.SyntaxKind.ImplementsKeyword) { this.incrementCounters(tsTypeExpr, FaultID.ImplementsClass); } } @@ -1107,96 +1239,111 @@ export class TypeScriptLinter { this.handleDecorators(ts.getDecorators(tsClassDecl)); } - private handleModuleDeclaration(node: ts.Node) { + private handleModuleDeclaration(node: ts.Node): void { // early exit via exception if cancellation was requested this.cancellationToken?.throwIfCancellationRequested(); - let tsModuleDecl = node as ts.ModuleDeclaration; + const tsModuleDecl = node as ts.ModuleDeclaration; this.countDeclarationsWithDuplicateName(tsModuleDecl.name, tsModuleDecl); - let tsModuleBody = tsModuleDecl.body; - let tsModifiers = ts.getModifiers(tsModuleDecl); + const tsModuleBody = tsModuleDecl.body; + const tsModifiers = ts.getModifiers(tsModuleDecl); if (tsModuleBody) { if (ts.isModuleBlock(tsModuleBody)) { - for (const tsModuleStmt of tsModuleBody.statements) { - switch (tsModuleStmt.kind) { - case ts.SyntaxKind.VariableStatement: - case ts.SyntaxKind.FunctionDeclaration: - case ts.SyntaxKind.ClassDeclaration: - case ts.SyntaxKind.InterfaceDeclaration: - case ts.SyntaxKind.TypeAliasDeclaration: - case ts.SyntaxKind.EnumDeclaration: - case ts.SyntaxKind.ExportDeclaration: - break; - // Nested namespace declarations are prohibited - // but there is no cookbook recipe for it! - case ts.SyntaxKind.ModuleDeclaration: - break; - default: - this.incrementCounters(tsModuleStmt, FaultID.NonDeclarationInNamespace); - break; - } - } + this.handleModuleBlock(tsModuleBody); } } - if (!(tsModuleDecl.flags & ts.NodeFlags.Namespace) && - this.tsUtils.hasModifier(tsModifiers, ts.SyntaxKind.DeclareKeyword)) { + if ( + !(tsModuleDecl.flags & ts.NodeFlags.Namespace) && + this.tsUtils.hasModifier(tsModifiers, ts.SyntaxKind.DeclareKeyword) + ) { this.incrementCounters(tsModuleDecl, FaultID.ShorthandAmbientModuleDecl); } - if (ts.isStringLiteral(tsModuleDecl.name) && tsModuleDecl.name.text.includes('*')) + if (ts.isStringLiteral(tsModuleDecl.name) && tsModuleDecl.name.text.includes('*')) { this.incrementCounters(tsModuleDecl, FaultID.WildcardsInModuleName); + } } - private handleTypeAliasDeclaration(node: ts.Node) { - let tsTypeAlias = node as ts.TypeAliasDeclaration; + private handleModuleBlock(moduleBlock: ts.ModuleBlock): void { + for (const tsModuleStmt of moduleBlock.statements) { + switch (tsModuleStmt.kind) { + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ExportDeclaration: + break; + + /* + * Nested namespace declarations are prohibited + * but there is no cookbook recipe for it! + */ + case ts.SyntaxKind.ModuleDeclaration: + break; + default: + this.incrementCounters(tsModuleStmt, FaultID.NonDeclarationInNamespace); + break; + } + } + } + + private handleTypeAliasDeclaration(node: ts.Node): void { + const tsTypeAlias = node as ts.TypeAliasDeclaration; this.countDeclarationsWithDuplicateName(tsTypeAlias.name, tsTypeAlias); } - private handleImportClause(node: ts.Node) { - let tsImportClause = node as ts.ImportClause; + private handleImportClause(node: ts.Node): void { + const tsImportClause = node as ts.ImportClause; if (tsImportClause.name) { this.countDeclarationsWithDuplicateName(tsImportClause.name, tsImportClause); } if (tsImportClause.namedBindings && ts.isNamedImports(tsImportClause.namedBindings)) { - let nonDefaultSpecs: ts.ImportSpecifier[] = []; + const nonDefaultSpecs: ts.ImportSpecifier[] = []; let defaultSpec: ts.ImportSpecifier | undefined; for (const importSpec of tsImportClause.namedBindings.elements) { - if (this.tsUtils.isDefaultImport(importSpec)) defaultSpec = importSpec; - else nonDefaultSpecs.push(importSpec); + if (this.tsUtils.isDefaultImport(importSpec)) { + defaultSpec = importSpec; + } else { + nonDefaultSpecs.push(importSpec); + } } if (defaultSpec) { let autofix: Autofix[] | undefined; - if (this.autofixesInfo.shouldAutofix(defaultSpec, FaultID.DefaultImport)) - autofix = [ Autofixer.fixDefaultImport(tsImportClause, defaultSpec, nonDefaultSpecs) ]; + if (this.autofixesInfo.shouldAutofix(defaultSpec, FaultID.DefaultImport)) { + autofix = [Autofixer.fixDefaultImport(tsImportClause, defaultSpec, nonDefaultSpecs)]; + } this.incrementCounters(defaultSpec, FaultID.DefaultImport, true, autofix); } } } - private handleImportSpecifier(node: ts.Node) { - let importSpec = node as ts.ImportSpecifier; + private handleImportSpecifier(node: ts.Node): void { + const importSpec = node as ts.ImportSpecifier; this.countDeclarationsWithDuplicateName(importSpec.name, importSpec); } - private handleNamespaceImport(node: ts.Node) { - let tsNamespaceImport = node as ts.NamespaceImport; + private handleNamespaceImport(node: ts.Node): void { + const tsNamespaceImport = node as ts.NamespaceImport; this.countDeclarationsWithDuplicateName(tsNamespaceImport.name, tsNamespaceImport); } - private handleTypeAssertionExpression(node: ts.Node) { - let tsTypeAssertion = node as ts.TypeAssertion; - if (tsTypeAssertion.type.getText() === 'const') + private handleTypeAssertionExpression(node: ts.Node): void { + const tsTypeAssertion = node as ts.TypeAssertion; + if (tsTypeAssertion.type.getText() === 'const') { this.incrementCounters(tsTypeAssertion, FaultID.ConstAssertion); - else - this.incrementCounters(node, FaultID.TypeAssertion, true, [ Autofixer.fixTypeAssertion(tsTypeAssertion) ]); + } else { + this.incrementCounters(node, FaultID.TypeAssertion, true, [Autofixer.fixTypeAssertion(tsTypeAssertion)]); + } } - private handleMethodDeclaration(node: ts.Node) { + private handleMethodDeclaration(node: ts.Node): void { const tsMethodDecl = node as ts.MethodDeclaration; - let isStatic = false + let isStatic = false; if (tsMethodDecl.modifiers) { for (const mod of tsMethodDecl.modifiers) { if (mod.kind === ts.SyntaxKind.StaticKeyword) { @@ -1215,19 +1362,22 @@ export class TypeScriptLinter { this.incrementCounters(node, FaultID.GeneratorFunction); } this.handleDecorators(ts.getDecorators(tsMethodDecl)); - this.filterOutDecoratorsDiagnostics(ts.getDecorators(tsMethodDecl), NON_RETURN_FUNCTION_DECORATORS, - {begin: tsMethodDecl.parameters.end, end: tsMethodDecl.body?.getStart() ?? tsMethodDecl.parameters.end}, - FUNCTION_HAS_NO_RETURN_ERROR_CODE); + this.filterOutDecoratorsDiagnostics( + ts.getDecorators(tsMethodDecl), + NON_RETURN_FUNCTION_DECORATORS, + { begin: tsMethodDecl.parameters.end, end: tsMethodDecl.body?.getStart() ?? tsMethodDecl.parameters.end }, + FUNCTION_HAS_NO_RETURN_ERROR_CODE + ); } - private handleMethodSignature(node: ts.MethodSignature) { - const tsMethodSign = node as ts.MethodSignature; + private handleMethodSignature(node: ts.MethodSignature): void { + const tsMethodSign = node; if (!tsMethodSign.type) { this.handleMissingReturnType(tsMethodSign); } } - private handleClassStaticBlockDeclaration(node: ts.Node) { + private handleClassStaticBlockDeclaration(node: ts.Node): void { const classStaticBlockDecl = node as ts.ClassStaticBlockDeclaration; const parent = classStaticBlockDecl.parent; if (!ts.isClassDeclaration(parent)) { @@ -1243,11 +1393,11 @@ export class TypeScriptLinter { } } - private handleIdentifier(node: ts.Node) { + private handleIdentifier(node: ts.Node): void { const tsIdentifier = node as ts.Identifier; const tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); if (!tsIdentSym) { - return + return; } if ( (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && @@ -1261,7 +1411,7 @@ export class TypeScriptLinter { } // hard-coded alternative to TypeScriptLinter.advancedClassChecks - private isAllowedClassValueContext(tsIdentifier: ts.Identifier, tsIdentSym: ts.Symbol): boolean { + private isAllowedClassValueContext(tsIdentifier: ts.Identifier): boolean { let ctx: ts.Node = tsIdentifier; while (ts.isPropertyAccessExpression(ctx.parent) || ts.isQualifiedName(ctx.parent)) { ctx = ctx.parent; @@ -1269,39 +1419,48 @@ export class TypeScriptLinter { if (ts.isPropertyAssignment(ctx.parent) && ts.isObjectLiteralExpression(ctx.parent.parent)) { ctx = ctx.parent.parent; } - if (ts.isArrowFunction(ctx.parent) && ctx.parent.body == ctx) { + if (ts.isArrowFunction(ctx.parent) && ctx.parent.body === ctx) { ctx = ctx.parent; } if (ts.isCallExpression(ctx.parent) || ts.isNewExpression(ctx.parent)) { - let callee = ctx.parent.expression; + const callee = ctx.parent.expression; const isAny = this.tsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)); const isDynamic = isAny || this.tsUtils.hasLibraryType(callee); - if (callee != ctx && isDynamic) { + if (callee !== ctx && isDynamic) { return true; } } return false; } - private handleRestrictedValues(tsIdentifier: ts.Identifier, tsIdentSym: ts.Symbol) { - const illegalValues = ts.SymbolFlags.ConstEnum | ts.SymbolFlags.RegularEnum | ts.SymbolFlags.ValueModule | - (TypeScriptLinter.advancedClassChecks? 0 : ts.SymbolFlags.Class); + private handleRestrictedValues(tsIdentifier: ts.Identifier, tsIdentSym: ts.Symbol): void { + const illegalValues = + ts.SymbolFlags.ConstEnum | + ts.SymbolFlags.RegularEnum | + ts.SymbolFlags.ValueModule | + (TypeScriptLinter.advancedClassChecks ? 0 : ts.SymbolFlags.Class); - // If module name is duplicated by another declaration, this increases the possibility - // of finding a lot of false positives. Thus, do not check further in that case. - if ((tsIdentSym.flags & ts.SymbolFlags.ValueModule) != 0) { + /* + * If module name is duplicated by another declaration, this increases the possibility + * of finding a lot of false positives. Thus, do not check further in that case. + */ + if ((tsIdentSym.flags & ts.SymbolFlags.ValueModule) !== 0) { if (!!tsIdentSym && this.tsUtils.symbolHasDuplicateName(tsIdentSym, ts.SyntaxKind.ModuleDeclaration)) { return; } } - if ((tsIdentSym.flags & illegalValues) == 0 || isStruct(tsIdentSym) || !identiferUseInValueContext(tsIdentifier, tsIdentSym)) { + if ( + (tsIdentSym.flags & illegalValues) === 0 || + isStruct(tsIdentSym) || + !identiferUseInValueContext(tsIdentifier, tsIdentSym) + ) { return; } - if ((tsIdentSym.flags & ts.SymbolFlags.Class) != 0) { - if (!TypeScriptLinter.advancedClassChecks && this.isAllowedClassValueContext(tsIdentifier, tsIdentSym)) { + if ((tsIdentSym.flags & ts.SymbolFlags.Class) !== 0) { + if (!TypeScriptLinter.advancedClassChecks && this.isAllowedClassValueContext(tsIdentifier)) { return; } } @@ -1314,10 +1473,14 @@ export class TypeScriptLinter { } } - private handleElementAccessExpression(node: ts.Node) { + private handleElementAccessExpression(node: ts.Node): void { const tsElementAccessExpr = node as ts.ElementAccessExpression; const tsElemAccessBaseExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression); - const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode(tsElemAccessBaseExprType, undefined, ts.NodeBuilderFlags.None); + const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode( + tsElemAccessBaseExprType, + undefined, + ts.NodeBuilderFlags.None + ); if ( !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && !this.tsUtils.isAnyType(tsElemAccessBaseExprType) && @@ -1329,7 +1492,7 @@ export class TypeScriptLinter { !this.tsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) ) { let autofix = Autofixer.fixPropertyAccessByIndex(node); - const autofixable = autofix != undefined; + const autofixable = autofix !== undefined; if (!this.autofixesInfo.shouldAutofix(node, FaultID.PropertyAccessByIndex)) { autofix = undefined; } @@ -1341,39 +1504,53 @@ export class TypeScriptLinter { } } - private handleEnumMember(node: ts.Node) { - let tsEnumMember = node as ts.EnumMember; - let tsEnumMemberType = this.tsTypeChecker.getTypeAtLocation(tsEnumMember); - let constVal = this.tsTypeChecker.getConstantValue(tsEnumMember); - if (tsEnumMember.initializer && !this.tsUtils.isValidEnumMemberInit(tsEnumMember.initializer)) + private handleEnumMember(node: ts.Node): void { + const tsEnumMember = node as ts.EnumMember; + const tsEnumMemberType = this.tsTypeChecker.getTypeAtLocation(tsEnumMember); + const constVal = this.tsTypeChecker.getConstantValue(tsEnumMember); + if (tsEnumMember.initializer && !this.tsUtils.isValidEnumMemberInit(tsEnumMember.initializer)) { this.incrementCounters(node, FaultID.EnumMemberNonConstInit); + } // check for type - all members should be of same type - let enumDecl = tsEnumMember.parent; - let firstEnumMember = enumDecl.members[0]; - let firstEnumMemberType = this.tsTypeChecker.getTypeAtLocation(firstEnumMember); - let firstElewmVal = this.tsTypeChecker.getConstantValue(firstEnumMember); - // each string enum member has its own type - // so check that value type is string - if( constVal !==undefined && typeof constVal === 'string' && - firstElewmVal !==undefined && typeof firstElewmVal === 'string' ) + const enumDecl = tsEnumMember.parent; + const firstEnumMember = enumDecl.members[0]; + const firstEnumMemberType = this.tsTypeChecker.getTypeAtLocation(firstEnumMember); + const firstElewmVal = this.tsTypeChecker.getConstantValue(firstEnumMember); + + /* + * each string enum member has its own type + * so check that value type is string + */ + if ( + constVal !== undefined && + typeof constVal === 'string' && + firstElewmVal !== undefined && + typeof firstElewmVal === 'string' + ) { return; - if( constVal !==undefined && typeof constVal === 'number' && - firstElewmVal !==undefined && typeof firstElewmVal === 'number' ) + } + if ( + constVal !== undefined && + typeof constVal === 'number' && + firstElewmVal !== undefined && + typeof firstElewmVal === 'number' + ) { return; - if(firstEnumMemberType !== tsEnumMemberType) { + } + if (firstEnumMemberType !== tsEnumMemberType) { this.incrementCounters(node, FaultID.EnumMemberNonConstInit); } } - private handleExportAssignment(node: ts.Node) { + private handleExportAssignment(node: ts.Node): void { const exportAssignment = node as ts.ExportAssignment; if (exportAssignment.isExportEquals) { this.incrementCounters(node, FaultID.ExportAssignment); } } - private handleCallExpression(node: ts.Node) { - let tsCallExpr = node as ts.CallExpression; + private handleCallExpression(node: ts.Node): void { + const tsCallExpr = node as ts.CallExpression; const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); const calleeType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); @@ -1397,12 +1574,15 @@ export class TypeScriptLinter { } this.handleLibraryTypeCall(tsCallExpr, calleeType); - if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { + if ( + ts.isPropertyAccessExpression(tsCallExpr.expression) && + this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression) + ) { this.incrementCounters(node, FaultID.EsObjectType); } } - private handleImportCall(tsCallExpr: ts.CallExpression) { + private handleImportCall(tsCallExpr: ts.CallExpression): void { if (tsCallExpr.expression.kind === ts.SyntaxKind.ImportKeyword) { // relax rule#133 "arkts-no-runtime-import" const tsArgs = tsCallExpr.arguments; @@ -1420,27 +1600,41 @@ export class TypeScriptLinter { } } - private handleRequireCall(tsCallExpr: ts.CallExpression) { + private handleRequireCall(tsCallExpr: ts.CallExpression): void { if ( ts.isIdentifier(tsCallExpr.expression) && tsCallExpr.expression.text === 'require' && ts.isVariableDeclaration(tsCallExpr.parent) ) { - let tsType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); - if (this.tsUtils.isInterfaceType(tsType) && tsType.symbol.name === 'NodeRequire') + const tsType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); + if (this.tsUtils.isInterfaceType(tsType) && tsType.symbol.name === 'NodeRequire') { this.incrementCounters(tsCallExpr.parent, FaultID.ImportAssignment); + } } } - private handleGenericCallWithNoTypeArgs(callLikeExpr: ts.CallExpression | ts.NewExpression, callSignature: ts.Signature) { - // Note: The PR!716 has led to a significant performance degradation. - // Since initial problem was fixed in a more general way, this change - // became redundant. Therefore, it was reverted. See #13721 comments - // for a detailed analysis. - const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? ts.SyntaxKind.Constructor : ts.SyntaxKind.FunctionDeclaration; + private handleGenericCallWithNoTypeArgs( + callLikeExpr: ts.CallExpression | ts.NewExpression, + callSignature: ts.Signature + ): void { + + /* + * Note: The PR!716 has led to a significant performance degradation. + * Since initial problem was fixed in a more general way, this change + * became redundant. Therefore, it was reverted. See #13721 comments + * for a detailed analysis. + */ + const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? + ts.SyntaxKind.Constructor : + ts.SyntaxKind.FunctionDeclaration; const signFlags = ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature | ts.NodeBuilderFlags.IgnoreErrors; - const signDecl = this.tsTypeChecker.signatureToSignatureDeclaration(callSignature, tsSyntaxKind, undefined, signFlags); + const signDecl = this.tsTypeChecker.signatureToSignatureDeclaration( + callSignature, + tsSyntaxKind, + undefined, + signFlags + ); if (!signDecl?.typeArguments) { return; } @@ -1448,19 +1642,22 @@ export class TypeScriptLinter { const startTypeArg = callLikeExpr.typeArguments?.length ?? 0; for (let i = startTypeArg; i < resolvedTypeArgs.length; ++i) { const typeNode = resolvedTypeArgs[i]; - // if compiler infers 'unknown' type there are 2 possible cases: - // 1. Compiler unable to infer type from arguments and use 'unknown' - // 2. Compiler infer 'unknown' from arguments - // We report error in both cases. It is ok because we cannot use 'unknown' - // in ArkTS and already have separate check for it. - if (typeNode.kind == ts.SyntaxKind.UnknownKeyword) { + + /* + * if compiler infers 'unknown' type there are 2 possible cases: + * 1. Compiler unable to infer type from arguments and use 'unknown' + * 2. Compiler infer 'unknown' from arguments + * We report error in both cases. It is ok because we cannot use 'unknown' + * in ArkTS and already have separate check for it. + */ + if (typeNode.kind === ts.SyntaxKind.UnknownKeyword) { this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs); break; } } } - private static listApplyBindCallApis = [ + private static readonly listApplyBindCallApis = [ 'Function.apply', 'Function.call', 'Function.bind', @@ -1468,29 +1665,33 @@ export class TypeScriptLinter { 'CallableFunction.call', 'CallableFunction.bind' ]; - private handleFunctionApplyBindPropCall(tsCallExpr: ts.CallExpression, calleeSym: ts.Symbol) { + + private handleFunctionApplyBindPropCall(tsCallExpr: ts.CallExpression, calleeSym: ts.Symbol): void { const exprName = this.tsTypeChecker.getFullyQualifiedName(calleeSym); if (TypeScriptLinter.listApplyBindCallApis.includes(exprName)) { this.incrementCounters(tsCallExpr, FaultID.FunctionApplyBindCall); } } - private handleStructIdentAndUndefinedInArgs(tsCallOrNewExpr: ts.CallExpression | ts.NewExpression, callSignature: ts.Signature) { + private handleStructIdentAndUndefinedInArgs( + tsCallOrNewExpr: ts.CallExpression | ts.NewExpression, + callSignature: ts.Signature + ): void { if (!tsCallOrNewExpr.arguments) { return; } for (let argIndex = 0; argIndex < tsCallOrNewExpr.arguments.length; ++argIndex) { - let tsArg = tsCallOrNewExpr.arguments[argIndex]; - let tsArgType = this.tsTypeChecker.getTypeAtLocation(tsArg); + const tsArg = tsCallOrNewExpr.arguments[argIndex]; + const tsArgType = this.tsTypeChecker.getTypeAtLocation(tsArg); if (!tsArgType) { continue; } - let paramIndex = argIndex < callSignature.parameters.length ? argIndex : callSignature.parameters.length-1; - let tsParamSym = callSignature.parameters[paramIndex]; + const paramIndex = argIndex < callSignature.parameters.length ? argIndex : callSignature.parameters.length - 1; + const tsParamSym = callSignature.parameters[paramIndex]; if (!tsParamSym) { continue; } - let tsParamDecl = tsParamSym.valueDeclaration; + const tsParamDecl = tsParamSym.valueDeclaration; if (tsParamDecl && ts.isParameter(tsParamDecl)) { let tsParamType = this.tsTypeChecker.getTypeOfSymbolAtLocation(tsParamSym, tsParamDecl); if (tsParamDecl.dotDotDotToken && this.tsUtils.isGenericArrayType(tsParamType) && tsParamType.typeArguments) { @@ -1506,17 +1707,17 @@ export class TypeScriptLinter { } } - private static LimitedApis = new Map | null, fault: FaultID}> ([ - ['global', {arr: LIMITED_STD_GLOBAL_FUNC, fault: FaultID.LimitedStdLibApi}], - ['Object', {arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], - ['ObjectConstructor', {arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi}], - ['Reflect', {arr: LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi}], - ['ProxyHandler', {arr: LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi}], - ['Symbol', {arr: null, fault: FaultID.SymbolType}], - ['SymbolConstructor', {arr: null, fault: FaultID.SymbolType}], - ]) + private static readonly LimitedApis = new Map | null; fault: FaultID }>([ + ['global', { arr: LIMITED_STD_GLOBAL_FUNC, fault: FaultID.LimitedStdLibApi }], + ['Object', { arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi }], + ['ObjectConstructor', { arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi }], + ['Reflect', { arr: LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi }], + ['ProxyHandler', { arr: LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi }], + ['Symbol', { arr: null, fault: FaultID.SymbolType }], + ['SymbolConstructor', { arr: null, fault: FaultID.SymbolType }] + ]); - private handleStdlibAPICall(callExpr: ts.CallExpression, calleeSym: ts.Symbol) { + private handleStdlibAPICall(callExpr: ts.CallExpression, calleeSym: ts.Symbol): void { const name = calleeSym.getName(); const parName = this.tsUtils.getParentSymbolName(calleeSym); if (parName === undefined) { @@ -1524,109 +1725,114 @@ export class TypeScriptLinter { this.incrementCounters(callExpr, FaultID.LimitedStdLibApi); return; } - let escapedName = calleeSym.escapedName; + const escapedName = calleeSym.escapedName; if (escapedName === 'Symbol' || escapedName === 'SymbolConstructor') { this.incrementCounters(callExpr, FaultID.SymbolType); } return; } - let lookup = TypeScriptLinter.LimitedApis.get(parName); + const lookup = TypeScriptLinter.LimitedApis.get(parName); if (lookup !== undefined && (lookup.arr === null || lookup.arr.includes(name))) { this.incrementCounters(callExpr, lookup.fault); } } - private findNonFilteringRangesFunctionCalls(callExpr: ts.CallExpression): { begin: number, end: number }[] { - let args = callExpr.arguments; - let result: { begin: number, end: number }[] = []; + private static findNonFilteringRangesFunctionCalls(callExpr: ts.CallExpression): { begin: number; end: number }[] { + const args = callExpr.arguments; + const result: { begin: number; end: number }[] = []; for (const arg of args) { if (ts.isArrowFunction(arg)) { - let arrowFuncExpr = arg as ts.ArrowFunction; - result.push({begin: arrowFuncExpr.body.pos, end: arrowFuncExpr.body.end}); + const arrowFuncExpr = arg; + result.push({ begin: arrowFuncExpr.body.pos, end: arrowFuncExpr.body.end }); } else if (ts.isCallExpression(arg)) { - result.push({begin: arg.arguments.pos, end: arg.arguments.end}); + result.push({ begin: arg.arguments.pos, end: arg.arguments.end }); } // there may be other cases } return result; } - private handleLibraryTypeCall(callExpr: ts.CallExpression, calleeType: ts.Type) { - let inLibCall = this.tsUtils.isLibraryType(calleeType); - const diagnosticMessages: Array = [] + private handleLibraryTypeCall(callExpr: ts.CallExpression, calleeType: ts.Type): void { + const inLibCall = this.tsUtils.isLibraryType(calleeType); + const diagnosticMessages: Array = []; this.libraryTypeCallDiagnosticChecker.configure(inLibCall, diagnosticMessages); - let nonFilteringRanges = this.findNonFilteringRangesFunctionCalls(callExpr); - let rangesToFilter: { begin: number, end: number }[] = []; + const nonFilteringRanges = TypeScriptLinter.findNonFilteringRangesFunctionCalls(callExpr); + const rangesToFilter: { begin: number; end: number }[] = []; if (nonFilteringRanges.length !== 0) { - let rangesSize = nonFilteringRanges.length; - rangesToFilter.push({ begin: callExpr.arguments.pos, end: nonFilteringRanges[0].begin }) - rangesToFilter.push({ begin: nonFilteringRanges[rangesSize - 1].end, end: callExpr.arguments.end }) + const rangesSize = nonFilteringRanges.length; + rangesToFilter.push({ begin: callExpr.arguments.pos, end: nonFilteringRanges[0].begin }); + rangesToFilter.push({ begin: nonFilteringRanges[rangesSize - 1].end, end: callExpr.arguments.end }); for (let i = 0; i < rangesSize - 1; i++) { - rangesToFilter.push({ begin: nonFilteringRanges[i].end, end: nonFilteringRanges[i + 1].begin }) + rangesToFilter.push({ begin: nonFilteringRanges[i].end, end: nonFilteringRanges[i + 1].begin }); } } else { - rangesToFilter.push({ begin: callExpr.arguments.pos, end: callExpr.arguments.end }) - } - - this.filterStrictDiagnostics({ - [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { - return this.checkInRange(rangesToFilter, pos); - }, - [NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE]: (pos: number) => { - return this.checkInRange([{begin: callExpr.pos, end: callExpr.end}], pos); + rangesToFilter.push({ begin: callExpr.arguments.pos, end: callExpr.arguments.end }); + } + + this.filterStrictDiagnostics( + { + [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { + return TypeScriptLinter.checkInRange(rangesToFilter, pos); + }, + [NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE]: (pos: number) => { + return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); + }, + [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { + return TypeScriptLinter.checkInRange(rangesToFilter, pos); + } }, - [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { - return this.checkInRange(rangesToFilter, pos); - } - }, - this.libraryTypeCallDiagnosticChecker + this.libraryTypeCallDiagnosticChecker ); for (const msgChain of diagnosticMessages) { - TypeScriptLinter.filteredDiagnosticMessages.add(msgChain) + TypeScriptLinter.filteredDiagnosticMessages.add(msgChain); } } - private handleNewExpression(node: ts.Node) { - let tsNewExpr = node as ts.NewExpression; + private handleNewExpression(node: ts.Node): void { + const tsNewExpr = node as ts.NewExpression; if (TypeScriptLinter.advancedClassChecks) { - let calleeExpr = tsNewExpr.expression; - let calleeType = this.tsTypeChecker.getTypeAtLocation(calleeExpr); - if (!this.tsUtils.isClassTypeExrepssion(calleeExpr) && !isStdLibraryType(calleeType) && - !this.tsUtils.isLibraryType(calleeType) && !this.tsUtils.hasEsObjectType(calleeExpr)) { + const calleeExpr = tsNewExpr.expression; + const calleeType = this.tsTypeChecker.getTypeAtLocation(calleeExpr); + if ( + !this.tsUtils.isClassTypeExrepssion(calleeExpr) && + !isStdLibraryType(calleeType) && + !this.tsUtils.isLibraryType(calleeType) && + !this.tsUtils.hasEsObjectType(calleeExpr) + ) { // missing exact rule this.incrementCounters(calleeExpr, FaultID.ClassAsObject); } } - let callSignature = this.tsTypeChecker.getResolvedSignature(tsNewExpr); + const callSignature = this.tsTypeChecker.getResolvedSignature(tsNewExpr); if (callSignature !== undefined) { this.handleStructIdentAndUndefinedInArgs(tsNewExpr, callSignature); this.handleGenericCallWithNoTypeArgs(tsNewExpr, callSignature); } } - private handleAsExpression(node: ts.Node) { - let tsAsExpr = node as ts.AsExpression; + private handleAsExpression(node: ts.Node): void { + const tsAsExpr = node as ts.AsExpression; if (tsAsExpr.type.getText() === 'const') { this.incrementCounters(node, FaultID.ConstAssertion); } - let targetType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.type).getNonNullableType(); - let exprType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.expression).getNonNullableType(); + const targetType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.type).getNonNullableType(); + const exprType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.expression).getNonNullableType(); if (this.tsUtils.needToDeduceStructuralIdentity(targetType, exprType, tsAsExpr.expression, true)) { this.incrementCounters(tsAsExpr, FaultID.StructuralIdentity); } // check for rule#65: 'number as Number' and 'boolean as Boolean' are disabled if ( - ( this.tsUtils.isNumberType(exprType) && targetType.getSymbol()?.getName() === 'Number' ) || - ( this.tsUtils.isBooleanType(exprType) && targetType.getSymbol()?.getName() === 'Boolean' ) + this.tsUtils.isNumberType(exprType) && targetType.getSymbol()?.getName() === 'Number' || + this.tsUtils.isBooleanType(exprType) && targetType.getSymbol()?.getName() === 'Boolean' ) { this.incrementCounters(node, FaultID.TypeAssertion); } } - private handleTypeReference(node: ts.Node) { + private handleTypeReference(node: ts.Node): void { const typeRef = node as ts.TypeReferenceNode; const isESObject = this.tsUtils.isEsObjectType(typeRef); @@ -1649,27 +1855,29 @@ export class TypeScriptLinter { const argType = hasSingleTypeArgument && this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[0]); if (isStdPartial && argType && !argType.isClassOrInterface()) { this.incrementCounters(node, FaultID.UtilityType); - return; } } - private handleMetaProperty(node: ts.Node) { - let tsMetaProperty = node as ts.MetaProperty; + private handleMetaProperty(node: ts.Node): void { + const tsMetaProperty = node as ts.MetaProperty; if (tsMetaProperty.name.text === 'target') { this.incrementCounters(node, FaultID.NewTarget); } } - private handleSpreadOp(node: ts.Node) { - // spread assignment is disabled - // spread element is allowed only for arrays as rest parameter - if( ts.isSpreadElement(node) ) { - let spreadElemNode = node as ts.SpreadElement; - let spreadExprType = this.tsTypeChecker.getTypeAtLocation(spreadElemNode.expression); + private handleSpreadOp(node: ts.Node): void { + + /* + * spread assignment is disabled + * spread element is allowed only for arrays as rest parameter + */ + if (ts.isSpreadElement(node)) { + const spreadElemNode = node; + const spreadExprType = this.tsTypeChecker.getTypeAtLocation(spreadElemNode.expression); if (spreadExprType) { if (ts.isCallLikeExpression(node.parent) || ts.isArrayLiteralExpression(node.parent)) { if (this.tsUtils.isOrDerivedFrom(spreadExprType, this.tsUtils.isArray)) { - return + return; } } } @@ -1677,7 +1885,7 @@ export class TypeScriptLinter { this.incrementCounters(node, FaultID.SpreadOperator); } - private handleConstructSignature(node: ts.Node) { + private handleConstructSignature(node: ts.Node): void { switch (node.parent.kind) { case ts.SyntaxKind.TypeLiteral: this.incrementCounters(node, FaultID.ConstructorType); @@ -1686,45 +1894,10 @@ export class TypeScriptLinter { this.incrementCounters(node, FaultID.ConstructorIface); break; default: - return; } } - private handleComments(node: ts.Node) { - // Note: Same comment may be owned by several nodes if their - // start/end position matches. Thus, look for the most parental - // owner of the specific comment (by the node's position). - const srcText = node.getSourceFile().getFullText(); - const parent = node.parent; - if (!parent || parent.getFullStart() !== node.getFullStart()) { - let leadingComments = ts.getLeadingCommentRanges(srcText, node.getFullStart()); - if (leadingComments) { - for (const comment of leadingComments) { - // In the real-time linter comment from the first line is double proccessed. - // It may be caused by tsc, but it should be investigated. This is a workaround - if (!this.walkedComments.has(comment.pos) && comment.pos !== comment.end) { - this.walkedComments.add(comment.pos); - this.checkErrorSuppressingAnnotation(comment, srcText); - } - } - } - } - if (!parent || parent.getEnd() !== node.getEnd()) { - let trailingComments = ts.getTrailingCommentRanges(srcText, node.getEnd()); - if (trailingComments) { - for (const comment of trailingComments) { - // In the real-time linter comment from the first line is double proccessed. - // It may be caused by tsc, but it should be investigated. This is a workaround - if (!this.walkedComments.has(comment.pos) && comment.pos !== comment.end) { - this.walkedComments.add(comment.pos); - this.checkErrorSuppressingAnnotation(comment, srcText); - } - } - } - } - } - - private handleExpressionWithTypeArguments(node: ts.Node) { + private handleExpressionWithTypeArguments(node: ts.Node): void { const tsTypeExpr = node as ts.ExpressionWithTypeArguments; const symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); if (!!symbol && this.tsUtils.isEsObjectSymbol(symbol)) { @@ -1732,29 +1905,15 @@ export class TypeScriptLinter { } } - private handleComputedPropertyName(node: ts.Node) { + private handleComputedPropertyName(node: ts.Node): void { const computedProperty = node as ts.ComputedPropertyName; const symbol = this.tsUtils.trueSymbolAtLocation(computedProperty.expression); if (!!symbol && this.tsUtils.isSymbolIterator(symbol)) { - return + return; } this.incrementCounters(node, FaultID.ComputedPropertyName); } - private checkErrorSuppressingAnnotation(comment: ts.CommentRange, srcText: string) { - const commentContent = comment.kind === ts.SyntaxKind.MultiLineCommentTrivia - ? srcText.slice(comment.pos + 2, comment.end - 2) - : srcText.slice(comment.pos + 2, comment.end); - // if comment is multiline end closing '*/' is not at the same line as '@ts-xxx' - do nothing (see #13851) - if (commentContent.endsWith('\n')) - return; - const trimmedContent = commentContent.trim(); - if (trimmedContent.startsWith('@ts-ignore') || - trimmedContent.startsWith('@ts-nocheck') || - trimmedContent.startsWith('@ts-expect-error')) - this.incrementCounters(comment, FaultID.ErrorSuppression); - } - private handleDecorators(decorators: readonly ts.Decorator[] | undefined): void { if (!decorators) { return; @@ -1772,26 +1931,29 @@ export class TypeScriptLinter { } } - private handleGetAccessor(node: ts.Node) { + private handleGetAccessor(node: ts.Node): void { this.handleDecorators(ts.getDecorators(node as ts.GetAccessorDeclaration)); } - private handleSetAccessor(node: ts.Node) { + private handleSetAccessor(node: ts.Node): void { this.handleDecorators(ts.getDecorators(node as ts.SetAccessorDeclaration)); } private handleDeclarationInferredType( decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration - ) { + ): void { // The type is explicitly specified, no need to check inferred type. if (decl.type) { return; } - // issue 13161: - // In TypeScript, the catch clause variable must be 'any' or 'unknown' type. Since - // ArkTS doesn't support these types, the type for such variable is simply omitted, - // and we don't report it as an error. See TypeScriptLinter.handleCatchClause() - // for reference. + + /* + * issue 13161: + * In TypeScript, the catch clause variable must be 'any' or 'unknown' type. Since + * ArkTS doesn't support these types, the type for such variable is simply omitted, + * and we don't report it as an error. See TypeScriptLinter.handleCatchClause() + * for reference. + */ if (ts.isCatchClause(decl.parent)) { return; } @@ -1800,14 +1962,19 @@ export class TypeScriptLinter { return; } - // issue 13987: - // When variable have no type annotation and no initial value, and 'noImplicitAny' - // option is enabled, compiler attempts to infer type from variable references: - // see https://github.com/microsoft/TypeScript/pull/11263. - // In this case, we still want to report the error, since ArkTS doesn't allow - // to omit both type annotation and initializer. - if (((ts.isVariableDeclaration(decl) && ts.isVariableStatement(decl.parent.parent)) || ts.isPropertyDeclaration(decl)) - && !decl.initializer) { + /* + * issue 13987: + * When variable have no type annotation and no initial value, and 'noImplicitAny' + * option is enabled, compiler attempts to infer type from variable references: + * see https://github.com/microsoft/TypeScript/pull/11263. + * In this case, we still want to report the error, since ArkTS doesn't allow + * to omit both type annotation and initializer. + */ + if ( + (ts.isVariableDeclaration(decl) && ts.isVariableStatement(decl.parent.parent) || + ts.isPropertyDeclaration(decl)) && + !decl.initializer + ) { this.incrementCounters(decl, FaultID.AnyType); return; } @@ -1818,20 +1985,19 @@ export class TypeScriptLinter { } } - private handleDefiniteAssignmentAssertion(decl: ts.VariableDeclaration | ts.PropertyDeclaration) { + private handleDefiniteAssignmentAssertion(decl: ts.VariableDeclaration | ts.PropertyDeclaration): void { if (decl.exclamationToken !== undefined) { this.incrementCounters(decl, FaultID.DefiniteAssignment); } } - private validatedTypesSet = new Set(); + private readonly validatedTypesSet = new Set(); private checkAnyOrUnknownChildNode(node: ts.Node): boolean { - if (node.kind === ts.SyntaxKind.AnyKeyword || - node.kind === ts.SyntaxKind.UnknownKeyword) { + if (node.kind === ts.SyntaxKind.AnyKeyword || node.kind === ts.SyntaxKind.UnknownKeyword) { return true; } - for (let child of node.getChildren()) { + for (const child of node.getChildren()) { if (this.checkAnyOrUnknownChildNode(child)) { return true; } @@ -1842,7 +2008,7 @@ export class TypeScriptLinter { private handleInferredObjectreference( type: ts.Type, decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration - ) { + ): void { const typeArgs = this.tsTypeChecker.getTypeArguments(type as ts.TypeReference); if (typeArgs) { const haveAnyOrUnknownNodes = this.checkAnyOrUnknownChildNode(decl); @@ -1858,7 +2024,7 @@ export class TypeScriptLinter { type: ts.Type, decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration ): void { - if (type.aliasSymbol != undefined) { + if (type.aliasSymbol !== undefined) { return; } if (this.tsUtils.isObjectType(type) && !!(type.objectFlags & ts.ObjectFlags.Reference)) { @@ -1870,8 +2036,8 @@ export class TypeScriptLinter { } if (type.isUnion()) { this.validatedTypesSet.add(type); - for (let unionElem of type.types) { - this.validateDeclInferredType(unionElem, decl) + for (const unionElem of type.types) { + this.validateDeclInferredType(unionElem, decl); } } if (this.tsUtils.isAnyType(type)) { @@ -1881,12 +2047,15 @@ export class TypeScriptLinter { } } - private handleCommentDirectives(sourceFile: ts.SourceFile) { - // We use a dirty hack to retrieve list of parsed comment directives by accessing - // internal properties of SourceFile node. + private handleCommentDirectives(sourceFile: ts.SourceFile): void { + + /* + * We use a dirty hack to retrieve list of parsed comment directives by accessing + * internal properties of SourceFile node. + */ // Handle comment directive '@ts-nocheck' - let pragmas = (sourceFile as any)['pragmas']; + const pragmas = (sourceFile as any).pragmas; if (pragmas && pragmas instanceof Map) { for (const pragma of pragmas) { if (pragma[0] !== 'ts-nocheck' || !pragma[1]?.range.kind || !pragma[1]?.range.pos || !pragma[1]?.range.end) { @@ -1898,16 +2067,19 @@ export class TypeScriptLinter { } // Handle comment directives '@ts-ignore' and '@ts-expect-error' - let commentDirectives = (sourceFile as any)['commentDirectives']; + const commentDirectives = (sourceFile as any).commentDirectives; if (commentDirectives && Array.isArray(commentDirectives)) { for (const directive of commentDirectives) { - if (!directive.range?.pos || !directive.range?.end) continue; + if (!directive.range?.pos || !directive.range?.end) { + continue; + } const range = directive.range as ts.TextRange; - const kind: ts.SyntaxKind = sourceFile.text.slice(range.pos, range.pos + 2) === '/*' - ? ts.SyntaxKind.MultiLineCommentTrivia - : ts.SyntaxKind.SingleLineCommentTrivia; - let commentRange: ts.CommentRange = { + const kind: ts.SyntaxKind = + sourceFile.text.slice(range.pos, range.pos + 2) === '/*' ? + ts.SyntaxKind.MultiLineCommentTrivia : + ts.SyntaxKind.SingleLineCommentTrivia; + const commentRange: ts.CommentRange = { pos: range.pos, end: range.end, kind @@ -1917,22 +2089,23 @@ export class TypeScriptLinter { } } } + private reportThisKeywordsInScope(scope: ts.Block | ts.Expression): void { - const callback = (node: ts.Node) => { + const callback = (node: ts.Node): void => { if (node.kind === ts.SyntaxKind.ThisKeyword) { this.incrementCounters(node, FaultID.FunctionContainsThis); } - } - const stopCondition = (node: ts.Node) => { + }; + const stopCondition = (node: ts.Node): boolean => { const isClassLike = ts.isClassDeclaration(node) || ts.isClassExpression(node); const isFunctionLike = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node); const isModuleDecl = ts.isModuleDeclaration(node); return isClassLike || isFunctionLike || isModuleDecl; - } + }; this.forEachNodeInSubtree(scope, callback, stopCondition); } - public lint(sourceFile: ts.SourceFile) { + lint(sourceFile: ts.SourceFile): void { this.walkedComments.clear(); this.sourceFile = sourceFile; this.visitSourceFile(this.sourceFile); diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/src/TypeScriptLinterConfig.ts index 64c2c1126..91a851e24 100644 --- a/linter/src/TypeScriptLinterConfig.ts +++ b/linter/src/TypeScriptLinterConfig.ts @@ -17,14 +17,17 @@ import * as ts from 'typescript'; import { FaultID } from './Problems'; export class LinterConfig { - // The SyntaxKind enum defines additional elements at the end of the enum - // that serve as markers (FirstX/LastX). Those elements are initialized - // with indices of the previously defined elements. As result, the enum - // may return incorrect name for a certain kind index (e.g. 'FirstStatement' - // instead of 'VariableStatement'). - // The following code creates a map with correct syntax kind names. - // It can be used when need to print name of syntax kind of certain - // AST node in diagnostic messages. + + /* + * The SyntaxKind enum defines additional elements at the end of the enum + * that serve as markers (FirstX/LastX). Those elements are initialized + * with indices of the previously defined elements. As result, the enum + * may return incorrect name for a certain kind index (e.g. 'FirstStatement' + * instead of 'VariableStatement'). + * The following code creates a map with correct syntax kind names. + * It can be used when need to print name of syntax kind of certain + * AST node in diagnostic messages. + */ static tsSyntaxKindNames: string[] = []; static { @@ -46,47 +49,97 @@ export class LinterConfig { // must detect terminals during parsing static terminalTokens: Set = new Set([ - ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, ts.SyntaxKind.OpenParenToken, - ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.OpenBracketToken, ts.SyntaxKind.CloseBracketToken, - ts.SyntaxKind.DotToken, ts.SyntaxKind.DotDotDotToken, ts.SyntaxKind.SemicolonToken, ts.SyntaxKind.CommaToken, - ts.SyntaxKind.QuestionDotToken, ts.SyntaxKind.LessThanToken, ts.SyntaxKind.LessThanSlashToken, - ts.SyntaxKind.GreaterThanToken, ts.SyntaxKind.LessThanEqualsToken, ts.SyntaxKind.GreaterThanEqualsToken, - ts.SyntaxKind.EqualsEqualsToken, ts.SyntaxKind.ExclamationEqualsToken, ts.SyntaxKind.EqualsEqualsEqualsToken, - ts.SyntaxKind.ExclamationEqualsEqualsToken, ts.SyntaxKind.EqualsGreaterThanToken, ts.SyntaxKind.PlusToken, - ts.SyntaxKind.MinusToken, ts.SyntaxKind.AsteriskToken, ts.SyntaxKind.AsteriskAsteriskToken, - ts.SyntaxKind.SlashToken, ts.SyntaxKind.PercentToken, ts.SyntaxKind.PlusPlusToken, ts.SyntaxKind.MinusMinusToken, - ts.SyntaxKind.LessThanLessThanToken, ts.SyntaxKind.GreaterThanGreaterThanToken, - ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken, ts.SyntaxKind.AmpersandToken, ts.SyntaxKind.BarToken, - ts.SyntaxKind.CaretToken, ts.SyntaxKind.ExclamationToken, ts.SyntaxKind.TildeToken, - ts.SyntaxKind.AmpersandAmpersandToken, ts.SyntaxKind.BarBarToken, ts.SyntaxKind.QuestionQuestionToken, - ts.SyntaxKind.QuestionToken, ts.SyntaxKind.ColonToken, ts.SyntaxKind.AtToken, ts.SyntaxKind.BacktickToken, - ts.SyntaxKind.HashToken, ts.SyntaxKind.EqualsToken, ts.SyntaxKind.PlusEqualsToken, ts.SyntaxKind.MinusEqualsToken, - ts.SyntaxKind.AsteriskEqualsToken, ts.SyntaxKind.AsteriskAsteriskEqualsToken, ts.SyntaxKind.SlashEqualsToken, - ts.SyntaxKind.PercentEqualsToken, ts.SyntaxKind.LessThanLessThanEqualsToken, - ts.SyntaxKind.GreaterThanGreaterThanEqualsToken, ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, - ts.SyntaxKind.AmpersandEqualsToken, ts.SyntaxKind.BarEqualsToken, ts.SyntaxKind.CaretEqualsToken, - ts.SyntaxKind.EndOfFileToken, ts.SyntaxKind.SingleLineCommentTrivia, - ts.SyntaxKind.MultiLineCommentTrivia, ts.SyntaxKind.NewLineTrivia, ts.SyntaxKind.WhitespaceTrivia, - ts.SyntaxKind.ShebangTrivia, /* We detect and preserve #! on the first line */ ts.SyntaxKind.ConflictMarkerTrivia, + ts.SyntaxKind.OpenBraceToken, + ts.SyntaxKind.CloseBraceToken, + ts.SyntaxKind.OpenParenToken, + ts.SyntaxKind.CloseParenToken, + ts.SyntaxKind.OpenBracketToken, + ts.SyntaxKind.CloseBracketToken, + ts.SyntaxKind.DotToken, + ts.SyntaxKind.DotDotDotToken, + ts.SyntaxKind.SemicolonToken, + ts.SyntaxKind.CommaToken, + ts.SyntaxKind.QuestionDotToken, + ts.SyntaxKind.LessThanToken, + ts.SyntaxKind.LessThanSlashToken, + ts.SyntaxKind.GreaterThanToken, + ts.SyntaxKind.LessThanEqualsToken, + ts.SyntaxKind.GreaterThanEqualsToken, + ts.SyntaxKind.EqualsEqualsToken, + ts.SyntaxKind.ExclamationEqualsToken, + ts.SyntaxKind.EqualsEqualsEqualsToken, + ts.SyntaxKind.ExclamationEqualsEqualsToken, + ts.SyntaxKind.EqualsGreaterThanToken, + ts.SyntaxKind.PlusToken, + ts.SyntaxKind.MinusToken, + ts.SyntaxKind.AsteriskToken, + ts.SyntaxKind.AsteriskAsteriskToken, + ts.SyntaxKind.SlashToken, + ts.SyntaxKind.PercentToken, + ts.SyntaxKind.PlusPlusToken, + ts.SyntaxKind.MinusMinusToken, + ts.SyntaxKind.LessThanLessThanToken, + ts.SyntaxKind.GreaterThanGreaterThanToken, + ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken, + ts.SyntaxKind.AmpersandToken, + ts.SyntaxKind.BarToken, + ts.SyntaxKind.CaretToken, + ts.SyntaxKind.ExclamationToken, + ts.SyntaxKind.TildeToken, + ts.SyntaxKind.AmpersandAmpersandToken, + ts.SyntaxKind.BarBarToken, + ts.SyntaxKind.QuestionQuestionToken, + ts.SyntaxKind.QuestionToken, + ts.SyntaxKind.ColonToken, + ts.SyntaxKind.AtToken, + ts.SyntaxKind.BacktickToken, + ts.SyntaxKind.HashToken, + ts.SyntaxKind.EqualsToken, + ts.SyntaxKind.PlusEqualsToken, + ts.SyntaxKind.MinusEqualsToken, + ts.SyntaxKind.AsteriskEqualsToken, + ts.SyntaxKind.AsteriskAsteriskEqualsToken, + ts.SyntaxKind.SlashEqualsToken, + ts.SyntaxKind.PercentEqualsToken, + ts.SyntaxKind.LessThanLessThanEqualsToken, + ts.SyntaxKind.GreaterThanGreaterThanEqualsToken, + ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, + ts.SyntaxKind.AmpersandEqualsToken, + ts.SyntaxKind.BarEqualsToken, + ts.SyntaxKind.CaretEqualsToken, + ts.SyntaxKind.EndOfFileToken, + ts.SyntaxKind.SingleLineCommentTrivia, + ts.SyntaxKind.MultiLineCommentTrivia, + ts.SyntaxKind.NewLineTrivia, + ts.SyntaxKind.WhitespaceTrivia, + ts.SyntaxKind.ShebangTrivia, + /* We detect and preserve #! on the first line */ ts.SyntaxKind.ConflictMarkerTrivia ]); // tokens which can be reported without additional parsing static incrementOnlyTokens: Map = new Map([ - [ts.SyntaxKind.AnyKeyword, FaultID.AnyType], [ts.SyntaxKind.SymbolKeyword, FaultID.SymbolType], + [ts.SyntaxKind.AnyKeyword, FaultID.AnyType], + [ts.SyntaxKind.SymbolKeyword, FaultID.SymbolType], [ts.SyntaxKind.ThisType, FaultID.ThisType], [ts.SyntaxKind.TypeQuery, FaultID.TypeQuery], [ts.SyntaxKind.DeleteExpression, FaultID.DeleteOperator], [ts.SyntaxKind.RegularExpressionLiteral, FaultID.RegexLiteral], - [ts.SyntaxKind.TypePredicate, FaultID.IsOperator], [ts.SyntaxKind.YieldExpression, FaultID.YieldExpression], - [ts.SyntaxKind.IndexSignature, FaultID.IndexMember], [ts.SyntaxKind.WithStatement, FaultID.WithStatement], - [ts.SyntaxKind.IndexedAccessType, FaultID.IndexedAccessType], [ts.SyntaxKind.UnknownKeyword, FaultID.UnknownType], + [ts.SyntaxKind.TypePredicate, FaultID.IsOperator], + [ts.SyntaxKind.YieldExpression, FaultID.YieldExpression], + [ts.SyntaxKind.IndexSignature, FaultID.IndexMember], + [ts.SyntaxKind.WithStatement, FaultID.WithStatement], + [ts.SyntaxKind.IndexedAccessType, FaultID.IndexedAccessType], + [ts.SyntaxKind.UnknownKeyword, FaultID.UnknownType], [ts.SyntaxKind.CallSignature, FaultID.CallSignature], [ts.SyntaxKind.IntersectionType, FaultID.IntersectionType], - [ts.SyntaxKind.TypeLiteral, FaultID.ObjectTypeLiteral], [ts.SyntaxKind.ConstructorType, FaultID.ConstructorFuncs], + [ts.SyntaxKind.TypeLiteral, FaultID.ObjectTypeLiteral], + [ts.SyntaxKind.ConstructorType, FaultID.ConstructorFuncs], [ts.SyntaxKind.PrivateIdentifier, FaultID.PrivateIdentifier], - [ts.SyntaxKind.ConditionalType, FaultID.ConditionalType], [ts.SyntaxKind.MappedType, FaultID.MappedType], - [ts.SyntaxKind.JsxElement, FaultID.JsxElement], [ts.SyntaxKind.JsxSelfClosingElement, FaultID.JsxElement], + [ts.SyntaxKind.ConditionalType, FaultID.ConditionalType], + [ts.SyntaxKind.MappedType, FaultID.MappedType], + [ts.SyntaxKind.JsxElement, FaultID.JsxElement], + [ts.SyntaxKind.JsxSelfClosingElement, FaultID.JsxElement], [ts.SyntaxKind.ImportEqualsDeclaration, FaultID.ImportAssignment], - [ts.SyntaxKind.NamespaceExportDeclaration, FaultID.UMDModuleDefinition], + [ts.SyntaxKind.NamespaceExportDeclaration, FaultID.UMDModuleDefinition] ]); } diff --git a/linter/src/autofixes/AutofixTitles.ts b/linter/src/autofixes/AutofixTitles.ts index 89bad0381..91b7ff1f0 100644 --- a/linter/src/autofixes/AutofixTitles.ts +++ b/linter/src/autofixes/AutofixTitles.ts @@ -1,17 +1,17 @@ -/* - * Copyright (c) 2022-2023 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. - */ +/* + * Copyright (c) 2022-2023 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. + */ // generated from recipes.rst export const cookBookRefToFixTitle: Map = new Map([ @@ -24,5 +24,5 @@ export const cookBookRefToFixTitle: Map = new Map([ [90, 'Annotate return type'], [118, 'Replace with ordinary import'], [120, 'Replace with explicit import'], - [127, 'Replace with ordinary export'], + [127, 'Replace with ordinary export'] ]); diff --git a/linter/src/autofixes/ReportAutofixCallback.ts b/linter/src/autofixes/ReportAutofixCallback.ts index 0338538bc..81f035891 100644 --- a/linter/src/autofixes/ReportAutofixCallback.ts +++ b/linter/src/autofixes/ReportAutofixCallback.ts @@ -1,19 +1,19 @@ -/* - * Copyright (c) 2022-2023 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. - */ +/* + * Copyright (c) 2022-2023 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 { ProblemInfo } from '../ProblemInfo'; +import type { ProblemInfo } from '../ProblemInfo'; export type ReportAutofixCallback = (p: ProblemInfo) => void; diff --git a/linter/src/ts-compiler/FormTscOptions.ts b/linter/src/ts-compiler/FormTscOptions.ts index 08a04429a..19fce66c1 100644 --- a/linter/src/ts-compiler/FormTscOptions.ts +++ b/linter/src/ts-compiler/FormTscOptions.ts @@ -14,29 +14,29 @@ */ import * as ts from 'typescript'; -import { CommandLineOptions } from '../CommandLineOptions'; +import type { CommandLineOptions } from '../CommandLineOptions'; -export function formTscOptions(cmdOptions: CommandLineOptions, extraOptions?: any): ts.CreateProgramOptions { +export function formTscOptions(cmdOptions: CommandLineOptions, extraOptions?: unknown): ts.CreateProgramOptions { if (cmdOptions.parsedConfigFile) { - let options: ts.CreateProgramOptions = { + const options: ts.CreateProgramOptions = { rootNames: cmdOptions.parsedConfigFile.fileNames, options: cmdOptions.parsedConfigFile.options, projectReferences: cmdOptions.parsedConfigFile.projectReferences, - configFileParsingDiagnostics: ts.getConfigFileParsingDiagnostics(cmdOptions.parsedConfigFile), + configFileParsingDiagnostics: ts.getConfigFileParsingDiagnostics(cmdOptions.parsedConfigFile) }; if (extraOptions) { options.options = Object.assign(options.options, extraOptions); } return options; } - let options: ts.CreateProgramOptions = { + const options: ts.CreateProgramOptions = { rootNames: cmdOptions.inputFiles, options: { target: ts.ScriptTarget.Latest, module: ts.ModuleKind.CommonJS, allowJs: true, - checkJs: true, - }, + checkJs: true + } }; if (extraOptions) { options.options = Object.assign(options.options, extraOptions); diff --git a/linter/src/ts-diagnostics/GetTscDiagnostics.ts b/linter/src/ts-diagnostics/GetTscDiagnostics.ts index 3b75a69aa..4c7d640ff 100644 --- a/linter/src/ts-diagnostics/GetTscDiagnostics.ts +++ b/linter/src/ts-diagnostics/GetTscDiagnostics.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import * as ts from 'typescript'; +import type * as ts from 'typescript'; import * as path from 'node:path'; -import { TSCCompiledProgram } from './TSCCompiledProgram'; +import type { TSCCompiledProgram } from './TSCCompiledProgram'; /** * Extracts TSC diagnostics emitted by strict checks. @@ -26,12 +26,12 @@ import { TSCCompiledProgram } from './TSCCompiledProgram'; */ export function getTscDiagnostics( tscDiagnosticsLinter: TSCCompiledProgram, - sourceFiles: ts.SourceFile[], + sourceFiles: ts.SourceFile[] ): Map { const strictDiagnostics = new Map(); - sourceFiles.forEach(file => { + sourceFiles.forEach((file) => { const diagnostics = tscDiagnosticsLinter.getStrictDiagnostics(file.fileName); - if (diagnostics.length != 0) { + if (diagnostics.length > 0) { strictDiagnostics.set(path.normalize(file.fileName), diagnostics); } }); diff --git a/linter/src/ts-diagnostics/TSCCompiledProgram.ts b/linter/src/ts-diagnostics/TSCCompiledProgram.ts index cee480fd8..6e203aa38 100644 --- a/linter/src/ts-diagnostics/TSCCompiledProgram.ts +++ b/linter/src/ts-diagnostics/TSCCompiledProgram.ts @@ -14,39 +14,41 @@ */ import * as ts from 'typescript'; -import { ProblemInfo } from '../ProblemInfo'; +import type { ProblemInfo } from '../ProblemInfo'; import { ProblemSeverity } from '../ProblemSeverity'; -import { LintOptions } from '../LintOptions'; +import type { LintOptions } from '../LintOptions'; import { TypeScriptDiagnosticsExtractor } from './TypeScriptDiagnosticsExtractor'; import { compile } from '../CompilerWrapper'; import { FaultID } from '../Problems'; import { faultsAttrs } from '../FaultAttrs'; export interface TSCCompiledProgram { - getOriginalProgram(): ts.Program; - getStrictDiagnostics(fileName: string): ts.Diagnostic[]; + getOriginalProgram: () => ts.Program; + getStrictDiagnostics: (fileName: string) => ts.Diagnostic[]; } export class TSCCompiledProgramSimple implements TSCCompiledProgram { - private tsProgram: ts.Program; + private readonly tsProgram: ts.Program; constructor(program: ts.Program) { this.tsProgram = program; } - public getOriginalProgram(): ts.Program { + getOriginalProgram(): ts.Program { return this.tsProgram; } - public getStrictDiagnostics(fileName: string): ts.Diagnostic[] { + getStrictDiagnostics(fileName: string): ts.Diagnostic[] { + void fileName; + void this; return []; } } export class TSCCompiledProgramWithDiagnostics implements TSCCompiledProgram { - private diagnosticsExtractor: TypeScriptDiagnosticsExtractor; - private wasStrict: boolean; - private cachedDiagnostics: Map; + private readonly diagnosticsExtractor: TypeScriptDiagnosticsExtractor; + private readonly wasStrict: boolean; + private readonly cachedDiagnostics: Map; constructor(program: ts.Program, options: LintOptions) { const { strict, nonStrict, wasStrict } = getTwoCompiledVersions(program, options); @@ -55,35 +57,40 @@ export class TSCCompiledProgramWithDiagnostics implements TSCCompiledProgram { this.cachedDiagnostics = new Map(); } - public getOriginalProgram(): ts.Program { + getOriginalProgram(): ts.Program { return this.wasStrict ? this.diagnosticsExtractor.strictProgram : this.diagnosticsExtractor.nonStrictProgram; } - public getStrictDiagnostics(fileName: string): ts.Diagnostic[] { + getStrictDiagnostics(fileName: string): ts.Diagnostic[] { const cachedDiagnostic = this.cachedDiagnostics.get(fileName); if (cachedDiagnostic) { - return cachedDiagnostic + return cachedDiagnostic; } const diagnostic = this.diagnosticsExtractor.getStrictDiagnostics(fileName); - this.cachedDiagnostics.set(fileName, diagnostic) + this.cachedDiagnostics.set(fileName, diagnostic); return diagnostic; } } -export function getStrictOptions(strict: boolean = true) { +export function getStrictOptions(strict: boolean = true): { + strictNullChecks: boolean; + strictFunctionTypes: boolean; + strictPropertyInitialization: boolean; + noImplicitReturns: boolean; +} { return { strictNullChecks: strict, strictFunctionTypes: strict, strictPropertyInitialization: strict, - noImplicitReturns: strict, - } + noImplicitReturns: strict + }; } function getTwoCompiledVersions( program: ts.Program, - options: LintOptions, + options: LintOptions ): { strict: ts.Program; nonStrict: ts.Program; wasStrict: boolean } { - const compilerOptions = { ...program.getCompilerOptions()}; + const compilerOptions = { ...program.getCompilerOptions() }; const wasStrict = inverseStrictOptions(compilerOptions); const inversedOptions = getStrictOptions(!wasStrict); @@ -92,8 +99,8 @@ function getTwoCompiledVersions( return { strict: wasStrict ? program : withInversedOptions, nonStrict: wasStrict ? withInversedOptions : program, - wasStrict: wasStrict, - } + wasStrict: wasStrict + }; } /** @@ -102,7 +109,7 @@ function getTwoCompiledVersions( function inverseStrictOptions(compilerOptions: ts.CompilerOptions): boolean { const strictOptions = getStrictOptions(); let wasStrict = false; - Object.keys(strictOptions).forEach(x => { + Object.keys(strictOptions).forEach((x) => { wasStrict = wasStrict || !!compilerOptions[x]; }); // wasStrict evaluates true if any of the strict options was set @@ -125,12 +132,13 @@ export function transformDiagnostic(diagnostic: ts.Diagnostic): ProblemInfo { start: startPos, end: endPos, type: 'StrictModeError', - severity: ProblemSeverity.ERROR, // expect strict options to always present + // expect strict options to always present + severity: ProblemSeverity.ERROR, problem: FaultID[faultId], suggest: messageText, rule: messageText, ruleTag: faultsAttrs[faultId] ? Number(faultsAttrs[faultId].cookBookRef) : 0, - autofixable: false, + autofixable: false }; } @@ -138,10 +146,10 @@ export function transformDiagnostic(diagnostic: ts.Diagnostic): ProblemInfo { * Returns line and column of the position, counts from 1 */ function getLineAndColumn(file: ts.SourceFile, position: number): { line: number; column: number } { - let { line, character } = file.getLineAndCharacterOfPosition(position); + const { line, character } = file.getLineAndCharacterOfPosition(position); // TSC counts lines and columns from zero return { line: line + 1, - column: character + 1, - } + column: character + 1 + }; } diff --git a/linter/src/ts-diagnostics/TransformTscDiagnostics.ts b/linter/src/ts-diagnostics/TransformTscDiagnostics.ts index 9c644117e..718d3e5f0 100644 --- a/linter/src/ts-diagnostics/TransformTscDiagnostics.ts +++ b/linter/src/ts-diagnostics/TransformTscDiagnostics.ts @@ -13,16 +13,19 @@ * limitations under the License. */ -import * as ts from 'typescript'; -import { ProblemInfo } from '../ProblemInfo'; +import type * as ts from 'typescript'; +import type { ProblemInfo } from '../ProblemInfo'; import { transformDiagnostic } from './TSCCompiledProgram'; -export function transformTscDiagnostics( - strictDiagnostics: Map -): Map { +export function transformTscDiagnostics(strictDiagnostics: Map): Map { const problemsInfos = new Map(); - strictDiagnostics.forEach((diagnostics, file, map) => { - problemsInfos.set(file, diagnostics.map(x => transformDiagnostic(x))); + strictDiagnostics.forEach((diagnostics, file) => { + problemsInfos.set( + file, + diagnostics.map((x) => { + return transformDiagnostic(x); + }) + ); }); return problemsInfos; } diff --git a/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts b/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts index 89380f130..7ce161575 100644 --- a/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts +++ b/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts @@ -13,19 +13,22 @@ * limitations under the License. */ -import * as ts from 'typescript'; +import type * as ts from 'typescript'; export class TypeScriptDiagnosticsExtractor { - constructor(public strictProgram: ts.Program, public nonStrictProgram: ts.Program) { - } + constructor( + public strictProgram: ts.Program, + public nonStrictProgram: ts.Program + ) {} /** * Returns diagnostics which appear in strict compilation mode only */ - public getStrictDiagnostics(fileName: string): ts.Diagnostic[] { + getStrictDiagnostics(fileName: string): ts.Diagnostic[] { // applying filter is a workaround for tsc bug - const strict = getAllDiagnostics(this.strictProgram, fileName) - .filter(diag => !(diag.length === 0 && diag.start === 0)); + const strict = getAllDiagnostics(this.strictProgram, fileName).filter((diag) => { + return !(diag.length === 0 && diag.start === 0); + }); const nonStrict = getAllDiagnostics(this.nonStrictProgram, fileName); // collect hashes for later easier comparison @@ -37,18 +40,21 @@ export class TypeScriptDiagnosticsExtractor { return result; }, new Set()); // return diagnostics which weren't detected in non-strict mode - return strict.filter(value => { + return strict.filter((value) => { const hash = hashDiagnostic(value); - return (hash && !nonStrictHashes.has(hash)); + return hash && !nonStrictHashes.has(hash); }); } } function getAllDiagnostics(program: ts.Program, fileName: string): ts.Diagnostic[] { const sourceFile = program.getSourceFile(fileName); - return program.getSemanticDiagnostics(sourceFile) - .concat(program.getSyntacticDiagnostics(sourceFile)) - .filter(diag => diag.file === sourceFile); + return program. + getSemanticDiagnostics(sourceFile). + concat(program.getSyntacticDiagnostics(sourceFile)). + filter((diag) => { + return diag.file === sourceFile; + }); } function hashDiagnostic(diagnostic: ts.Diagnostic): string | undefined { diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index 5bff6b0aa..dfa4de9f9 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -25,10 +25,13 @@ import { pathContainsDirectory } from './functions/PathHelper'; import { ARKTS_IGNORE_DIRS, ARKTS_IGNORE_FILES } from './consts/ArktsIgnorePaths'; import { isAssignmentOperator } from './functions/isAssignmentOperator'; -export type CheckType = ((t: ts.Type) => boolean); +export type CheckType = (t: ts.Type) => boolean; export class TsUtils { - constructor(private tsTypeChecker: ts.TypeChecker, private testMode: boolean, private advancedClassChecks: boolean) { - } + constructor( + private tsTypeChecker: ts.TypeChecker, + private testMode: boolean, + private advancedClassChecks: boolean + ) {} public isType(tsType: ts.TypeNode | undefined, checkType: string): boolean { if (tsType === undefined || !ts.isTypeReferenceNode(tsType)) { @@ -104,8 +107,7 @@ export class TsUtils { public findParentIf(asExpr: ts.AsExpression): ts.IfStatement | null { let node = asExpr.parent; while (node) { - if (node.kind === ts.SyntaxKind.IfStatement) - return node as ts.IfStatement; + if (node.kind === ts.SyntaxKind.IfStatement) return node as ts.IfStatement; node = node.parent; } @@ -113,23 +115,23 @@ export class TsUtils { return null; } - public isDestructuringAssignmentLHS( - tsExpr: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression - ): boolean { + public isDestructuringAssignmentLHS(tsExpr: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression): boolean { // Check whether given expression is the LHS part of the destructuring // assignment (or is a nested element of destructuring pattern). let tsParent = tsExpr.parent; let tsCurrentExpr: ts.Node = tsExpr; while (tsParent) { if ( - ts.isBinaryExpression(tsParent) && isAssignmentOperator(tsParent.operatorToken) && + ts.isBinaryExpression(tsParent) && + isAssignmentOperator(tsParent.operatorToken) && tsParent.left === tsCurrentExpr ) return true; if ( (ts.isForStatement(tsParent) || ts.isForInStatement(tsParent) || ts.isForOfStatement(tsParent)) && - tsParent.initializer && tsParent.initializer === tsCurrentExpr + tsParent.initializer && + tsParent.initializer === tsCurrentExpr ) return true; @@ -173,8 +175,7 @@ export class TsUtils { public unwrapParenthesized(tsExpr: ts.Expression): ts.Expression { let unwrappedExpr = tsExpr; - while (ts.isParenthesizedExpression(unwrappedExpr)) - unwrappedExpr = unwrappedExpr.expression; + while (ts.isParenthesizedExpression(unwrappedExpr)) unwrappedExpr = unwrappedExpr.expression; return unwrappedExpr; } @@ -185,7 +186,7 @@ export class TsUtils { } return sym; } - + private trueSymbolAtLocationCache = new Map(); public trueSymbolAtLocation(node: ts.Node): ts.Symbol | undefined { @@ -205,11 +206,13 @@ export class TsUtils { } private isTypeDeclSyntaxKind(kind: ts.SyntaxKind) { - return isStructDeclarationKind(kind) || + return ( + isStructDeclarationKind(kind) || kind === ts.SyntaxKind.EnumDeclaration || kind === ts.SyntaxKind.ClassDeclaration || kind === ts.SyntaxKind.InterfaceDeclaration || - kind === ts.SyntaxKind.TypeAliasDeclaration; + kind === ts.SyntaxKind.TypeAliasDeclaration + ); } public symbolHasDuplicateName(symbol: ts.Symbol, tsDeclKind: ts.SyntaxKind): boolean { @@ -223,7 +226,7 @@ export class TsUtils { // we relax arkts-unique-names for namespace collision with class/interface/enum/type/struct const isNamespaceTypeCollision = (this.isTypeDeclSyntaxKind(declKind) && tsDeclKind === ts.SyntaxKind.ModuleDeclaration) || - (this.isTypeDeclSyntaxKind(tsDeclKind) && declKind === ts.SyntaxKind.ModuleDeclaration) + (this.isTypeDeclSyntaxKind(tsDeclKind) && declKind === ts.SyntaxKind.ModuleDeclaration); // Don't count declarations with 'Identifier' syntax kind as those // usually depict declaring an object's property through assignment. @@ -237,17 +240,23 @@ export class TsUtils { public isReferenceType(tsType: ts.Type): boolean { const f = tsType.getFlags(); return ( - (f & ts.TypeFlags.InstantiableNonPrimitive) != 0 || (f & ts.TypeFlags.Object) != 0 || - (f & ts.TypeFlags.Boolean) != 0 || (f & ts.TypeFlags.Enum) != 0 || (f & ts.TypeFlags.NonPrimitive) != 0 || - (f & ts.TypeFlags.Number) != 0 || (f & ts.TypeFlags.String) != 0 + (f & ts.TypeFlags.InstantiableNonPrimitive) != 0 || + (f & ts.TypeFlags.Object) != 0 || + (f & ts.TypeFlags.Boolean) != 0 || + (f & ts.TypeFlags.Enum) != 0 || + (f & ts.TypeFlags.NonPrimitive) != 0 || + (f & ts.TypeFlags.Number) != 0 || + (f & ts.TypeFlags.String) != 0 ); } public isPrimitiveType(type: ts.Type): boolean { const f = type.getFlags(); return ( - (f & ts.TypeFlags.Boolean) != 0 || (f & ts.TypeFlags.BooleanLiteral) != 0 || - (f & ts.TypeFlags.Number) != 0 || (f & ts.TypeFlags.NumberLiteral) != 0 + (f & ts.TypeFlags.Boolean) != 0 || + (f & ts.TypeFlags.BooleanLiteral) != 0 || + (f & ts.TypeFlags.Number) != 0 || + (f & ts.TypeFlags.NumberLiteral) != 0 // In ArkTS 'string' is not a primitive type. So for the common subset 'string' // should be considered as a reference type. That is why next line is commented out. //(f & ts.TypeFlags.String) != 0 || (f & ts.TypeFlags.StringLiteral) != 0 @@ -256,7 +265,8 @@ export class TsUtils { public isTypeSymbol(symbol: ts.Symbol | undefined): boolean { return ( - !!symbol && !!symbol.flags && + !!symbol && + !!symbol.flags && ((symbol.flags & ts.SymbolFlags.Class) !== 0 || (symbol.flags & ts.SymbolFlags.Interface) !== 0) ); } @@ -264,7 +274,9 @@ export class TsUtils { // Check whether type is generic 'Array' type defined in TypeScript standard library. public isGenericArrayType(tsType: ts.Type): tsType is ts.TypeReference { return ( - this.isTypeReference(tsType) && tsType.typeArguments?.length === 1 && tsType.target.typeParameters?.length === 1 && + this.isTypeReference(tsType) && + tsType.typeArguments?.length === 1 && + tsType.target.typeParameters?.length === 1 && tsType.getSymbol()?.getName() === 'Array' ); } @@ -324,25 +336,24 @@ export class TsUtils { } public isNullType(tsTypeNode: ts.TypeNode): boolean { - return (ts.isLiteralTypeNode(tsTypeNode) && tsTypeNode.literal.kind === ts.SyntaxKind.NullKeyword); + return ts.isLiteralTypeNode(tsTypeNode) && tsTypeNode.literal.kind === ts.SyntaxKind.NullKeyword; } public isThisOrSuperExpr(tsExpr: ts.Expression): boolean { - return (tsExpr.kind == ts.SyntaxKind.ThisKeyword || tsExpr.kind == ts.SyntaxKind.SuperKeyword); + return tsExpr.kind == ts.SyntaxKind.ThisKeyword || tsExpr.kind == ts.SyntaxKind.SuperKeyword; } public isPrototypeSymbol(symbol: ts.Symbol | undefined): boolean { - return (!!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Prototype) !== 0); + return !!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Prototype) !== 0; } public isFunctionSymbol(symbol: ts.Symbol | undefined): boolean { - return (!!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Function) !== 0); + return !!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Function) !== 0; } public isInterfaceType(tsType: ts.Type | undefined): boolean { return ( - !!tsType && !!tsType.symbol && !!tsType.symbol.flags && - (tsType.symbol.flags & ts.SymbolFlags.Interface) !== 0 + !!tsType && !!tsType.symbol && !!tsType.symbol.flags && (tsType.symbol.flags & ts.SymbolFlags.Interface) !== 0 ); } @@ -356,7 +367,9 @@ export class TsUtils { public isUnsupportedType(tsType: ts.Type): boolean { return ( - !!tsType.flags && ((tsType.flags & ts.TypeFlags.Any) !== 0 || (tsType.flags & ts.TypeFlags.Unknown) !== 0 || + !!tsType.flags && + ((tsType.flags & ts.TypeFlags.Any) !== 0 || + (tsType.flags & ts.TypeFlags.Unknown) !== 0 || (tsType.flags & ts.TypeFlags.Intersection) !== 0) ); } @@ -374,21 +387,18 @@ export class TsUtils { public isFunctionOrMethod(tsSymbol: ts.Symbol | undefined): boolean { return ( - !!tsSymbol && - ((tsSymbol.flags & ts.SymbolFlags.Function) !== 0 || (tsSymbol.flags & ts.SymbolFlags.Method) !== 0) + !!tsSymbol && ((tsSymbol.flags & ts.SymbolFlags.Function) !== 0 || (tsSymbol.flags & ts.SymbolFlags.Method) !== 0) ); } public isMethodAssignment(tsSymbol: ts.Symbol | undefined): boolean { return ( - !!tsSymbol && - ((tsSymbol.flags & ts.SymbolFlags.Method) !== 0 && (tsSymbol.flags & ts.SymbolFlags.Assignment) !== 0) + !!tsSymbol && (tsSymbol.flags & ts.SymbolFlags.Method) !== 0 && (tsSymbol.flags & ts.SymbolFlags.Assignment) !== 0 ); } public getDeclaration(tsSymbol: ts.Symbol | undefined): ts.Declaration | undefined { - if (tsSymbol && tsSymbol.declarations && tsSymbol.declarations.length > 0) - return tsSymbol.declarations[0]; + if (tsSymbol && tsSymbol.declarations && tsSymbol.declarations.length > 0) return tsSymbol.declarations[0]; return undefined; } @@ -397,17 +407,16 @@ export class TsUtils { } public isValidEnumMemberInit(tsExpr: ts.Expression): boolean { - if (this.isNumberConstantValue(tsExpr.parent as ts.EnumMember)) - return true; - if (this.isStringConstantValue(tsExpr.parent as ts.EnumMember)) - return true; + if (this.isNumberConstantValue(tsExpr.parent as ts.EnumMember)) return true; + if (this.isStringConstantValue(tsExpr.parent as ts.EnumMember)) return true; return this.isCompileTimeExpression(tsExpr); } public isCompileTimeExpression(tsExpr: ts.Expression): boolean { if ( ts.isParenthesizedExpression(tsExpr) || - (ts.isAsExpression(tsExpr) && tsExpr.type.kind === ts.SyntaxKind.NumberKeyword)) + (ts.isAsExpression(tsExpr) && tsExpr.type.kind === ts.SyntaxKind.NumberKeyword) + ) return this.isCompileTimeExpression(tsExpr.expression); switch (tsExpr.kind) { @@ -428,14 +437,11 @@ export class TsUtils { // if enum member is in current enum declaration try to get value // if it comes from another enum consider as constant const propertyAccess = tsExpr as ts.PropertyAccessExpression; - if (this.isNumberConstantValue(propertyAccess)) - return true; + if (this.isNumberConstantValue(propertyAccess)) return true; const leftHandSymbol = this.trueSymbolAtLocation(propertyAccess.expression); - if (!leftHandSymbol) - return false; + if (!leftHandSymbol) return false; const decls = leftHandSymbol.getDeclarations(); - if (!decls || decls.length !== 1) - return false; + if (!decls || decls.length !== 1) return false; return ts.isEnumDeclaration(decls[0]); } default: @@ -444,46 +450,53 @@ export class TsUtils { } private isPrefixUnaryExprValidEnumMemberInit(tsExpr: ts.PrefixUnaryExpression): boolean { - return (this.isUnaryOpAllowedForEnumMemberInit(tsExpr.operator) && this.isCompileTimeExpression(tsExpr.operand)); + return this.isUnaryOpAllowedForEnumMemberInit(tsExpr.operator) && this.isCompileTimeExpression(tsExpr.operand); } private isBinaryExprValidEnumMemberInit(tsExpr: ts.BinaryExpression): boolean { return ( - this.isBinaryOpAllowedForEnumMemberInit(tsExpr.operatorToken) && this.isCompileTimeExpression(tsExpr.left) && + this.isBinaryOpAllowedForEnumMemberInit(tsExpr.operatorToken) && + this.isCompileTimeExpression(tsExpr.left) && this.isCompileTimeExpression(tsExpr.right) ); } private isConditionalExprValidEnumMemberInit(tsExpr: ts.ConditionalExpression): boolean { - return (this.isCompileTimeExpression(tsExpr.whenTrue) && this.isCompileTimeExpression(tsExpr.whenFalse)); + return this.isCompileTimeExpression(tsExpr.whenTrue) && this.isCompileTimeExpression(tsExpr.whenFalse); } private isIdentifierValidEnumMemberInit(tsExpr: ts.Identifier): boolean { let tsSymbol = this.trueSymbolAtLocation(tsExpr); let tsDecl = this.getDeclaration(tsSymbol); - return (!!tsDecl && - ((this.isVarDeclaration(tsDecl) && this.isConst(tsDecl.parent)) || - (tsDecl.kind === ts.SyntaxKind.EnumMember) - ) + return ( + !!tsDecl && + ((this.isVarDeclaration(tsDecl) && this.isConst(tsDecl.parent)) || tsDecl.kind === ts.SyntaxKind.EnumMember) ); } private isUnaryOpAllowedForEnumMemberInit(tsPrefixUnaryOp: ts.PrefixUnaryOperator): boolean { return ( - tsPrefixUnaryOp === ts.SyntaxKind.PlusToken || tsPrefixUnaryOp === ts.SyntaxKind.MinusToken || + tsPrefixUnaryOp === ts.SyntaxKind.PlusToken || + tsPrefixUnaryOp === ts.SyntaxKind.MinusToken || tsPrefixUnaryOp === ts.SyntaxKind.TildeToken ); } private isBinaryOpAllowedForEnumMemberInit(tsBinaryOp: ts.BinaryOperatorToken): boolean { return ( - tsBinaryOp.kind === ts.SyntaxKind.AsteriskToken || tsBinaryOp.kind === ts.SyntaxKind.SlashToken || - tsBinaryOp.kind === ts.SyntaxKind.PercentToken || tsBinaryOp.kind === ts.SyntaxKind.MinusToken || - tsBinaryOp.kind === ts.SyntaxKind.PlusToken || tsBinaryOp.kind === ts.SyntaxKind.LessThanLessThanToken || - tsBinaryOp.kind === ts.SyntaxKind.GreaterThanGreaterThanToken || tsBinaryOp.kind === ts.SyntaxKind.BarBarToken || + tsBinaryOp.kind === ts.SyntaxKind.AsteriskToken || + tsBinaryOp.kind === ts.SyntaxKind.SlashToken || + tsBinaryOp.kind === ts.SyntaxKind.PercentToken || + tsBinaryOp.kind === ts.SyntaxKind.MinusToken || + tsBinaryOp.kind === ts.SyntaxKind.PlusToken || + tsBinaryOp.kind === ts.SyntaxKind.LessThanLessThanToken || + tsBinaryOp.kind === ts.SyntaxKind.GreaterThanGreaterThanToken || + tsBinaryOp.kind === ts.SyntaxKind.BarBarToken || tsBinaryOp.kind === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken || - tsBinaryOp.kind === ts.SyntaxKind.AmpersandToken || tsBinaryOp.kind === ts.SyntaxKind.CaretToken || - tsBinaryOp.kind === ts.SyntaxKind.BarToken || tsBinaryOp.kind === ts.SyntaxKind.AmpersandAmpersandToken + tsBinaryOp.kind === ts.SyntaxKind.AmpersandToken || + tsBinaryOp.kind === ts.SyntaxKind.CaretToken || + tsBinaryOp.kind === ts.SyntaxKind.BarToken || + tsBinaryOp.kind === ts.SyntaxKind.AmpersandAmpersandToken ); } @@ -494,23 +507,24 @@ export class TsUtils { public isNumberConstantValue( tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.NumericLiteral ): boolean { + const tsConstValue = + tsExpr.kind === ts.SyntaxKind.NumericLiteral + ? Number(tsExpr.getText()) + : this.tsTypeChecker.getConstantValue(tsExpr); - const tsConstValue = (tsExpr.kind === ts.SyntaxKind.NumericLiteral) ? - Number(tsExpr.getText()) : - this.tsTypeChecker.getConstantValue(tsExpr); - - return tsConstValue !== undefined && typeof tsConstValue === 'number'; + return tsConstValue !== undefined && typeof tsConstValue === 'number'; } public isIntegerConstantValue( tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.NumericLiteral ): boolean { - - const tsConstValue = (tsExpr.kind === ts.SyntaxKind.NumericLiteral) ? - Number(tsExpr.getText()) : - this.tsTypeChecker.getConstantValue(tsExpr); + const tsConstValue = + tsExpr.kind === ts.SyntaxKind.NumericLiteral + ? Number(tsExpr.getText()) + : this.tsTypeChecker.getConstantValue(tsExpr); return ( - tsConstValue !== undefined && typeof tsConstValue === 'number' && + tsConstValue !== undefined && + typeof tsConstValue === 'number' && tsConstValue.toFixed(0) === tsConstValue.toString() ); } @@ -519,9 +533,7 @@ export class TsUtils { tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression ): boolean { const tsConstValue = this.tsTypeChecker.getConstantValue(tsExpr); - return ( - tsConstValue !== undefined && typeof tsConstValue === 'string' - ); + return tsConstValue !== undefined && typeof tsConstValue === 'string'; } // Returns true iff typeA is a subtype of typeB @@ -533,12 +545,10 @@ export class TsUtils { if (!typeA.symbol || !typeA.symbol.declarations) return false; for (let typeADecl of typeA.symbol.declarations) { - if ( - (!ts.isClassDeclaration(typeADecl) && !ts.isInterfaceDeclaration(typeADecl)) || - !typeADecl.heritageClauses - ) continue; + if ((!ts.isClassDeclaration(typeADecl) && !ts.isInterfaceDeclaration(typeADecl)) || !typeADecl.heritageClauses) + continue; for (let heritageClause of typeADecl.heritageClauses) { - let processInterfaces = typeA.isClass() ? (heritageClause.token != ts.SyntaxKind.ExtendsKeyword) : true; + let processInterfaces = typeA.isClass() ? heritageClause.token != ts.SyntaxKind.ExtendsKeyword : true; if (this.processParentTypes(heritageClause.types, typeB, processInterfaces)) return true; } } @@ -547,8 +557,12 @@ export class TsUtils { } // return true if two class types are not related by inheritance and structural identity check is needed - public needToDeduceStructuralIdentity(lhsType: ts.Type, rhsType: ts.Type, rhsExpr: ts.Expression, - allowPromotion: boolean = false): boolean { + public needToDeduceStructuralIdentity( + lhsType: ts.Type, + rhsType: ts.Type, + rhsExpr: ts.Expression, + allowPromotion: boolean = false + ): boolean { // Compare non-nullable version of types. lhsType = this.getNonNullableType(lhsType); rhsType = this.getNonNullableType(rhsType); @@ -581,12 +595,20 @@ export class TsUtils { return true; } - if (this.advancedClassChecks && this.isClassValueType(rhsType) && lhsType != rhsType && !this.isObjectType(lhsType)) { + if ( + this.advancedClassChecks && + this.isClassValueType(rhsType) && + lhsType != rhsType && + !this.isObjectType(lhsType) + ) { // missing exact rule return true; } - let res = lhsType.isClassOrInterface() && rhsType.isClassOrInterface() && !this.relatedByInheritanceOrIdentical(rhsType, lhsType); + let res = + lhsType.isClassOrInterface() && + rhsType.isClassOrInterface() && + !this.relatedByInheritanceOrIdentical(rhsType, lhsType); if (allowPromotion) { res &&= !this.relatedByInheritanceOrIdentical(lhsType, rhsType); @@ -595,11 +617,16 @@ export class TsUtils { return res; } - private processParentTypes(parentTypes: ts.NodeArray, typeB: ts.Type, processInterfaces: boolean): boolean { + private processParentTypes( + parentTypes: ts.NodeArray, + typeB: ts.Type, + processInterfaces: boolean + ): boolean { for (let baseTypeExpr of parentTypes) { let baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeExpr); if (this.isTypeReference(baseType) && baseType.target !== baseType) baseType = baseType.target; - if (baseType && (baseType.isClass() != processInterfaces) && this.relatedByInheritanceOrIdentical(baseType, typeB)) return true; + if (baseType && baseType.isClass() != processInterfaces && this.relatedByInheritanceOrIdentical(baseType, typeB)) + return true; } return false; } @@ -621,7 +648,7 @@ export class TsUtils { if (!tsType) { return false; } - if (tsType.symbol && (tsType.isClassOrInterface() && tsType.symbol.name === 'Object')) { + if (tsType.symbol && tsType.isClassOrInterface() && tsType.symbol.name === 'Object') { return true; } let node = this.tsTypeChecker.typeToTypeNode(tsType, undefined, undefined); @@ -648,7 +675,8 @@ export class TsUtils { type.symbol.members.forEach((value, key) => { if ( - value.declarations !== undefined && value.declarations.length > 0 && + value.declarations !== undefined && + value.declarations.length > 0 && ts.isPropertyDeclaration(value.declarations[0]) ) { let propmMods = ts.getModifiers(value.declarations[0] as ts.PropertyDeclaration); @@ -689,8 +717,7 @@ export class TsUtils { if (type.isClass() && type.symbol.declarations && type.symbol.declarations.length > 0) { let declClass = type.symbol.declarations[0] as ts.ClassDeclaration; let classMods = ts.getModifiers(declClass); - if (this.hasModifier(classMods, ts.SyntaxKind.AbstractKeyword)) - return true; + if (this.hasModifier(classMods, ts.SyntaxKind.AbstractKeyword)) return true; } return false; @@ -702,8 +729,10 @@ export class TsUtils { } type = this.getTargetType(type); return ( - type.isClassOrInterface() && this.hasDefaultCtor(type) && - !this.hasReadonlyFields(type) && !this.isAbstractClass(type) + type.isClassOrInterface() && + this.hasDefaultCtor(type) && + !this.hasReadonlyFields(type) && + !this.isAbstractClass(type) ); } @@ -792,7 +821,9 @@ export class TsUtils { return this.validateRecordObjectKeys(rhsExpr); } - return this.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr); + return ( + this.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr) + ); } isFunctionalType(type: ts.Type): boolean { @@ -805,8 +836,7 @@ export class TsUtils { let rhsSym = ts.isCallExpression(rhsExpr) ? this.getSymbolOfCallExpression(rhsExpr) : this.trueSymbolAtLocation(rhsExpr); - if (rhsSym && this.isLibrarySymbol(rhsSym)) - return true; + if (rhsSym && this.isLibrarySymbol(rhsSym)) return true; } return false; } @@ -818,7 +848,7 @@ export class TsUtils { return false; } } - }; + } return true; } @@ -835,7 +865,7 @@ export class TsUtils { if (ts.isObjectLiteralExpression(initExpr)) { if (!this.isObjectLiteralAssignable(propType, initExpr)) { return false; - } + } } else { // Only check for structural sub-typing. if (this.needToDeduceStructuralIdentity(propType, this.tsTypeChecker.getTypeAtLocation(initExpr), initExpr)) { @@ -854,15 +884,21 @@ export class TsUtils { } getTargetType(type: ts.Type): ts.Type { - return (type.getFlags() & ts.TypeFlags.Object) && - (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference ? (type as ts.TypeReference).target : type; + return type.getFlags() & ts.TypeFlags.Object && (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference + ? (type as ts.TypeReference).target + : type; } private isSupportedTypeNodeKind(kind: ts.SyntaxKind): boolean { - return kind !== ts.SyntaxKind.AnyKeyword && kind !== ts.SyntaxKind.UnknownKeyword && - kind !== ts.SyntaxKind.SymbolKeyword && kind !== ts.SyntaxKind.IndexedAccessType && - kind !== ts.SyntaxKind.ConditionalType && kind !== ts.SyntaxKind.MappedType && - kind !== ts.SyntaxKind.InferType; + return ( + kind !== ts.SyntaxKind.AnyKeyword && + kind !== ts.SyntaxKind.UnknownKeyword && + kind !== ts.SyntaxKind.SymbolKeyword && + kind !== ts.SyntaxKind.IndexedAccessType && + kind !== ts.SyntaxKind.ConditionalType && + kind !== ts.SyntaxKind.MappedType && + kind !== ts.SyntaxKind.InferType + ); } public isSupportedType(typeNode: ts.TypeNode): boolean { @@ -871,14 +907,12 @@ export class TsUtils { if (ts.isArrayTypeNode(typeNode)) return this.isSupportedType(typeNode.elementType); if (ts.isTypeReferenceNode(typeNode) && typeNode.typeArguments) { - for (const typeArg of typeNode.typeArguments) - if (!this.isSupportedType(typeArg)) return false; + for (const typeArg of typeNode.typeArguments) if (!this.isSupportedType(typeArg)) return false; return true; } if (ts.isUnionTypeNode(typeNode)) { - for (const unionTypeElem of typeNode.types) - if (!this.isSupportedType(unionTypeElem)) return false; + for (const unionTypeElem of typeNode.types) if (!this.isSupportedType(unionTypeElem)) return false; return true; } @@ -890,8 +924,12 @@ export class TsUtils { return true; } - return !ts.isTypeLiteralNode(typeNode) && (this.advancedClassChecks || !ts.isTypeQueryNode(typeNode)) && - !ts.isIntersectionTypeNode(typeNode) && this.isSupportedTypeNodeKind(typeNode.kind); + return ( + !ts.isTypeLiteralNode(typeNode) && + (this.advancedClassChecks || !ts.isTypeQueryNode(typeNode)) && + !ts.isIntersectionTypeNode(typeNode) && + this.isSupportedTypeNodeKind(typeNode.kind) + ); } public isStructObjectInitializer(objectLiteral: ts.ObjectLiteralExpression): boolean { @@ -906,7 +944,7 @@ export class TsUtils { public getParentSymbolName(symbol: ts.Symbol): string | undefined { const name = this.tsTypeChecker.getFullyQualifiedName(symbol); const dotPosition = name.lastIndexOf('.'); - return (dotPosition === -1) ? undefined : name.substring(0, dotPosition); + return dotPosition === -1 ? undefined : name.substring(0, dotPosition); } public isGlobalSymbol(symbol: ts.Symbol): boolean { @@ -920,12 +958,12 @@ export class TsUtils { } public isStdSymbol(symbol: ts.Symbol): boolean { - const name = this.tsTypeChecker.getFullyQualifiedName(symbol) + const name = this.tsTypeChecker.getFullyQualifiedName(symbol); return name === 'Symbol' && this.isGlobalSymbol(symbol); } public isSymbolIterator(symbol: ts.Symbol): boolean { - return this.isSymbolAPI(symbol) && symbol.name === 'iterator' + return this.isSymbolAPI(symbol) && symbol.name === 'iterator'; } public isDefaultImport(importSpec: ts.ImportSpecifier): boolean { @@ -933,13 +971,15 @@ export class TsUtils { } public getStartPos(nodeOrComment: ts.Node | ts.CommentRange): number { - return (nodeOrComment.kind === ts.SyntaxKind.SingleLineCommentTrivia || nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia) + return nodeOrComment.kind === ts.SyntaxKind.SingleLineCommentTrivia || + nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? (nodeOrComment as ts.CommentRange).pos : (nodeOrComment as ts.Node).getStart(); } public getEndPos(nodeOrComment: ts.Node | ts.CommentRange): number { - return (nodeOrComment.kind === ts.SyntaxKind.SingleLineCommentTrivia || nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia) + return nodeOrComment.kind === ts.SyntaxKind.SingleLineCommentTrivia || + nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? (nodeOrComment as ts.CommentRange).end : (nodeOrComment as ts.Node).getEnd(); } @@ -977,7 +1017,7 @@ export class TsUtils { const sym = type.aliasSymbol; return !!sym && sym.getName() === 'Required' && this.isGlobalSymbol(sym); } - + public isStdReadonlyType(type: ts.Type): boolean { const sym = type.aliasSymbol; return !!sym && sym.getName() === 'Readonly' && this.isGlobalSymbol(sym); @@ -1006,16 +1046,16 @@ export class TsUtils { if (!srcFile) { return false; } - const fileName = srcFile.fileName + const fileName = srcFile.fileName; // Symbols from both *.ts and *.d.ts files should obey interop rules. // We disable such behavior for *.ts files in the test mode due to lack of 'ets' // extension support. const ext = path.extname(fileName).toLowerCase(); const isThirdPartyCode = - ARKTS_IGNORE_DIRS.some(ignore => pathContainsDirectory(path.normalize(fileName), ignore)) || - ARKTS_IGNORE_FILES.some(ignore => path.basename(fileName) === ignore); - const isEts = (ext === '.ets'); - const isTs = (ext === '.ts' && !srcFile.isDeclarationFile); + ARKTS_IGNORE_DIRS.some((ignore) => pathContainsDirectory(path.normalize(fileName), ignore)) || + ARKTS_IGNORE_FILES.some((ignore) => path.basename(fileName) === ignore); + const isEts = ext === '.ets'; + const isTs = ext === '.ts' && !srcFile.isDeclarationFile; const isStatic = (isEts || (isTs && this.testMode)) && !isThirdPartyCode; const isStdLib = STANDARD_LIBRARIES.includes(path.basename(fileName).toLowerCase()); // We still need to confirm support for certain API from the @@ -1041,7 +1081,7 @@ export class TsUtils { if (type.isUnion()) { for (let compType of type.types) { - let isDynamic = this.isDynamicType(compType); + let isDynamic = this.isDynamicType(compType); if (isDynamic || isDynamic === undefined) { return isDynamic; } @@ -1061,7 +1101,7 @@ export class TsUtils { } public isObjectType(type: ts.Type): type is ts.ObjectType { - return !!(type.flags & ts.TypeFlags.Object) + return !!(type.flags & ts.TypeFlags.Object); } private isAnonymous(type: ts.Type): boolean { @@ -1082,7 +1122,7 @@ export class TsUtils { while (ts.isObjectLiteralExpression(curNode) || ts.isArrayLiteralExpression(curNode)) { const exprType = this.tsTypeChecker.getContextualType(curNode); if (exprType !== undefined && !this.isAnonymous(exprType)) { - const res = this.isDynamicType(exprType) + const res = this.isDynamicType(exprType); if (res !== undefined) { return res; } @@ -1098,14 +1138,14 @@ export class TsUtils { // foo({ ... }) if (ts.isCallExpression(curNode)) { const callExpr = curNode as ts.CallExpression; - const type = this.tsTypeChecker.getTypeAtLocation(callExpr.expression) + const type = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); if (this.isAnyType(type)) { return true; } let sym: ts.Symbol | undefined = type.symbol; - if(this.isLibrarySymbol(sym)) { + if (this.isLibrarySymbol(sym)) { return true; } @@ -1134,12 +1174,16 @@ export class TsUtils { } public isEsObjectType(typeNode: ts.TypeNode | undefined): boolean { - return !!typeNode && ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName) && - typeNode.typeName.text == ES_OBJECT; + return ( + !!typeNode && + ts.isTypeReferenceNode(typeNode) && + ts.isIdentifier(typeNode.typeName) && + typeNode.typeName.text == ES_OBJECT + ); } public isInsideBlock(node: ts.Node): boolean { - let par = node.parent + let par = node.parent; while (par) { if (ts.isBlock(par)) { return true; @@ -1158,7 +1202,7 @@ export class TsUtils { return false; } const valueType = this.tsTypeChecker.getTypeAtLocation(node); - return this.isUnsupportedType(valueType) || this.isAnonymousType(valueType) + return this.isUnsupportedType(valueType) || this.isAnonymousType(valueType); } public getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { @@ -1178,7 +1222,7 @@ export class TsUtils { } public hasEsObjectType(node: ts.Node): boolean { - const typeNode = this.getVariableDeclarationTypeNode(node) + const typeNode = this.getVariableDeclarationTypeNode(node); return typeNode !== undefined && this.isEsObjectType(typeNode); } @@ -1189,8 +1233,12 @@ export class TsUtils { public isEsObjectSymbol(sym: ts.Symbol): boolean { let decl = this.getDeclaration(sym); - return !!decl && ts.isTypeAliasDeclaration(decl) && decl.name.escapedText == ES_OBJECT && - decl.type.kind === ts.SyntaxKind.AnyKeyword; + return ( + !!decl && + ts.isTypeAliasDeclaration(decl) && + decl.name.escapedText == ES_OBJECT && + decl.type.kind === ts.SyntaxKind.AnyKeyword + ); } public isAnonymousType(type: ts.Type): boolean { @@ -1203,8 +1251,9 @@ export class TsUtils { return false; } - return (type.flags & ts.TypeFlags.Object) !== 0 && - ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) !== 0; + return ( + (type.flags & ts.TypeFlags.Object) !== 0 && ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) !== 0 + ); } public getSymbolOfCallExpression(callExpr: ts.CallExpression): ts.Symbol | undefined { @@ -1247,7 +1296,10 @@ export class TsUtils { } public isClassValueType(type: ts.Type): boolean { - if ((type.flags & ts.TypeFlags.Object) === 0 || ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) === 0) { + if ( + (type.flags & ts.TypeFlags.Object) === 0 || + ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) === 0 + ) { return false; } return type.symbol && (type.symbol.flags & ts.SymbolFlags.Class) !== 0; diff --git a/linter/src/utils/consts/AllowedStdSymbolAPI.ts b/linter/src/utils/consts/AllowedStdSymbolAPI.ts index 69c95812a..6af85d868 100644 --- a/linter/src/utils/consts/AllowedStdSymbolAPI.ts +++ b/linter/src/utils/consts/AllowedStdSymbolAPI.ts @@ -13,4 +13,4 @@ * limitations under the License. */ -export const ALLOWED_STD_SYMBOL_API = ['iterator']; +export const ALLOWED_STD_SYMBOL_API = ['iterator']; diff --git a/linter/src/utils/consts/ArkUIDecorators.ts b/linter/src/utils/consts/ArkUIDecorators.ts index b60a1f522..295314fe4 100644 --- a/linter/src/utils/consts/ArkUIDecorators.ts +++ b/linter/src/utils/consts/ArkUIDecorators.ts @@ -36,5 +36,5 @@ export const ARKUI_DECORATORS = [ 'StorageLink', 'StorageProp', 'Styles', - 'Watch', + 'Watch' ]; diff --git a/linter/src/utils/consts/ESObject.ts b/linter/src/utils/consts/ESObject.ts index e1c9a2b10..2837d1cea 100644 --- a/linter/src/utils/consts/ESObject.ts +++ b/linter/src/utils/consts/ESObject.ts @@ -13,4 +13,4 @@ * limitations under the License. */ -export const ES_OBJECT = 'ESObject' +export const ES_OBJECT = 'ESObject'; diff --git a/linter/src/utils/consts/LimitedStandardUtilityTypes.ts b/linter/src/utils/consts/LimitedStandardUtilityTypes.ts index ba9181506..a9853ecb4 100644 --- a/linter/src/utils/consts/LimitedStandardUtilityTypes.ts +++ b/linter/src/utils/consts/LimitedStandardUtilityTypes.ts @@ -14,7 +14,21 @@ */ export const LIMITED_STANDARD_UTILITY_TYPES = [ - 'Awaited', 'Pick', 'Omit', 'Exclude', 'Extract', 'NonNullable', 'Parameters', - 'ConstructorParameters', 'ReturnType', 'InstanceType', 'ThisParameterType', 'OmitThisParameter', - 'ThisType', 'Uppercase', 'Lowercase', 'Capitalize', 'Uncapitalize', + 'Awaited', + 'Pick', + 'Omit', + 'Exclude', + 'Extract', + 'NonNullable', + 'Parameters', + 'ConstructorParameters', + 'ReturnType', + 'InstanceType', + 'ThisParameterType', + 'OmitThisParameter', + 'ThisType', + 'Uppercase', + 'Lowercase', + 'Capitalize', + 'Uncapitalize' ]; diff --git a/linter/src/utils/consts/LimitedStdGlobalFunc.ts b/linter/src/utils/consts/LimitedStdGlobalFunc.ts index 841b81dda..7000b1681 100644 --- a/linter/src/utils/consts/LimitedStdGlobalFunc.ts +++ b/linter/src/utils/consts/LimitedStdGlobalFunc.ts @@ -13,6 +13,4 @@ * limitations under the License. */ -export const LIMITED_STD_GLOBAL_FUNC = [ - 'eval' -]; +export const LIMITED_STD_GLOBAL_FUNC = ['eval']; diff --git a/linter/src/utils/consts/LimitedStdObjectAPI.ts b/linter/src/utils/consts/LimitedStdObjectAPI.ts index 55b7ffede..1f82add5f 100644 --- a/linter/src/utils/consts/LimitedStdObjectAPI.ts +++ b/linter/src/utils/consts/LimitedStdObjectAPI.ts @@ -14,9 +14,29 @@ */ export const LIMITED_STD_OBJECT_API = [ - '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'assign', 'create', - 'defineProperties', 'defineProperty', 'freeze', 'fromEntries', 'getOwnPropertyDescriptor', - 'getOwnPropertyDescriptors', 'getOwnPropertySymbols', 'getPrototypeOf', - 'hasOwnProperty', 'is', 'isExtensible', 'isFrozen', 'isPrototypeOf', 'isSealed', 'preventExtensions', - 'propertyIsEnumerable', 'seal', 'setPrototypeOf' + '__proto__', + '__defineGetter__', + '__defineSetter__', + '__lookupGetter__', + '__lookupSetter__', + 'assign', + 'create', + 'defineProperties', + 'defineProperty', + 'freeze', + 'fromEntries', + 'getOwnPropertyDescriptor', + 'getOwnPropertyDescriptors', + 'getOwnPropertySymbols', + 'getPrototypeOf', + 'hasOwnProperty', + 'is', + 'isExtensible', + 'isFrozen', + 'isPrototypeOf', + 'isSealed', + 'preventExtensions', + 'propertyIsEnumerable', + 'seal', + 'setPrototypeOf' ]; diff --git a/linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts b/linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts index 7113b2b5c..ea8675a5d 100644 --- a/linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts +++ b/linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts @@ -14,6 +14,17 @@ */ export const LIMITED_STD_PROXYHANDLER_API = [ - 'apply', 'construct', 'defineProperty', 'deleteProperty', 'get', 'getOwnPropertyDescriptor', 'getPrototypeOf', - 'has', 'isExtensible', 'ownKeys', 'preventExtensions', 'set', 'setPrototypeOf' + 'apply', + 'construct', + 'defineProperty', + 'deleteProperty', + 'get', + 'getOwnPropertyDescriptor', + 'getPrototypeOf', + 'has', + 'isExtensible', + 'ownKeys', + 'preventExtensions', + 'set', + 'setPrototypeOf' ]; diff --git a/linter/src/utils/consts/LimitedStdReflectAPI.ts b/linter/src/utils/consts/LimitedStdReflectAPI.ts index e1f58f802..c5db6d293 100644 --- a/linter/src/utils/consts/LimitedStdReflectAPI.ts +++ b/linter/src/utils/consts/LimitedStdReflectAPI.ts @@ -14,6 +14,13 @@ */ export const LIMITED_STD_REFLECT_API = [ - 'apply', 'construct', 'defineProperty', 'deleteProperty', 'getOwnPropertyDescriptor', 'getPrototypeOf', - 'isExtensible', 'preventExtensions', 'setPrototypeOf' + 'apply', + 'construct', + 'defineProperty', + 'deleteProperty', + 'getOwnPropertyDescriptor', + 'getPrototypeOf', + 'isExtensible', + 'preventExtensions', + 'setPrototypeOf' ]; diff --git a/linter/src/utils/consts/NonInitializablePropertyDecorators.ts b/linter/src/utils/consts/NonInitializablePropertyDecorators.ts index 251272c14..670ccb67d 100644 --- a/linter/src/utils/consts/NonInitializablePropertyDecorators.ts +++ b/linter/src/utils/consts/NonInitializablePropertyDecorators.ts @@ -15,4 +15,4 @@ export const NON_INITIALIZABLE_PROPERTY_DECORATORS = ['Link', 'Consume', 'ObjectLink', 'Prop', 'BuilderParam']; -export const NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS = ['CustomDialog'] +export const NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS = ['CustomDialog']; diff --git a/linter/src/utils/consts/StandardLibraries.ts b/linter/src/utils/consts/StandardLibraries.ts index 229ffefbf..2776e4ee7 100644 --- a/linter/src/utils/consts/StandardLibraries.ts +++ b/linter/src/utils/consts/StandardLibraries.ts @@ -14,18 +14,58 @@ */ export const STANDARD_LIBRARIES = [ - 'lib.dom.d.ts', 'lib.dom.iterable.d.ts', 'lib.webworker.d.ts', 'lib.webworker.importscripts.d.ts', - 'lib.webworker.iterable.d.ts', 'lib.scripthost.d.ts', 'lib.decorators.d.ts', 'lib.decorators.legacy.d.ts', - 'lib.es5.d.ts', 'lib.es2015.core.d.ts', 'lib.es2015.collection.d.ts', 'lib.es2015.generator.d.ts', - 'lib.es2015.iterable.d.ts', 'lib.es2015.promise.d.ts', 'lib.es2015.proxy.d.ts', 'lib.es2015.reflect.d.ts', - 'lib.es2015.symbol.d.ts', 'lib.es2015.symbol.wellknown.d.ts', 'lib.es2016.array.include.d.ts', - 'lib.es2017.object.d.ts', 'lib.es2017.sharedmemory.d.ts', 'lib.es2017.string.d.ts', 'lib.es2017.intl.d.ts', - 'lib.es2017.typedarrays.d.ts', 'lib.es2018.asyncgenerator.d.ts', 'lib.es2018.asynciterable.d.ts', - 'lib.es2018.intl.d.ts', 'lib.es2018.promise.d.ts', 'lib.es2018.regexp.d.ts', 'lib.es2019.array.d.ts', - 'lib.es2019.object.d.ts', 'lib.es2019.string.d.ts', 'lib.es2019.symbol.d.ts', 'lib.es2019.intl.d.ts', - 'lib.es2020.bigint.d.ts', 'lib.es2020.date.d.ts', 'lib.es2020.promise.d.ts', 'lib.es2020.sharedmemory.d.ts', - 'lib.es2020.string.d.ts', 'lib.es2020.symbol.wellknown.d.ts', 'lib.es2020.intl.d.ts', 'lib.es2020.number.d.ts', - 'lib.es2021.promise.d.ts', 'lib.es2021.string.d.ts', 'lib.es2021.weakref.d.ts', 'lib.es2021.intl.d.ts', - 'lib.es2022.array.d.ts', 'lib.es2022.error.d.ts', 'lib.es2022.intl.d.ts', 'lib.es2022.object.d.ts', - 'lib.es2022.sharedmemory.d.ts', 'lib.es2022.string.d.ts', 'lib.es2022.regexp.d.ts', 'lib.es2023.array.d.ts', + 'lib.dom.d.ts', + 'lib.dom.iterable.d.ts', + 'lib.webworker.d.ts', + 'lib.webworker.importscripts.d.ts', + 'lib.webworker.iterable.d.ts', + 'lib.scripthost.d.ts', + 'lib.decorators.d.ts', + 'lib.decorators.legacy.d.ts', + 'lib.es5.d.ts', + 'lib.es2015.core.d.ts', + 'lib.es2015.collection.d.ts', + 'lib.es2015.generator.d.ts', + 'lib.es2015.iterable.d.ts', + 'lib.es2015.promise.d.ts', + 'lib.es2015.proxy.d.ts', + 'lib.es2015.reflect.d.ts', + 'lib.es2015.symbol.d.ts', + 'lib.es2015.symbol.wellknown.d.ts', + 'lib.es2016.array.include.d.ts', + 'lib.es2017.object.d.ts', + 'lib.es2017.sharedmemory.d.ts', + 'lib.es2017.string.d.ts', + 'lib.es2017.intl.d.ts', + 'lib.es2017.typedarrays.d.ts', + 'lib.es2018.asyncgenerator.d.ts', + 'lib.es2018.asynciterable.d.ts', + 'lib.es2018.intl.d.ts', + 'lib.es2018.promise.d.ts', + 'lib.es2018.regexp.d.ts', + 'lib.es2019.array.d.ts', + 'lib.es2019.object.d.ts', + 'lib.es2019.string.d.ts', + 'lib.es2019.symbol.d.ts', + 'lib.es2019.intl.d.ts', + 'lib.es2020.bigint.d.ts', + 'lib.es2020.date.d.ts', + 'lib.es2020.promise.d.ts', + 'lib.es2020.sharedmemory.d.ts', + 'lib.es2020.string.d.ts', + 'lib.es2020.symbol.wellknown.d.ts', + 'lib.es2020.intl.d.ts', + 'lib.es2020.number.d.ts', + 'lib.es2021.promise.d.ts', + 'lib.es2021.string.d.ts', + 'lib.es2021.weakref.d.ts', + 'lib.es2021.intl.d.ts', + 'lib.es2022.array.d.ts', + 'lib.es2022.error.d.ts', + 'lib.es2022.intl.d.ts', + 'lib.es2022.object.d.ts', + 'lib.es2022.sharedmemory.d.ts', + 'lib.es2022.string.d.ts', + 'lib.es2022.regexp.d.ts', + 'lib.es2023.array.d.ts' ]; diff --git a/linter/src/utils/consts/TypedArrays.ts b/linter/src/utils/consts/TypedArrays.ts index 9ef717311..c29dd2b73 100644 --- a/linter/src/utils/consts/TypedArrays.ts +++ b/linter/src/utils/consts/TypedArrays.ts @@ -24,5 +24,5 @@ export const TYPED_ARRAYS = [ 'Float32Array', 'Float64Array', 'BigInt64Array', - 'BigUint64Array', -] + 'BigUint64Array' +]; diff --git a/linter/src/utils/functions/DiagnosticChecker.ts b/linter/src/utils/functions/DiagnosticChecker.ts index 841d0d5b4..820d24a3e 100644 --- a/linter/src/utils/functions/DiagnosticChecker.ts +++ b/linter/src/utils/functions/DiagnosticChecker.ts @@ -17,4 +17,4 @@ import * as ts from 'typescript'; export interface DiagnosticChecker { checkDiagnosticMessage(msgText: string | ts.DiagnosticMessageChain): boolean; -} \ No newline at end of file +} diff --git a/linter/src/utils/functions/GetScriptKind.ts b/linter/src/utils/functions/GetScriptKind.ts index e1bedc1b3..98643872d 100644 --- a/linter/src/utils/functions/GetScriptKind.ts +++ b/linter/src/utils/functions/GetScriptKind.ts @@ -17,8 +17,8 @@ import * as ts from 'typescript'; import * as path from 'node:path'; export function getScriptKind(srcFile: ts.SourceFile): ts.ScriptKind { - const fileName = srcFile.fileName - const ext = path.extname(fileName).toLowerCase() + const fileName = srcFile.fileName; + const ext = path.extname(fileName).toLowerCase(); switch (ext) { case ts.Extension.Ts: return ts.ScriptKind.TS; @@ -33,4 +33,4 @@ export function getScriptKind(srcFile: ts.SourceFile): ts.ScriptKind { default: return ts.ScriptKind.Unknown; } -} \ No newline at end of file +} diff --git a/linter/src/utils/functions/IsStdLibrary.ts b/linter/src/utils/functions/IsStdLibrary.ts index 95c15e4a4..8471acb26 100644 --- a/linter/src/utils/functions/IsStdLibrary.ts +++ b/linter/src/utils/functions/IsStdLibrary.ts @@ -27,4 +27,4 @@ export function isStdLibrarySymbol(sym: ts.Symbol | undefined) { return srcFile && STANDARD_LIBRARIES.includes(path.basename(srcFile.fileName).toLowerCase()); } return false; -} \ No newline at end of file +} diff --git a/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts b/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts index 3adf03b3e..1fee64b82 100644 --- a/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts +++ b/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts @@ -19,14 +19,17 @@ import { DiagnosticChecker } from './DiagnosticChecker'; // Current approach relates on error code and error message matching and it is quite fragile, // so this place should be checked thoroughly in the case of typescript upgrade export const TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE = 2322; -export const TYPE_UNKNOWN_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE = /^Type '(.*)\bunknown\b(.*)' is not assignable to type '.*'\.$/; +export const TYPE_UNKNOWN_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE = + /^Type '(.*)\bunknown\b(.*)' is not assignable to type '.*'\.$/; export const TYPE_NULL_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE = /^Type 'null' is not assignable to type '.*'\.$/; export const TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE = /^Type 'undefined' is not assignable to type '.*'\.$/; export const ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE = 2345; export const NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE = 2769; -export const ARGUMENT_OF_TYPE_NULL_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE = /^Argument of type 'null' is not assignable to parameter of type '.*'\.$/; -export const ARGUMENT_OF_TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE = /^Argument of type 'undefined' is not assignable to parameter of type '.*'\.$/; +export const ARGUMENT_OF_TYPE_NULL_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE = + /^Argument of type 'null' is not assignable to parameter of type '.*'\.$/; +export const ARGUMENT_OF_TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE = + /^Argument of type 'undefined' is not assignable to parameter of type '.*'\.$/; export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { inLibCall: boolean = false; @@ -36,7 +39,7 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { constructor(filteredDiagnosticMessages: Set) { this.filteredDiagnosticMessages = filteredDiagnosticMessages; } - + configure(inLibCall: boolean, diagnosticMessages: Array) { this.inLibCall = inLibCall; this.diagnosticMessages = diagnosticMessages; @@ -44,7 +47,8 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { checkMessageText(msg: string): boolean { if (this.inLibCall) { - const match = msg.match(ARGUMENT_OF_TYPE_NULL_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE) || + const match = + msg.match(ARGUMENT_OF_TYPE_NULL_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE) || msg.match(ARGUMENT_OF_TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE) || msg.match(TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE) || msg.match(TYPE_NULL_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE); @@ -66,15 +70,21 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { } } if (chain.code == ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE) { - if (this.inLibCall && chain.messageText.match(ARGUMENT_OF_TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE)) { + if ( + this.inLibCall && + chain.messageText.match(ARGUMENT_OF_TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE) + ) { return false; } - if (this.inLibCall && chain.messageText.match(ARGUMENT_OF_TYPE_NULL_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE)) { + if ( + this.inLibCall && + chain.messageText.match(ARGUMENT_OF_TYPE_NULL_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE) + ) { return false; } } return chain.next == undefined ? true : this.checkMessageChain(chain.next[0]); - }; + } checkFilteredDiagnosticMessages(msgText: ts.DiagnosticMessageChain | string) { if (this.filteredDiagnosticMessages.size == 0) { @@ -108,8 +118,8 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { return true; } - curMsg = curMsg.next ? curMsg.next[0]: undefined; - curFilteredMsg = curFilteredMsg.next ? curFilteredMsg.next[0]: undefined; + curMsg = curMsg.next ? curMsg.next[0] : undefined; + curFilteredMsg = curFilteredMsg.next ? curFilteredMsg.next[0] : undefined; } return false; @@ -136,4 +146,4 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { } return true; } -} \ No newline at end of file +} diff --git a/linter/src/utils/functions/LinterInfo.ts b/linter/src/utils/functions/LinterInfo.ts index 9699dab3c..61f875ba2 100644 --- a/linter/src/utils/functions/LinterInfo.ts +++ b/linter/src/utils/functions/LinterInfo.ts @@ -13,18 +13,18 @@ * limitations under the License. */ -import { ProblemInfo } from '../../ProblemInfo'; -import { AutofixInfo } from '../../autofixes/AutofixInfo'; +import type { ProblemInfo } from '../../ProblemInfo'; +import type { AutofixInfo } from '../../autofixes/AutofixInfo'; export function encodeProblemInfo(problem: ProblemInfo): string { return `${problem.problem}%${problem.start}%${problem.end}`; } export function decodeAutofixInfo(info: string): AutofixInfo { - let infos = info.split('%'); + const infos = info.split('%'); return { problemID: infos[0], start: Number.parseInt(infos[1]), - end: Number.parseInt(infos[2]), + end: Number.parseInt(infos[2]) }; } diff --git a/linter/src/utils/functions/MergeArrayMaps.ts b/linter/src/utils/functions/MergeArrayMaps.ts index 7eb70c55a..3e9a98fa3 100644 --- a/linter/src/utils/functions/MergeArrayMaps.ts +++ b/linter/src/utils/functions/MergeArrayMaps.ts @@ -13,10 +13,7 @@ * limitations under the License. */ -export function mergeArrayMaps( - lhs: Map, - rhs: Map -): Map { +export function mergeArrayMaps(lhs: Map, rhs: Map): Map { if (lhs.size == 0) { return rhs; } diff --git a/linter/src/utils/functions/PathHelper.ts b/linter/src/utils/functions/PathHelper.ts index d4e3f566a..46b5ff253 100644 --- a/linter/src/utils/functions/PathHelper.ts +++ b/linter/src/utils/functions/PathHelper.ts @@ -22,4 +22,4 @@ export function pathContainsDirectory(path: string, dir: string): boolean { } } return false; -} \ No newline at end of file +} diff --git a/linter/src/utils/functions/identiferUseInValueContext.ts b/linter/src/utils/functions/identiferUseInValueContext.ts index 96a762c2d..0a8d82bc6 100644 --- a/linter/src/utils/functions/identiferUseInValueContext.ts +++ b/linter/src/utils/functions/identiferUseInValueContext.ts @@ -16,22 +16,24 @@ import * as ts from 'typescript'; function isInstanceofContext(tsIdentStart: ts.Node): boolean { - return ts.isBinaryExpression(tsIdentStart.parent) && + return ( + ts.isBinaryExpression(tsIdentStart.parent) && tsIdentStart.parent.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword + ); } function isNewExpressionContext(tsIdentStart: ts.Node): boolean { - return ts.isNewExpression(tsIdentStart.parent) && tsIdentStart === tsIdentStart.parent.expression + return ts.isNewExpression(tsIdentStart.parent) && tsIdentStart === tsIdentStart.parent.expression; } function isQualifiedNameContext(tsIdentStart: ts.Node, tsIdentifier: ts.Identifier): boolean { // rightmost in AST is rightmost in qualified name chain - return ts.isQualifiedName(tsIdentStart) && tsIdentifier !== tsIdentStart.right + return ts.isQualifiedName(tsIdentStart) && tsIdentifier !== tsIdentStart.right; } function isPropertyAccessContext(tsIdentStart: ts.Node, tsIdentifier: ts.Identifier): boolean { // rightmost in AST is rightmost in qualified name chain - return ts.isPropertyAccessExpression(tsIdentStart) && tsIdentifier !== tsIdentStart.name + return ts.isPropertyAccessExpression(tsIdentStart) && tsIdentifier !== tsIdentStart.name; } function getQualifiedStart(ident: ts.Node): ts.Node { @@ -43,41 +45,44 @@ function getQualifiedStart(ident: ts.Node): ts.Node { } function isEnumPropAccess(ident: ts.Identifier, tsSym: ts.Symbol, context: ts.Node): boolean { - return ts.isElementAccessExpression(context) && !!(tsSym.flags & ts.SymbolFlags.Enum) && + return ( + ts.isElementAccessExpression(context) && + !!(tsSym.flags & ts.SymbolFlags.Enum) && (context.expression == ident || - (ts.isPropertyAccessExpression(context.expression) && context.expression.name == ident)); + (ts.isPropertyAccessExpression(context.expression) && context.expression.name == ident)) + ); } function isValidTypeNode(node: ts.TypeNode): boolean { return !ts.isTypeOfExpression(node); } -export function identiferUseInValueContext( - ident: ts.Identifier, tsSym: ts.Symbol -) { +export function identiferUseInValueContext(ident: ts.Identifier, tsSym: ts.Symbol) { let qualifiedStart = getQualifiedStart(ident); let parent = qualifiedStart.parent; return !( // treat TypeQuery as valid because it's already forbidden (FaultID.TypeQuery) - ts.isTypeNode(parent) && isValidTypeNode(parent) || - // If identifier is the right-most name of Property Access chain or Qualified name, - // or it's a separate identifier expression, then identifier is being referenced as an value. - isEnumPropAccess(ident, tsSym, parent) || - ts.isExpressionWithTypeArguments(parent) || - ts.isExportAssignment(parent) || - ts.isExportSpecifier(parent) || - ts.isMetaProperty(parent) || - ts.isImportClause(parent) || - ts.isClassLike(parent) || - ts.isInterfaceDeclaration(parent) || - ts.isModuleDeclaration(parent) || - ts.isEnumDeclaration(parent) || - ts.isNamespaceImport(parent) || - ts.isImportSpecifier(parent) || - isQualifiedNameContext(qualifiedStart, ident) || - isPropertyAccessContext(qualifiedStart, ident) || - isNewExpressionContext(qualifiedStart) || - isInstanceofContext(qualifiedStart) || - ts.isImportEqualsDeclaration(parent) + ( + (ts.isTypeNode(parent) && isValidTypeNode(parent)) || + // If identifier is the right-most name of Property Access chain or Qualified name, + // or it's a separate identifier expression, then identifier is being referenced as an value. + isEnumPropAccess(ident, tsSym, parent) || + ts.isExpressionWithTypeArguments(parent) || + ts.isExportAssignment(parent) || + ts.isExportSpecifier(parent) || + ts.isMetaProperty(parent) || + ts.isImportClause(parent) || + ts.isClassLike(parent) || + ts.isInterfaceDeclaration(parent) || + ts.isModuleDeclaration(parent) || + ts.isEnumDeclaration(parent) || + ts.isNamespaceImport(parent) || + ts.isImportSpecifier(parent) || + isQualifiedNameContext(qualifiedStart, ident) || + isPropertyAccessContext(qualifiedStart, ident) || + isNewExpressionContext(qualifiedStart) || + isInstanceofContext(qualifiedStart) || + ts.isImportEqualsDeclaration(parent) + ) ); } diff --git a/linter/src/utils/functions/isAssignmentOperator.ts b/linter/src/utils/functions/isAssignmentOperator.ts index d2476dc2f..4fde599e8 100644 --- a/linter/src/utils/functions/isAssignmentOperator.ts +++ b/linter/src/utils/functions/isAssignmentOperator.ts @@ -17,4 +17,4 @@ import * as ts from 'typescript'; export function isAssignmentOperator(tsBinOp: ts.BinaryOperatorToken): boolean { return tsBinOp.kind >= ts.SyntaxKind.FirstAssignment && tsBinOp.kind <= ts.SyntaxKind.LastAssignment; -} \ No newline at end of file +} -- Gitee From d0531deaed278d856688c8b1a856209cfcbc5158 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Mon, 13 Nov 2023 14:57:05 +0300 Subject: [PATCH 30/49] [arkts-linter] #14386 follow-up, remove src/utils from ignore Signed-off-by: Nazarov Konstantin --- linter/.eslintignore | 30 +- linter/src/TypeScriptLinter.ts | 117 +-- linter/src/utils/TsUtils.ts | 951 ++++++++++-------- linter/src/utils/functions/ContainsThis.ts | 6 +- .../src/utils/functions/DiagnosticChecker.ts | 4 +- .../utils/functions/ForEachNodeInSubtree.ts | 36 + linter/src/utils/functions/HasPredecessor.ts | 2 +- linter/src/utils/functions/IsStdLibrary.ts | 6 +- linter/src/utils/functions/IsStruct.ts | 8 +- .../LibraryTypeCallDiagnosticChecker.ts | 28 +- .../src/utils/functions/LogTscDiagnostic.ts | 5 +- linter/src/utils/functions/MergeArrayMaps.ts | 6 +- .../functions/identiferUseInValueContext.ts | 68 +- 13 files changed, 723 insertions(+), 544 deletions(-) create mode 100644 linter/src/utils/functions/ForEachNodeInSubtree.ts diff --git a/linter/.eslintignore b/linter/.eslintignore index b633cbdd8..4ab82f2f9 100644 --- a/linter/.eslintignore +++ b/linter/.eslintignore @@ -1,15 +1,15 @@ -bin -build -bundle -cookbook_convertor -dist -docs -node_modules -scripts -stats_calculator -test -test_extended_features -test_rules -utils -*.json -*.js +./bin +./build +./bundle +./cookbook_convertor +./dist +./docs +./node_modules +./scripts +./stats_calculator +./test +./test_extended_features +./test_rules +./utils +**.json +**.js diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index c2cb4cb59..436d4f540 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -56,6 +56,7 @@ import { TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE, LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; +import { forEachNodeInSubtree } from './utils/functions/ForEachNodeInSubtree'; const logger = Logger.getLogger(); @@ -178,7 +179,7 @@ export class TypeScriptLinter { ]); private getLineAndCharacterOfNode(node: ts.Node | ts.CommentRange): ts.LineAndCharacter { - const startPos = this.tsUtils.getStartPos(node); + const startPos = TsUtils.getStartPos(node); const { line, character } = this.sourceFile!.getLineAndCharacterOfPosition(startPos); // TSC counts lines and columns from zero return { line: line + 1, character: character + 1 }; @@ -230,8 +231,8 @@ export class TypeScriptLinter { if (!TypeScriptLinter.ideMode) { return; } - const startPos = this.tsUtils.getStartPos(node); - const endPos = this.tsUtils.getEndPos(node); + const startPos = TsUtils.getStartPos(node); + const endPos = TsUtils.getEndPos(node); const pos = this.sourceFile!.getLineAndCharacterOfPosition(endPos); const faultDescr = faultDesc[faultId]; @@ -268,22 +269,6 @@ export class TypeScriptLinter { } } - private forEachNodeInSubtree(node: ts.Node, cb: (n: ts.Node) => void, stopCond?: (n: ts.Node) => boolean): void { - cb.call(this, node); - if (stopCond?.call(this, node)) { - return; - } - - /* - * #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. - * As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. - * to traverse child nodes. - */ - for (const child of node.getChildren()) { - this.forEachNodeInSubtree(child, cb, stopCond); - } - } - private visitSourceFile(sf: ts.SourceFile): void { const callback = (node: ts.Node): void => { this.totalVisitedNodes++; @@ -322,7 +307,7 @@ export class TypeScriptLinter { } return false; }; - this.forEachNodeInSubtree(sf, callback, stopCondition); + forEachNodeInSubtree(sf, callback, stopCondition); } private countInterfaceExtendsDifferentPropertyTypes( @@ -349,7 +334,7 @@ export class TypeScriptLinter { * If specific declaration kind is provided, check against it. * Otherwise, use syntax kind of corresponding declaration node. */ - if (!!symbol && this.tsUtils.symbolHasDuplicateName(symbol, tsDeclKind ?? tsDeclNode.kind)) { + if (!!symbol && TsUtils.symbolHasDuplicateName(symbol, tsDeclKind ?? tsDeclNode.kind)) { this.incrementCounters(tsDeclNode, FaultID.DeclWithDuplicateName); } } @@ -422,17 +407,17 @@ export class TypeScriptLinter { if (ts.isIdentifier(curPropAccess) && curPropAccess.text !== 'prototype') { const type = this.tsTypeChecker.getTypeAtLocation(curPropAccess); - if (this.tsUtils.isAnyType(type)) { + if (TsUtils.isAnyType(type)) { return false; } } // Check if property symbol is 'Prototype' - if (this.tsUtils.isPrototypeSymbol(propAccessSym)) { + if (TsUtils.isPrototypeSymbol(propAccessSym)) { return true; } // Check if symbol of LHS-expression is Class or Function. - if (this.tsUtils.isTypeSymbol(baseExprSym) || this.tsUtils.isFunctionSymbol(baseExprSym)) { + if (TsUtils.isTypeSymbol(baseExprSym) || TsUtils.isFunctionSymbol(baseExprSym)) { return true; } @@ -443,7 +428,7 @@ export class TypeScriptLinter { * X.prototype.prototype.prototype = ... */ const baseExprTypeNode = this.tsTypeChecker.typeToTypeNode(baseExprType, undefined, ts.NodeBuilderFlags.None); - return baseExprTypeNode && ts.isFunctionTypeNode(baseExprTypeNode) || this.tsUtils.isAnyType(baseExprType); + return baseExprTypeNode && ts.isFunctionTypeNode(baseExprTypeNode) || TsUtils.isAnyType(baseExprType); } private interfaceInheritanceLint(node: ts.Node, heritageClauses: ts.NodeArray): void { @@ -485,7 +470,7 @@ export class TypeScriptLinter { private handleObjectLiteralExpression(node: ts.Node): void { const objectLiteralExpr = node as ts.ObjectLiteralExpression; // If object literal is a part of destructuring assignment, then don't process it further. - if (this.tsUtils.isDestructuringAssignmentLHS(objectLiteralExpr)) { + if (TsUtils.isDestructuringAssignmentLHS(objectLiteralExpr)) { return; } // issue 13082: Allow initializing struct instances with object literal. @@ -505,7 +490,7 @@ export class TypeScriptLinter { * If array literal is a part of destructuring assignment, then * don't process it further. */ - if (this.tsUtils.isDestructuringAssignmentLHS(node as ts.ArrayLiteralExpression)) { + if (TsUtils.isDestructuringAssignmentLHS(node as ts.ArrayLiteralExpression)) { return; } const arrayLitNode = node as ts.ArrayLiteralExpression; @@ -541,10 +526,10 @@ export class TypeScriptLinter { const tsParamMods = ts.getModifiers(tsParam); if ( tsParamMods && - (this.tsUtils.hasModifier(tsParamMods, ts.SyntaxKind.PublicKeyword) || - this.tsUtils.hasModifier(tsParamMods, ts.SyntaxKind.ProtectedKeyword) || - this.tsUtils.hasModifier(tsParamMods, ts.SyntaxKind.ReadonlyKeyword) || - this.tsUtils.hasModifier(tsParamMods, ts.SyntaxKind.PrivateKeyword)) + (TsUtils.hasModifier(tsParamMods, ts.SyntaxKind.PublicKeyword) || + TsUtils.hasModifier(tsParamMods, ts.SyntaxKind.ProtectedKeyword) || + TsUtils.hasModifier(tsParamMods, ts.SyntaxKind.ReadonlyKeyword) || + TsUtils.hasModifier(tsParamMods, ts.SyntaxKind.PrivateKeyword)) ) { this.incrementCounters(node, FaultID.ParameterProperties); } @@ -694,7 +679,7 @@ export class TypeScriptLinter { // missing exact rule this.incrementCounters(propertyAccessNode.expression, FaultID.ClassAsObject); } - if (!!baseExprSym && this.tsUtils.symbolHasEsObjectType(baseExprSym)) { + if (!!baseExprSym && TsUtils.symbolHasEsObjectType(baseExprSym)) { this.incrementCounters(propertyAccessNode, FaultID.EsObjectType); } } @@ -951,7 +936,7 @@ export class TypeScriptLinter { const tsSignature = this.tsTypeChecker.getSignatureFromDeclaration(funcLikeDecl); if (tsSignature) { const tsRetType = this.tsTypeChecker.getReturnTypeOfSignature(tsSignature); - if (!tsRetType || this.tsUtils.isUnsupportedType(tsRetType)) { + if (!tsRetType || TsUtils.isUnsupportedType(tsRetType)) { hasLimitedRetTypeInference = true; } else if (hasLimitedRetTypeInference) { newRetTypeNode = this.tsTypeChecker.typeToTypeNode(tsRetType, funcLikeDecl, ts.NodeBuilderFlags.None); @@ -984,7 +969,7 @@ export class TypeScriptLinter { if ( ts.isReturnStatement(node) && node.expression && - this.tsUtils.isCallToFunctionWithOmittedReturnType(this.tsUtils.unwrapParenthesized(node.expression)) + this.tsUtils.isCallToFunctionWithOmittedReturnType(TsUtils.unwrapParenthesized(node.expression)) ) { hasLimitedTypeInference = true; } @@ -1000,9 +985,9 @@ export class TypeScriptLinter { ); }; if (ts.isBlock(funBody)) { - this.forEachNodeInSubtree(funBody, callback, stopCondition); + forEachNodeInSubtree(funBody, callback, stopCondition); } else { - const tsExpr = this.tsUtils.unwrapParenthesized(funBody); + const tsExpr = TsUtils.unwrapParenthesized(funBody); hasLimitedTypeInference = this.tsUtils.isCallToFunctionWithOmittedReturnType(tsExpr); } return hasLimitedTypeInference; @@ -1070,7 +1055,7 @@ export class TypeScriptLinter { this.incrementCounters(tsLhsExpr, FaultID.MethodReassignment); } if ( - this.tsUtils.isMethodAssignment(tsLhsSymbol) && + TsUtils.isMethodAssignment(tsLhsSymbol) && tsLhsBaseSymbol && (tsLhsBaseSymbol.flags & ts.SymbolFlags.Function) !== 0 ) { @@ -1097,7 +1082,7 @@ export class TypeScriptLinter { } private processBinaryInstanceOf(node: ts.Node, tsLhsExpr: ts.Expression, leftOperandType: ts.Type): void { - const leftExpr = this.tsUtils.unwrapParenthesized(tsLhsExpr); + const leftExpr = TsUtils.unwrapParenthesized(tsLhsExpr); const leftSymbol = this.tsUtils.trueSymbolAtLocation(leftExpr); /* @@ -1108,11 +1093,7 @@ export class TypeScriptLinter { return; } - if ( - this.tsUtils.isPrimitiveType(leftOperandType) || - ts.isTypeNode(leftExpr) || - this.tsUtils.isTypeSymbol(leftSymbol) - ) { + if (TsUtils.isPrimitiveType(leftOperandType) || ts.isTypeNode(leftExpr) || TsUtils.isTypeSymbol(leftSymbol)) { this.incrementCounters(node, FaultID.InstanceofUnsupported); } } @@ -1161,10 +1142,10 @@ export class TypeScriptLinter { } private handleEsObjectDelaration(node: ts.VariableDeclaration): void { - const isDeclaredESObject = !!node.type && this.tsUtils.isEsObjectType(node.type); + const isDeclaredESObject = !!node.type && TsUtils.isEsObjectType(node.type); const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); - const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); - const isLocal = this.tsUtils.isInsideBlock(node); + const isInitializedWithESObject = !!initalizerTypeNode && TsUtils.isEsObjectType(initalizerTypeNode); + const isLocal = TsUtils.isInsideBlock(node); if ((isDeclaredESObject || isInitializedWithESObject) && !isLocal) { this.incrementCounters(node, FaultID.EsObjectType); return; @@ -1177,9 +1158,9 @@ export class TypeScriptLinter { private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node): void { const isTypeAnnotated = !!nodeDeclType; - const isDeclaredESObject = isTypeAnnotated && this.tsUtils.isEsObjectType(nodeDeclType); + const isDeclaredESObject = isTypeAnnotated && TsUtils.isEsObjectType(nodeDeclType); const initalizerTypeNode = this.tsUtils.getVariableDeclarationTypeNode(initializer); - const isInitializedWithESObject = !!initalizerTypeNode && this.tsUtils.isEsObjectType(initalizerTypeNode); + const isInitializedWithESObject = !!initalizerTypeNode && TsUtils.isEsObjectType(initalizerTypeNode); if (isTypeAnnotated && !isDeclaredESObject && isInitializedWithESObject) { this.incrementCounters(node, FaultID.EsObjectType); return; @@ -1257,7 +1238,7 @@ export class TypeScriptLinter { if ( !(tsModuleDecl.flags & ts.NodeFlags.Namespace) && - this.tsUtils.hasModifier(tsModifiers, ts.SyntaxKind.DeclareKeyword) + TsUtils.hasModifier(tsModifiers, ts.SyntaxKind.DeclareKeyword) ) { this.incrementCounters(tsModuleDecl, FaultID.ShorthandAmbientModuleDecl); } @@ -1306,7 +1287,7 @@ export class TypeScriptLinter { const nonDefaultSpecs: ts.ImportSpecifier[] = []; let defaultSpec: ts.ImportSpecifier | undefined; for (const importSpec of tsImportClause.namedBindings.elements) { - if (this.tsUtils.isDefaultImport(importSpec)) { + if (TsUtils.isDefaultImport(importSpec)) { defaultSpec = importSpec; } else { nonDefaultSpecs.push(importSpec); @@ -1425,7 +1406,7 @@ export class TypeScriptLinter { if (ts.isCallExpression(ctx.parent) || ts.isNewExpression(ctx.parent)) { const callee = ctx.parent.expression; - const isAny = this.tsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)); + const isAny = TsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)); const isDynamic = isAny || this.tsUtils.hasLibraryType(callee); if (callee !== ctx && isDynamic) { return true; @@ -1446,7 +1427,7 @@ export class TypeScriptLinter { * of finding a lot of false positives. Thus, do not check further in that case. */ if ((tsIdentSym.flags & ts.SymbolFlags.ValueModule) !== 0) { - if (!!tsIdentSym && this.tsUtils.symbolHasDuplicateName(tsIdentSym, ts.SyntaxKind.ModuleDeclaration)) { + if (!!tsIdentSym && TsUtils.symbolHasDuplicateName(tsIdentSym, ts.SyntaxKind.ModuleDeclaration)) { return; } } @@ -1483,13 +1464,13 @@ export class TypeScriptLinter { ); if ( !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && - !this.tsUtils.isAnyType(tsElemAccessBaseExprType) && + !TsUtils.isAnyType(tsElemAccessBaseExprType) && !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isArray) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isTuple) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, TsUtils.isTuple) && !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStdRecordType) && - !this.tsUtils.isEnumType(tsElemAccessBaseExprType) && - !this.tsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) + !TsUtils.isEnumType(tsElemAccessBaseExprType) && + !TsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) ) { let autofix = Autofixer.fixPropertyAccessByIndex(node); const autofixable = autofix !== undefined; @@ -1562,7 +1543,7 @@ export class TypeScriptLinter { if (calleeSym !== undefined) { this.handleStdlibAPICall(tsCallExpr, calleeSym); this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); - if (this.tsUtils.symbolHasEsObjectType(calleeSym)) { + if (TsUtils.symbolHasEsObjectType(calleeSym)) { this.incrementCounters(tsCallExpr, FaultID.EsObjectType); } } @@ -1607,7 +1588,7 @@ export class TypeScriptLinter { ts.isVariableDeclaration(tsCallExpr.parent) ) { const tsType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); - if (this.tsUtils.isInterfaceType(tsType) && tsType.symbol.name === 'NodeRequire') { + if (TsUtils.isInterfaceType(tsType) && tsType.symbol.name === 'NodeRequire') { this.incrementCounters(tsCallExpr.parent, FaultID.ImportAssignment); } } @@ -1694,7 +1675,7 @@ export class TypeScriptLinter { const tsParamDecl = tsParamSym.valueDeclaration; if (tsParamDecl && ts.isParameter(tsParamDecl)) { let tsParamType = this.tsTypeChecker.getTypeOfSymbolAtLocation(tsParamSym, tsParamDecl); - if (tsParamDecl.dotDotDotToken && this.tsUtils.isGenericArrayType(tsParamType) && tsParamType.typeArguments) { + if (tsParamDecl.dotDotDotToken && TsUtils.isGenericArrayType(tsParamType) && tsParamType.typeArguments) { tsParamType = tsParamType.typeArguments[0]; } if (!tsParamType) { @@ -1825,8 +1806,8 @@ export class TypeScriptLinter { } // check for rule#65: 'number as Number' and 'boolean as Boolean' are disabled if ( - this.tsUtils.isNumberType(exprType) && targetType.getSymbol()?.getName() === 'Number' || - this.tsUtils.isBooleanType(exprType) && targetType.getSymbol()?.getName() === 'Boolean' + TsUtils.isNumberType(exprType) && targetType.getSymbol()?.getName() === 'Number' || + TsUtils.isBooleanType(exprType) && targetType.getSymbol()?.getName() === 'Boolean' ) { this.incrementCounters(node, FaultID.TypeAssertion); } @@ -1835,8 +1816,8 @@ export class TypeScriptLinter { private handleTypeReference(node: ts.Node): void { const typeRef = node as ts.TypeReferenceNode; - const isESObject = this.tsUtils.isEsObjectType(typeRef); - const isPossiblyValidContext = this.tsUtils.isEsObjectPossiblyAllowed(typeRef); + const isESObject = TsUtils.isEsObjectType(typeRef); + const isPossiblyValidContext = TsUtils.isEsObjectPossiblyAllowed(typeRef); if (isESObject && !isPossiblyValidContext) { this.incrementCounters(node, FaultID.EsObjectType); return; @@ -1900,7 +1881,7 @@ export class TypeScriptLinter { private handleExpressionWithTypeArguments(node: ts.Node): void { const tsTypeExpr = node as ts.ExpressionWithTypeArguments; const symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); - if (!!symbol && this.tsUtils.isEsObjectSymbol(symbol)) { + if (!!symbol && TsUtils.isEsObjectSymbol(symbol)) { this.incrementCounters(tsTypeExpr, FaultID.EsObjectType); } } @@ -2027,7 +2008,7 @@ export class TypeScriptLinter { if (type.aliasSymbol !== undefined) { return; } - if (this.tsUtils.isObjectType(type) && !!(type.objectFlags & ts.ObjectFlags.Reference)) { + if (TsUtils.isObjectType(type) && !!(type.objectFlags & ts.ObjectFlags.Reference)) { this.handleInferredObjectreference(type, decl); return; } @@ -2040,9 +2021,9 @@ export class TypeScriptLinter { this.validateDeclInferredType(unionElem, decl); } } - if (this.tsUtils.isAnyType(type)) { + if (TsUtils.isAnyType(type)) { this.incrementCounters(decl, FaultID.AnyType); - } else if (this.tsUtils.isUnknownType(type)) { + } else if (TsUtils.isUnknownType(type)) { this.incrementCounters(decl, FaultID.UnknownType); } } @@ -2102,7 +2083,7 @@ export class TypeScriptLinter { const isModuleDecl = ts.isModuleDeclaration(node); return isClassLike || isFunctionLike || isModuleDecl; }; - this.forEachNodeInSubtree(scope, callback, stopCondition); + forEachNodeInSubtree(scope, callback, stopCondition); } lint(sourceFile: ts.SourceFile): void { diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index dfa4de9f9..2b9ed9922 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -24,61 +24,65 @@ import { isStructDeclaration, isStructDeclarationKind } from './functions/IsStru import { pathContainsDirectory } from './functions/PathHelper'; import { ARKTS_IGNORE_DIRS, ARKTS_IGNORE_FILES } from './consts/ArktsIgnorePaths'; import { isAssignmentOperator } from './functions/isAssignmentOperator'; +import { forEachNodeInSubtree } from './functions/ForEachNodeInSubtree'; export type CheckType = (t: ts.Type) => boolean; export class TsUtils { constructor( - private tsTypeChecker: ts.TypeChecker, - private testMode: boolean, - private advancedClassChecks: boolean + private readonly tsTypeChecker: ts.TypeChecker, + private readonly testMode: boolean, + private readonly advancedClassChecks: boolean ) {} - public isType(tsType: ts.TypeNode | undefined, checkType: string): boolean { + isType(tsType: ts.TypeNode | undefined, checkType: string): boolean { if (tsType === undefined || !ts.isTypeReferenceNode(tsType)) { return false; } - return this.entityNameToString(tsType.typeName) == checkType; + return this.entityNameToString(tsType.typeName) === checkType; } - public entityNameToString(name: ts.EntityName): string { + entityNameToString(name: ts.EntityName): string { if (ts.isIdentifier(name)) { return name.escapedText.toString(); - } else { - return this.entityNameToString(name.left) + this.entityNameToString(name.right); } + return this.entityNameToString(name.left) + this.entityNameToString(name.right); } - public isNumberType(tsType: ts.Type): boolean { + static isNumberType(tsType: ts.Type): boolean { if (tsType.isUnion()) { - for (let tsCompType of tsType.types) { - if ((tsCompType.flags & ts.TypeFlags.NumberLike) === 0) return false; + for (const tsCompType of tsType.types) { + if ((tsCompType.flags & ts.TypeFlags.NumberLike) === 0) { + return false; + } } return true; } return (tsType.getFlags() & ts.TypeFlags.NumberLike) !== 0; } - public isBooleanType(tsType: ts.Type): boolean { + static isBooleanType(tsType: ts.Type): boolean { return (tsType.getFlags() & ts.TypeFlags.BooleanLike) !== 0; } - public isStringLikeType(tsType: ts.Type): boolean { + static isStringLikeType(tsType: ts.Type): boolean { if (tsType.isUnion()) { - for (let tsCompType of tsType.types) { - if ((tsCompType.flags & ts.TypeFlags.StringLike) === 0) return false; + for (const tsCompType of tsType.types) { + if ((tsCompType.flags & ts.TypeFlags.StringLike) === 0) { + return false; + } } return true; } return (tsType.getFlags() & ts.TypeFlags.StringLike) !== 0; } - public isStringType(type: ts.Type): boolean { + static isStringType(type: ts.Type): boolean { return (type.getFlags() & ts.TypeFlags.String) !== 0; } - public isPrimitiveEnumType(type: ts.Type, primitiveType: ts.TypeFlags): boolean { + static isPrimitiveEnumType(type: ts.Type, primitiveType: ts.TypeFlags): boolean { const isNonPrimitive = (type.flags & ts.TypeFlags.NonPrimitive) !== 0; - if (!this.isEnumType(type) || !type.isUnion() || isNonPrimitive) { + if (!TsUtils.isEnumType(type) || !type.isUnion() || isNonPrimitive) { return false; } for (const t of type.types) { @@ -89,25 +93,27 @@ export class TsUtils { return true; } - public isPrimitiveEnumMemberType(type: ts.Type, primitiveType: ts.TypeFlags): boolean { + static isPrimitiveEnumMemberType(type: ts.Type, primitiveType: ts.TypeFlags): boolean { const isNonPrimitive = (type.flags & ts.TypeFlags.NonPrimitive) !== 0; - if (!this.isEnumMemberType(type) || isNonPrimitive) { + if (!TsUtils.isEnumMemberType(type) || isNonPrimitive) { return false; } return (type.flags & primitiveType) !== 0; } - public unwrapParenthesizedType(tsType: ts.TypeNode): ts.TypeNode { + static unwrapParenthesizedType(tsType: ts.TypeNode): ts.TypeNode { while (ts.isParenthesizedTypeNode(tsType)) { tsType = tsType.type; } return tsType; } - public findParentIf(asExpr: ts.AsExpression): ts.IfStatement | null { + static findParentIf(asExpr: ts.AsExpression): ts.IfStatement | null { let node = asExpr.parent; while (node) { - if (node.kind === ts.SyntaxKind.IfStatement) return node as ts.IfStatement; + if (node.kind === ts.SyntaxKind.IfStatement) { + return node as ts.IfStatement; + } node = node.parent; } @@ -115,9 +121,12 @@ export class TsUtils { return null; } - public isDestructuringAssignmentLHS(tsExpr: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression): boolean { - // Check whether given expression is the LHS part of the destructuring - // assignment (or is a nested element of destructuring pattern). + static isDestructuringAssignmentLHS(tsExpr: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression): boolean { + + /* + * Check whether given expression is the LHS part of the destructuring + * assignment (or is a nested element of destructuring pattern). + */ let tsParent = tsExpr.parent; let tsCurrentExpr: ts.Node = tsExpr; while (tsParent) { @@ -125,15 +134,17 @@ export class TsUtils { ts.isBinaryExpression(tsParent) && isAssignmentOperator(tsParent.operatorToken) && tsParent.left === tsCurrentExpr - ) + ) { return true; + } if ( (ts.isForStatement(tsParent) || ts.isForInStatement(tsParent) || ts.isForOfStatement(tsParent)) && tsParent.initializer && tsParent.initializer === tsCurrentExpr - ) + ) { return true; + } tsCurrentExpr = tsParent; tsParent = tsParent.parent; @@ -142,56 +153,67 @@ export class TsUtils { return false; } - public isEnumType(tsType: ts.Type): boolean { - // Note: For some reason, test (tsType.flags & ts.TypeFlags.Enum) != 0 doesn't work here. - // Must use SymbolFlags to figure out if this is an enum type. + static isEnumType(tsType: ts.Type): boolean { + + /* + * Note: For some reason, test (tsType.flags & ts.TypeFlags.Enum) != 0 doesn't work here. + * Must use SymbolFlags to figure out if this is an enum type. + */ return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.Enum) !== 0; } - public isEnumMemberType(tsType: ts.Type): boolean { - // Note: For some reason, test (tsType.flags & ts.TypeFlags.Enum) != 0 doesn't work here. - // Must use SymbolFlags to figure out if this is an enum type. + static isEnumMemberType(tsType: ts.Type): boolean { + + /* + * Note: For some reason, test (tsType.flags & ts.TypeFlags.Enum) != 0 doesn't work here. + * Must use SymbolFlags to figure out if this is an enum type. + */ return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.EnumMember) !== 0; } - public isObjectLiteralType(tsType: ts.Type): boolean { + static isObjectLiteralType(tsType: ts.Type): boolean { return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.ObjectLiteral) !== 0; } - public isNumberLikeType(tsType: ts.Type): boolean { + static isNumberLikeType(tsType: ts.Type): boolean { return (tsType.getFlags() & ts.TypeFlags.NumberLike) !== 0; } - public hasModifier(tsModifiers: readonly ts.Modifier[] | undefined, tsModifierKind: number): boolean { - // Sanity check. - if (!tsModifiers) return false; + static hasModifier(tsModifiers: readonly ts.Modifier[] | undefined, tsModifierKind: number): boolean { + if (!tsModifiers) { + return false; + } for (const tsModifier of tsModifiers) { - if (tsModifier.kind === tsModifierKind) return true; + if (tsModifier.kind === tsModifierKind) { + return true; + } } return false; } - public unwrapParenthesized(tsExpr: ts.Expression): ts.Expression { + static unwrapParenthesized(tsExpr: ts.Expression): ts.Expression { let unwrappedExpr = tsExpr; - while (ts.isParenthesizedExpression(unwrappedExpr)) unwrappedExpr = unwrappedExpr.expression; + while (ts.isParenthesizedExpression(unwrappedExpr)) { + unwrappedExpr = unwrappedExpr.expression; + } return unwrappedExpr; } - public followIfAliased(sym: ts.Symbol): ts.Symbol { + followIfAliased(sym: ts.Symbol): ts.Symbol { if ((sym.getFlags() & ts.SymbolFlags.Alias) !== 0) { return this.tsTypeChecker.getAliasedSymbol(sym); } return sym; } - private trueSymbolAtLocationCache = new Map(); + private readonly trueSymbolAtLocationCache = new Map(); - public trueSymbolAtLocation(node: ts.Node): ts.Symbol | undefined { - let cache = this.trueSymbolAtLocationCache; - let val = cache.get(node); + trueSymbolAtLocation(node: ts.Node): ts.Symbol | undefined { + const cache = this.trueSymbolAtLocationCache; + const val = cache.get(node); if (val !== undefined) { return val !== null ? val : undefined; } @@ -205,7 +227,7 @@ export class TsUtils { return sym; } - private isTypeDeclSyntaxKind(kind: ts.SyntaxKind) { + private static isTypeDeclSyntaxKind(kind: ts.SyntaxKind): boolean { return ( isStructDeclarationKind(kind) || kind === ts.SyntaxKind.EnumDeclaration || @@ -215,55 +237,65 @@ export class TsUtils { ); } - public symbolHasDuplicateName(symbol: ts.Symbol, tsDeclKind: ts.SyntaxKind): boolean { - // Type Checker merges all declarations with the same name in one scope into one symbol. - // Thus, check whether the symbol of certain declaration has any declaration with - // different syntax kind. + static symbolHasDuplicateName(symbol: ts.Symbol, tsDeclKind: ts.SyntaxKind): boolean { + + /* + * Type Checker merges all declarations with the same name in one scope into one symbol. + * Thus, check whether the symbol of certain declaration has any declaration with + * different syntax kind. + */ const symbolDecls = symbol?.getDeclarations(); if (symbolDecls) { for (const symDecl of symbolDecls) { const declKind = symDecl.kind; // we relax arkts-unique-names for namespace collision with class/interface/enum/type/struct const isNamespaceTypeCollision = - (this.isTypeDeclSyntaxKind(declKind) && tsDeclKind === ts.SyntaxKind.ModuleDeclaration) || - (this.isTypeDeclSyntaxKind(tsDeclKind) && declKind === ts.SyntaxKind.ModuleDeclaration); - - // Don't count declarations with 'Identifier' syntax kind as those - // usually depict declaring an object's property through assignment. - if (declKind !== ts.SyntaxKind.Identifier && declKind !== tsDeclKind && !isNamespaceTypeCollision) return true; + TsUtils.isTypeDeclSyntaxKind(declKind) && tsDeclKind === ts.SyntaxKind.ModuleDeclaration || + TsUtils.isTypeDeclSyntaxKind(tsDeclKind) && declKind === ts.SyntaxKind.ModuleDeclaration; + + /* + * Don't count declarations with 'Identifier' syntax kind as those + * usually depict declaring an object's property through assignment. + */ + if (declKind !== ts.SyntaxKind.Identifier && declKind !== tsDeclKind && !isNamespaceTypeCollision) { + return true; + } } } return false; } - public isReferenceType(tsType: ts.Type): boolean { + static isReferenceType(tsType: ts.Type): boolean { const f = tsType.getFlags(); return ( - (f & ts.TypeFlags.InstantiableNonPrimitive) != 0 || - (f & ts.TypeFlags.Object) != 0 || - (f & ts.TypeFlags.Boolean) != 0 || - (f & ts.TypeFlags.Enum) != 0 || - (f & ts.TypeFlags.NonPrimitive) != 0 || - (f & ts.TypeFlags.Number) != 0 || - (f & ts.TypeFlags.String) != 0 + (f & ts.TypeFlags.InstantiableNonPrimitive) !== 0 || + (f & ts.TypeFlags.Object) !== 0 || + (f & ts.TypeFlags.Boolean) !== 0 || + (f & ts.TypeFlags.Enum) !== 0 || + (f & ts.TypeFlags.NonPrimitive) !== 0 || + (f & ts.TypeFlags.Number) !== 0 || + (f & ts.TypeFlags.String) !== 0 ); } - public isPrimitiveType(type: ts.Type): boolean { + static isPrimitiveType(type: ts.Type): boolean { const f = type.getFlags(); return ( - (f & ts.TypeFlags.Boolean) != 0 || - (f & ts.TypeFlags.BooleanLiteral) != 0 || - (f & ts.TypeFlags.Number) != 0 || - (f & ts.TypeFlags.NumberLiteral) != 0 - // In ArkTS 'string' is not a primitive type. So for the common subset 'string' - // should be considered as a reference type. That is why next line is commented out. - //(f & ts.TypeFlags.String) != 0 || (f & ts.TypeFlags.StringLiteral) != 0 + (f & ts.TypeFlags.Boolean) !== 0 || + (f & ts.TypeFlags.BooleanLiteral) !== 0 || + (f & ts.TypeFlags.Number) !== 0 || + (f & ts.TypeFlags.NumberLiteral) !== 0 + + /* + * In ArkTS 'string' is not a primitive type. So for the common subset 'string' + * should be considered as a reference type. That is why next line is commented out. + * (f & ts.TypeFlags.String) != 0 || (f & ts.TypeFlags.StringLiteral) != 0 + */ ); } - public isTypeSymbol(symbol: ts.Symbol | undefined): boolean { + static isTypeSymbol(symbol: ts.Symbol | undefined): boolean { return ( !!symbol && !!symbol.flags && @@ -272,16 +304,16 @@ export class TsUtils { } // Check whether type is generic 'Array' type defined in TypeScript standard library. - public isGenericArrayType(tsType: ts.Type): tsType is ts.TypeReference { + static isGenericArrayType(tsType: ts.Type): tsType is ts.TypeReference { return ( - this.isTypeReference(tsType) && + TsUtils.isTypeReference(tsType) && tsType.typeArguments?.length === 1 && tsType.target.typeParameters?.length === 1 && tsType.getSymbol()?.getName() === 'Array' ); } - public isTypedArray(tsType: ts.Type): boolean { + isTypedArray(tsType: ts.Type): boolean { const symbol = tsType.symbol; if (!symbol) { return false; @@ -290,17 +322,17 @@ export class TsUtils { return this.isGlobalSymbol(symbol) && TYPED_ARRAYS.includes(name); } - public isArray(tsType: ts.Type): boolean { - return this.isGenericArrayType(tsType) || this.isTypedArray(tsType); + isArray(tsType: ts.Type): boolean { + return TsUtils.isGenericArrayType(tsType) || this.isTypedArray(tsType); } - public isTuple(tsType: ts.Type): boolean { - return this.isTypeReference(tsType) && !!(tsType.objectFlags & ts.ObjectFlags.Tuple); + static isTuple(tsType: ts.Type): boolean { + return TsUtils.isTypeReference(tsType) && !!(tsType.objectFlags & ts.ObjectFlags.Tuple); } // does something similar to relatedByInheritanceOrIdentical function - public isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { - if (this.isTypeReference(tsType) && tsType.target !== tsType) { + isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { + if (TsUtils.isTypeReference(tsType) && tsType.target !== tsType) { tsType = tsType.target; } @@ -308,7 +340,7 @@ export class TsUtils { return true; } - if (!tsType.symbol || !tsType.symbol.declarations) { + if (!tsType.symbol?.declarations) { return false; } @@ -318,7 +350,7 @@ export class TsUtils { if (!isDerived) { continue; } - for (let heritageClause of tsTypeDecl.heritageClauses) { + for (const heritageClause of tsTypeDecl.heritageClauses) { if (this.processParentTypesCheck(heritageClause.types, checkType)) { return true; } @@ -328,44 +360,44 @@ export class TsUtils { return false; } - public isTypeReference(tsType: ts.Type): tsType is ts.TypeReference { + static isTypeReference(tsType: ts.Type): tsType is ts.TypeReference { return ( (tsType.getFlags() & ts.TypeFlags.Object) !== 0 && ((tsType as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference) !== 0 ); } - public isNullType(tsTypeNode: ts.TypeNode): boolean { + static isNullType(tsTypeNode: ts.TypeNode): boolean { return ts.isLiteralTypeNode(tsTypeNode) && tsTypeNode.literal.kind === ts.SyntaxKind.NullKeyword; } - public isThisOrSuperExpr(tsExpr: ts.Expression): boolean { - return tsExpr.kind == ts.SyntaxKind.ThisKeyword || tsExpr.kind == ts.SyntaxKind.SuperKeyword; + static isThisOrSuperExpr(tsExpr: ts.Expression): boolean { + return tsExpr.kind === ts.SyntaxKind.ThisKeyword || tsExpr.kind === ts.SyntaxKind.SuperKeyword; } - public isPrototypeSymbol(symbol: ts.Symbol | undefined): boolean { + static isPrototypeSymbol(symbol: ts.Symbol | undefined): boolean { return !!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Prototype) !== 0; } - public isFunctionSymbol(symbol: ts.Symbol | undefined): boolean { + static isFunctionSymbol(symbol: ts.Symbol | undefined): boolean { return !!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Function) !== 0; } - public isInterfaceType(tsType: ts.Type | undefined): boolean { + static isInterfaceType(tsType: ts.Type | undefined): boolean { return ( !!tsType && !!tsType.symbol && !!tsType.symbol.flags && (tsType.symbol.flags & ts.SymbolFlags.Interface) !== 0 ); } - public isAnyType(tsType: ts.Type): tsType is ts.TypeReference { + static isAnyType(tsType: ts.Type): tsType is ts.TypeReference { return (tsType.getFlags() & ts.TypeFlags.Any) !== 0; } - public isUnknownType(tsType: ts.Type): boolean { + static isUnknownType(tsType: ts.Type): boolean { return (tsType.getFlags() & ts.TypeFlags.Unknown) !== 0; } - public isUnsupportedType(tsType: ts.Type): boolean { + static isUnsupportedType(tsType: ts.Type): boolean { return ( !!tsType.flags && ((tsType.flags & ts.TypeFlags.Any) !== 0 || @@ -374,7 +406,7 @@ export class TsUtils { ); } - public isNullableUnionType(type: ts.Type): boolean { + static isNullableUnionType(type: ts.Type): boolean { if (type.isUnion()) { for (const t of type.types) { if (!!(t.flags & ts.TypeFlags.Undefined) || !!(t.flags & ts.TypeFlags.Null)) { @@ -385,39 +417,70 @@ export class TsUtils { return false; } - public isFunctionOrMethod(tsSymbol: ts.Symbol | undefined): boolean { + static isFunctionOrMethod(tsSymbol: ts.Symbol | undefined): boolean { return ( !!tsSymbol && ((tsSymbol.flags & ts.SymbolFlags.Function) !== 0 || (tsSymbol.flags & ts.SymbolFlags.Method) !== 0) ); } - public isMethodAssignment(tsSymbol: ts.Symbol | undefined): boolean { + static isMethodAssignment(tsSymbol: ts.Symbol | undefined): boolean { return ( !!tsSymbol && (tsSymbol.flags & ts.SymbolFlags.Method) !== 0 && (tsSymbol.flags & ts.SymbolFlags.Assignment) !== 0 ); } - public getDeclaration(tsSymbol: ts.Symbol | undefined): ts.Declaration | undefined { - if (tsSymbol && tsSymbol.declarations && tsSymbol.declarations.length > 0) return tsSymbol.declarations[0]; + static getDeclaration(tsSymbol: ts.Symbol | undefined): ts.Declaration | undefined { + if (tsSymbol?.declarations && tsSymbol.declarations.length > 0) { + return tsSymbol.declarations[0]; + } return undefined; } - private isVarDeclaration(tsDecl: ts.Node): boolean { + private static isVarDeclaration(tsDecl: ts.Node): boolean { return ts.isVariableDeclaration(tsDecl) && ts.isVariableDeclarationList(tsDecl.parent); } - public isValidEnumMemberInit(tsExpr: ts.Expression): boolean { - if (this.isNumberConstantValue(tsExpr.parent as ts.EnumMember)) return true; - if (this.isStringConstantValue(tsExpr.parent as ts.EnumMember)) return true; + isValidEnumMemberInit(tsExpr: ts.Expression): boolean { + if (this.isNumberConstantValue(tsExpr.parent as ts.EnumMember)) { + return true; + } + if (this.isStringConstantValue(tsExpr.parent as ts.EnumMember)) { + return true; + } return this.isCompileTimeExpression(tsExpr); } - public isCompileTimeExpression(tsExpr: ts.Expression): boolean { + private isCompileTimeExpressionHandlePropertyAccess(tsExpr: ts.Expression): boolean { + if (!ts.isPropertyAccessExpression(tsExpr)) { + return false; + } + + /* + * if enum member is in current enum declaration try to get value + * if it comes from another enum consider as constant + */ + const propertyAccess = tsExpr; + if (this.isNumberConstantValue(propertyAccess)) { + return true; + } + const leftHandSymbol = this.trueSymbolAtLocation(propertyAccess.expression); + if (!leftHandSymbol) { + return false; + } + const decls = leftHandSymbol.getDeclarations(); + if (!decls || decls.length !== 1) { + return false; + } + return ts.isEnumDeclaration(decls[0]); + } + + isCompileTimeExpression(tsExpr: ts.Expression): boolean { if ( ts.isParenthesizedExpression(tsExpr) || - (ts.isAsExpression(tsExpr) && tsExpr.type.kind === ts.SyntaxKind.NumberKeyword) - ) + ts.isAsExpression(tsExpr) && tsExpr.type.kind === ts.SyntaxKind.NumberKeyword + ) { return this.isCompileTimeExpression(tsExpr.expression); + } switch (tsExpr.kind) { case ts.SyntaxKind.PrefixUnaryExpression: @@ -433,29 +496,20 @@ export class TsUtils { return true; case ts.SyntaxKind.StringLiteral: return true; - case ts.SyntaxKind.PropertyAccessExpression: { - // if enum member is in current enum declaration try to get value - // if it comes from another enum consider as constant - const propertyAccess = tsExpr as ts.PropertyAccessExpression; - if (this.isNumberConstantValue(propertyAccess)) return true; - const leftHandSymbol = this.trueSymbolAtLocation(propertyAccess.expression); - if (!leftHandSymbol) return false; - const decls = leftHandSymbol.getDeclarations(); - if (!decls || decls.length !== 1) return false; - return ts.isEnumDeclaration(decls[0]); - } + case ts.SyntaxKind.PropertyAccessExpression: + return this.isCompileTimeExpressionHandlePropertyAccess(tsExpr); default: return false; } } private isPrefixUnaryExprValidEnumMemberInit(tsExpr: ts.PrefixUnaryExpression): boolean { - return this.isUnaryOpAllowedForEnumMemberInit(tsExpr.operator) && this.isCompileTimeExpression(tsExpr.operand); + return TsUtils.isUnaryOpAllowedForEnumMemberInit(tsExpr.operator) && this.isCompileTimeExpression(tsExpr.operand); } private isBinaryExprValidEnumMemberInit(tsExpr: ts.BinaryExpression): boolean { return ( - this.isBinaryOpAllowedForEnumMemberInit(tsExpr.operatorToken) && + TsUtils.isBinaryOpAllowedForEnumMemberInit(tsExpr.operatorToken) && this.isCompileTimeExpression(tsExpr.left) && this.isCompileTimeExpression(tsExpr.right) ); @@ -466,15 +520,15 @@ export class TsUtils { } private isIdentifierValidEnumMemberInit(tsExpr: ts.Identifier): boolean { - let tsSymbol = this.trueSymbolAtLocation(tsExpr); - let tsDecl = this.getDeclaration(tsSymbol); + const tsSymbol = this.trueSymbolAtLocation(tsExpr); + const tsDecl = TsUtils.getDeclaration(tsSymbol); return ( !!tsDecl && - ((this.isVarDeclaration(tsDecl) && this.isConst(tsDecl.parent)) || tsDecl.kind === ts.SyntaxKind.EnumMember) + (TsUtils.isVarDeclaration(tsDecl) && TsUtils.isConst(tsDecl.parent) || tsDecl.kind === ts.SyntaxKind.EnumMember) ); } - private isUnaryOpAllowedForEnumMemberInit(tsPrefixUnaryOp: ts.PrefixUnaryOperator): boolean { + private static isUnaryOpAllowedForEnumMemberInit(tsPrefixUnaryOp: ts.PrefixUnaryOperator): boolean { return ( tsPrefixUnaryOp === ts.SyntaxKind.PlusToken || tsPrefixUnaryOp === ts.SyntaxKind.MinusToken || @@ -482,7 +536,7 @@ export class TsUtils { ); } - private isBinaryOpAllowedForEnumMemberInit(tsBinaryOp: ts.BinaryOperatorToken): boolean { + private static isBinaryOpAllowedForEnumMemberInit(tsBinaryOp: ts.BinaryOperatorToken): boolean { return ( tsBinaryOp.kind === ts.SyntaxKind.AsteriskToken || tsBinaryOp.kind === ts.SyntaxKind.SlashToken || @@ -500,28 +554,28 @@ export class TsUtils { ); } - public isConst(tsNode: ts.Node): boolean { + static isConst(tsNode: ts.Node): boolean { return !!(ts.getCombinedNodeFlags(tsNode) & ts.NodeFlags.Const); } - public isNumberConstantValue( + isNumberConstantValue( tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.NumericLiteral ): boolean { const tsConstValue = - tsExpr.kind === ts.SyntaxKind.NumericLiteral - ? Number(tsExpr.getText()) - : this.tsTypeChecker.getConstantValue(tsExpr); + tsExpr.kind === ts.SyntaxKind.NumericLiteral ? + Number(tsExpr.getText()) : + this.tsTypeChecker.getConstantValue(tsExpr); return tsConstValue !== undefined && typeof tsConstValue === 'number'; } - public isIntegerConstantValue( + isIntegerConstantValue( tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.NumericLiteral ): boolean { const tsConstValue = - tsExpr.kind === ts.SyntaxKind.NumericLiteral - ? Number(tsExpr.getText()) - : this.tsTypeChecker.getConstantValue(tsExpr); + tsExpr.kind === ts.SyntaxKind.NumericLiteral ? + Number(tsExpr.getText()) : + this.tsTypeChecker.getConstantValue(tsExpr); return ( tsConstValue !== undefined && typeof tsConstValue === 'number' && @@ -529,52 +583,48 @@ export class TsUtils { ); } - public isStringConstantValue( - tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression - ): boolean { + isStringConstantValue(tsExpr: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression): boolean { const tsConstValue = this.tsTypeChecker.getConstantValue(tsExpr); return tsConstValue !== undefined && typeof tsConstValue === 'string'; } // Returns true iff typeA is a subtype of typeB - public relatedByInheritanceOrIdentical(typeA: ts.Type, typeB: ts.Type): boolean { - if (this.isTypeReference(typeA) && typeA.target !== typeA) typeA = typeA.target; - if (this.isTypeReference(typeB) && typeB.target !== typeB) typeB = typeB.target; + relatedByInheritanceOrIdentical(typeA: ts.Type, typeB: ts.Type): boolean { + if (TsUtils.isTypeReference(typeA) && typeA.target !== typeA) { + typeA = typeA.target; + } + if (TsUtils.isTypeReference(typeB) && typeB.target !== typeB) { + typeB = typeB.target; + } - if (typeA === typeB || this.isObject(typeB)) return true; - if (!typeA.symbol || !typeA.symbol.declarations) return false; + if (typeA === typeB || this.isObject(typeB)) { + return true; + } + if (!typeA.symbol?.declarations) { + return false; + } - for (let typeADecl of typeA.symbol.declarations) { - if ((!ts.isClassDeclaration(typeADecl) && !ts.isInterfaceDeclaration(typeADecl)) || !typeADecl.heritageClauses) + for (const typeADecl of typeA.symbol.declarations) { + if (!ts.isClassDeclaration(typeADecl) && !ts.isInterfaceDeclaration(typeADecl) || !typeADecl.heritageClauses) { continue; - for (let heritageClause of typeADecl.heritageClauses) { - let processInterfaces = typeA.isClass() ? heritageClause.token != ts.SyntaxKind.ExtendsKeyword : true; - if (this.processParentTypes(heritageClause.types, typeB, processInterfaces)) return true; + } + for (const heritageClause of typeADecl.heritageClauses) { + const processInterfaces = typeA.isClass() ? heritageClause.token !== ts.SyntaxKind.ExtendsKeyword : true; + if (this.processParentTypes(heritageClause.types, typeB, processInterfaces)) { + return true; + } } } return false; } - // return true if two class types are not related by inheritance and structural identity check is needed - public needToDeduceStructuralIdentity( + private needToDeduceStructuralIdentityHandleUnions( lhsType: ts.Type, rhsType: ts.Type, rhsExpr: ts.Expression, - allowPromotion: boolean = false + allowPromotion: boolean ): boolean { - // Compare non-nullable version of types. - lhsType = this.getNonNullableType(lhsType); - rhsType = this.getNonNullableType(rhsType); - - if (this.isLibraryType(lhsType)) { - return false; - } - - if (this.isDynamicObjectAssignedToStdType(lhsType, rhsExpr)) { - return false; - } - if (rhsType.isUnion()) { // Each Class/Interface of the RHS union type must be compatible with LHS type. for (const compType of rhsType.types) { @@ -584,7 +634,6 @@ export class TsUtils { } return false; } - if (lhsType.isUnion()) { // RHS type needs to be compatible with at least one type of the LHS union. for (const compType of lhsType.types) { @@ -594,26 +643,44 @@ export class TsUtils { } return true; } + // should be unreachable + return false; + } + // return true if two class types are not related by inheritance and structural identity check is needed + needToDeduceStructuralIdentity( + lhsType: ts.Type, + rhsType: ts.Type, + rhsExpr: ts.Expression, + allowPromotion: boolean = false + ): boolean { + lhsType = TsUtils.getNonNullableType(lhsType); + rhsType = TsUtils.getNonNullableType(rhsType); + if (this.isLibraryType(lhsType)) { + return false; + } + if (this.isDynamicObjectAssignedToStdType(lhsType, rhsExpr)) { + return false; + } + if (rhsType.isUnion() || lhsType.isUnion()) { + return this.needToDeduceStructuralIdentityHandleUnions(lhsType, rhsType, rhsExpr, allowPromotion); + } if ( this.advancedClassChecks && - this.isClassValueType(rhsType) && - lhsType != rhsType && - !this.isObjectType(lhsType) + TsUtils.isClassValueType(rhsType) && + lhsType !== rhsType && + !TsUtils.isObjectType(lhsType) ) { // missing exact rule return true; } - let res = lhsType.isClassOrInterface() && rhsType.isClassOrInterface() && !this.relatedByInheritanceOrIdentical(rhsType, lhsType); - if (allowPromotion) { res &&= !this.relatedByInheritanceOrIdentical(lhsType, rhsType); } - return res; } @@ -622,11 +689,18 @@ export class TsUtils { typeB: ts.Type, processInterfaces: boolean ): boolean { - for (let baseTypeExpr of parentTypes) { + for (const baseTypeExpr of parentTypes) { let baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeExpr); - if (this.isTypeReference(baseType) && baseType.target !== baseType) baseType = baseType.target; - if (baseType && baseType.isClass() != processInterfaces && this.relatedByInheritanceOrIdentical(baseType, typeB)) + if (TsUtils.isTypeReference(baseType) && baseType.target !== baseType) { + baseType = baseType.target; + } + if ( + baseType && + baseType.isClass() !== processInterfaces && + this.relatedByInheritanceOrIdentical(baseType, typeB) + ) { return true; + } } return false; } @@ -634,7 +708,7 @@ export class TsUtils { private processParentTypesCheck(parentTypes: ts.NodeArray, checkType: CheckType): boolean { for (const baseTypeExpr of parentTypes) { let baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeExpr); - if (this.isTypeReference(baseType) && baseType.target !== baseType) { + if (TsUtils.isTypeReference(baseType) && baseType.target !== baseType) { baseType = baseType.target; } if (baseType && this.isOrDerivedFrom(baseType, checkType)) { @@ -644,45 +718,49 @@ export class TsUtils { return false; } - public isObject(tsType: ts.Type): boolean { + isObject(tsType: ts.Type): boolean { if (!tsType) { return false; } if (tsType.symbol && tsType.isClassOrInterface() && tsType.symbol.name === 'Object') { return true; } - let node = this.tsTypeChecker.typeToTypeNode(tsType, undefined, undefined); - return node != undefined && node.kind === ts.SyntaxKind.ObjectKeyword; + const node = this.tsTypeChecker.typeToTypeNode(tsType, undefined, undefined); + return node !== undefined && node.kind === ts.SyntaxKind.ObjectKeyword; } - public isCallToFunctionWithOmittedReturnType(tsExpr: ts.Expression): boolean { + isCallToFunctionWithOmittedReturnType(tsExpr: ts.Expression): boolean { if (ts.isCallExpression(tsExpr)) { - let tsCallSignature = this.tsTypeChecker.getResolvedSignature(tsExpr); + const tsCallSignature = this.tsTypeChecker.getResolvedSignature(tsExpr); if (tsCallSignature) { const tsSignDecl = tsCallSignature.getDeclaration(); // `tsSignDecl` is undefined when `getResolvedSignature` returns `unknownSignature` - if (!tsSignDecl || !tsSignDecl.type) return true; + if (!tsSignDecl?.type) { + return true; + } } } return false; } - private hasReadonlyFields(type: ts.Type): boolean { - if (type.symbol.members === undefined) return false; // No members -> no readonly fields + private static hasReadonlyFields(type: ts.Type): boolean { + // No members -> no readonly fields + if (type.symbol.members === undefined) { + return false; + } let result: boolean = false; - type.symbol.members.forEach((value, key) => { + type.symbol.members.forEach((value) => { if ( value.declarations !== undefined && value.declarations.length > 0 && ts.isPropertyDeclaration(value.declarations[0]) ) { - let propmMods = ts.getModifiers(value.declarations[0] as ts.PropertyDeclaration); - if (this.hasModifier(propmMods, ts.SyntaxKind.ReadonlyKeyword)) { + const propmMods = ts.getModifiers(value.declarations[0]); + if (TsUtils.hasModifier(propmMods, ts.SyntaxKind.ReadonlyKeyword)) { result = true; - return; } } }); @@ -690,57 +768,66 @@ export class TsUtils { return result; } - private hasDefaultCtor(type: ts.Type): boolean { - if (type.symbol.members === undefined) return true; // No members -> no explicite constructors -> there is default ctor + private static hasDefaultCtor(type: ts.Type): boolean { + // No members -> no explicit constructors -> there is default ctor + if (type.symbol.members === undefined) { + return true; + } - let hasCtor: boolean = false; // has any constructor - let hasDefaultCtor: boolean = false; // has default constructor + // has any constructor + let hasCtor: boolean = false; + // has default constructor + let hasDefaultCtor: boolean = false; - type.symbol.members.forEach((value, key) => { + type.symbol.members.forEach((value) => { if ((value.flags & ts.SymbolFlags.Constructor) !== 0) { hasCtor = true; if (value.declarations !== undefined && value.declarations.length > 0) { - let declCtor = value.declarations[0] as ts.ConstructorDeclaration; + const declCtor = value.declarations[0] as ts.ConstructorDeclaration; if (declCtor.parameters.length === 0) { hasDefaultCtor = true; - return; } } } }); - return !hasCtor || hasDefaultCtor; // Has no any explicite constructor -> has implicite default constructor. + // Has no any explicit constructor -> has implicit default constructor. + return !hasCtor || hasDefaultCtor; } - private isAbstractClass(type: ts.Type): boolean { + private static isAbstractClass(type: ts.Type): boolean { if (type.isClass() && type.symbol.declarations && type.symbol.declarations.length > 0) { - let declClass = type.symbol.declarations[0] as ts.ClassDeclaration; - let classMods = ts.getModifiers(declClass); - if (this.hasModifier(classMods, ts.SyntaxKind.AbstractKeyword)) return true; + const declClass = type.symbol.declarations[0] as ts.ClassDeclaration; + const classMods = ts.getModifiers(declClass); + if (TsUtils.hasModifier(classMods, ts.SyntaxKind.AbstractKeyword)) { + return true; + } } return false; } - public validateObjectLiteralType(type: ts.Type | undefined): boolean { + static validateObjectLiteralType(type: ts.Type | undefined): boolean { if (!type) { return false; } - type = this.getTargetType(type); + type = TsUtils.getTargetType(type); return ( type.isClassOrInterface() && - this.hasDefaultCtor(type) && - !this.hasReadonlyFields(type) && - !this.isAbstractClass(type) + TsUtils.hasDefaultCtor(type) && + !TsUtils.hasReadonlyFields(type) && + !TsUtils.isAbstractClass(type) ); } - public hasMethods(type: ts.Type): boolean { + hasMethods(type: ts.Type): boolean { const properties = this.tsTypeChecker.getPropertiesOfType(type); if (properties?.length) { for (const prop of properties) { - if (prop.getFlags() & ts.SymbolFlags.Method) return true; + if (prop.getFlags() & ts.SymbolFlags.Method) { + return true; + } } } return false; @@ -750,18 +837,20 @@ export class TsUtils { const properties = this.tsTypeChecker.getPropertiesOfType(type); if (properties?.length) { for (const prop of properties) { - if (prop.name === name) return prop; + if (prop.name === name) { + return prop; + } } } return undefined; } - public checkTypeSet(uType: ts.Type, predicate: (t: ts.Type) => boolean): boolean { + checkTypeSet(uType: ts.Type, predicate: (t: ts.Type) => boolean): boolean { if (!uType.isUnionOrIntersection()) { return predicate(uType); } - for (let elemType of uType.types) { + for (const elemType of uType.types) { if (!this.checkTypeSet(elemType, predicate)) { return false; } @@ -769,42 +858,48 @@ export class TsUtils { return true; } - private getNonNullableType(t: ts.Type) { - if (this.isNullableUnionType(t)) { + private static getNonNullableType(t: ts.Type): ts.Type { + if (TsUtils.isNullableUnionType(t)) { return t.getNonNullableType(); } return t; } - public isObjectLiteralAssignable(lhsType: ts.Type | undefined, rhsExpr: ts.ObjectLiteralExpression): boolean { + private isObjectLiteralAssignableToUnion(lhsType: ts.UnionType, rhsExpr: ts.ObjectLiteralExpression): boolean { + for (const compType of lhsType.types) { + if (this.isObjectLiteralAssignable(compType, rhsExpr)) { + return true; + } + } + return false; + } + + isObjectLiteralAssignable(lhsType: ts.Type | undefined, rhsExpr: ts.ObjectLiteralExpression): boolean { if (lhsType === undefined) { return false; } - // Always check with the non-nullable variant of lhs type. - lhsType = this.getNonNullableType(lhsType); - - if (lhsType.isUnion()) { - for (const compType of lhsType.types) { - if (this.isObjectLiteralAssignable(compType, rhsExpr)) { - return true; - } - } + lhsType = TsUtils.getNonNullableType(lhsType); + if (lhsType.isUnion() && this.isObjectLiteralAssignableToUnion(lhsType, rhsExpr)) { + return true; } - // Allow initializing with anything when the type - // originates from the library. - if (this.isAnyType(lhsType) || this.isLibraryType(lhsType)) { + /* + * Allow initializing with anything when the type + * originates from the library. + */ + if (TsUtils.isAnyType(lhsType) || this.isLibraryType(lhsType)) { return true; } - // issue 13412: - // Allow initializing with a dynamic object when the LHS type - // is primitive or defined in standard library. + /* + * issue 13412: + * Allow initializing with a dynamic object when the LHS type + * is primitive or defined in standard library. + */ if (this.isDynamicObjectAssignedToStdType(lhsType, rhsExpr)) { return true; } - // For Partial, Required, Readonly types, validate their argument type. if (this.isStdPartialType(lhsType) || this.isStdRequiredType(lhsType) || this.isStdReadonlyType(lhsType)) { if (lhsType.aliasTypeArguments && lhsType.aliasTypeArguments.length === 1) { @@ -814,29 +909,32 @@ export class TsUtils { } } - // Allow initializing Record objects with object initializer. - // Record supports any type for a its value, but the key value - // must be either a string or number literal. + /* + * Allow initializing Record objects with object initializer. + * Record supports any type for a its value, but the key value + * must be either a string or number literal. + */ if (this.isStdRecordType(lhsType)) { - return this.validateRecordObjectKeys(rhsExpr); + return TsUtils.validateRecordObjectKeys(rhsExpr); } - return ( - this.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr) + TsUtils.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr) ); } - isFunctionalType(type: ts.Type): boolean { + static isFunctionalType(type: ts.Type): boolean { const callSigns = type.getCallSignatures(); return callSigns && callSigns.length > 0; } private isDynamicObjectAssignedToStdType(lhsType: ts.Type, rhsExpr: ts.Expression): boolean { - if (isStdLibraryType(lhsType) || this.isPrimitiveType(lhsType)) { - let rhsSym = ts.isCallExpression(rhsExpr) - ? this.getSymbolOfCallExpression(rhsExpr) - : this.trueSymbolAtLocation(rhsExpr); - if (rhsSym && this.isLibrarySymbol(rhsSym)) return true; + if (isStdLibraryType(lhsType) || TsUtils.isPrimitiveType(lhsType)) { + const rhsSym = ts.isCallExpression(rhsExpr) ? + this.getSymbolOfCallExpression(rhsExpr) : + this.trueSymbolAtLocation(rhsExpr); + if (rhsSym && this.isLibrarySymbol(rhsSym)) { + return true; + } } return false; } @@ -856,40 +954,42 @@ export class TsUtils { private validateField(type: ts.Type, prop: ts.PropertyAssignment): boolean { const propName = prop.name.getText(); const propSym = this.findProperty(type, propName); - if (!propSym || !propSym.declarations?.length) { + if (!propSym?.declarations?.length) { return false; } const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation(propSym, propSym.declarations[0]); - const initExpr = this.unwrapParenthesized(prop.initializer); + const initExpr = TsUtils.unwrapParenthesized(prop.initializer); if (ts.isObjectLiteralExpression(initExpr)) { if (!this.isObjectLiteralAssignable(propType, initExpr)) { return false; } - } else { + } else if ( + this.needToDeduceStructuralIdentity(propType, this.tsTypeChecker.getTypeAtLocation(initExpr), initExpr) + ) { // Only check for structural sub-typing. - if (this.needToDeduceStructuralIdentity(propType, this.tsTypeChecker.getTypeAtLocation(initExpr), initExpr)) { - return false; - } + return false; } return true; } - validateRecordObjectKeys(objectLiteral: ts.ObjectLiteralExpression): boolean { + static validateRecordObjectKeys(objectLiteral: ts.ObjectLiteralExpression): boolean { for (const prop of objectLiteral.properties) { - if (!prop.name || (!ts.isStringLiteral(prop.name) && !ts.isNumericLiteral(prop.name))) return false; + if (!prop.name || !ts.isStringLiteral(prop.name) && !ts.isNumericLiteral(prop.name)) { + return false; + } } return true; } - getTargetType(type: ts.Type): ts.Type { - return type.getFlags() & ts.TypeFlags.Object && (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference - ? (type as ts.TypeReference).target - : type; + static getTargetType(type: ts.Type): ts.Type { + return type.getFlags() & ts.TypeFlags.Object && (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference ? + (type as ts.TypeReference).target : + type; } - private isSupportedTypeNodeKind(kind: ts.SyntaxKind): boolean { + private static isSupportedTypeNodeKind(kind: ts.SyntaxKind): boolean { return ( kind !== ts.SyntaxKind.AnyKeyword && kind !== ts.SyntaxKind.UnknownKeyword && @@ -901,38 +1001,62 @@ export class TsUtils { ); } - public isSupportedType(typeNode: ts.TypeNode): boolean { - if (ts.isParenthesizedTypeNode(typeNode)) return this.isSupportedType(typeNode.type); + private isSupportedTypeHandleUnionTypeNode(typeNode: ts.UnionTypeNode): boolean { + for (const unionTypeElem of typeNode.types) { + if (!this.isSupportedType(unionTypeElem)) { + return false; + } + } + return true; + } + + private isSupportedTypeHandleTupleTypeNode(typeNode: ts.TupleTypeNode): boolean { + for (const elem of typeNode.elements) { + if (ts.isTypeNode(elem) && !this.isSupportedType(elem)) { + return false; + } + if (ts.isNamedTupleMember(elem) && !this.isSupportedType(elem.type)) { + return false; + } + } + return true; + } - if (ts.isArrayTypeNode(typeNode)) return this.isSupportedType(typeNode.elementType); + isSupportedType(typeNode: ts.TypeNode): boolean { + if (ts.isParenthesizedTypeNode(typeNode)) { + return this.isSupportedType(typeNode.type); + } + + if (ts.isArrayTypeNode(typeNode)) { + return this.isSupportedType(typeNode.elementType); + } if (ts.isTypeReferenceNode(typeNode) && typeNode.typeArguments) { - for (const typeArg of typeNode.typeArguments) if (!this.isSupportedType(typeArg)) return false; + for (const typeArg of typeNode.typeArguments) { + if (!this.isSupportedType(typeArg)) { + return false; + } + } return true; } if (ts.isUnionTypeNode(typeNode)) { - for (const unionTypeElem of typeNode.types) if (!this.isSupportedType(unionTypeElem)) return false; - return true; + return this.isSupportedTypeHandleUnionTypeNode(typeNode); } if (ts.isTupleTypeNode(typeNode)) { - for (const elem of typeNode.elements) { - if (ts.isTypeNode(elem) && !this.isSupportedType(elem)) return false; - if (ts.isNamedTupleMember(elem) && !this.isSupportedType(elem.type)) return false; - } - return true; + return this.isSupportedTypeHandleTupleTypeNode(typeNode); } return ( !ts.isTypeLiteralNode(typeNode) && (this.advancedClassChecks || !ts.isTypeQueryNode(typeNode)) && !ts.isIntersectionTypeNode(typeNode) && - this.isSupportedTypeNodeKind(typeNode.kind) + TsUtils.isSupportedTypeNodeKind(typeNode.kind) ); } - public isStructObjectInitializer(objectLiteral: ts.ObjectLiteralExpression): boolean { + isStructObjectInitializer(objectLiteral: ts.ObjectLiteralExpression): boolean { if (ts.isCallLikeExpression(objectLiteral.parent)) { const signature = this.tsTypeChecker.getResolvedSignature(objectLiteral.parent); const signDecl = signature?.declaration; @@ -941,53 +1065,56 @@ export class TsUtils { return false; } - public getParentSymbolName(symbol: ts.Symbol): string | undefined { + getParentSymbolName(symbol: ts.Symbol): string | undefined { const name = this.tsTypeChecker.getFullyQualifiedName(symbol); const dotPosition = name.lastIndexOf('.'); return dotPosition === -1 ? undefined : name.substring(0, dotPosition); } - public isGlobalSymbol(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); + isGlobalSymbol(symbol: ts.Symbol): boolean { + const parentName = this.getParentSymbolName(symbol); return !parentName || parentName === 'global'; } - public isSymbolAPI(symbol: ts.Symbol): boolean { - let parentName = this.getParentSymbolName(symbol); + isSymbolAPI(symbol: ts.Symbol): boolean { + const parentName = this.getParentSymbolName(symbol); return !!parentName && (parentName === 'Symbol' || parentName === 'SymbolConstructor'); } - public isStdSymbol(symbol: ts.Symbol): boolean { + isStdSymbol(symbol: ts.Symbol): boolean { const name = this.tsTypeChecker.getFullyQualifiedName(symbol); return name === 'Symbol' && this.isGlobalSymbol(symbol); } - public isSymbolIterator(symbol: ts.Symbol): boolean { + isSymbolIterator(symbol: ts.Symbol): boolean { return this.isSymbolAPI(symbol) && symbol.name === 'iterator'; } - public isDefaultImport(importSpec: ts.ImportSpecifier): boolean { + static isDefaultImport(importSpec: ts.ImportSpecifier): boolean { return importSpec?.propertyName?.text === 'default'; } - public getStartPos(nodeOrComment: ts.Node | ts.CommentRange): number { + static getStartPos(nodeOrComment: ts.Node | ts.CommentRange): number { return nodeOrComment.kind === ts.SyntaxKind.SingleLineCommentTrivia || - nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia - ? (nodeOrComment as ts.CommentRange).pos - : (nodeOrComment as ts.Node).getStart(); + nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? + (nodeOrComment as ts.CommentRange).pos : + (nodeOrComment as ts.Node).getStart(); } - public getEndPos(nodeOrComment: ts.Node | ts.CommentRange): number { + static getEndPos(nodeOrComment: ts.Node | ts.CommentRange): number { return nodeOrComment.kind === ts.SyntaxKind.SingleLineCommentTrivia || - nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia - ? (nodeOrComment as ts.CommentRange).end - : (nodeOrComment as ts.Node).getEnd(); + nodeOrComment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? + (nodeOrComment as ts.CommentRange).end : + (nodeOrComment as ts.Node).getEnd(); } - public isStdRecordType(type: ts.Type): boolean { - // In TypeScript, 'Record' is defined as type alias to a mapped type. - // Thus, it should have 'aliasSymbol' and 'target' properties. The 'target' - // in this case will resolve to origin 'Record' symbol. + isStdRecordType(type: ts.Type): boolean { + + /* + * In TypeScript, 'Record' is defined as type alias to a mapped type. + * Thus, it should have 'aliasSymbol' and 'target' properties. The 'target' + * in this case will resolve to origin 'Record' symbol. + */ if (type.aliasSymbol) { const target = (type as ts.TypeReference).target; if (target) { @@ -999,7 +1126,7 @@ export class TsUtils { return false; } - public isStdErrorType(type: ts.Type): boolean { + isStdErrorType(type: ts.Type): boolean { const symbol = type.symbol; if (!symbol) { return false; @@ -1008,22 +1135,22 @@ export class TsUtils { return name === 'Error' && this.isGlobalSymbol(symbol); } - public isStdPartialType(type: ts.Type): boolean { + isStdPartialType(type: ts.Type): boolean { const sym = type.aliasSymbol; return !!sym && sym.getName() === 'Partial' && this.isGlobalSymbol(sym); } - public isStdRequiredType(type: ts.Type): boolean { + isStdRequiredType(type: ts.Type): boolean { const sym = type.aliasSymbol; return !!sym && sym.getName() === 'Required' && this.isGlobalSymbol(sym); } - public isStdReadonlyType(type: ts.Type): boolean { + isStdReadonlyType(type: ts.Type): boolean { const sym = type.aliasSymbol; return !!sym && sym.getName() === 'Readonly' && this.isGlobalSymbol(sym); } - public isLibraryType(type: ts.Type): boolean { + isLibraryType(type: ts.Type): boolean { const nonNullableType = type.getNonNullableType(); if (nonNullableType.isUnion()) { for (const componentType of nonNullableType.types) { @@ -1036,52 +1163,66 @@ export class TsUtils { return this.isLibrarySymbol(nonNullableType.aliasSymbol ?? nonNullableType.getSymbol()); } - public hasLibraryType(node: ts.Node): boolean { + hasLibraryType(node: ts.Node): boolean { return this.isLibraryType(this.tsTypeChecker.getTypeAtLocation(node)); } - public isLibrarySymbol(sym: ts.Symbol | undefined): boolean { - if (sym && sym.declarations && sym.declarations.length > 0) { + isLibrarySymbol(sym: ts.Symbol | undefined): boolean { + if (sym?.declarations && sym.declarations.length > 0) { const srcFile = sym.declarations[0].getSourceFile(); if (!srcFile) { return false; } const fileName = srcFile.fileName; - // Symbols from both *.ts and *.d.ts files should obey interop rules. - // We disable such behavior for *.ts files in the test mode due to lack of 'ets' - // extension support. + + /* + * Symbols from both *.ts and *.d.ts files should obey interop rules. + * We disable such behavior for *.ts files in the test mode due to lack of 'ets' + * extension support. + */ const ext = path.extname(fileName).toLowerCase(); const isThirdPartyCode = - ARKTS_IGNORE_DIRS.some((ignore) => pathContainsDirectory(path.normalize(fileName), ignore)) || - ARKTS_IGNORE_FILES.some((ignore) => path.basename(fileName) === ignore); + ARKTS_IGNORE_DIRS.some((ignore) => { + return pathContainsDirectory(path.normalize(fileName), ignore); + }) || + ARKTS_IGNORE_FILES.some((ignore) => { + return path.basename(fileName) === ignore; + }); const isEts = ext === '.ets'; const isTs = ext === '.ts' && !srcFile.isDeclarationFile; - const isStatic = (isEts || (isTs && this.testMode)) && !isThirdPartyCode; + const isStatic = (isEts || isTs && this.testMode) && !isThirdPartyCode; const isStdLib = STANDARD_LIBRARIES.includes(path.basename(fileName).toLowerCase()); - // We still need to confirm support for certain API from the - // TypeScript standard library in ArkTS. Thus, for now do not - // count standard library modules as dynamic. + + /* + * We still need to confirm support for certain API from the + * TypeScript standard library in ArkTS. Thus, for now do not + * count standard library modules as dynamic. + */ return !isStatic && !isStdLib; } return false; } - public isDynamicType(type: ts.Type | undefined): boolean | undefined { + isDynamicType(type: ts.Type | undefined): boolean | undefined { if (type === undefined) { return false; } - // Return 'true' if it is an object of library type initialization, otherwise - // return 'false' if it is not an object of standard library type one. - // In the case of standard library type we need to determine context. + /* + * Return 'true' if it is an object of library type initialization, otherwise + * return 'false' if it is not an object of standard library type one. + * In the case of standard library type we need to determine context. + */ - // Check the non-nullable version of type to eliminate 'undefined' type - // from the union type elements. + /* + * Check the non-nullable version of type to eliminate 'undefined' type + * from the union type elements. + */ type = type.getNonNullableType(); if (type.isUnion()) { - for (let compType of type.types) { - let isDynamic = this.isDynamicType(compType); + for (const compType of type.types) { + const isDynamic = this.isDynamicType(compType); if (isDynamic || isDynamic === undefined) { return isDynamic; } @@ -1093,35 +1234,63 @@ export class TsUtils { return true; } - if (!isStdLibraryType(type) && !isIntrinsicObjectType(type) && !this.isAnyType(type)) { + if (!isStdLibraryType(type) && !isIntrinsicObjectType(type) && !TsUtils.isAnyType(type)) { return false; } return undefined; } - public isObjectType(type: ts.Type): type is ts.ObjectType { + static isObjectType(type: ts.Type): type is ts.ObjectType { return !!(type.flags & ts.TypeFlags.Object); } - private isAnonymous(type: ts.Type): boolean { - if (this.isObjectType(type)) { + private static isAnonymous(type: ts.Type): boolean { + if (TsUtils.isObjectType(type)) { return !!(type.objectFlags & ts.ObjectFlags.Anonymous); } return false; } - public isDynamicLiteralInitializer(expr: ts.Expression): boolean { + private isDynamicLiteralInitializerHandleCallExpression(callExpr: ts.CallExpression): boolean { + const type = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); + + if (TsUtils.isAnyType(type)) { + return true; + } + + let sym: ts.Symbol | undefined = type.symbol; + if (this.isLibrarySymbol(sym)) { + return true; + } + + /* + * #13483: + * x.foo({ ... }), where 'x' is exported from some library: + */ + if (ts.isPropertyAccessExpression(callExpr.expression)) { + sym = this.trueSymbolAtLocation(callExpr.expression.expression); + if (sym && this.isLibrarySymbol(sym)) { + return true; + } + } + + return false; + } + + isDynamicLiteralInitializer(expr: ts.Expression): boolean { if (!ts.isObjectLiteralExpression(expr) && !ts.isArrayLiteralExpression(expr)) { return false; } - // Handle nested literals: - // { f: { ... } } + /* + * Handle nested literals: + * { f: { ... } } + */ let curNode: ts.Node = expr; while (ts.isObjectLiteralExpression(curNode) || ts.isArrayLiteralExpression(curNode)) { const exprType = this.tsTypeChecker.getContextualType(curNode); - if (exprType !== undefined && !this.isAnonymous(exprType)) { + if (exprType !== undefined && !TsUtils.isAnonymous(exprType)) { const res = this.isDynamicType(exprType); if (res !== undefined) { return res; @@ -1134,37 +1303,22 @@ export class TsUtils { } } - // Handle calls with literals: - // foo({ ... }) - if (ts.isCallExpression(curNode)) { - const callExpr = curNode as ts.CallExpression; - const type = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); - - if (this.isAnyType(type)) { - return true; - } - - let sym: ts.Symbol | undefined = type.symbol; - if (this.isLibrarySymbol(sym)) { - return true; - } - - // #13483: - // x.foo({ ... }), where 'x' is exported from some library: - if (ts.isPropertyAccessExpression(callExpr.expression)) { - sym = this.trueSymbolAtLocation(callExpr.expression.expression); - if (sym && this.isLibrarySymbol(sym)) { - return true; - } - } + /* + * Handle calls with literals: + * foo({ ... }) + */ + if (ts.isCallExpression(curNode) && this.isDynamicLiteralInitializerHandleCallExpression(curNode)) { + return true; } - // Handle property assignments with literals: - // obj.f = { ... } + /* + * Handle property assignments with literals: + * obj.f = { ... } + */ if (ts.isBinaryExpression(curNode)) { - const binExpr = curNode as ts.BinaryExpression; + const binExpr = curNode; if (ts.isPropertyAccessExpression(binExpr.left)) { - const propAccessExpr = binExpr.left as ts.PropertyAccessExpression; + const propAccessExpr = binExpr.left; const type = this.tsTypeChecker.getTypeAtLocation(propAccessExpr.expression); return this.isLibrarySymbol(type.symbol); } @@ -1173,16 +1327,16 @@ export class TsUtils { return false; } - public isEsObjectType(typeNode: ts.TypeNode | undefined): boolean { + static isEsObjectType(typeNode: ts.TypeNode | undefined): boolean { return ( !!typeNode && ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName) && - typeNode.typeName.text == ES_OBJECT + typeNode.typeName.text === ES_OBJECT ); } - public isInsideBlock(node: ts.Node): boolean { + static isInsideBlock(node: ts.Node): boolean { let par = node.parent; while (par) { if (ts.isBlock(par)) { @@ -1193,58 +1347,58 @@ export class TsUtils { return false; } - public isEsObjectPossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean { + static isEsObjectPossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean { return ts.isVariableDeclaration(typeRef.parent); } - public isValueAssignableToESObject(node: ts.Node): boolean { + isValueAssignableToESObject(node: ts.Node): boolean { if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) { return false; } const valueType = this.tsTypeChecker.getTypeAtLocation(node); - return this.isUnsupportedType(valueType) || this.isAnonymousType(valueType); + return TsUtils.isUnsupportedType(valueType) || TsUtils.isAnonymousType(valueType); } - public getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { - let sym = this.trueSymbolAtLocation(node); + getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { + const sym = this.trueSymbolAtLocation(node); if (sym === undefined) { return undefined; } - return this.getSymbolDeclarationTypeNode(sym); + return TsUtils.getSymbolDeclarationTypeNode(sym); } - public getSymbolDeclarationTypeNode(sym: ts.Symbol): ts.TypeNode | undefined { - const decl = this.getDeclaration(sym); + static getSymbolDeclarationTypeNode(sym: ts.Symbol): ts.TypeNode | undefined { + const decl = TsUtils.getDeclaration(sym); if (!!decl && ts.isVariableDeclaration(decl)) { return decl.type; } return undefined; } - public hasEsObjectType(node: ts.Node): boolean { + hasEsObjectType(node: ts.Node): boolean { const typeNode = this.getVariableDeclarationTypeNode(node); - return typeNode !== undefined && this.isEsObjectType(typeNode); + return typeNode !== undefined && TsUtils.isEsObjectType(typeNode); } - public symbolHasEsObjectType(sym: ts.Symbol): boolean { - const typeNode = this.getSymbolDeclarationTypeNode(sym); - return typeNode !== undefined && this.isEsObjectType(typeNode); + static symbolHasEsObjectType(sym: ts.Symbol): boolean { + const typeNode = TsUtils.getSymbolDeclarationTypeNode(sym); + return typeNode !== undefined && TsUtils.isEsObjectType(typeNode); } - public isEsObjectSymbol(sym: ts.Symbol): boolean { - let decl = this.getDeclaration(sym); + static isEsObjectSymbol(sym: ts.Symbol): boolean { + const decl = TsUtils.getDeclaration(sym); return ( !!decl && ts.isTypeAliasDeclaration(decl) && - decl.name.escapedText == ES_OBJECT && + decl.name.escapedText === ES_OBJECT && decl.type.kind === ts.SyntaxKind.AnyKeyword ); } - public isAnonymousType(type: ts.Type): boolean { + static isAnonymousType(type: ts.Type): boolean { if (type.isUnionOrIntersection()) { - for (let compType of type.types) { - if (this.isAnonymousType(compType)) { + for (const compType of type.types) { + if (TsUtils.isAnonymousType(compType)) { return true; } } @@ -1256,27 +1410,27 @@ export class TsUtils { ); } - public getSymbolOfCallExpression(callExpr: ts.CallExpression): ts.Symbol | undefined { + getSymbolOfCallExpression(callExpr: ts.CallExpression): ts.Symbol | undefined { const signature = this.tsTypeChecker.getResolvedSignature(callExpr); const signDecl = signature?.getDeclaration(); - if (signDecl && signDecl.name) { + if (signDecl?.name) { return this.trueSymbolAtLocation(signDecl.name); } return undefined; } // has to be re-implemented with local loop detection - public typeIsRecursive(topType: ts.Type, type: ts.Type | undefined = undefined): boolean { - if (type == undefined) { + typeIsRecursive(topType: ts.Type, type: ts.Type | undefined = undefined): boolean { + if (type === undefined) { type = topType; - } else if (type == topType) { + } else if (type === topType) { return true; } else if (type.aliasSymbol) { return false; } if (type.isUnion()) { - for (let unionElem of type.types) { + for (const unionElem of type.types) { if (this.typeIsRecursive(topType, unionElem)) { return true; } @@ -1295,7 +1449,7 @@ export class TsUtils { return false; } - public isClassValueType(type: ts.Type): boolean { + static isClassValueType(type: ts.Type): boolean { if ( (type.flags & ts.TypeFlags.Object) === 0 || ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) === 0 @@ -1305,53 +1459,52 @@ export class TsUtils { return type.symbol && (type.symbol.flags & ts.SymbolFlags.Class) !== 0; } - public isClassObjectExpression(expr: ts.Expression): boolean { - if (!this.isClassValueType(this.tsTypeChecker.getTypeAtLocation(expr))) { + isClassObjectExpression(expr: ts.Expression): boolean { + if (!TsUtils.isClassValueType(this.tsTypeChecker.getTypeAtLocation(expr))) { return false; } - let symbol = this.trueSymbolAtLocation(expr); + const symbol = this.trueSymbolAtLocation(expr); return !symbol || (symbol.flags & ts.SymbolFlags.Class) === 0; } - public isClassTypeExrepssion(expr: ts.Expression): boolean { - let sym = this.trueSymbolAtLocation(expr); + isClassTypeExrepssion(expr: ts.Expression): boolean { + const sym = this.trueSymbolAtLocation(expr); return sym !== undefined && (sym.flags & ts.SymbolFlags.Class) !== 0; } - public isFunctionCalledRecursively(funcExpr: ts.FunctionExpression): boolean { - if (!funcExpr.name) return false; + isFunctionCalledRecursively(funcExpr: ts.FunctionExpression): boolean { + if (!funcExpr.name) { + return false; + } const sym = this.tsTypeChecker.getSymbolAtLocation(funcExpr.name); - if (!sym) return false; + if (!sym) { + return false; + } let found = false; - const self = this; - function visitNode(tsNode: ts.Node) { - // Stop visiting child nodes if finished searching. - if (found) { - return; - } - - if (ts.isCallExpression(tsNode) && ts.isIdentifier(tsNode.expression)) { - const callSym = self.tsTypeChecker.getSymbolAtLocation(tsNode.expression); + const callback = (node: ts.Node): void => { + if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) { + const callSym = this.tsTypeChecker.getSymbolAtLocation(node.expression); if (callSym && callSym === sym) { found = true; - return; } } + }; - // Visit children nodes. - tsNode.forEachChild(visitNode); - } + const stopCondition = (node: ts.Node): boolean => { + void node; + return found; + }; - visitNode(funcExpr); + forEachNodeInSubtree(funcExpr, callback, stopCondition); return found; } - public getTypeOrTypeConstraintAtLocation(expr: ts.Expression): ts.Type { - let type = this.tsTypeChecker.getTypeAtLocation(expr); + getTypeOrTypeConstraintAtLocation(expr: ts.Expression): ts.Type { + const type = this.tsTypeChecker.getTypeAtLocation(expr); if (type.isTypeParameter()) { - let constraint = type.getConstraint(); + const constraint = type.getConstraint(); if (constraint) { return constraint; } diff --git a/linter/src/utils/functions/ContainsThis.ts b/linter/src/utils/functions/ContainsThis.ts index 27018edf6..1a720dad6 100644 --- a/linter/src/utils/functions/ContainsThis.ts +++ b/linter/src/utils/functions/ContainsThis.ts @@ -20,8 +20,10 @@ function scopeContainsThisVisitor(tsNode: ts.Node): boolean { return true; } - // Visit children nodes. Skip any local declaration that defines - // its own scope as it needs to be checked separately. + /* + * Visit children nodes. Skip any local declaration that defines + * its own scope as it needs to be checked separately. + */ const isClassLike = ts.isClassDeclaration(tsNode) || ts.isClassExpression(tsNode); const isFunctionLike = ts.isFunctionDeclaration(tsNode) || ts.isFunctionExpression(tsNode); const isModuleDecl = ts.isModuleDeclaration(tsNode); diff --git a/linter/src/utils/functions/DiagnosticChecker.ts b/linter/src/utils/functions/DiagnosticChecker.ts index 820d24a3e..b64436f90 100644 --- a/linter/src/utils/functions/DiagnosticChecker.ts +++ b/linter/src/utils/functions/DiagnosticChecker.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import * as ts from 'typescript'; +import type * as ts from 'typescript'; export interface DiagnosticChecker { - checkDiagnosticMessage(msgText: string | ts.DiagnosticMessageChain): boolean; + checkDiagnosticMessage: (msgText: string | ts.DiagnosticMessageChain) => boolean; } diff --git a/linter/src/utils/functions/ForEachNodeInSubtree.ts b/linter/src/utils/functions/ForEachNodeInSubtree.ts new file mode 100644 index 000000000..4780f71d8 --- /dev/null +++ b/linter/src/utils/functions/ForEachNodeInSubtree.ts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022-2023 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 type * as ts from 'typescript'; + +export function forEachNodeInSubtree( + node: ts.Node, + cb: (n: ts.Node) => void, + stopCond?: (n: ts.Node) => boolean +): void { + cb(node); + if (stopCond && stopCond(node)) { + return; + } + + /* + * #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. + * As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. + * to traverse child nodes. + */ + for (const child of node.getChildren()) { + forEachNodeInSubtree(child, cb, stopCond); + } +} diff --git a/linter/src/utils/functions/HasPredecessor.ts b/linter/src/utils/functions/HasPredecessor.ts index 8c389cfa1..c3500a3cd 100644 --- a/linter/src/utils/functions/HasPredecessor.ts +++ b/linter/src/utils/functions/HasPredecessor.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import * as ts from 'typescript'; +import type * as ts from 'typescript'; export function hasPredecessor(node: ts.Node, predicate: (node: ts.Node) => boolean): boolean { let parent = node.parent; diff --git a/linter/src/utils/functions/IsStdLibrary.ts b/linter/src/utils/functions/IsStdLibrary.ts index 8471acb26..3df8028ee 100644 --- a/linter/src/utils/functions/IsStdLibrary.ts +++ b/linter/src/utils/functions/IsStdLibrary.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import * as ts from 'typescript'; +import type * as ts from 'typescript'; import * as path from 'node:path'; import { STANDARD_LIBRARIES } from '../consts/StandardLibraries'; @@ -21,8 +21,8 @@ export function isStdLibraryType(type: ts.Type): boolean { return isStdLibrarySymbol(type.aliasSymbol ?? type.getSymbol()); } -export function isStdLibrarySymbol(sym: ts.Symbol | undefined) { - if (sym && sym.declarations && sym.declarations.length > 0) { +export function isStdLibrarySymbol(sym: ts.Symbol | undefined): boolean { + if (sym?.declarations && sym.declarations.length > 0) { const srcFile = sym.declarations[0].getSourceFile(); return srcFile && STANDARD_LIBRARIES.includes(path.basename(srcFile.fileName).toLowerCase()); } diff --git a/linter/src/utils/functions/IsStruct.ts b/linter/src/utils/functions/IsStruct.ts index 4ba05fe20..66ca6708a 100644 --- a/linter/src/utils/functions/IsStruct.ts +++ b/linter/src/utils/functions/IsStruct.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import * as ts from 'typescript'; +import type * as ts from 'typescript'; import { LinterConfig } from '../../TypeScriptLinterConfig'; -export function isStruct(symbol: ts.Symbol) { +export function isStruct(symbol: ts.Symbol): boolean { if (!symbol.declarations) { return false; } @@ -28,10 +28,10 @@ export function isStruct(symbol: ts.Symbol) { return false; } -export function isStructDeclarationKind(kind: ts.SyntaxKind) { +export function isStructDeclarationKind(kind: ts.SyntaxKind): boolean { return LinterConfig.tsSyntaxKindNames[kind] === 'StructDeclaration'; } -export function isStructDeclaration(node: ts.Node) { +export function isStructDeclaration(node: ts.Node): boolean { return isStructDeclarationKind(node.kind); } diff --git a/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts b/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts index 1fee64b82..fb17ba5b7 100644 --- a/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts +++ b/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts @@ -13,11 +13,13 @@ * limitations under the License. */ -import * as ts from 'typescript'; -import { DiagnosticChecker } from './DiagnosticChecker'; +import type * as ts from 'typescript'; +import type { DiagnosticChecker } from './DiagnosticChecker'; -// Current approach relates on error code and error message matching and it is quite fragile, -// so this place should be checked thoroughly in the case of typescript upgrade +/* + * Current approach relates on error code and error message matching and it is quite fragile, + * so this place should be checked thoroughly in the case of typescript upgrade + */ export const TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE = 2322; export const TYPE_UNKNOWN_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE = /^Type '(.*)\bunknown\b(.*)' is not assignable to type '.*'\.$/; @@ -40,7 +42,7 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { this.filteredDiagnosticMessages = filteredDiagnosticMessages; } - configure(inLibCall: boolean, diagnosticMessages: Array) { + configure(inLibCall: boolean, diagnosticMessages: Array): void { this.inLibCall = inLibCall; this.diagnosticMessages = diagnosticMessages; } @@ -58,7 +60,7 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { } checkMessageChain(chain: ts.DiagnosticMessageChain): boolean { - if (chain.code == TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE) { + if (chain.code === TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE) { if (chain.messageText.match(TYPE_UNKNOWN_IS_NOT_ASSIGNABLE_TO_TYPE_1_RE)) { return false; } @@ -69,7 +71,7 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { return false; } } - if (chain.code == ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE) { + if (chain.code === ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE) { if ( this.inLibCall && chain.messageText.match(ARGUMENT_OF_TYPE_UNDEFINED_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_RE) @@ -83,11 +85,11 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { return false; } } - return chain.next == undefined ? true : this.checkMessageChain(chain.next[0]); + return chain.next === undefined ? true : this.checkMessageChain(chain.next[0]); } - checkFilteredDiagnosticMessages(msgText: ts.DiagnosticMessageChain | string) { - if (this.filteredDiagnosticMessages.size == 0) { + checkFilteredDiagnosticMessages(msgText: ts.DiagnosticMessageChain | string): boolean { + if (this.filteredDiagnosticMessages.size === 0) { return true; } @@ -97,7 +99,7 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { for (const msgChain of this.filteredDiagnosticMessages) { if (typeof msgText == 'string') { - if (msgText == msgChain.messageText) { + if (msgText === msgChain.messageText) { return false; } continue; @@ -110,11 +112,11 @@ export class LibraryTypeCallDiagnosticChecker implements DiagnosticChecker { return true; } - if (curMsg.code != curFilteredMsg.code) { + if (curMsg.code !== curFilteredMsg.code) { return true; } - if (curMsg.messageText != curFilteredMsg.messageText) { + if (curMsg.messageText !== curFilteredMsg.messageText) { return true; } diff --git a/linter/src/utils/functions/LogTscDiagnostic.ts b/linter/src/utils/functions/LogTscDiagnostic.ts index a5b217420..a12d9c4e2 100644 --- a/linter/src/utils/functions/LogTscDiagnostic.ts +++ b/linter/src/utils/functions/LogTscDiagnostic.ts @@ -15,7 +15,10 @@ import * as ts from 'typescript'; -export function logTscDiagnostic(diagnostics: readonly ts.Diagnostic[], log: (message: any, ...args: any[]) => void) { +export function logTscDiagnostic( + diagnostics: readonly ts.Diagnostic[], + log: (message: unknown, ...args: unknown[]) => void +): void { diagnostics.forEach((diagnostic) => { let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); diff --git a/linter/src/utils/functions/MergeArrayMaps.ts b/linter/src/utils/functions/MergeArrayMaps.ts index 3e9a98fa3..fa37711e0 100644 --- a/linter/src/utils/functions/MergeArrayMaps.ts +++ b/linter/src/utils/functions/MergeArrayMaps.ts @@ -14,15 +14,15 @@ */ export function mergeArrayMaps(lhs: Map, rhs: Map): Map { - if (lhs.size == 0) { + if (lhs.size === 0) { return rhs; } - if (rhs.size == 0) { + if (rhs.size === 0) { return lhs; } rhs.forEach((values, key) => { - if (values.length != 0) { + if (values.length !== 0) { if (lhs.has(key)) { lhs.get(key)!.push(...values); } else { diff --git a/linter/src/utils/functions/identiferUseInValueContext.ts b/linter/src/utils/functions/identiferUseInValueContext.ts index 0a8d82bc6..0ebd1ed97 100644 --- a/linter/src/utils/functions/identiferUseInValueContext.ts +++ b/linter/src/utils/functions/identiferUseInValueContext.ts @@ -26,6 +26,10 @@ function isNewExpressionContext(tsIdentStart: ts.Node): boolean { return ts.isNewExpression(tsIdentStart.parent) && tsIdentStart === tsIdentStart.parent.expression; } +/* + * If identifier is the right-most name of Property Access chain or Qualified name, + * or it's a separate identifier expression, then identifier is being referenced as an value. + */ function isQualifiedNameContext(tsIdentStart: ts.Node, tsIdentifier: ts.Identifier): boolean { // rightmost in AST is rightmost in qualified name chain return ts.isQualifiedName(tsIdentStart) && tsIdentifier !== tsIdentStart.right; @@ -48,41 +52,39 @@ function isEnumPropAccess(ident: ts.Identifier, tsSym: ts.Symbol, context: ts.No return ( ts.isElementAccessExpression(context) && !!(tsSym.flags & ts.SymbolFlags.Enum) && - (context.expression == ident || - (ts.isPropertyAccessExpression(context.expression) && context.expression.name == ident)) + (context.expression === ident || + ts.isPropertyAccessExpression(context.expression) && context.expression.name === ident) ); } -function isValidTypeNode(node: ts.TypeNode): boolean { - return !ts.isTypeOfExpression(node); -} - -export function identiferUseInValueContext(ident: ts.Identifier, tsSym: ts.Symbol) { - let qualifiedStart = getQualifiedStart(ident); - let parent = qualifiedStart.parent; - return !( - // treat TypeQuery as valid because it's already forbidden (FaultID.TypeQuery) - ( - (ts.isTypeNode(parent) && isValidTypeNode(parent)) || - // If identifier is the right-most name of Property Access chain or Qualified name, - // or it's a separate identifier expression, then identifier is being referenced as an value. - isEnumPropAccess(ident, tsSym, parent) || - ts.isExpressionWithTypeArguments(parent) || - ts.isExportAssignment(parent) || - ts.isExportSpecifier(parent) || - ts.isMetaProperty(parent) || - ts.isImportClause(parent) || - ts.isClassLike(parent) || - ts.isInterfaceDeclaration(parent) || - ts.isModuleDeclaration(parent) || - ts.isEnumDeclaration(parent) || - ts.isNamespaceImport(parent) || - ts.isImportSpecifier(parent) || - isQualifiedNameContext(qualifiedStart, ident) || - isPropertyAccessContext(qualifiedStart, ident) || - isNewExpressionContext(qualifiedStart) || - isInstanceofContext(qualifiedStart) || - ts.isImportEqualsDeclaration(parent) - ) +function isValidParent(parent: ts.Node): boolean { + // treat TypeQuery as valid because it's already forbidden (FaultID.TypeQuery) + return ( + ts.isTypeNode(parent) && !ts.isTypeOfExpression(parent) || + ts.isExpressionWithTypeArguments(parent) || + ts.isExportAssignment(parent) || + ts.isExportSpecifier(parent) || + ts.isMetaProperty(parent) || + ts.isImportClause(parent) || + ts.isClassLike(parent) || + ts.isInterfaceDeclaration(parent) || + ts.isModuleDeclaration(parent) || + ts.isEnumDeclaration(parent) || + ts.isNamespaceImport(parent) || + ts.isImportSpecifier(parent) || + ts.isImportEqualsDeclaration(parent) ); } + +export function identiferUseInValueContext(ident: ts.Identifier, tsSym: ts.Symbol): boolean { + const qualifiedStart = getQualifiedStart(ident); + const parent = qualifiedStart.parent; + const isValidUse = + isValidParent(parent) || + isEnumPropAccess(ident, tsSym, parent) || + isQualifiedNameContext(qualifiedStart, ident) || + isPropertyAccessContext(qualifiedStart, ident) || + isNewExpressionContext(qualifiedStart) || + isInstanceofContext(qualifiedStart); + return !isValidUse; +} -- Gitee From 417ef249802c7cef9c3987161846578897b91a68 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 13 Nov 2023 22:46:30 +0300 Subject: [PATCH 31/49] [ArkTS Linter] #14415: Fix 'property-access-by-index' check when base expression is nullable type. Change-Id: I44e032cd028c822c1fcd610d692bfa6d1601a01e Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 4 +++- linter-4.2/src/Utils.ts | 2 +- linter-4.2/test/property_access_by_index.ts | 12 ++++++++++++ linter/src/TypeScriptLinter.ts | 4 +++- linter/src/utils/TsUtils.ts | 2 +- linter/test/property_access_by_index.ts | 12 ++++++++++++ 6 files changed, 32 insertions(+), 4 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 91aae8d38..ff8e7ea24 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1588,7 +1588,9 @@ export class TypeScriptLinter { private handleElementAccessExpression(node: ts.Node) { const tsElementAccessExpr = node as ts.ElementAccessExpression; - const tsElemAccessBaseExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression); + const tsElemAccessBaseExprType = this.tsUtils.getNonNullableType( + this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) + ); const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode( tsElemAccessBaseExprType, undefined, diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 9c6531412..fd80bc577 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -918,7 +918,7 @@ export class TsUtils { return true; } - private getNonNullableType(t: ts.Type) { + public getNonNullableType(t: ts.Type) { if (this.isNullableUnionType(t)) { return t.getNonNullableType(); } diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index 03b2c8f71..1f2ef598d 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -119,3 +119,15 @@ while (!!tmp_arr) { console.log(tmp_arr[0]) tmp_arr = iter_arr.next().value } + +// #14415 +class ArrayContainer { + numbers: number[] = []; +} +class NullableArray { + container: ArrayContainer | null = null; + + print() { + console.log(this.container?.numbers[0]); + } +} \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 436d4f540..d2e12bef0 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1456,7 +1456,9 @@ export class TypeScriptLinter { private handleElementAccessExpression(node: ts.Node): void { const tsElementAccessExpr = node as ts.ElementAccessExpression; - const tsElemAccessBaseExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression); + let tsElemAccessBaseExprType = TsUtils.getNonNullableType( + this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) + ); const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode( tsElemAccessBaseExprType, undefined, diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index 2b9ed9922..d9de50374 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -858,7 +858,7 @@ export class TsUtils { return true; } - private static getNonNullableType(t: ts.Type): ts.Type { + public static getNonNullableType(t: ts.Type): ts.Type { if (TsUtils.isNullableUnionType(t)) { return t.getNonNullableType(); } diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index d7cd6781f..1f2ef598d 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -118,4 +118,16 @@ let tmp_arr = iter_arr.next().value; while (!!tmp_arr) { console.log(tmp_arr[0]) tmp_arr = iter_arr.next().value +} + +// #14415 +class ArrayContainer { + numbers: number[] = []; +} +class NullableArray { + container: ArrayContainer | null = null; + + print() { + console.log(this.container?.numbers[0]); + } } \ No newline at end of file -- Gitee From a53bd43f7833f21934e13234f5a430399bebe4bb Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Tue, 14 Nov 2023 13:23:07 +0300 Subject: [PATCH 32/49] [ArkTS][Linter] Extract library part from linter Signed-off-by: Urakov Alexandr --- linter/{src => lib}/Autofixer.ts | 0 linter/{src => lib}/CommandLineOptions.ts | 0 linter/lib/Compiler.ts | 38 +++++++++++++ linter/{src => lib}/CookBookMsg.ts | 0 linter/{src => lib}/FaultAttrs.ts | 0 linter/{src => lib}/FaultDesc.ts | 0 linter/{src => lib}/IncrementalLintInfo.ts | 0 .../{src => lib}/IsFileFromModuleCallback.ts | 0 linter/{src => lib}/LintOptions.ts | 0 linter/{src => lib}/LintRunResult.ts | 0 linter/{src => lib}/LinterRunner.ts | 4 +- linter/lib/Logger.ts | 55 +++++++++++++++++++ linter/{src => lib}/ProblemInfo.ts | 0 linter/{src => lib}/ProblemSeverity.ts | 0 linter/{src => lib}/Problems.ts | 0 linter/{src => lib}/TypeScriptLinter.ts | 10 ++-- linter/{src => lib}/TypeScriptLinterConfig.ts | 0 linter/{src => lib}/autofixes/AutofixInfo.ts | 0 .../{src => lib}/autofixes/AutofixTitles.ts | 0 .../autofixes/ReportAutofixCallback.ts | 0 .../ts-diagnostics/GetTscDiagnostics.ts | 0 .../ts-diagnostics/TSCCompiledProgram.ts | 4 +- .../ts-diagnostics/TransformTscDiagnostics.ts | 0 .../TypeScriptDiagnosticsExtractor.ts | 0 linter/{src => lib}/utils/TsUtils.ts | 2 +- .../utils/consts/AllowedStdSymbolAPI.ts | 0 .../utils/consts/ArkUIDecorators.ts | 0 .../utils/consts/ArktsIgnorePaths.ts | 0 linter/{src => lib}/utils/consts/ESObject.ts | 0 .../consts/FunctionHasNoReturnErrorCode.ts | 0 .../consts/LimitedStandardUtilityTypes.ts | 0 .../utils/consts/LimitedStdGlobalFunc.ts | 0 .../utils/consts/LimitedStdObjectAPI.ts | 0 .../utils/consts/LimitedStdProxyHandlerAPI.ts | 0 .../utils/consts/LimitedStdReflectAPI.ts | 0 .../NonInitializablePropertyDecorators.ts | 0 .../consts/NonReturnFunctionDecorators.ts | 0 .../PropertyHasNoInitializerErrorCode.ts | 0 .../utils/consts/StandardLibraries.ts | 0 .../{src => lib}/utils/consts/TypedArrays.ts | 0 .../utils/functions/ContainsThis.ts | 0 .../utils/functions/DiagnosticChecker.ts | 0 .../utils/functions/ForEachNodeInSubtree.ts | 0 .../utils/functions/GetScriptKind.ts | 0 .../utils/functions/HasPredecessor.ts | 0 .../utils/functions/IsStdLibrary.ts | 0 .../{src => lib}/utils/functions/IsStruct.ts | 0 .../LibraryTypeCallDiagnosticChecker.ts | 0 .../utils/functions/LinterInfo.ts | 0 .../utils/functions/LogTscDiagnostic.ts | 5 +- .../utils/functions/MergeArrayMaps.ts | 0 .../utils/functions/PathHelper.ts | 0 .../functions/identiferUseInValueContext.ts | 0 .../utils/functions/isAssignmentOperator.ts | 0 .../utils/functions/isIntrinsicObjectType.ts | 0 linter/package.json | 4 +- linter/src/CommandLineParser.ts | 22 ++++---- .../{CompilerWrapper.ts => CompilerImpl.ts} | 45 ++++++++------- linter/src/LinterCLI.ts | 16 +++--- linter/src/LoggerImpl.ts | 44 +++++++++++++++ linter/src/TestRunner.ts | 37 +++++++------ linter/src/main.ts | 8 +++ linter/src/ts-compiler/FormTscOptions.ts | 2 +- linter/tsconfig.json | 4 +- 64 files changed, 223 insertions(+), 77 deletions(-) rename linter/{src => lib}/Autofixer.ts (100%) rename linter/{src => lib}/CommandLineOptions.ts (100%) create mode 100644 linter/lib/Compiler.ts rename linter/{src => lib}/CookBookMsg.ts (100%) rename linter/{src => lib}/FaultAttrs.ts (100%) rename linter/{src => lib}/FaultDesc.ts (100%) rename linter/{src => lib}/IncrementalLintInfo.ts (100%) rename linter/{src => lib}/IsFileFromModuleCallback.ts (100%) rename linter/{src => lib}/LintOptions.ts (100%) rename linter/{src => lib}/LintRunResult.ts (100%) rename linter/{src => lib}/LinterRunner.ts (98%) create mode 100644 linter/lib/Logger.ts rename linter/{src => lib}/ProblemInfo.ts (100%) rename linter/{src => lib}/ProblemSeverity.ts (100%) rename linter/{src => lib}/Problems.ts (100%) rename linter/{src => lib}/TypeScriptLinter.ts (99%) rename linter/{src => lib}/TypeScriptLinterConfig.ts (100%) rename linter/{src => lib}/autofixes/AutofixInfo.ts (100%) rename linter/{src => lib}/autofixes/AutofixTitles.ts (100%) rename linter/{src => lib}/autofixes/ReportAutofixCallback.ts (100%) rename linter/{src => lib}/ts-diagnostics/GetTscDiagnostics.ts (100%) rename linter/{src => lib}/ts-diagnostics/TSCCompiledProgram.ts (97%) rename linter/{src => lib}/ts-diagnostics/TransformTscDiagnostics.ts (100%) rename linter/{src => lib}/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts (100%) rename linter/{src => lib}/utils/TsUtils.ts (99%) rename linter/{src => lib}/utils/consts/AllowedStdSymbolAPI.ts (100%) rename linter/{src => lib}/utils/consts/ArkUIDecorators.ts (100%) rename linter/{src => lib}/utils/consts/ArktsIgnorePaths.ts (100%) rename linter/{src => lib}/utils/consts/ESObject.ts (100%) rename linter/{src => lib}/utils/consts/FunctionHasNoReturnErrorCode.ts (100%) rename linter/{src => lib}/utils/consts/LimitedStandardUtilityTypes.ts (100%) rename linter/{src => lib}/utils/consts/LimitedStdGlobalFunc.ts (100%) rename linter/{src => lib}/utils/consts/LimitedStdObjectAPI.ts (100%) rename linter/{src => lib}/utils/consts/LimitedStdProxyHandlerAPI.ts (100%) rename linter/{src => lib}/utils/consts/LimitedStdReflectAPI.ts (100%) rename linter/{src => lib}/utils/consts/NonInitializablePropertyDecorators.ts (100%) rename linter/{src => lib}/utils/consts/NonReturnFunctionDecorators.ts (100%) rename linter/{src => lib}/utils/consts/PropertyHasNoInitializerErrorCode.ts (100%) rename linter/{src => lib}/utils/consts/StandardLibraries.ts (100%) rename linter/{src => lib}/utils/consts/TypedArrays.ts (100%) rename linter/{src => lib}/utils/functions/ContainsThis.ts (100%) rename linter/{src => lib}/utils/functions/DiagnosticChecker.ts (100%) rename linter/{src => lib}/utils/functions/ForEachNodeInSubtree.ts (100%) rename linter/{src => lib}/utils/functions/GetScriptKind.ts (100%) rename linter/{src => lib}/utils/functions/HasPredecessor.ts (100%) rename linter/{src => lib}/utils/functions/IsStdLibrary.ts (100%) rename linter/{src => lib}/utils/functions/IsStruct.ts (100%) rename linter/{src => lib}/utils/functions/LibraryTypeCallDiagnosticChecker.ts (100%) rename linter/{src => lib}/utils/functions/LinterInfo.ts (100%) rename linter/{src => lib}/utils/functions/LogTscDiagnostic.ts (88%) rename linter/{src => lib}/utils/functions/MergeArrayMaps.ts (100%) rename linter/{src => lib}/utils/functions/PathHelper.ts (100%) rename linter/{src => lib}/utils/functions/identiferUseInValueContext.ts (100%) rename linter/{src => lib}/utils/functions/isAssignmentOperator.ts (100%) rename linter/{src => lib}/utils/functions/isIntrinsicObjectType.ts (100%) rename linter/src/{CompilerWrapper.ts => CompilerImpl.ts} (36%) create mode 100644 linter/src/LoggerImpl.ts diff --git a/linter/src/Autofixer.ts b/linter/lib/Autofixer.ts similarity index 100% rename from linter/src/Autofixer.ts rename to linter/lib/Autofixer.ts diff --git a/linter/src/CommandLineOptions.ts b/linter/lib/CommandLineOptions.ts similarity index 100% rename from linter/src/CommandLineOptions.ts rename to linter/lib/CommandLineOptions.ts diff --git a/linter/lib/Compiler.ts b/linter/lib/Compiler.ts new file mode 100644 index 000000000..b8c2aa553 --- /dev/null +++ b/linter/lib/Compiler.ts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023-2023 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 type { LintOptions } from './LintOptions'; +import type * as ts from 'typescript'; + +export abstract class Compiler { + static init(instance: Compiler): void { + this.instance_ = instance; + } + + static compile(options: LintOptions, extraOptions?: any): ts.Program { + return this.getInstance().doCompile(options, extraOptions); + } + + protected abstract doCompile(options: LintOptions, extraOptions?: any): ts.Program; + + private static getInstance(): Compiler { + if (!this.instance_) { + throw new Error('Not initialized'); + } + return this.instance_; + } + + private static instance_?: Compiler; +} diff --git a/linter/src/CookBookMsg.ts b/linter/lib/CookBookMsg.ts similarity index 100% rename from linter/src/CookBookMsg.ts rename to linter/lib/CookBookMsg.ts diff --git a/linter/src/FaultAttrs.ts b/linter/lib/FaultAttrs.ts similarity index 100% rename from linter/src/FaultAttrs.ts rename to linter/lib/FaultAttrs.ts diff --git a/linter/src/FaultDesc.ts b/linter/lib/FaultDesc.ts similarity index 100% rename from linter/src/FaultDesc.ts rename to linter/lib/FaultDesc.ts diff --git a/linter/src/IncrementalLintInfo.ts b/linter/lib/IncrementalLintInfo.ts similarity index 100% rename from linter/src/IncrementalLintInfo.ts rename to linter/lib/IncrementalLintInfo.ts diff --git a/linter/src/IsFileFromModuleCallback.ts b/linter/lib/IsFileFromModuleCallback.ts similarity index 100% rename from linter/src/IsFileFromModuleCallback.ts rename to linter/lib/IsFileFromModuleCallback.ts diff --git a/linter/src/LintOptions.ts b/linter/lib/LintOptions.ts similarity index 100% rename from linter/src/LintOptions.ts rename to linter/lib/LintOptions.ts diff --git a/linter/src/LintRunResult.ts b/linter/lib/LintRunResult.ts similarity index 100% rename from linter/src/LintRunResult.ts rename to linter/lib/LintRunResult.ts diff --git a/linter/src/LinterRunner.ts b/linter/lib/LinterRunner.ts similarity index 98% rename from linter/src/LinterRunner.ts rename to linter/lib/LinterRunner.ts index 2737bdb76..48254ef0f 100644 --- a/linter/src/LinterRunner.ts +++ b/linter/lib/LinterRunner.ts @@ -21,7 +21,7 @@ import { faultDesc } from './FaultDesc'; import { faultsAttrs } from './FaultAttrs'; import type { LintRunResult } from './LintRunResult'; import * as path from 'node:path'; -import { compile } from './CompilerWrapper'; +import { Compiler } from './Compiler'; import type { LintOptions } from './LintOptions'; import type { CommandLineOptions } from './CommandLineOptions'; import { AutofixInfoSet } from './Autofixer'; @@ -137,7 +137,7 @@ export function createLinter(options: LintOptions): TSCCompiledProgram { if (options.tscDiagnosticsLinter) { return options.tscDiagnosticsLinter; } - const tsProgram = options.tsProgram ?? compile(options, getStrictOptions()); + const tsProgram = options.tsProgram ?? Compiler.compile(options, getStrictOptions()); if (options.realtimeLint) { return new TSCCompiledProgramSimple(tsProgram); } diff --git a/linter/lib/Logger.ts b/linter/lib/Logger.ts new file mode 100644 index 000000000..73002788a --- /dev/null +++ b/linter/lib/Logger.ts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023-2023 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. + */ + +export abstract class Logger { + static init(instance: Logger): void { + this.instance_ = instance; + } + + static trace(message: string): void { + this.getInstance().doTrace(message); + } + + static debug(message: string): void { + this.getInstance().doDebug(message); + } + + static info(message: string): void { + this.getInstance().doInfo(message); + } + + static warn(message: string): void { + this.getInstance().doWarn(message); + } + + static error(message: string): void { + this.getInstance().doError(message); + } + + protected abstract doTrace(message: string): void; + protected abstract doDebug(message: string): void; + protected abstract doInfo(message: string): void; + protected abstract doWarn(message: string): void; + protected abstract doError(message: string): void; + + private static getInstance(): Logger { + if (!this.instance_) { + throw new Error('Not initialized'); + } + return this.instance_; + } + + private static instance_?: Logger; +} diff --git a/linter/src/ProblemInfo.ts b/linter/lib/ProblemInfo.ts similarity index 100% rename from linter/src/ProblemInfo.ts rename to linter/lib/ProblemInfo.ts diff --git a/linter/src/ProblemSeverity.ts b/linter/lib/ProblemSeverity.ts similarity index 100% rename from linter/src/ProblemSeverity.ts rename to linter/lib/ProblemSeverity.ts diff --git a/linter/src/Problems.ts b/linter/lib/Problems.ts similarity index 100% rename from linter/src/Problems.ts rename to linter/lib/Problems.ts diff --git a/linter/src/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts similarity index 99% rename from linter/src/TypeScriptLinter.ts rename to linter/lib/TypeScriptLinter.ts index d2e12bef0..97c357ecb 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -25,7 +25,7 @@ import type { Autofix, AutofixInfoSet } from './Autofixer'; import * as Autofixer from './Autofixer'; import type { ProblemInfo } from './ProblemInfo'; import { ProblemSeverity } from './ProblemSeverity'; -import Logger from '../utils/logger'; +import { Logger } from './Logger'; import { ARKUI_DECORATORS } from './utils/consts/ArkUIDecorators'; import { LIMITED_STD_GLOBAL_FUNC } from './utils/consts/LimitedStdGlobalFunc'; import { LIMITED_STD_OBJECT_API } from './utils/consts/LimitedStdObjectAPI'; @@ -58,8 +58,6 @@ import { } from './utils/functions/LibraryTypeCallDiagnosticChecker'; import { forEachNodeInSubtree } from './utils/functions/ForEachNodeInSubtree'; -const logger = Logger.getLogger(); - export function consoleLog(...args: unknown[]): void { if (TypeScriptLinter.ideMode) { return; @@ -68,7 +66,7 @@ export function consoleLog(...args: unknown[]): void { for (let k = 0; k < args.length; k++) { outLine += `${args[k]} `; } - logger.info(outLine); + Logger.info(outLine); } export class TypeScriptLinter { @@ -202,7 +200,7 @@ export class TypeScriptLinter { } else { const faultDescr = faultDesc[faultId]; const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - logger.info( + Logger.info( `Warning: ${this.sourceFile!.fileName} (${line}, ${character}): ${faultDescr ? faultDescr : faultType}` ); } @@ -1456,7 +1454,7 @@ export class TypeScriptLinter { private handleElementAccessExpression(node: ts.Node): void { const tsElementAccessExpr = node as ts.ElementAccessExpression; - let tsElemAccessBaseExprType = TsUtils.getNonNullableType( + const tsElemAccessBaseExprType = TsUtils.getNonNullableType( this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) ); const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode( diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/lib/TypeScriptLinterConfig.ts similarity index 100% rename from linter/src/TypeScriptLinterConfig.ts rename to linter/lib/TypeScriptLinterConfig.ts diff --git a/linter/src/autofixes/AutofixInfo.ts b/linter/lib/autofixes/AutofixInfo.ts similarity index 100% rename from linter/src/autofixes/AutofixInfo.ts rename to linter/lib/autofixes/AutofixInfo.ts diff --git a/linter/src/autofixes/AutofixTitles.ts b/linter/lib/autofixes/AutofixTitles.ts similarity index 100% rename from linter/src/autofixes/AutofixTitles.ts rename to linter/lib/autofixes/AutofixTitles.ts diff --git a/linter/src/autofixes/ReportAutofixCallback.ts b/linter/lib/autofixes/ReportAutofixCallback.ts similarity index 100% rename from linter/src/autofixes/ReportAutofixCallback.ts rename to linter/lib/autofixes/ReportAutofixCallback.ts diff --git a/linter/src/ts-diagnostics/GetTscDiagnostics.ts b/linter/lib/ts-diagnostics/GetTscDiagnostics.ts similarity index 100% rename from linter/src/ts-diagnostics/GetTscDiagnostics.ts rename to linter/lib/ts-diagnostics/GetTscDiagnostics.ts diff --git a/linter/src/ts-diagnostics/TSCCompiledProgram.ts b/linter/lib/ts-diagnostics/TSCCompiledProgram.ts similarity index 97% rename from linter/src/ts-diagnostics/TSCCompiledProgram.ts rename to linter/lib/ts-diagnostics/TSCCompiledProgram.ts index 6e203aa38..77d288831 100644 --- a/linter/src/ts-diagnostics/TSCCompiledProgram.ts +++ b/linter/lib/ts-diagnostics/TSCCompiledProgram.ts @@ -18,7 +18,7 @@ import type { ProblemInfo } from '../ProblemInfo'; import { ProblemSeverity } from '../ProblemSeverity'; import type { LintOptions } from '../LintOptions'; import { TypeScriptDiagnosticsExtractor } from './TypeScriptDiagnosticsExtractor'; -import { compile } from '../CompilerWrapper'; +import { Compiler } from '../Compiler'; import { FaultID } from '../Problems'; import { faultsAttrs } from '../FaultAttrs'; @@ -94,7 +94,7 @@ function getTwoCompiledVersions( const wasStrict = inverseStrictOptions(compilerOptions); const inversedOptions = getStrictOptions(!wasStrict); - const withInversedOptions = compile(options, inversedOptions); + const withInversedOptions = Compiler.compile(options, inversedOptions); return { strict: wasStrict ? program : withInversedOptions, diff --git a/linter/src/ts-diagnostics/TransformTscDiagnostics.ts b/linter/lib/ts-diagnostics/TransformTscDiagnostics.ts similarity index 100% rename from linter/src/ts-diagnostics/TransformTscDiagnostics.ts rename to linter/lib/ts-diagnostics/TransformTscDiagnostics.ts diff --git a/linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts b/linter/lib/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts similarity index 100% rename from linter/src/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts rename to linter/lib/ts-diagnostics/TypeScriptDiagnosticsExtractor.ts diff --git a/linter/src/utils/TsUtils.ts b/linter/lib/utils/TsUtils.ts similarity index 99% rename from linter/src/utils/TsUtils.ts rename to linter/lib/utils/TsUtils.ts index d9de50374..e3cd75be8 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/lib/utils/TsUtils.ts @@ -858,7 +858,7 @@ export class TsUtils { return true; } - public static getNonNullableType(t: ts.Type): ts.Type { + static getNonNullableType(t: ts.Type): ts.Type { if (TsUtils.isNullableUnionType(t)) { return t.getNonNullableType(); } diff --git a/linter/src/utils/consts/AllowedStdSymbolAPI.ts b/linter/lib/utils/consts/AllowedStdSymbolAPI.ts similarity index 100% rename from linter/src/utils/consts/AllowedStdSymbolAPI.ts rename to linter/lib/utils/consts/AllowedStdSymbolAPI.ts diff --git a/linter/src/utils/consts/ArkUIDecorators.ts b/linter/lib/utils/consts/ArkUIDecorators.ts similarity index 100% rename from linter/src/utils/consts/ArkUIDecorators.ts rename to linter/lib/utils/consts/ArkUIDecorators.ts diff --git a/linter/src/utils/consts/ArktsIgnorePaths.ts b/linter/lib/utils/consts/ArktsIgnorePaths.ts similarity index 100% rename from linter/src/utils/consts/ArktsIgnorePaths.ts rename to linter/lib/utils/consts/ArktsIgnorePaths.ts diff --git a/linter/src/utils/consts/ESObject.ts b/linter/lib/utils/consts/ESObject.ts similarity index 100% rename from linter/src/utils/consts/ESObject.ts rename to linter/lib/utils/consts/ESObject.ts diff --git a/linter/src/utils/consts/FunctionHasNoReturnErrorCode.ts b/linter/lib/utils/consts/FunctionHasNoReturnErrorCode.ts similarity index 100% rename from linter/src/utils/consts/FunctionHasNoReturnErrorCode.ts rename to linter/lib/utils/consts/FunctionHasNoReturnErrorCode.ts diff --git a/linter/src/utils/consts/LimitedStandardUtilityTypes.ts b/linter/lib/utils/consts/LimitedStandardUtilityTypes.ts similarity index 100% rename from linter/src/utils/consts/LimitedStandardUtilityTypes.ts rename to linter/lib/utils/consts/LimitedStandardUtilityTypes.ts diff --git a/linter/src/utils/consts/LimitedStdGlobalFunc.ts b/linter/lib/utils/consts/LimitedStdGlobalFunc.ts similarity index 100% rename from linter/src/utils/consts/LimitedStdGlobalFunc.ts rename to linter/lib/utils/consts/LimitedStdGlobalFunc.ts diff --git a/linter/src/utils/consts/LimitedStdObjectAPI.ts b/linter/lib/utils/consts/LimitedStdObjectAPI.ts similarity index 100% rename from linter/src/utils/consts/LimitedStdObjectAPI.ts rename to linter/lib/utils/consts/LimitedStdObjectAPI.ts diff --git a/linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts b/linter/lib/utils/consts/LimitedStdProxyHandlerAPI.ts similarity index 100% rename from linter/src/utils/consts/LimitedStdProxyHandlerAPI.ts rename to linter/lib/utils/consts/LimitedStdProxyHandlerAPI.ts diff --git a/linter/src/utils/consts/LimitedStdReflectAPI.ts b/linter/lib/utils/consts/LimitedStdReflectAPI.ts similarity index 100% rename from linter/src/utils/consts/LimitedStdReflectAPI.ts rename to linter/lib/utils/consts/LimitedStdReflectAPI.ts diff --git a/linter/src/utils/consts/NonInitializablePropertyDecorators.ts b/linter/lib/utils/consts/NonInitializablePropertyDecorators.ts similarity index 100% rename from linter/src/utils/consts/NonInitializablePropertyDecorators.ts rename to linter/lib/utils/consts/NonInitializablePropertyDecorators.ts diff --git a/linter/src/utils/consts/NonReturnFunctionDecorators.ts b/linter/lib/utils/consts/NonReturnFunctionDecorators.ts similarity index 100% rename from linter/src/utils/consts/NonReturnFunctionDecorators.ts rename to linter/lib/utils/consts/NonReturnFunctionDecorators.ts diff --git a/linter/src/utils/consts/PropertyHasNoInitializerErrorCode.ts b/linter/lib/utils/consts/PropertyHasNoInitializerErrorCode.ts similarity index 100% rename from linter/src/utils/consts/PropertyHasNoInitializerErrorCode.ts rename to linter/lib/utils/consts/PropertyHasNoInitializerErrorCode.ts diff --git a/linter/src/utils/consts/StandardLibraries.ts b/linter/lib/utils/consts/StandardLibraries.ts similarity index 100% rename from linter/src/utils/consts/StandardLibraries.ts rename to linter/lib/utils/consts/StandardLibraries.ts diff --git a/linter/src/utils/consts/TypedArrays.ts b/linter/lib/utils/consts/TypedArrays.ts similarity index 100% rename from linter/src/utils/consts/TypedArrays.ts rename to linter/lib/utils/consts/TypedArrays.ts diff --git a/linter/src/utils/functions/ContainsThis.ts b/linter/lib/utils/functions/ContainsThis.ts similarity index 100% rename from linter/src/utils/functions/ContainsThis.ts rename to linter/lib/utils/functions/ContainsThis.ts diff --git a/linter/src/utils/functions/DiagnosticChecker.ts b/linter/lib/utils/functions/DiagnosticChecker.ts similarity index 100% rename from linter/src/utils/functions/DiagnosticChecker.ts rename to linter/lib/utils/functions/DiagnosticChecker.ts diff --git a/linter/src/utils/functions/ForEachNodeInSubtree.ts b/linter/lib/utils/functions/ForEachNodeInSubtree.ts similarity index 100% rename from linter/src/utils/functions/ForEachNodeInSubtree.ts rename to linter/lib/utils/functions/ForEachNodeInSubtree.ts diff --git a/linter/src/utils/functions/GetScriptKind.ts b/linter/lib/utils/functions/GetScriptKind.ts similarity index 100% rename from linter/src/utils/functions/GetScriptKind.ts rename to linter/lib/utils/functions/GetScriptKind.ts diff --git a/linter/src/utils/functions/HasPredecessor.ts b/linter/lib/utils/functions/HasPredecessor.ts similarity index 100% rename from linter/src/utils/functions/HasPredecessor.ts rename to linter/lib/utils/functions/HasPredecessor.ts diff --git a/linter/src/utils/functions/IsStdLibrary.ts b/linter/lib/utils/functions/IsStdLibrary.ts similarity index 100% rename from linter/src/utils/functions/IsStdLibrary.ts rename to linter/lib/utils/functions/IsStdLibrary.ts diff --git a/linter/src/utils/functions/IsStruct.ts b/linter/lib/utils/functions/IsStruct.ts similarity index 100% rename from linter/src/utils/functions/IsStruct.ts rename to linter/lib/utils/functions/IsStruct.ts diff --git a/linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts b/linter/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts similarity index 100% rename from linter/src/utils/functions/LibraryTypeCallDiagnosticChecker.ts rename to linter/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts diff --git a/linter/src/utils/functions/LinterInfo.ts b/linter/lib/utils/functions/LinterInfo.ts similarity index 100% rename from linter/src/utils/functions/LinterInfo.ts rename to linter/lib/utils/functions/LinterInfo.ts diff --git a/linter/src/utils/functions/LogTscDiagnostic.ts b/linter/lib/utils/functions/LogTscDiagnostic.ts similarity index 88% rename from linter/src/utils/functions/LogTscDiagnostic.ts rename to linter/lib/utils/functions/LogTscDiagnostic.ts index a12d9c4e2..23a8ab166 100644 --- a/linter/src/utils/functions/LogTscDiagnostic.ts +++ b/linter/lib/utils/functions/LogTscDiagnostic.ts @@ -15,10 +15,7 @@ import * as ts from 'typescript'; -export function logTscDiagnostic( - diagnostics: readonly ts.Diagnostic[], - log: (message: unknown, ...args: unknown[]) => void -): void { +export function logTscDiagnostic(diagnostics: readonly ts.Diagnostic[], log: (message: string) => void): void { diagnostics.forEach((diagnostic) => { let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); diff --git a/linter/src/utils/functions/MergeArrayMaps.ts b/linter/lib/utils/functions/MergeArrayMaps.ts similarity index 100% rename from linter/src/utils/functions/MergeArrayMaps.ts rename to linter/lib/utils/functions/MergeArrayMaps.ts diff --git a/linter/src/utils/functions/PathHelper.ts b/linter/lib/utils/functions/PathHelper.ts similarity index 100% rename from linter/src/utils/functions/PathHelper.ts rename to linter/lib/utils/functions/PathHelper.ts diff --git a/linter/src/utils/functions/identiferUseInValueContext.ts b/linter/lib/utils/functions/identiferUseInValueContext.ts similarity index 100% rename from linter/src/utils/functions/identiferUseInValueContext.ts rename to linter/lib/utils/functions/identiferUseInValueContext.ts diff --git a/linter/src/utils/functions/isAssignmentOperator.ts b/linter/lib/utils/functions/isAssignmentOperator.ts similarity index 100% rename from linter/src/utils/functions/isAssignmentOperator.ts rename to linter/lib/utils/functions/isAssignmentOperator.ts diff --git a/linter/src/utils/functions/isIntrinsicObjectType.ts b/linter/lib/utils/functions/isIntrinsicObjectType.ts similarity index 100% rename from linter/src/utils/functions/isIntrinsicObjectType.ts rename to linter/lib/utils/functions/isIntrinsicObjectType.ts diff --git a/linter/package.json b/linter/package.json index 6acb1be18..5ac5d3dfc 100644 --- a/linter/package.json +++ b/linter/package.json @@ -21,9 +21,9 @@ "test_main": "npm run compile && rimraf test/results && node build/src/TestRunner.js test", "test_rules": "npm run compile && rimraf test_rules/results && node build/src/TestRunner.js test_rules", "update-tests": "node scripts/update-test-results.mjs test test_rules", - "eslint-check": "npx eslint --ext .ts src", + "eslint-check": "npx eslint --ext .ts src lib", "eslint-fix": "npm run eslint-check -- --fix", - "prettier-fix": "prettier src --write", + "prettier-fix": "prettier src lib --write", "fix": "npm run prettier-fix && npm run eslint-fix" }, "dependencies": { diff --git a/linter/src/CommandLineParser.ts b/linter/src/CommandLineParser.ts index 77c4116c1..aa06dccac 100644 --- a/linter/src/CommandLineParser.ts +++ b/linter/src/CommandLineParser.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import Logger from '../utils/logger'; -import { logTscDiagnostic } from './utils/functions/LogTscDiagnostic'; -import { decodeAutofixInfo } from './utils/functions/LinterInfo'; -import type { CommandLineOptions } from './CommandLineOptions'; -import { AUTOFIX_ALL } from './Autofixer'; +import { Logger } from '../lib/Logger'; +import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; +import { decodeAutofixInfo } from '../lib/utils/functions/LinterInfo'; +import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import { AUTOFIX_ALL } from '../lib/Autofixer'; import { Command, Option } from 'commander'; import * as ts from 'typescript'; import * as fs from 'node:fs'; @@ -28,8 +28,6 @@ const TSX_EXT = '.tsx'; const ETS_EXT = '.ets'; const JSON_EXT = '.json'; -const logger = Logger.getLogger(); - let inputFiles: string[]; let responseFile = ''; function addSrcFile(value: string): void { @@ -132,7 +130,7 @@ export function parseCommandLine(commandLineArgs: string[]): CommandLineOptions cmdArgs.push(...commandLineArgs); program.parse(cmdArgs); } catch (error) { - logger.error('Failed to read response file: ', error); + Logger.error('Failed to read response file: ' + error); process.exit(-1); } } @@ -146,7 +144,7 @@ function doProjectFolderArg(prjFolders: string[], opts: CommandLineOptions): voi try { opts.inputFiles.push(...getFiles(prjFolderPath)); } catch (error) { - logger.error('Failed to read folder: ', error); + Logger.error('Failed to read folder: ' + error); process.exit(-1); } } @@ -174,12 +172,12 @@ function doProjectArg(cfgPath: string, opts: CommandLineOptions): void { if (diagnostics.length > 0) { // Log all diagnostic messages and exit program. - logger.error('Failed to read config file.'); - logTscDiagnostic(diagnostics, logger.info); + Logger.error('Failed to read config file.'); + logTscDiagnostic(diagnostics, Logger.info); process.exit(-1); } } catch (error) { - logger.error('Failed to read config file: ', error); + Logger.error('Failed to read config file: ' + error); process.exit(-1); } } diff --git a/linter/src/CompilerWrapper.ts b/linter/src/CompilerImpl.ts similarity index 36% rename from linter/src/CompilerWrapper.ts rename to linter/src/CompilerImpl.ts index 7bbd53274..2a8c85126 100644 --- a/linter/src/CompilerWrapper.ts +++ b/linter/src/CompilerImpl.ts @@ -13,28 +13,33 @@ * limitations under the License. */ +import { Compiler as CompilerInterface } from '../lib/Compiler'; import * as ts from 'typescript'; -import { logTscDiagnostic } from './utils/functions/LogTscDiagnostic'; -import { consoleLog } from './TypeScriptLinter'; +import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; +import { consoleLog } from '../lib/TypeScriptLinter'; import { formTscOptions } from './ts-compiler/FormTscOptions'; -import type { LintOptions } from './LintOptions'; +import type { LintOptions } from '../lib/LintOptions'; -export function compile(options: LintOptions, extraOptions?: unknown): ts.Program { - const createProgramOptions = formTscOptions(options.cmdOptions, extraOptions); - const program = ts.createProgram(createProgramOptions); - // Log Tsc errors if needed - if (options.cmdOptions.logTscErrors) { - const diagnostics = ts.getPreEmitDiagnostics(program); - logTscDiagnostic(diagnostics, consoleLog); - diagnostics.forEach((diagnostic) => { - if (diagnostic.file && diagnostic.start) { - const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start); - const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); - consoleLog(`${diagnostic.file.fileName} (${line + 1}, ${character + 1}): ${message}`); - } else { - consoleLog(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); - } - }); +export class CompilerImpl extends CompilerInterface { + doCompile(options: LintOptions, extraOptions?: unknown): ts.Program { + void this; + + const createProgramOptions = formTscOptions(options.cmdOptions, extraOptions); + const program = ts.createProgram(createProgramOptions); + // Log Tsc errors if needed + if (options.cmdOptions.logTscErrors) { + const diagnostics = ts.getPreEmitDiagnostics(program); + logTscDiagnostic(diagnostics, consoleLog); + diagnostics.forEach((diagnostic) => { + if (diagnostic.file && diagnostic.start) { + const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start); + const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + consoleLog(`${diagnostic.file.fileName} (${line + 1}, ${character + 1}): ${message}`); + } else { + consoleLog(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); + } + }); + } + return program; } - return program; } diff --git a/linter/src/LinterCLI.ts b/linter/src/LinterCLI.ts index ae6ad55a2..4dc1cc791 100644 --- a/linter/src/LinterCLI.ts +++ b/linter/src/LinterCLI.ts @@ -13,22 +13,20 @@ * limitations under the License. */ -import { TypeScriptLinter } from './TypeScriptLinter'; +import { TypeScriptLinter } from '../lib/TypeScriptLinter'; import { parseCommandLine } from './CommandLineParser'; -import Logger from '../utils/logger'; +import { Logger } from '../lib/Logger'; import * as fs from 'node:fs'; import * as os from 'node:os'; import * as readline from 'node:readline'; import * as path from 'node:path'; -import type { CommandLineOptions } from './CommandLineOptions'; -import { lint } from './LinterRunner'; - -const logger = Logger.getLogger(); +import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import { lint } from '../lib/LinterRunner'; export function run(): void { const commandLineArgs = process.argv.slice(2); if (commandLineArgs.length === 0) { - logger.info('Command line error: no arguments'); + Logger.info('Command line error: no arguments'); process.exit(-1); } @@ -90,9 +88,9 @@ function runIDEMode(cmdOptions: CommandLineOptions): void { autofix: x.autofix }; }); - logger.info(`{"linter messages":${JSON.stringify(jsonMessage)}}`); + Logger.info(`{"linter messages":${JSON.stringify(jsonMessage)}}`); } else { - logger.error('Unexpected error: could not lint file'); + Logger.error('Unexpected error: could not lint file'); } fs.unlinkSync(tmpFileName); }); diff --git a/linter/src/LoggerImpl.ts b/linter/src/LoggerImpl.ts new file mode 100644 index 000000000..2ea175929 --- /dev/null +++ b/linter/src/LoggerImpl.ts @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023-2023 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 { Logger as LoggerInterface } from '../lib/Logger'; +import Logger from '../utils/logger'; + +export class LoggerImpl extends LoggerInterface { + doTrace(message: string): void { + void this; + Logger.getLogger().trace(message); + } + + doDebug(message: string): void { + void this; + Logger.getLogger().debug(message); + } + + doInfo(message: string): void { + void this; + Logger.getLogger().info(message); + } + + doWarn(message: string): void { + void this; + Logger.getLogger().warn(message); + } + + doError(message: string): void { + void this; + Logger.getLogger().error(message); + } +} diff --git a/linter/src/TestRunner.ts b/linter/src/TestRunner.ts index d2fbb0ca8..563194ee1 100644 --- a/linter/src/TestRunner.ts +++ b/linter/src/TestRunner.ts @@ -13,21 +13,26 @@ * limitations under the License. */ -import { TypeScriptLinter } from './TypeScriptLinter'; -import { lint } from './LinterRunner'; +import { Logger } from '../lib/Logger'; +import { LoggerImpl } from './LoggerImpl'; +Logger.init(new LoggerImpl()); + +import { Compiler } from '../lib/Compiler'; +import { CompilerImpl } from './CompilerImpl'; +Compiler.init(new CompilerImpl()); + +import { TypeScriptLinter } from '../lib/TypeScriptLinter'; +import { lint } from '../lib/LinterRunner'; import { parseCommandLine } from './CommandLineParser'; -import type { Autofix } from './Autofixer'; -import Logger from '../utils/logger'; +import type { Autofix } from '../lib/Autofixer'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as ts from 'typescript'; -import type { CommandLineOptions } from './CommandLineOptions'; +import type { CommandLineOptions } from '../lib/CommandLineOptions'; const TEST_DIR = 'test'; const TAB = ' '; -const logger = Logger.getLogger(); - interface TestNodeInfo { line: number; column: number; @@ -76,7 +81,7 @@ function runTests(testDirs: string[]): number { x.trimEnd().endsWith(ts.Extension.Tsx) ); }); - logger.info(`\nProcessing "${testDir}" directory:\n`); + Logger.info(`\nProcessing "${testDir}" directory:\n`); // Run each test in Strict, Autofix, and Relax mode: for (const testFile of testFiles) { if (runTest(testDir, testFile, Mode.STRICT)) { @@ -99,8 +104,8 @@ function runTests(testDirs: string[]): number { } } } - logger.info(`\nSUMMARY: ${passed + failed} total, ${passed} passed or skipped, ${failed} failed.`); - logger.info(failed > 0 ? '\nTEST FAILED' : '\nTEST SUCCESSFUL'); + Logger.info(`\nSUMMARY: ${passed + failed} total, ${passed} passed or skipped, ${failed} failed.`); + Logger.info(failed > 0 ? '\nTEST FAILED' : '\nTEST SUCCESSFUL'); process.exit(hasComparisonFailures ? -1 : 0); } @@ -143,16 +148,16 @@ function compareExpectedAndActual(testDir: string, testFile: string, mode: Mode, if (!expectedResult?.nodes || expectedResult.nodes.length !== resultNodes.length) { const expectedResultCount = expectedResult?.nodes ? expectedResult.nodes.length : 0; diff = `Expected count: ${expectedResultCount} vs actual count: ${resultNodes.length}`; - logger.info(`${TAB}${diff}`); + Logger.info(`${TAB}${diff}`); } else { diff = expectedAndActualMatch(expectedResult.nodes, resultNodes); } if (diff) { - logger.info(`${TAB}Test failed. Expected and actual results differ.`); + Logger.info(`${TAB}Test failed. Expected and actual results differ.`); } } catch (error) { - logger.info(`${TAB}Test failed. `, error); + Logger.info(`${TAB}Test failed. ` + error); } return diff; @@ -160,10 +165,10 @@ function compareExpectedAndActual(testDir: string, testFile: string, mode: Mode, function runTest(testDir: string, testFile: string, mode: Mode): boolean { if (mode === Mode.AUTOFIX && fs.existsSync(path.join(testDir, testFile + AUTOFIX_SKIP_EXT))) { - logger.info(`Skipping test ${testFile} (${Mode[mode]} mode)`); + Logger.info(`Skipping test ${testFile} (${Mode[mode]} mode)`); return false; } - logger.info(`Running test ${testFile} (${Mode[mode]} mode)`); + Logger.info(`Running test ${testFile} (${Mode[mode]} mode)`); TypeScriptLinter.initGlobals(); @@ -271,7 +276,7 @@ ${expectedNode} Actual: ${actualNode}`; - logger.info(diff); + Logger.info(diff); return diff; } diff --git a/linter/src/main.ts b/linter/src/main.ts index e1b7ecf91..6ffe1703d 100644 --- a/linter/src/main.ts +++ b/linter/src/main.ts @@ -13,6 +13,14 @@ * limitations under the License. */ +import { Logger } from '../lib/Logger'; +import { LoggerImpl } from './LoggerImpl'; +Logger.init(new LoggerImpl()); + +import { Compiler } from '../lib/Compiler'; +import { CompilerImpl } from './CompilerImpl'; +Compiler.init(new CompilerImpl()); + import { run } from './LinterCLI'; run(); diff --git a/linter/src/ts-compiler/FormTscOptions.ts b/linter/src/ts-compiler/FormTscOptions.ts index 19fce66c1..de293100b 100644 --- a/linter/src/ts-compiler/FormTscOptions.ts +++ b/linter/src/ts-compiler/FormTscOptions.ts @@ -14,7 +14,7 @@ */ import * as ts from 'typescript'; -import type { CommandLineOptions } from '../CommandLineOptions'; +import type { CommandLineOptions } from '../../lib/CommandLineOptions'; export function formTscOptions(cmdOptions: CommandLineOptions, extraOptions?: unknown): ts.CreateProgramOptions { if (cmdOptions.parsedConfigFile) { diff --git a/linter/tsconfig.json b/linter/tsconfig.json index 38bce99f8..5e1d00ae0 100644 --- a/linter/tsconfig.json +++ b/linter/tsconfig.json @@ -12,5 +12,5 @@ "strict": true }, - "include": ["src/**/*", "utils/*"] -} \ No newline at end of file + "include": ["src/**/*", "lib/**/*", "utils/*"] +} -- Gitee From e7d1a5d0f51eed731c310d5daee300a37e09c84f Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Tue, 14 Nov 2023 15:06:20 +0300 Subject: [PATCH 33/49] [ArkTS][Linter] Extract independent parts from linter's library part Signed-off-by: Urakov Alexandr --- linter/src/CommandLineParser.ts | 4 ++-- linter/src/CompilerImpl.ts | 2 +- linter/{lib/utils/functions => src}/LinterInfo.ts | 4 ++-- linter/{lib/utils/functions => src}/LogTscDiagnostic.ts | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename linter/{lib/utils/functions => src}/LinterInfo.ts (88%) rename linter/{lib/utils/functions => src}/LogTscDiagnostic.ts (100%) diff --git a/linter/src/CommandLineParser.ts b/linter/src/CommandLineParser.ts index aa06dccac..a1e4aeb82 100644 --- a/linter/src/CommandLineParser.ts +++ b/linter/src/CommandLineParser.ts @@ -14,8 +14,8 @@ */ import { Logger } from '../lib/Logger'; -import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; -import { decodeAutofixInfo } from '../lib/utils/functions/LinterInfo'; +import { logTscDiagnostic } from './LogTscDiagnostic'; +import { decodeAutofixInfo } from './LinterInfo'; import type { CommandLineOptions } from '../lib/CommandLineOptions'; import { AUTOFIX_ALL } from '../lib/Autofixer'; import { Command, Option } from 'commander'; diff --git a/linter/src/CompilerImpl.ts b/linter/src/CompilerImpl.ts index 2a8c85126..65ed64502 100644 --- a/linter/src/CompilerImpl.ts +++ b/linter/src/CompilerImpl.ts @@ -15,7 +15,7 @@ import { Compiler as CompilerInterface } from '../lib/Compiler'; import * as ts from 'typescript'; -import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; +import { logTscDiagnostic } from './LogTscDiagnostic'; import { consoleLog } from '../lib/TypeScriptLinter'; import { formTscOptions } from './ts-compiler/FormTscOptions'; import type { LintOptions } from '../lib/LintOptions'; diff --git a/linter/lib/utils/functions/LinterInfo.ts b/linter/src/LinterInfo.ts similarity index 88% rename from linter/lib/utils/functions/LinterInfo.ts rename to linter/src/LinterInfo.ts index 61f875ba2..c13b1030d 100644 --- a/linter/lib/utils/functions/LinterInfo.ts +++ b/linter/src/LinterInfo.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import type { ProblemInfo } from '../../ProblemInfo'; -import type { AutofixInfo } from '../../autofixes/AutofixInfo'; +import type { ProblemInfo } from '../lib/ProblemInfo'; +import type { AutofixInfo } from '../lib/autofixes/AutofixInfo'; export function encodeProblemInfo(problem: ProblemInfo): string { return `${problem.problem}%${problem.start}%${problem.end}`; diff --git a/linter/lib/utils/functions/LogTscDiagnostic.ts b/linter/src/LogTscDiagnostic.ts similarity index 100% rename from linter/lib/utils/functions/LogTscDiagnostic.ts rename to linter/src/LogTscDiagnostic.ts -- Gitee From 6714930d351471fd21e83b71f065a44c38c6bf7b Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Tue, 14 Nov 2023 15:23:21 +0300 Subject: [PATCH 34/49] [ArkTS][Linter] Remove redundant code Signed-off-by: Urakov Alexandr --- linter/lib/Autofixer.ts | 26 --- linter/lib/LinterRunner.ts | 1 - linter/lib/TypeScriptLinter.ts | 4 +- linter/lib/autofixes/ReportAutofixCallback.ts | 6 - linter/lib/utils/TsUtils.ts | 160 ------------------ linter/lib/utils/functions/GetScriptKind.ts | 36 ---- linter/src/LinterInfo.ts | 5 - 7 files changed, 1 insertion(+), 237 deletions(-) delete mode 100644 linter/lib/utils/functions/GetScriptKind.ts diff --git a/linter/lib/Autofixer.ts b/linter/lib/Autofixer.ts index 58f6cec9a..c2aaf55c8 100644 --- a/linter/lib/Autofixer.ts +++ b/linter/lib/Autofixer.ts @@ -125,32 +125,6 @@ export function dropTypeOnVarDecl(varDecl: ts.VariableDeclaration): Autofix { return { start: varDecl.getStart(), end: varDecl.getEnd(), replacementText: text }; } -export function dropTypeOnlyFlag( - impExpNode: ts.ImportClause | ts.ImportSpecifier | ts.ExportDeclaration | ts.ExportSpecifier -): Autofix { - let text: string; - if (ts.isImportClause(impExpNode)) { - const newImportClause = ts.factory.createImportClause(false, impExpNode.name, impExpNode.namedBindings); - text = printer.printNode(ts.EmitHint.Unspecified, newImportClause, impExpNode.getSourceFile()); - } else if (ts.isImportSpecifier(impExpNode)) { - const newImportSpec = ts.factory.createImportSpecifier(false, impExpNode.propertyName, impExpNode.name); - text = printer.printNode(ts.EmitHint.Unspecified, newImportSpec, impExpNode.getSourceFile()); - } else if (ts.isExportDeclaration(impExpNode)) { - const newExportDecl = ts.factory.createExportDeclaration( - impExpNode.modifiers, - false, - impExpNode.exportClause, - impExpNode.moduleSpecifier, - impExpNode.assertClause - ); - text = printer.printNode(ts.EmitHint.Unspecified, newExportDecl, impExpNode.getSourceFile()); - } else { - const newExportSpec = ts.factory.createExportSpecifier(false, impExpNode.propertyName, impExpNode.name); - text = printer.printNode(ts.EmitHint.Unspecified, newExportSpec, impExpNode.getSourceFile()); - } - return { start: impExpNode.getStart(), end: impExpNode.getEnd(), replacementText: text }; -} - export function fixDefaultImport( importClause: ts.ImportClause, defaultSpec: ts.ImportSpecifier, diff --git a/linter/lib/LinterRunner.ts b/linter/lib/LinterRunner.ts index 48254ef0f..6144b0bb4 100644 --- a/linter/lib/LinterRunner.ts +++ b/linter/lib/LinterRunner.ts @@ -111,7 +111,6 @@ export function lint(options: LintOptions): LintRunResult { tsProgram.getTypeChecker(), new AutofixInfoSet(cmdOptions.autofixInfo), !!cmdOptions.strictMode, - cmdOptions.warningsAsErrors, cancellationToken, options.incrementalLintInfo, tscStrictDiagnostics, diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index 97c357ecb..0733d6155 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -104,7 +104,6 @@ export class TypeScriptLinter { private readonly tsTypeChecker: ts.TypeChecker, private readonly autofixesInfo: AutofixInfoSet, public strictMode: boolean, - public warningsAsErrors: boolean, private readonly cancellationToken?: ts.CancellationToken, private readonly incrementalLintInfo?: IncrementalLintInfo, private readonly tscStrictDiagnostics?: Map, @@ -1853,8 +1852,7 @@ export class TypeScriptLinter { * spread element is allowed only for arrays as rest parameter */ if (ts.isSpreadElement(node)) { - const spreadElemNode = node; - const spreadExprType = this.tsTypeChecker.getTypeAtLocation(spreadElemNode.expression); + const spreadExprType = this.tsTypeChecker.getTypeAtLocation(node.expression); if (spreadExprType) { if (ts.isCallLikeExpression(node.parent) || ts.isArrayLiteralExpression(node.parent)) { if (this.tsUtils.isOrDerivedFrom(spreadExprType, this.tsUtils.isArray)) { diff --git a/linter/lib/autofixes/ReportAutofixCallback.ts b/linter/lib/autofixes/ReportAutofixCallback.ts index 81f035891..62e03bff4 100644 --- a/linter/lib/autofixes/ReportAutofixCallback.ts +++ b/linter/lib/autofixes/ReportAutofixCallback.ts @@ -16,9 +16,3 @@ import type { ProblemInfo } from '../ProblemInfo'; export type ReportAutofixCallback = (p: ProblemInfo) => void; - -export function getDefaultCallback(withAutofixes: ProblemInfo[]): ReportAutofixCallback { - return (p: ProblemInfo) => { - withAutofixes.push(p); - }; -} diff --git a/linter/lib/utils/TsUtils.ts b/linter/lib/utils/TsUtils.ts index e3cd75be8..2ea649b93 100644 --- a/linter/lib/utils/TsUtils.ts +++ b/linter/lib/utils/TsUtils.ts @@ -34,13 +34,6 @@ export class TsUtils { private readonly advancedClassChecks: boolean ) {} - isType(tsType: ts.TypeNode | undefined, checkType: string): boolean { - if (tsType === undefined || !ts.isTypeReferenceNode(tsType)) { - return false; - } - return this.entityNameToString(tsType.typeName) === checkType; - } - entityNameToString(name: ts.EntityName): string { if (ts.isIdentifier(name)) { return name.escapedText.toString(); @@ -64,63 +57,6 @@ export class TsUtils { return (tsType.getFlags() & ts.TypeFlags.BooleanLike) !== 0; } - static isStringLikeType(tsType: ts.Type): boolean { - if (tsType.isUnion()) { - for (const tsCompType of tsType.types) { - if ((tsCompType.flags & ts.TypeFlags.StringLike) === 0) { - return false; - } - } - return true; - } - return (tsType.getFlags() & ts.TypeFlags.StringLike) !== 0; - } - - static isStringType(type: ts.Type): boolean { - return (type.getFlags() & ts.TypeFlags.String) !== 0; - } - - static isPrimitiveEnumType(type: ts.Type, primitiveType: ts.TypeFlags): boolean { - const isNonPrimitive = (type.flags & ts.TypeFlags.NonPrimitive) !== 0; - if (!TsUtils.isEnumType(type) || !type.isUnion() || isNonPrimitive) { - return false; - } - for (const t of type.types) { - if ((t.flags & primitiveType) === 0) { - return false; - } - } - return true; - } - - static isPrimitiveEnumMemberType(type: ts.Type, primitiveType: ts.TypeFlags): boolean { - const isNonPrimitive = (type.flags & ts.TypeFlags.NonPrimitive) !== 0; - if (!TsUtils.isEnumMemberType(type) || isNonPrimitive) { - return false; - } - return (type.flags & primitiveType) !== 0; - } - - static unwrapParenthesizedType(tsType: ts.TypeNode): ts.TypeNode { - while (ts.isParenthesizedTypeNode(tsType)) { - tsType = tsType.type; - } - return tsType; - } - - static findParentIf(asExpr: ts.AsExpression): ts.IfStatement | null { - let node = asExpr.parent; - while (node) { - if (node.kind === ts.SyntaxKind.IfStatement) { - return node as ts.IfStatement; - } - - node = node.parent; - } - - return null; - } - static isDestructuringAssignmentLHS(tsExpr: ts.ArrayLiteralExpression | ts.ObjectLiteralExpression): boolean { /* @@ -162,23 +98,6 @@ export class TsUtils { return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.Enum) !== 0; } - static isEnumMemberType(tsType: ts.Type): boolean { - - /* - * Note: For some reason, test (tsType.flags & ts.TypeFlags.Enum) != 0 doesn't work here. - * Must use SymbolFlags to figure out if this is an enum type. - */ - return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.EnumMember) !== 0; - } - - static isObjectLiteralType(tsType: ts.Type): boolean { - return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.ObjectLiteral) !== 0; - } - - static isNumberLikeType(tsType: ts.Type): boolean { - return (tsType.getFlags() & ts.TypeFlags.NumberLike) !== 0; - } - static hasModifier(tsModifiers: readonly ts.Modifier[] | undefined, tsModifierKind: number): boolean { if (!tsModifiers) { return false; @@ -266,19 +185,6 @@ export class TsUtils { return false; } - static isReferenceType(tsType: ts.Type): boolean { - const f = tsType.getFlags(); - return ( - (f & ts.TypeFlags.InstantiableNonPrimitive) !== 0 || - (f & ts.TypeFlags.Object) !== 0 || - (f & ts.TypeFlags.Boolean) !== 0 || - (f & ts.TypeFlags.Enum) !== 0 || - (f & ts.TypeFlags.NonPrimitive) !== 0 || - (f & ts.TypeFlags.Number) !== 0 || - (f & ts.TypeFlags.String) !== 0 - ); - } - static isPrimitiveType(type: ts.Type): boolean { const f = type.getFlags(); return ( @@ -367,14 +273,6 @@ export class TsUtils { ); } - static isNullType(tsTypeNode: ts.TypeNode): boolean { - return ts.isLiteralTypeNode(tsTypeNode) && tsTypeNode.literal.kind === ts.SyntaxKind.NullKeyword; - } - - static isThisOrSuperExpr(tsExpr: ts.Expression): boolean { - return tsExpr.kind === ts.SyntaxKind.ThisKeyword || tsExpr.kind === ts.SyntaxKind.SuperKeyword; - } - static isPrototypeSymbol(symbol: ts.Symbol | undefined): boolean { return !!symbol && !!symbol.flags && (symbol.flags & ts.SymbolFlags.Prototype) !== 0; } @@ -417,12 +315,6 @@ export class TsUtils { return false; } - static isFunctionOrMethod(tsSymbol: ts.Symbol | undefined): boolean { - return ( - !!tsSymbol && ((tsSymbol.flags & ts.SymbolFlags.Function) !== 0 || (tsSymbol.flags & ts.SymbolFlags.Method) !== 0) - ); - } - static isMethodAssignment(tsSymbol: ts.Symbol | undefined): boolean { return ( !!tsSymbol && (tsSymbol.flags & ts.SymbolFlags.Method) !== 0 && (tsSymbol.flags & ts.SymbolFlags.Assignment) !== 0 @@ -846,18 +738,6 @@ export class TsUtils { return undefined; } - checkTypeSet(uType: ts.Type, predicate: (t: ts.Type) => boolean): boolean { - if (!uType.isUnionOrIntersection()) { - return predicate(uType); - } - for (const elemType of uType.types) { - if (!this.checkTypeSet(elemType, predicate)) { - return false; - } - } - return true; - } - static getNonNullableType(t: ts.Type): ts.Type { if (TsUtils.isNullableUnionType(t)) { return t.getNonNullableType(); @@ -922,11 +802,6 @@ export class TsUtils { ); } - static isFunctionalType(type: ts.Type): boolean { - const callSigns = type.getCallSignatures(); - return callSigns && callSigns.length > 0; - } - private isDynamicObjectAssignedToStdType(lhsType: ts.Type, rhsExpr: ts.Expression): boolean { if (isStdLibraryType(lhsType) || TsUtils.isPrimitiveType(lhsType)) { const rhsSym = ts.isCallExpression(rhsExpr) ? @@ -1081,11 +956,6 @@ export class TsUtils { return !!parentName && (parentName === 'Symbol' || parentName === 'SymbolConstructor'); } - isStdSymbol(symbol: ts.Symbol): boolean { - const name = this.tsTypeChecker.getFullyQualifiedName(symbol); - return name === 'Symbol' && this.isGlobalSymbol(symbol); - } - isSymbolIterator(symbol: ts.Symbol): boolean { return this.isSymbolAPI(symbol) && symbol.name === 'iterator'; } @@ -1419,36 +1289,6 @@ export class TsUtils { return undefined; } - // has to be re-implemented with local loop detection - typeIsRecursive(topType: ts.Type, type: ts.Type | undefined = undefined): boolean { - if (type === undefined) { - type = topType; - } else if (type === topType) { - return true; - } else if (type.aliasSymbol) { - return false; - } - - if (type.isUnion()) { - for (const unionElem of type.types) { - if (this.typeIsRecursive(topType, unionElem)) { - return true; - } - } - } - if (type.flags & ts.TypeFlags.Object && (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference) { - const typeArgs = this.tsTypeChecker.getTypeArguments(type as ts.TypeReference); - if (typeArgs) { - for (const typeArg of typeArgs) { - if (this.typeIsRecursive(topType, typeArg)) { - return true; - } - } - } - } - return false; - } - static isClassValueType(type: ts.Type): boolean { if ( (type.flags & ts.TypeFlags.Object) === 0 || diff --git a/linter/lib/utils/functions/GetScriptKind.ts b/linter/lib/utils/functions/GetScriptKind.ts deleted file mode 100644 index 98643872d..000000000 --- a/linter/lib/utils/functions/GetScriptKind.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022-2023 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 ts from 'typescript'; -import * as path from 'node:path'; - -export function getScriptKind(srcFile: ts.SourceFile): ts.ScriptKind { - const fileName = srcFile.fileName; - const ext = path.extname(fileName).toLowerCase(); - switch (ext) { - case ts.Extension.Ts: - return ts.ScriptKind.TS; - case ts.Extension.Tsx: - return ts.ScriptKind.TSX; - case ts.Extension.Js: - return ts.ScriptKind.JS; - case ts.Extension.Jsx: - return ts.ScriptKind.JSX; - case ts.Extension.Json: - return ts.ScriptKind.JSON; - default: - return ts.ScriptKind.Unknown; - } -} diff --git a/linter/src/LinterInfo.ts b/linter/src/LinterInfo.ts index c13b1030d..8f7bff013 100644 --- a/linter/src/LinterInfo.ts +++ b/linter/src/LinterInfo.ts @@ -13,13 +13,8 @@ * limitations under the License. */ -import type { ProblemInfo } from '../lib/ProblemInfo'; import type { AutofixInfo } from '../lib/autofixes/AutofixInfo'; -export function encodeProblemInfo(problem: ProblemInfo): string { - return `${problem.problem}%${problem.start}%${problem.end}`; -} - export function decodeAutofixInfo(info: string): AutofixInfo { const infos = info.split('%'); return { -- Gitee From 3bdfead094a39eb18ad30f2a49b668516fa86cda Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Wed, 15 Nov 2023 12:06:46 +0300 Subject: [PATCH 35/49] [ArkTS][Linter] Return `LogTscDiagnostic` to the lib Signed-off-by: Urakov Alexandr --- linter/{src => lib/utils/functions}/LogTscDiagnostic.ts | 0 linter/src/CommandLineParser.ts | 2 +- linter/src/CompilerImpl.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename linter/{src => lib/utils/functions}/LogTscDiagnostic.ts (100%) diff --git a/linter/src/LogTscDiagnostic.ts b/linter/lib/utils/functions/LogTscDiagnostic.ts similarity index 100% rename from linter/src/LogTscDiagnostic.ts rename to linter/lib/utils/functions/LogTscDiagnostic.ts diff --git a/linter/src/CommandLineParser.ts b/linter/src/CommandLineParser.ts index a1e4aeb82..47f7ddd92 100644 --- a/linter/src/CommandLineParser.ts +++ b/linter/src/CommandLineParser.ts @@ -14,7 +14,7 @@ */ import { Logger } from '../lib/Logger'; -import { logTscDiagnostic } from './LogTscDiagnostic'; +import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; import { decodeAutofixInfo } from './LinterInfo'; import type { CommandLineOptions } from '../lib/CommandLineOptions'; import { AUTOFIX_ALL } from '../lib/Autofixer'; diff --git a/linter/src/CompilerImpl.ts b/linter/src/CompilerImpl.ts index 65ed64502..2a8c85126 100644 --- a/linter/src/CompilerImpl.ts +++ b/linter/src/CompilerImpl.ts @@ -15,7 +15,7 @@ import { Compiler as CompilerInterface } from '../lib/Compiler'; import * as ts from 'typescript'; -import { logTscDiagnostic } from './LogTscDiagnostic'; +import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; import { consoleLog } from '../lib/TypeScriptLinter'; import { formTscOptions } from './ts-compiler/FormTscOptions'; import type { LintOptions } from '../lib/LintOptions'; -- Gitee From fab73557687165063a1bd1a4bff123c56d4c4847 Mon Sep 17 00:00:00 2001 From: Urakov Alexandr Date: Wed, 15 Nov 2023 12:22:11 +0300 Subject: [PATCH 36/49] [ArkTS][Linter] Introduce `TsUtils.reduceReference()` Signed-off-by: Urakov Alexandr --- linter/lib/utils/TsUtils.ts | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/linter/lib/utils/TsUtils.ts b/linter/lib/utils/TsUtils.ts index 2ea649b93..95e050b97 100644 --- a/linter/lib/utils/TsUtils.ts +++ b/linter/lib/utils/TsUtils.ts @@ -26,7 +26,7 @@ import { ARKTS_IGNORE_DIRS, ARKTS_IGNORE_FILES } from './consts/ArktsIgnorePaths import { isAssignmentOperator } from './functions/isAssignmentOperator'; import { forEachNodeInSubtree } from './functions/ForEachNodeInSubtree'; -export type CheckType = (t: ts.Type) => boolean; +export type CheckType = (this: TsUtils, t: ts.Type) => boolean; export class TsUtils { constructor( private readonly tsTypeChecker: ts.TypeChecker, @@ -238,9 +238,7 @@ export class TsUtils { // does something similar to relatedByInheritanceOrIdentical function isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { - if (TsUtils.isTypeReference(tsType) && tsType.target !== tsType) { - tsType = tsType.target; - } + tsType = TsUtils.reduceReference(tsType); if (checkType.call(this, tsType)) { return true; @@ -482,12 +480,8 @@ export class TsUtils { // Returns true iff typeA is a subtype of typeB relatedByInheritanceOrIdentical(typeA: ts.Type, typeB: ts.Type): boolean { - if (TsUtils.isTypeReference(typeA) && typeA.target !== typeA) { - typeA = typeA.target; - } - if (TsUtils.isTypeReference(typeB) && typeB.target !== typeB) { - typeB = typeB.target; - } + typeA = TsUtils.reduceReference(typeA); + typeB = TsUtils.reduceReference(typeB); if (typeA === typeB || this.isObject(typeB)) { return true; @@ -511,6 +505,10 @@ export class TsUtils { return false; } + static reduceReference(t: ts.Type): ts.Type { + return TsUtils.isTypeReference(t) && t.target !== t ? t.target : t; + } + private needToDeduceStructuralIdentityHandleUnions( lhsType: ts.Type, rhsType: ts.Type, @@ -582,10 +580,7 @@ export class TsUtils { processInterfaces: boolean ): boolean { for (const baseTypeExpr of parentTypes) { - let baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeExpr); - if (TsUtils.isTypeReference(baseType) && baseType.target !== baseType) { - baseType = baseType.target; - } + const baseType = TsUtils.reduceReference(this.tsTypeChecker.getTypeAtLocation(baseTypeExpr)); if ( baseType && baseType.isClass() !== processInterfaces && @@ -599,10 +594,7 @@ export class TsUtils { private processParentTypesCheck(parentTypes: ts.NodeArray, checkType: CheckType): boolean { for (const baseTypeExpr of parentTypes) { - let baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeExpr); - if (TsUtils.isTypeReference(baseType) && baseType.target !== baseType) { - baseType = baseType.target; - } + const baseType = TsUtils.reduceReference(this.tsTypeChecker.getTypeAtLocation(baseTypeExpr)); if (baseType && this.isOrDerivedFrom(baseType, checkType)) { return true; } @@ -704,7 +696,7 @@ export class TsUtils { if (!type) { return false; } - type = TsUtils.getTargetType(type); + type = TsUtils.reduceReference(type); return ( type.isClassOrInterface() && TsUtils.hasDefaultCtor(type) && @@ -858,12 +850,6 @@ export class TsUtils { return true; } - static getTargetType(type: ts.Type): ts.Type { - return type.getFlags() & ts.TypeFlags.Object && (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference ? - (type as ts.TypeReference).target : - type; - } - private static isSupportedTypeNodeKind(kind: ts.SyntaxKind): boolean { return ( kind !== ts.SyntaxKind.AnyKeyword && -- Gitee From 547eafdc81638a5bec7f51785fe262d6021d5f0f Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Mon, 13 Nov 2023 18:55:17 +0300 Subject: [PATCH 37/49] [arkts-linter] strip strict compilation flags before initializing linter Signed-off-by: Nazarov Konstantin --- linter-4.2/src/LinterRunner.ts | 30 +++++++++- linter-4.2/src/Utils.ts | 2 +- .../src/ts-diagnostics/TSCCompiledProgram.ts | 57 +++++++++++-------- linter/lib/LinterRunner.ts | 33 ++++++++++- linter/lib/TypeScriptLinter.ts | 2 +- .../lib/ts-diagnostics/TSCCompiledProgram.ts | 44 +++++++------- linter/lib/utils/TsUtils.ts | 2 +- 7 files changed, 118 insertions(+), 52 deletions(-) diff --git a/linter-4.2/src/LinterRunner.ts b/linter-4.2/src/LinterRunner.ts index d266f285d..62b081525 100644 --- a/linter-4.2/src/LinterRunner.ts +++ b/linter-4.2/src/LinterRunner.ts @@ -96,12 +96,38 @@ export function lint(options: LintOptions): LintRunResult { }; } +/* + * We want linter to accept program with no strict options set at all + * due to them affecting type deduction. + */ +function clearStrictOptions(options: LintOptions): LintOptions { + if (!options.parserOptions) { + return options; + } + const newOptions = { ...options }; + newOptions.parserOptions.strict = false; + newOptions.parserOptions.alwaysStrict = false; + newOptions.parserOptions.noImplicitAny = false; + newOptions.parserOptions.noImplicitThis = false; + newOptions.parserOptions.strictBindCallApply = false; + newOptions.parserOptions.strictFunctionTypes = false; + newOptions.parserOptions.strictNullChecks = false; + newOptions.parserOptions.strictPropertyInitialization = false; + newOptions.parserOptions.useUnknownInCatchVariables = false; + return newOptions; +} + export function createLinter(options: LintOptions): TSCCompiledProgram { if (options.tscDiagnosticsLinter) { return options.tscDiagnosticsLinter; } - const tsProgram = options.tsProgram ?? compile(options, getStrictOptions()); - return new TSCCompiledProgram(tsProgram, options); + /* + * if we are provided with the pre-compiled program, don't tamper with options + * otherwise, clear all strict related options to avoid differences in type deduction + */ + const newOptions = options.tsProgram ? options : clearStrictOptions(options); + const tsProgram = newOptions.tsProgram ?? compile(newOptions, getStrictOptions()); + return new TSCCompiledProgram(tsProgram, newOptions); } function lintFiles(srcFiles: ts.SourceFile[], linter: TypeScriptLinter): LintRunResult { diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index fd80bc577..2935d8a2e 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -458,7 +458,7 @@ export class TsUtils { } // does something similar to relatedByInheritanceOrIdentical function - public isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { + public isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): boolean { if (this.isTypeReference(tsType) && tsType.target !== tsType) { tsType = tsType.target; } diff --git a/linter-4.2/src/ts-diagnostics/TSCCompiledProgram.ts b/linter-4.2/src/ts-diagnostics/TSCCompiledProgram.ts index 29548ef9d..ca1072141 100644 --- a/linter-4.2/src/ts-diagnostics/TSCCompiledProgram.ts +++ b/linter-4.2/src/ts-diagnostics/TSCCompiledProgram.ts @@ -43,43 +43,52 @@ export class TSCCompiledProgram { } } -export function getStrictOptions(strict: boolean = true) { +export function getStrictOptions(): { + strictNullChecks: boolean; + strictFunctionTypes: boolean; + strictPropertyInitialization: boolean; + noImplicitReturns: boolean; +} { return { - strictNullChecks: strict, - strictFunctionTypes: strict, - strictPropertyInitialization: strict, - noImplicitReturns: strict, - } + strictNullChecks: true, + strictFunctionTypes: true, + strictPropertyInitialization: true, + noImplicitReturns: true + }; +} + +function isStrict(compilerOptions: ts.CompilerOptions): boolean { + const strictOptions = getStrictOptions(); + let wasStrict = false; + // wasStrict evaluates true if any of the strict options was set + Object.keys(strictOptions).forEach((x) => { + wasStrict = wasStrict || !!compilerOptions[x]; + }); + return wasStrict; } function getTwoCompiledVersions( program: ts.Program, - options: LintOptions, + options: LintOptions ): { strict: ts.Program; nonStrict: ts.Program; wasStrict: boolean } { - const compilerOptions = { ...program.getCompilerOptions()}; - - const wasStrict = inverseStrictOptions(compilerOptions); - const inversedOptions = getStrictOptions(!wasStrict); + const compilerOptions = program.getCompilerOptions(); + const inversedOptions = getInversedOptions(compilerOptions); const withInversedOptions = compile(options, inversedOptions); - + const wasStrict = isStrict(compilerOptions); return { strict: wasStrict ? program : withInversedOptions, nonStrict: wasStrict ? withInversedOptions : program, - wasStrict: wasStrict, - } + wasStrict: wasStrict + }; } -/** - * Returns true if options were initially strict - */ -function inverseStrictOptions(compilerOptions: ts.CompilerOptions): boolean { - const strictOptions = getStrictOptions(); - let wasStrict = false; - Object.keys(strictOptions).forEach(x => { - wasStrict = wasStrict || !!compilerOptions[x]; +function getInversedOptions(compilerOptions: ts.CompilerOptions): ts.CompilerOptions { + const newOptions = { ...compilerOptions }; + const wasStrict = isStrict(compilerOptions); + Object.keys(getStrictOptions()).forEach((key) => { + newOptions[key] = !wasStrict; }); - // wasStrict evaluates true if any of the strict options was set - return wasStrict; + return newOptions; } export function transformDiagnostic(diagnostic: ts.Diagnostic): ProblemInfo { diff --git a/linter/lib/LinterRunner.ts b/linter/lib/LinterRunner.ts index 6144b0bb4..ff5c122fc 100644 --- a/linter/lib/LinterRunner.ts +++ b/linter/lib/LinterRunner.ts @@ -132,15 +132,42 @@ export function lint(options: LintOptions): LintRunResult { }; } +/* + * We want linter to accept program with no strict options set at all + * due to them affecting type deduction. + */ +function clearStrictOptions(options: LintOptions): LintOptions { + if (!options.parserOptions) { + return options; + } + const newOptions = { ...options }; + newOptions.parserOptions.strict = false; + newOptions.parserOptions.alwaysStrict = false; + newOptions.parserOptions.noImplicitAny = false; + newOptions.parserOptions.noImplicitThis = false; + newOptions.parserOptions.strictBindCallApply = false; + newOptions.parserOptions.strictFunctionTypes = false; + newOptions.parserOptions.strictNullChecks = false; + newOptions.parserOptions.strictPropertyInitialization = false; + newOptions.parserOptions.useUnknownInCatchVariables = false; + return newOptions; +} + export function createLinter(options: LintOptions): TSCCompiledProgram { if (options.tscDiagnosticsLinter) { return options.tscDiagnosticsLinter; } - const tsProgram = options.tsProgram ?? Compiler.compile(options, getStrictOptions()); - if (options.realtimeLint) { + + /* + * if we are provided with the pre-compiled program, don't tamper with options + * otherwise, clear all strict related options to avoid differences in type deduction + */ + const newOptions = options.tsProgram ? options : clearStrictOptions(options); + const tsProgram = newOptions.tsProgram ?? Compiler.compile(newOptions, getStrictOptions()); + if (newOptions.realtimeLint) { return new TSCCompiledProgramSimple(tsProgram); } - return new TSCCompiledProgramWithDiagnostics(tsProgram, options); + return new TSCCompiledProgramWithDiagnostics(tsProgram, newOptions); } function lintFiles(srcFiles: ts.SourceFile[], linter: TypeScriptLinter): LintRunResult { diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index 0733d6155..0baa5998f 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -1756,7 +1756,7 @@ export class TypeScriptLinter { return TypeScriptLinter.checkInRange(rangesToFilter, pos); }, [NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); + return TypeScriptLinter.checkInRange(rangesToFilter, pos); }, [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { return TypeScriptLinter.checkInRange(rangesToFilter, pos); diff --git a/linter/lib/ts-diagnostics/TSCCompiledProgram.ts b/linter/lib/ts-diagnostics/TSCCompiledProgram.ts index 77d288831..b7f12489f 100644 --- a/linter/lib/ts-diagnostics/TSCCompiledProgram.ts +++ b/linter/lib/ts-diagnostics/TSCCompiledProgram.ts @@ -72,30 +72,38 @@ export class TSCCompiledProgramWithDiagnostics implements TSCCompiledProgram { } } -export function getStrictOptions(strict: boolean = true): { +export function getStrictOptions(): { strictNullChecks: boolean; strictFunctionTypes: boolean; strictPropertyInitialization: boolean; noImplicitReturns: boolean; } { return { - strictNullChecks: strict, - strictFunctionTypes: strict, - strictPropertyInitialization: strict, - noImplicitReturns: strict + strictNullChecks: true, + strictFunctionTypes: true, + strictPropertyInitialization: true, + noImplicitReturns: true }; } +function isStrict(compilerOptions: ts.CompilerOptions): boolean { + const strictOptions = getStrictOptions(); + let wasStrict = false; + // wasStrict evaluates true if any of the strict options was set + Object.keys(strictOptions).forEach((x) => { + wasStrict = wasStrict || !!compilerOptions[x]; + }); + return wasStrict; +} + function getTwoCompiledVersions( program: ts.Program, options: LintOptions ): { strict: ts.Program; nonStrict: ts.Program; wasStrict: boolean } { - const compilerOptions = { ...program.getCompilerOptions() }; - - const wasStrict = inverseStrictOptions(compilerOptions); - const inversedOptions = getStrictOptions(!wasStrict); + const compilerOptions = program.getCompilerOptions(); + const inversedOptions = getInversedOptions(compilerOptions); const withInversedOptions = Compiler.compile(options, inversedOptions); - + const wasStrict = isStrict(compilerOptions); return { strict: wasStrict ? program : withInversedOptions, nonStrict: wasStrict ? withInversedOptions : program, @@ -103,17 +111,13 @@ function getTwoCompiledVersions( }; } -/** - * Returns true if options were initially strict - */ -function inverseStrictOptions(compilerOptions: ts.CompilerOptions): boolean { - const strictOptions = getStrictOptions(); - let wasStrict = false; - Object.keys(strictOptions).forEach((x) => { - wasStrict = wasStrict || !!compilerOptions[x]; +function getInversedOptions(compilerOptions: ts.CompilerOptions): ts.CompilerOptions { + const newOptions = { ...compilerOptions }; + const wasStrict = isStrict(compilerOptions); + Object.keys(getStrictOptions()).forEach((key) => { + newOptions[key] = !wasStrict; }); - // wasStrict evaluates true if any of the strict options was set - return wasStrict; + return newOptions; } export function transformDiagnostic(diagnostic: ts.Diagnostic): ProblemInfo { diff --git a/linter/lib/utils/TsUtils.ts b/linter/lib/utils/TsUtils.ts index 95e050b97..4b0e49036 100644 --- a/linter/lib/utils/TsUtils.ts +++ b/linter/lib/utils/TsUtils.ts @@ -237,7 +237,7 @@ export class TsUtils { } // does something similar to relatedByInheritanceOrIdentical function - isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): tsType is ts.TypeReference { + isOrDerivedFrom(tsType: ts.Type, checkType: CheckType): boolean { tsType = TsUtils.reduceReference(tsType); if (checkType.call(this, tsType)) { -- Gitee From d644ccc65677022ca889c076a86e53470f48a65d Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Wed, 15 Nov 2023 23:27:36 +0300 Subject: [PATCH 38/49] [ArkTS Linter] #14463: Fix processing comment directives that are located at [1, 1] position. Change-Id: I785e96d24f139e900241c3d351e63796f8282976 Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 45 ++++++++++++++------ linter-4.2/test/ts_ignore_2.ts | 17 ++++++++ linter-4.2/test/ts_ignore_2.ts.autofix.json | 26 +++++++++++ linter-4.2/test/ts_ignore_2.ts.relax.json | 25 +++++++++++ linter-4.2/test/ts_ignore_2.ts.strict.json | 25 +++++++++++ linter-4.2/test/ts_nocheck_2.ts | 20 +++++++++ linter-4.2/test/ts_nocheck_2.ts.autofix.json | 34 +++++++++++++++ linter-4.2/test/ts_nocheck_2.ts.relax.json | 32 ++++++++++++++ linter-4.2/test/ts_nocheck_2.ts.strict.json | 32 ++++++++++++++ linter/lib/TypeScriptLinter.ts | 21 +++++++-- linter/test/ts_ignore_2.ts | 17 ++++++++ linter/test/ts_ignore_2.ts.autofix.json | 26 +++++++++++ linter/test/ts_ignore_2.ts.relax.json | 25 +++++++++++ linter/test/ts_ignore_2.ts.strict.json | 25 +++++++++++ linter/test/ts_nocheck_2.ts | 20 +++++++++ linter/test/ts_nocheck_2.ts.autofix.json | 34 +++++++++++++++ linter/test/ts_nocheck_2.ts.relax.json | 32 ++++++++++++++ linter/test/ts_nocheck_2.ts.strict.json | 32 ++++++++++++++ 18 files changed, 473 insertions(+), 15 deletions(-) create mode 100644 linter-4.2/test/ts_ignore_2.ts create mode 100644 linter-4.2/test/ts_ignore_2.ts.autofix.json create mode 100644 linter-4.2/test/ts_ignore_2.ts.relax.json create mode 100644 linter-4.2/test/ts_ignore_2.ts.strict.json create mode 100644 linter-4.2/test/ts_nocheck_2.ts create mode 100644 linter-4.2/test/ts_nocheck_2.ts.autofix.json create mode 100644 linter-4.2/test/ts_nocheck_2.ts.relax.json create mode 100644 linter-4.2/test/ts_nocheck_2.ts.strict.json create mode 100644 linter/test/ts_ignore_2.ts create mode 100644 linter/test/ts_ignore_2.ts.autofix.json create mode 100644 linter/test/ts_ignore_2.ts.relax.json create mode 100644 linter/test/ts_ignore_2.ts.strict.json create mode 100644 linter/test/ts_nocheck_2.ts create mode 100644 linter/test/ts_nocheck_2.ts.autofix.json create mode 100644 linter/test/ts_nocheck_2.ts.relax.json create mode 100644 linter/test/ts_nocheck_2.ts.strict.json diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index ff8e7ea24..0674a5064 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -2210,33 +2210,46 @@ export class TypeScriptLinter { this.incrementCounters(decl, FaultID.UnknownType); } - private handleCommentDirectives(sourceFile: ts.SourceFile) { - // We use a dirty hack to retrieve list of parsed comment directives by accessing - // internal properties of SourceFile node. + private handleCommentDirectives(sourceFile: ts.SourceFile): void { + + /* + * We use a dirty hack to retrieve list of parsed comment directives by accessing + * internal properties of SourceFile node. + */ // Handle comment directive '@ts-nocheck' - let pragmas = (sourceFile as any)['pragmas']; + const pragmas = (sourceFile as any).pragmas; if (pragmas && pragmas instanceof Map) { for (const pragma of pragmas) { - if (pragma[0] !== 'ts-nocheck' || !pragma[1]?.range.kind || !pragma[1]?.range.pos || !pragma[1]?.range.end) { + if (pragma[0] !== 'ts-nocheck' || !pragma[1]) { continue; } - this.incrementCounters(pragma[1].range as ts.CommentRange, FaultID.ErrorSuppression); + /* + * The value is either a single entry or an array of entries. + * Wrap up single entry with array to simplify processing. + */ + const noCheckEntries: any[] = Array.isArray(pragma[1]) ? pragma[1] : [pragma[1]]; + for (const entry of noCheckEntries) { + this.processNoCheckEntry(entry); + } } } // Handle comment directives '@ts-ignore' and '@ts-expect-error' - let commentDirectives = (sourceFile as any)['commentDirectives']; + const commentDirectives = (sourceFile as any).commentDirectives; if (commentDirectives && Array.isArray(commentDirectives)) { for (const directive of commentDirectives) { - if (!directive.range?.pos || !directive.range?.end) continue; + if (directive.range?.pos === undefined || directive.range?.end === undefined) { + continue; + } const range = directive.range as ts.TextRange; - const kind: ts.SyntaxKind = sourceFile.text.slice(range.pos, range.pos + 2) === '/*' - ? ts.SyntaxKind.MultiLineCommentTrivia - : ts.SyntaxKind.SingleLineCommentTrivia; - let commentRange: ts.CommentRange = { + const kind: ts.SyntaxKind = + sourceFile.text.slice(range.pos, range.pos + 2) === '/*' ? + ts.SyntaxKind.MultiLineCommentTrivia : + ts.SyntaxKind.SingleLineCommentTrivia; + const commentRange: ts.CommentRange = { pos: range.pos, end: range.end, kind @@ -2247,6 +2260,14 @@ export class TypeScriptLinter { } } + private processNoCheckEntry(entry: any): void { + if (entry.range?.kind === undefined || entry.range?.pos === undefined || entry.range?.end === undefined) { + return; + } + + this.incrementCounters(entry.range as ts.CommentRange, FaultID.ErrorSuppression); + } + private reportThisKeywordsInScope(scope: ts.Block | ts.Expression): void { const callback = (node: ts.Node) => { if (node.kind === ts.SyntaxKind.ThisKeyword) { diff --git a/linter-4.2/test/ts_ignore_2.ts b/linter-4.2/test/ts_ignore_2.ts new file mode 100644 index 000000000..bd5602e33 --- /dev/null +++ b/linter-4.2/test/ts_ignore_2.ts @@ -0,0 +1,17 @@ +// @ts-ignore - check for [1, 1] position +let x: number = null; // No error, type checking is suppressed + +/* + * Copyright (c) 2023-2023 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. + */ \ No newline at end of file diff --git a/linter-4.2/test/ts_ignore_2.ts.autofix.json b/linter-4.2/test/ts_ignore_2.ts.autofix.json new file mode 100644 index 000000000..87d88d712 --- /dev/null +++ b/linter-4.2/test/ts_ignore_2.ts.autofix.json @@ -0,0 +1,26 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "autofixable": false, + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter-4.2/test/ts_ignore_2.ts.relax.json b/linter-4.2/test/ts_ignore_2.ts.relax.json new file mode 100644 index 000000000..4f498993a --- /dev/null +++ b/linter-4.2/test/ts_ignore_2.ts.relax.json @@ -0,0 +1,25 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter-4.2/test/ts_ignore_2.ts.strict.json b/linter-4.2/test/ts_ignore_2.ts.strict.json new file mode 100644 index 000000000..4f498993a --- /dev/null +++ b/linter-4.2/test/ts_ignore_2.ts.strict.json @@ -0,0 +1,25 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter-4.2/test/ts_nocheck_2.ts b/linter-4.2/test/ts_nocheck_2.ts new file mode 100644 index 000000000..950ed1bf0 --- /dev/null +++ b/linter-4.2/test/ts_nocheck_2.ts @@ -0,0 +1,20 @@ +// @ts-nocheck - check for [1, 1] position +// @ts-nocheck - check for pragma with two entries +let x: number = null; // No error, type checking is suppressed + +/* + * Copyright (c) 2023-2023 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. + */ + +let y: number = null; // No error, type checking is suppressed \ No newline at end of file diff --git a/linter-4.2/test/ts_nocheck_2.ts.autofix.json b/linter-4.2/test/ts_nocheck_2.ts.autofix.json new file mode 100644 index 000000000..e56817ef3 --- /dev/null +++ b/linter-4.2/test/ts_nocheck_2.ts.autofix.json @@ -0,0 +1,34 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "autofixable": false, + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 2, + "column": 1, + "problem": "ErrorSuppression", + "autofixable": false, + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter-4.2/test/ts_nocheck_2.ts.relax.json b/linter-4.2/test/ts_nocheck_2.ts.relax.json new file mode 100644 index 000000000..a8844f27f --- /dev/null +++ b/linter-4.2/test/ts_nocheck_2.ts.relax.json @@ -0,0 +1,32 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 2, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter-4.2/test/ts_nocheck_2.ts.strict.json b/linter-4.2/test/ts_nocheck_2.ts.strict.json new file mode 100644 index 000000000..a8844f27f --- /dev/null +++ b/linter-4.2/test/ts_nocheck_2.ts.strict.json @@ -0,0 +1,32 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 2, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index 0baa5998f..2c4e6d46b 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -2037,11 +2037,18 @@ export class TypeScriptLinter { const pragmas = (sourceFile as any).pragmas; if (pragmas && pragmas instanceof Map) { for (const pragma of pragmas) { - if (pragma[0] !== 'ts-nocheck' || !pragma[1]?.range.kind || !pragma[1]?.range.pos || !pragma[1]?.range.end) { + if (pragma[0] !== 'ts-nocheck' || !pragma[1]) { continue; } - this.incrementCounters(pragma[1].range as ts.CommentRange, FaultID.ErrorSuppression); + /* + * The value is either a single entry or an array of entries. + * Wrap up single entry with array to simplify processing. + */ + const noCheckEntries: any[] = Array.isArray(pragma[1]) ? pragma[1] : [pragma[1]]; + for (const entry of noCheckEntries) { + this.processNoCheckEntry(entry); + } } } @@ -2049,7 +2056,7 @@ export class TypeScriptLinter { const commentDirectives = (sourceFile as any).commentDirectives; if (commentDirectives && Array.isArray(commentDirectives)) { for (const directive of commentDirectives) { - if (!directive.range?.pos || !directive.range?.end) { + if (directive.range?.pos === undefined || directive.range?.end === undefined) { continue; } @@ -2069,6 +2076,14 @@ export class TypeScriptLinter { } } + private processNoCheckEntry(entry: any): void { + if (entry.range?.kind === undefined || entry.range?.pos === undefined || entry.range?.end === undefined) { + return; + } + + this.incrementCounters(entry.range as ts.CommentRange, FaultID.ErrorSuppression); + } + private reportThisKeywordsInScope(scope: ts.Block | ts.Expression): void { const callback = (node: ts.Node): void => { if (node.kind === ts.SyntaxKind.ThisKeyword) { diff --git a/linter/test/ts_ignore_2.ts b/linter/test/ts_ignore_2.ts new file mode 100644 index 000000000..bd5602e33 --- /dev/null +++ b/linter/test/ts_ignore_2.ts @@ -0,0 +1,17 @@ +// @ts-ignore - check for [1, 1] position +let x: number = null; // No error, type checking is suppressed + +/* + * Copyright (c) 2023-2023 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. + */ \ No newline at end of file diff --git a/linter/test/ts_ignore_2.ts.autofix.json b/linter/test/ts_ignore_2.ts.autofix.json new file mode 100644 index 000000000..87d88d712 --- /dev/null +++ b/linter/test/ts_ignore_2.ts.autofix.json @@ -0,0 +1,26 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "autofixable": false, + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter/test/ts_ignore_2.ts.relax.json b/linter/test/ts_ignore_2.ts.relax.json new file mode 100644 index 000000000..4f498993a --- /dev/null +++ b/linter/test/ts_ignore_2.ts.relax.json @@ -0,0 +1,25 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter/test/ts_ignore_2.ts.strict.json b/linter/test/ts_ignore_2.ts.strict.json new file mode 100644 index 000000000..4f498993a --- /dev/null +++ b/linter/test/ts_ignore_2.ts.strict.json @@ -0,0 +1,25 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter/test/ts_nocheck_2.ts b/linter/test/ts_nocheck_2.ts new file mode 100644 index 000000000..950ed1bf0 --- /dev/null +++ b/linter/test/ts_nocheck_2.ts @@ -0,0 +1,20 @@ +// @ts-nocheck - check for [1, 1] position +// @ts-nocheck - check for pragma with two entries +let x: number = null; // No error, type checking is suppressed + +/* + * Copyright (c) 2023-2023 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. + */ + +let y: number = null; // No error, type checking is suppressed \ No newline at end of file diff --git a/linter/test/ts_nocheck_2.ts.autofix.json b/linter/test/ts_nocheck_2.ts.autofix.json new file mode 100644 index 000000000..e56817ef3 --- /dev/null +++ b/linter/test/ts_nocheck_2.ts.autofix.json @@ -0,0 +1,34 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "autofixable": false, + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 2, + "column": 1, + "problem": "ErrorSuppression", + "autofixable": false, + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter/test/ts_nocheck_2.ts.relax.json b/linter/test/ts_nocheck_2.ts.relax.json new file mode 100644 index 000000000..a8844f27f --- /dev/null +++ b/linter/test/ts_nocheck_2.ts.relax.json @@ -0,0 +1,32 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 2, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file diff --git a/linter/test/ts_nocheck_2.ts.strict.json b/linter/test/ts_nocheck_2.ts.strict.json new file mode 100644 index 000000000..a8844f27f --- /dev/null +++ b/linter/test/ts_nocheck_2.ts.strict.json @@ -0,0 +1,32 @@ +{ + "copyright": [ + "Copyright (c) 2023-2023 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." + ], + "nodes": [ + { + "line": 1, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 2, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + } + ] +} \ No newline at end of file -- Gitee From d18db761cca1b37d6433293b70ab66c5647fa027 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Thu, 16 Nov 2023 18:19:51 +0300 Subject: [PATCH 39/49] [arkts-linter] add tests for string index accessing Signed-off-by: Nazarov Konstantin --- linter-4.2/test/property_access_by_index.ts | 16 ++++++- .../property_access_by_index.ts.autofix.json | 48 +++++++++++++++++++ .../property_access_by_index.ts.strict.json | 42 ++++++++++++++++ linter/test/property_access_by_index.ts | 16 ++++++- .../property_access_by_index.ts.autofix.json | 48 +++++++++++++++++++ .../property_access_by_index.ts.strict.json | 42 ++++++++++++++++ 6 files changed, 210 insertions(+), 2 deletions(-) diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index 1f2ef598d..26afc75bc 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -130,4 +130,18 @@ class NullableArray { print() { console.log(this.container?.numbers[0]); } -} \ No newline at end of file +} + +let str1 = 'sssss' +let str2 = "aaaaa" +let str3 = `sssss` +let str4 = new String('sssss') +let str5 = str1 +let str6 = str2 + +str1[1] +str2[1] +str3[1] +str4[1] +str5[1] +str6[1] diff --git a/linter-4.2/test/property_access_by_index.ts.autofix.json b/linter-4.2/test/property_access_by_index.ts.autofix.json index df5e23653..f79975252 100644 --- a/linter-4.2/test/property_access_by_index.ts.autofix.json +++ b/linter-4.2/test/property_access_by_index.ts.autofix.json @@ -69,6 +69,54 @@ "autofixable": false, "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 142, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 143, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 144, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 145, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 146, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 147, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.strict.json b/linter-4.2/test/property_access_by_index.ts.strict.json index daf068f0d..045ef8777 100644 --- a/linter-4.2/test/property_access_by_index.ts.strict.json +++ b/linter-4.2/test/property_access_by_index.ts.strict.json @@ -62,6 +62,48 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 142, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 143, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 144, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 145, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 146, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 147, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index 1f2ef598d..26afc75bc 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -130,4 +130,18 @@ class NullableArray { print() { console.log(this.container?.numbers[0]); } -} \ No newline at end of file +} + +let str1 = 'sssss' +let str2 = "aaaaa" +let str3 = `sssss` +let str4 = new String('sssss') +let str5 = str1 +let str6 = str2 + +str1[1] +str2[1] +str3[1] +str4[1] +str5[1] +str6[1] diff --git a/linter/test/property_access_by_index.ts.autofix.json b/linter/test/property_access_by_index.ts.autofix.json index df5e23653..f79975252 100644 --- a/linter/test/property_access_by_index.ts.autofix.json +++ b/linter/test/property_access_by_index.ts.autofix.json @@ -69,6 +69,54 @@ "autofixable": false, "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 142, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 143, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 144, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 145, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 146, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 147, + "column": 1, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.strict.json b/linter/test/property_access_by_index.ts.strict.json index daf068f0d..045ef8777 100644 --- a/linter/test/property_access_by_index.ts.strict.json +++ b/linter/test/property_access_by_index.ts.strict.json @@ -62,6 +62,48 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 142, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 143, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 144, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 145, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 146, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 147, + "column": 1, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file -- Gitee From 01f9c26bb4930cf66985fb430d9a68c780b27a09 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Fri, 17 Nov 2023 12:06:54 +0300 Subject: [PATCH 40/49] [arkts-linter] REVERT ME PLEASE AFTER RELEASE Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 3 +- linter-4.2/src/Utils.ts | 19 +++- linter-4.2/test/property_access_by_index.ts | 4 + .../property_access_by_index.ts.autofix.json | 48 ---------- .../property_access_by_index.ts.strict.json | 42 --------- linter/lib/TypeScriptLinter.ts | 7 +- linter/lib/utils/TsUtils.ts | 14 +++ linter/test/functions.ts | 36 -------- linter/test/functions.ts.autofix.json | 88 ------------------- linter/test/functions.ts.relax.json | 77 ---------------- linter/test/functions.ts.strict.json | 77 ---------------- linter/test/property_access_by_index.ts | 4 + .../property_access_by_index.ts.autofix.json | 48 ---------- .../property_access_by_index.ts.strict.json | 42 --------- 14 files changed, 43 insertions(+), 466 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 0674a5064..b283c094c 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1604,7 +1604,8 @@ export class TypeScriptLinter { !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isTuple) && !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStdRecordType) && !this.tsUtils.isEnumType(tsElemAccessBaseExprType) && - !this.tsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) + !this.tsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStringType) ) { let autofix = Autofixer.fixPropertyAccessByIndex(node); const autofixable = autofix != undefined; diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 2935d8a2e..c431bf166 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -240,10 +240,6 @@ export class TsUtils { return (tsType.getFlags() & ts.TypeFlags.StringLike) !== 0; } - public isStringType(type: ts.Type): boolean { - return (type.getFlags() & ts.TypeFlags.String) !== 0; - } - public isPrimitiveEnumType(type: ts.Type, primitiveType: ts.TypeFlags): boolean { const isNonPrimitive = (type.flags & ts.TypeFlags.NonPrimitive) !== 0; if (!this.isEnumType(type) || !type.isUnion() || isNonPrimitive) { @@ -522,6 +518,21 @@ export class TsUtils { return (tsType.getFlags() & ts.TypeFlags.Any) !== 0; } + + public isStringType(tsType: ts.Type): boolean { + if ((tsType.getFlags() & ts.TypeFlags.String) !== 0) { + return true; + } + + if (!this.isTypeReference(tsType)) { + return false; + } + + const symbol = tsType.symbol; + const name = this.tsTypeChecker.getFullyQualifiedName(symbol); + return name === 'String' && this.isGlobalSymbol(symbol); + } + public isUnknownType(tsType: ts.Type): boolean { return (tsType.getFlags() & ts.TypeFlags.Unknown) !== 0; } diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index 26afc75bc..e9193a11e 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -145,3 +145,7 @@ str3[1] str4[1] str5[1] str6[1] + +class AString extends String {} +let str7 = new AString('dwdd') +str7[1] diff --git a/linter-4.2/test/property_access_by_index.ts.autofix.json b/linter-4.2/test/property_access_by_index.ts.autofix.json index f79975252..df5e23653 100644 --- a/linter-4.2/test/property_access_by_index.ts.autofix.json +++ b/linter-4.2/test/property_access_by_index.ts.autofix.json @@ -69,54 +69,6 @@ "autofixable": false, "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 142, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 143, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 144, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 145, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 146, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 147, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.strict.json b/linter-4.2/test/property_access_by_index.ts.strict.json index 045ef8777..daf068f0d 100644 --- a/linter-4.2/test/property_access_by_index.ts.strict.json +++ b/linter-4.2/test/property_access_by_index.ts.strict.json @@ -62,48 +62,6 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 142, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 143, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 144, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 145, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 146, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 147, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index 2c4e6d46b..b4530cadd 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -1469,7 +1469,8 @@ export class TypeScriptLinter { !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, TsUtils.isTuple) && !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStdRecordType) && !TsUtils.isEnumType(tsElemAccessBaseExprType) && - !TsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) + !TsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) && + !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStringType) ) { let autofix = Autofixer.fixPropertyAccessByIndex(node); const autofixable = autofix !== undefined; @@ -1753,10 +1754,10 @@ export class TypeScriptLinter { this.filterStrictDiagnostics( { [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange(rangesToFilter, pos); + return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); }, [NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange(rangesToFilter, pos); + return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); }, [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { return TypeScriptLinter.checkInRange(rangesToFilter, pos); diff --git a/linter/lib/utils/TsUtils.ts b/linter/lib/utils/TsUtils.ts index 4b0e49036..803de5e59 100644 --- a/linter/lib/utils/TsUtils.ts +++ b/linter/lib/utils/TsUtils.ts @@ -289,6 +289,20 @@ export class TsUtils { return (tsType.getFlags() & ts.TypeFlags.Any) !== 0; } + isStringType(tsType: ts.Type): boolean { + if ((tsType.getFlags() & ts.TypeFlags.String) !== 0) { + return true; + } + + if (!TsUtils.isTypeReference(tsType)) { + return false; + } + + const symbol = tsType.symbol; + const name = this.tsTypeChecker.getFullyQualifiedName(symbol); + return name === 'String' && this.isGlobalSymbol(symbol); + } + static isUnknownType(tsType: ts.Type): boolean { return (tsType.getFlags() & ts.TypeFlags.Unknown) !== 0; } diff --git a/linter/test/functions.ts b/linter/test/functions.ts index fd8646324..47db164e7 100644 --- a/linter/test/functions.ts +++ b/linter/test/functions.ts @@ -89,39 +89,3 @@ const col2 = new Collection('a', 'b', 'c'); function f(a: string): number { return 42; } - -foo(f(null)); -foo(null); - -foo(() => { - f(null); -}); - -bar(() => { - f(null); -}, null, f(null)); - -bar(() => { - bar(() => { - f(null); - }, null, f(null)); -}, null, foo(f(null))); - -type PropDecorator = () => void; -let Builder: PropDecorator; - -// this test is useless until we use custom tsc -@Builder -function buildSwiper() { - f(null) - foo(null) { - f(null) - foo(null) { - f(null) - foo(() => { - f(null) - }) - } - .foo(null) - } -} diff --git a/linter/test/functions.ts.autofix.json b/linter/test/functions.ts.autofix.json index 0b6af45e6..78408c87e 100755 --- a/linter/test/functions.ts.autofix.json +++ b/linter/test/functions.ts.autofix.json @@ -101,94 +101,6 @@ "autofixable": false, "suggest": "Property 'c' has no initializer and is not definitely assigned in the constructor.", "rule": "Property 'c' has no initializer and is not definitely assigned in the constructor." - }, - { - "line": 93, - "column": 7, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 97, - "column": 5, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 101, - "column": 5, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 102, - "column": 12, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 106, - "column": 7, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 107, - "column": 14, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 108, - "column": 16, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 116, - "column": 5, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 118, - "column": 7, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 120, - "column": 11, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 122, - "column": 11, - "problem": "StrictDiagnostic", - "autofixable": false, - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file diff --git a/linter/test/functions.ts.relax.json b/linter/test/functions.ts.relax.json index 6729c50d2..0143aa3c4 100644 --- a/linter/test/functions.ts.relax.json +++ b/linter/test/functions.ts.relax.json @@ -76,83 +76,6 @@ "problem": "StrictDiagnostic", "suggest": "Property 'c' has no initializer and is not definitely assigned in the constructor.", "rule": "Property 'c' has no initializer and is not definitely assigned in the constructor." - }, - { - "line": 93, - "column": 7, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 97, - "column": 5, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 101, - "column": 5, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 102, - "column": 12, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 106, - "column": 7, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 107, - "column": 14, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 108, - "column": 16, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 116, - "column": 5, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 118, - "column": 7, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 120, - "column": 11, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 122, - "column": 11, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file diff --git a/linter/test/functions.ts.strict.json b/linter/test/functions.ts.strict.json index d57b74aa3..4a0d0ee42 100644 --- a/linter/test/functions.ts.strict.json +++ b/linter/test/functions.ts.strict.json @@ -90,83 +90,6 @@ "problem": "StrictDiagnostic", "suggest": "Property 'c' has no initializer and is not definitely assigned in the constructor.", "rule": "Property 'c' has no initializer and is not definitely assigned in the constructor." - }, - { - "line": 93, - "column": 7, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 97, - "column": 5, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 101, - "column": 5, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 102, - "column": 12, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 106, - "column": 7, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 107, - "column": 14, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 108, - "column": 16, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 116, - "column": 5, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 118, - "column": 7, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 120, - "column": 11, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." - }, - { - "line": 122, - "column": 11, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'null' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'null' is not assignable to parameter of type 'string'." } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index 26afc75bc..e9193a11e 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -145,3 +145,7 @@ str3[1] str4[1] str5[1] str6[1] + +class AString extends String {} +let str7 = new AString('dwdd') +str7[1] diff --git a/linter/test/property_access_by_index.ts.autofix.json b/linter/test/property_access_by_index.ts.autofix.json index f79975252..df5e23653 100644 --- a/linter/test/property_access_by_index.ts.autofix.json +++ b/linter/test/property_access_by_index.ts.autofix.json @@ -69,54 +69,6 @@ "autofixable": false, "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 142, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 143, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 144, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 145, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 146, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 147, - "column": 1, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.strict.json b/linter/test/property_access_by_index.ts.strict.json index 045ef8777..daf068f0d 100644 --- a/linter/test/property_access_by_index.ts.strict.json +++ b/linter/test/property_access_by_index.ts.strict.json @@ -62,48 +62,6 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" - }, - { - "line": 142, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 143, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 144, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 145, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 146, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, - { - "line": 147, - "column": 1, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file -- Gitee From e033f2d14fbe1ad1af15f8068503133306b52457 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Fri, 17 Nov 2023 16:27:22 +0300 Subject: [PATCH 41/49] [arkts-linter] #1504.3 process union types in access by index Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 43 ++++++++++++------- linter-4.2/test/property_access_by_index.ts | 8 ++++ .../property_access_by_index.ts.autofix.json | 8 ++++ .../property_access_by_index.ts.strict.json | 7 +++ linter/lib/TypeScriptLinter.ts | 39 +++++++++++------ linter/test/property_access_by_index.ts | 8 ++++ .../property_access_by_index.ts.autofix.json | 8 ++++ .../property_access_by_index.ts.strict.json | 7 +++ 8 files changed, 100 insertions(+), 28 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index b283c094c..bb25c0466 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1586,29 +1586,42 @@ export class TypeScriptLinter { (ts.isPropertyAccessExpression(context.expression) && context.expression.name == ident)); } - private handleElementAccessExpression(node: ts.Node) { + private isElementAcessAllowed(type: ts.Type): boolean { + if (type.isUnion()) { + for (const t of type.types) { + if (!this.isElementAcessAllowed(t)) { + return false; + } + } + return true; + } + + const typeNode = this.tsTypeChecker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.None); + + return ( + this.tsUtils.isLibraryType(type) || + this.tsUtils.isAnyType(type) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isArray) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isTuple) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || + this.tsUtils.isEnumType(type) || + // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType + this.tsUtils.isEsObjectType(typeNode) + ); + } + + private handleElementAccessExpression(node: ts.Node): void { const tsElementAccessExpr = node as ts.ElementAccessExpression; const tsElemAccessBaseExprType = this.tsUtils.getNonNullableType( this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) ); - const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode( - tsElemAccessBaseExprType, - undefined, - ts.NodeBuilderFlags.None - ); if ( - !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && - !this.tsUtils.isAnyType(tsElemAccessBaseExprType) && !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isArray) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isTuple) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStdRecordType) && - !this.tsUtils.isEnumType(tsElemAccessBaseExprType) && - !this.tsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStringType) + !this.isElementAcessAllowed(tsElemAccessBaseExprType) ) { let autofix = Autofixer.fixPropertyAccessByIndex(node); - const autofixable = autofix != undefined; + const autofixable = autofix !== undefined; if (!this.autofixesInfo.shouldAutofix(node, FaultID.PropertyAccessByIndex)) { autofix = undefined; } diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index e9193a11e..39ac6ee7e 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -149,3 +149,11 @@ str6[1] class AString extends String {} let str7 = new AString('dwdd') str7[1] + +type IndexableUnion = string[] | number[] | Uint8Array; +type NonIndexableUnion = string[] | number[] | Uint8Array | number; + +function indexUnion(iu: IndexableUnion, niu: NonIndexableUnion) { + iu[0]; + niu[0]; +} diff --git a/linter-4.2/test/property_access_by_index.ts.autofix.json b/linter-4.2/test/property_access_by_index.ts.autofix.json index df5e23653..ec238f953 100644 --- a/linter-4.2/test/property_access_by_index.ts.autofix.json +++ b/linter-4.2/test/property_access_by_index.ts.autofix.json @@ -69,6 +69,14 @@ "autofixable": false, "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 158, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.strict.json b/linter-4.2/test/property_access_by_index.ts.strict.json index daf068f0d..ffbb22f53 100644 --- a/linter-4.2/test/property_access_by_index.ts.strict.json +++ b/linter-4.2/test/property_access_by_index.ts.strict.json @@ -62,6 +62,13 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 158, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index b4530cadd..e2b06fb45 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -1451,26 +1451,39 @@ export class TypeScriptLinter { } } + private isElementAcessAllowed(type: ts.Type): boolean { + if (type.isUnion()) { + for (const t of type.types) { + if (!this.isElementAcessAllowed(t)) { + return false; + } + } + return true; + } + + const typeNode = this.tsTypeChecker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.None); + + return ( + this.tsUtils.isLibraryType(type) || + TsUtils.isAnyType(type) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isArray) || + this.tsUtils.isOrDerivedFrom(type, TsUtils.isTuple) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || + TsUtils.isEnumType(type) || + // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType + TsUtils.isEsObjectType(typeNode) + ); + } + private handleElementAccessExpression(node: ts.Node): void { const tsElementAccessExpr = node as ts.ElementAccessExpression; const tsElemAccessBaseExprType = TsUtils.getNonNullableType( this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) ); - const tsElemAccessBaseExprTypeNode = this.tsTypeChecker.typeToTypeNode( - tsElemAccessBaseExprType, - undefined, - ts.NodeBuilderFlags.None - ); if ( - !this.tsUtils.isLibraryType(tsElemAccessBaseExprType) && - !TsUtils.isAnyType(tsElemAccessBaseExprType) && !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isArray) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, TsUtils.isTuple) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStdRecordType) && - !TsUtils.isEnumType(tsElemAccessBaseExprType) && - !TsUtils.isEsObjectType(tsElemAccessBaseExprTypeNode) && - !this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isStringType) + !this.isElementAcessAllowed(tsElemAccessBaseExprType) ) { let autofix = Autofixer.fixPropertyAccessByIndex(node); const autofixable = autofix !== undefined; diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index e9193a11e..39ac6ee7e 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -149,3 +149,11 @@ str6[1] class AString extends String {} let str7 = new AString('dwdd') str7[1] + +type IndexableUnion = string[] | number[] | Uint8Array; +type NonIndexableUnion = string[] | number[] | Uint8Array | number; + +function indexUnion(iu: IndexableUnion, niu: NonIndexableUnion) { + iu[0]; + niu[0]; +} diff --git a/linter/test/property_access_by_index.ts.autofix.json b/linter/test/property_access_by_index.ts.autofix.json index df5e23653..ec238f953 100644 --- a/linter/test/property_access_by_index.ts.autofix.json +++ b/linter/test/property_access_by_index.ts.autofix.json @@ -69,6 +69,14 @@ "autofixable": false, "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 158, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.strict.json b/linter/test/property_access_by_index.ts.strict.json index daf068f0d..ffbb22f53 100644 --- a/linter/test/property_access_by_index.ts.strict.json +++ b/linter/test/property_access_by_index.ts.strict.json @@ -62,6 +62,13 @@ "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" + }, + { + "line": 158, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file -- Gitee From 340ffd9a7aedc72293a8849d0c7fe4ef90bde420 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Fri, 17 Nov 2023 16:48:21 +0300 Subject: [PATCH 42/49] [ArkTS Linter] Fix #14504, case 6: Use 'ts.forEachChild()' to traverse AST nodes in order to avoid processing JSDoc nodes. Change-Id: I4d5f5313c4ff67ba2bc1053b2ceddb86a40a4c02 Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 10 ++++------ linter-4.2/test/class_as_object.ts | 7 ++++++- linter/lib/utils/functions/ForEachNodeInSubtree.ts | 11 +++-------- linter/test/class_as_object.ts | 7 ++++++- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index b283c094c..1a5b64f4b 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -234,12 +234,10 @@ export class TypeScriptLinter { if (stopCond?.call(this, node)) { return; } - // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. - // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. - // to traverse child nodes. - for (const child of node.getChildren()) { - this.forEachNodeInSubtree(child, cb, stopCond) - } + + ts.forEachChild(node, (child) => { + this.forEachNodeInSubtree(child, cb, stopCond); + }); } private visitSourceFile(sf: ts.SourceFile): void { const callback = (node: ts.Node) => { diff --git a/linter-4.2/test/class_as_object.ts b/linter-4.2/test/class_as_object.ts index 195c076ec..1ee2fb6e8 100644 --- a/linter-4.2/test/class_as_object.ts +++ b/linter-4.2/test/class_as_object.ts @@ -115,4 +115,9 @@ let s2: string = NS.E[s]; for (let item = 0; item < Object.keys(NS.E).length; item++) { console.log(item); -} \ No newline at end of file +} + +/** + * {@link C} - should not report error + */ +class JSDocClass {} \ No newline at end of file diff --git a/linter/lib/utils/functions/ForEachNodeInSubtree.ts b/linter/lib/utils/functions/ForEachNodeInSubtree.ts index 4780f71d8..08fd8e714 100644 --- a/linter/lib/utils/functions/ForEachNodeInSubtree.ts +++ b/linter/lib/utils/functions/ForEachNodeInSubtree.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import type * as ts from 'typescript'; +import * as ts from 'typescript'; export function forEachNodeInSubtree( node: ts.Node, @@ -25,12 +25,7 @@ export function forEachNodeInSubtree( return; } - /* - * #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. - * As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. - * to traverse child nodes. - */ - for (const child of node.getChildren()) { + ts.forEachChild(node, (child) => { forEachNodeInSubtree(child, cb, stopCond); - } + }); } diff --git a/linter/test/class_as_object.ts b/linter/test/class_as_object.ts index 6fa062cdc..2f9511d5d 100644 --- a/linter/test/class_as_object.ts +++ b/linter/test/class_as_object.ts @@ -115,4 +115,9 @@ let s2: string = NS.E[s]; for (let item = 0; item < Object.keys(NS.E).length; item++) { console.log(item); -} \ No newline at end of file +} + +/** + * {@link C} - should not report error + */ +class JSDocClass {} \ No newline at end of file -- Gitee From dd86afe5a912037d801d381267908ef1dfb66706 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Fri, 17 Nov 2023 18:45:41 +0300 Subject: [PATCH 43/49] [arkts-linter] 1504.3 fix processing of library types in handleElementAcccessExpression Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 3 +++ linter-4.2/test/oh_modules/ohos_lib.ts | 6 ++++++ linter-4.2/test/property_access_by_index.ts | 8 ++++++-- linter/lib/TypeScriptLinter.ts | 3 +++ linter/test/oh_modules/ohos_lib.ts | 17 +++++++++++++---- linter/test/property_access_by_index.ts | 8 ++++++-- 6 files changed, 37 insertions(+), 8 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index e4e0b50ac..3c6aa34d7 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1611,10 +1611,13 @@ export class TypeScriptLinter { private handleElementAccessExpression(node: ts.Node): void { const tsElementAccessExpr = node as ts.ElementAccessExpression; + const tsElementAccessExprSymbol = this.tsUtils.trueSymbolAtLocation(tsElementAccessExpr.expression); const tsElemAccessBaseExprType = this.tsUtils.getNonNullableType( this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) ); if ( + // unnamed types do not have symbol, so need to check that explicitly + !this.tsUtils.isLibrarySymbol(tsElementAccessExprSymbol) && !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && !this.isElementAcessAllowed(tsElemAccessBaseExprType) ) { diff --git a/linter-4.2/test/oh_modules/ohos_lib.ts b/linter-4.2/test/oh_modules/ohos_lib.ts index c69856185..267e66b09 100644 --- a/linter-4.2/test/oh_modules/ohos_lib.ts +++ b/linter-4.2/test/oh_modules/ohos_lib.ts @@ -23,3 +23,9 @@ export function ohFunction2(p: {d: OhosI}): void {} export function fooOh(): any {} export function barOh(a: any) {} + +export interface OhosInterface { + fld: A & { + [key: string]: number; + }; +} diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index 39ac6ee7e..c6ed97915 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import {OhosInterface} from './oh_modules/ohos_lib' // #14071 class A { v: string = ''; @@ -150,10 +150,14 @@ class AString extends String {} let str7 = new AString('dwdd') str7[1] -type IndexableUnion = string[] | number[] | Uint8Array; +type IndexableUnion = string[] | (number | string)[] | Uint8Array; type NonIndexableUnion = string[] | number[] | Uint8Array | number; function indexUnion(iu: IndexableUnion, niu: NonIndexableUnion) { iu[0]; niu[0]; } + +function testLibraryUnnamedType(a: OhosInterface) { + a['kek']; +} diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index e2b06fb45..43dacfca3 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -1478,10 +1478,13 @@ export class TypeScriptLinter { private handleElementAccessExpression(node: ts.Node): void { const tsElementAccessExpr = node as ts.ElementAccessExpression; + const tsElementAccessExprSymbol = this.tsUtils.trueSymbolAtLocation(tsElementAccessExpr.expression); const tsElemAccessBaseExprType = TsUtils.getNonNullableType( this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) ); if ( + // unnamed types do not have symbol, so need to check that explicitly + !this.tsUtils.isLibrarySymbol(tsElementAccessExprSymbol) && !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && !this.isElementAcessAllowed(tsElemAccessBaseExprType) ) { diff --git a/linter/test/oh_modules/ohos_lib.ts b/linter/test/oh_modules/ohos_lib.ts index c69856185..cf99dd919 100644 --- a/linter/test/oh_modules/ohos_lib.ts +++ b/linter/test/oh_modules/ohos_lib.ts @@ -1,5 +1,8 @@ export class A { - constructor(public onAction?: () => void, public onH?: () => void) {} + constructor( + public onAction?: () => void, + public onH?: () => void + ) {} } export function f(a: Partial) {} @@ -15,11 +18,17 @@ export class OhosLibCC extends OhosLibC {} export class OhosLibCI implements OhosLibI {} export interface OhosI { - f: number + f: number; } -export function ohFunction1({d: OhosI}): void {} // incorrect usage, but it was an issue, so we check it too -export function ohFunction2(p: {d: OhosI}): void {} +export function ohFunction1({ d: OhosI }): void {} // incorrect usage, but it was an issue, so we check it too +export function ohFunction2(p: { d: OhosI }): void {} export function fooOh(): any {} export function barOh(a: any) {} + +export interface OhosInterface { + fld: A & { + [key: string]: number; + }; +} diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index 39ac6ee7e..c6ed97915 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import {OhosInterface} from './oh_modules/ohos_lib' // #14071 class A { v: string = ''; @@ -150,10 +150,14 @@ class AString extends String {} let str7 = new AString('dwdd') str7[1] -type IndexableUnion = string[] | number[] | Uint8Array; +type IndexableUnion = string[] | (number | string)[] | Uint8Array; type NonIndexableUnion = string[] | number[] | Uint8Array | number; function indexUnion(iu: IndexableUnion, niu: NonIndexableUnion) { iu[0]; niu[0]; } + +function testLibraryUnnamedType(a: OhosInterface) { + a['kek']; +} -- Gitee From 5907d55174d84de96d1e0c3e8ed43deb71ccc4b6 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Fri, 17 Nov 2023 20:04:01 +0300 Subject: [PATCH 44/49] [arkts-linter] REVERT THIS COMMIT allow indexed access to `object` type Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 1 + linter-4.2/test/property_access_by_index.ts | 5 +++++ .../property_access_by_index.ts.autofix.json | 16 ++++++++-------- .../test/property_access_by_index.ts.strict.json | 14 +++++++------- linter/lib/TypeScriptLinter.ts | 2 ++ linter/test/property_access_by_index.ts | 5 +++++ .../property_access_by_index.ts.autofix.json | 16 ++++++++-------- .../test/property_access_by_index.ts.strict.json | 14 +++++++------- 8 files changed, 43 insertions(+), 30 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 3c6aa34d7..a7c2c381f 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1604,6 +1604,7 @@ export class TypeScriptLinter { this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || this.tsUtils.isEnumType(type) || + this.tsUtils.isIntrinsicObjectType(type) || // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType this.tsUtils.isEsObjectType(typeNode) ); diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index c6ed97915..0985bb0f3 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -161,3 +161,8 @@ function indexUnion(iu: IndexableUnion, niu: NonIndexableUnion) { function testLibraryUnnamedType(a: OhosInterface) { a['kek']; } + +function indexObject(oSmall: object, oBig: Object) { + oSmall['fld']; + oBig['fld']; +} diff --git a/linter-4.2/test/property_access_by_index.ts.autofix.json b/linter-4.2/test/property_access_by_index.ts.autofix.json index ec238f953..c62f38544 100644 --- a/linter-4.2/test/property_access_by_index.ts.autofix.json +++ b/linter-4.2/test/property_access_by_index.ts.autofix.json @@ -30,14 +30,6 @@ "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" }, - { - "line": 45, - "column": 3, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 49, "column": 3, @@ -77,6 +69,14 @@ "autofixable": true, "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 167, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/property_access_by_index.ts.strict.json b/linter-4.2/test/property_access_by_index.ts.strict.json index ffbb22f53..fdf66e5c2 100644 --- a/linter-4.2/test/property_access_by_index.ts.strict.json +++ b/linter-4.2/test/property_access_by_index.ts.strict.json @@ -28,13 +28,6 @@ "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" }, - { - "line": 45, - "column": 3, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 49, "column": 3, @@ -69,6 +62,13 @@ "problem": "PropertyAccessByIndex", "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 167, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index 43dacfca3..d7c8d217a 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -57,6 +57,7 @@ import { LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; import { forEachNodeInSubtree } from './utils/functions/ForEachNodeInSubtree'; +import { isIntrinsicObjectType } from './utils/functions/isIntrinsicObjectType'; export function consoleLog(...args: unknown[]): void { if (TypeScriptLinter.ideMode) { @@ -1470,6 +1471,7 @@ export class TypeScriptLinter { this.tsUtils.isOrDerivedFrom(type, TsUtils.isTuple) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || + isIntrinsicObjectType(type) || TsUtils.isEnumType(type) || // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType TsUtils.isEsObjectType(typeNode) diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index c6ed97915..0985bb0f3 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -161,3 +161,8 @@ function indexUnion(iu: IndexableUnion, niu: NonIndexableUnion) { function testLibraryUnnamedType(a: OhosInterface) { a['kek']; } + +function indexObject(oSmall: object, oBig: Object) { + oSmall['fld']; + oBig['fld']; +} diff --git a/linter/test/property_access_by_index.ts.autofix.json b/linter/test/property_access_by_index.ts.autofix.json index ec238f953..c62f38544 100644 --- a/linter/test/property_access_by_index.ts.autofix.json +++ b/linter/test/property_access_by_index.ts.autofix.json @@ -30,14 +30,6 @@ "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" }, - { - "line": 45, - "column": 3, - "problem": "PropertyAccessByIndex", - "autofixable": true, - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 49, "column": 3, @@ -77,6 +69,14 @@ "autofixable": true, "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 167, + "column": 3, + "problem": "PropertyAccessByIndex", + "autofixable": true, + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file diff --git a/linter/test/property_access_by_index.ts.strict.json b/linter/test/property_access_by_index.ts.strict.json index ffbb22f53..fdf66e5c2 100644 --- a/linter/test/property_access_by_index.ts.strict.json +++ b/linter/test/property_access_by_index.ts.strict.json @@ -28,13 +28,6 @@ "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" }, - { - "line": 45, - "column": 3, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" - }, { "line": 49, "column": 3, @@ -69,6 +62,13 @@ "problem": "PropertyAccessByIndex", "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" + }, + { + "line": 167, + "column": 3, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)" } ] } \ No newline at end of file -- Gitee From 36a099fb52b4ab9adb59af1dc524f14e5e1b8fbf Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Mon, 20 Nov 2023 03:25:01 +0300 Subject: [PATCH 45/49] [arkts-linter] relax indexed access for Map type. REMOVE AFTER RELEASE Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 1 + linter-4.2/src/Utils.ts | 5 +++++ linter-4.2/test/property_access_by_index.ts | 10 ++++++++++ linter/lib/TypeScriptLinter.ts | 1 + linter/lib/utils/TsUtils.ts | 5 +++++ linter/test/property_access_by_index.ts | 10 ++++++++++ 6 files changed, 32 insertions(+) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index a7c2c381f..aaffb20c4 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1603,6 +1603,7 @@ export class TypeScriptLinter { this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isTuple) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdMapType) || this.tsUtils.isEnumType(type) || this.tsUtils.isIntrinsicObjectType(type) || // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index c431bf166..c56a9541f 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -1169,6 +1169,11 @@ export class TsUtils { return false; } + isStdMapType(type: ts.Type): boolean { + const sym = type.symbol; + return !!sym && sym.getName() === 'Map' && this.isGlobalSymbol(sym); + } + public isStdErrorType(type: ts.Type): boolean { const symbol = type.symbol; if (!symbol) { diff --git a/linter-4.2/test/property_access_by_index.ts b/linter-4.2/test/property_access_by_index.ts index 0985bb0f3..5593ddcea 100644 --- a/linter-4.2/test/property_access_by_index.ts +++ b/linter-4.2/test/property_access_by_index.ts @@ -166,3 +166,13 @@ function indexObject(oSmall: object, oBig: Object) { oSmall['fld']; oBig['fld']; } + +class MMap extends Map {} + +let mmap1 = new Map(); +let mmap2 = new Map(); +let mmap3 = new MMap(); + +mmap1[1]; +mmap2['222']; +mmap3["kkr"]; diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index d7c8d217a..0a500eee8 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -1471,6 +1471,7 @@ export class TypeScriptLinter { this.tsUtils.isOrDerivedFrom(type, TsUtils.isTuple) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdMapType) || isIntrinsicObjectType(type) || TsUtils.isEnumType(type) || // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType diff --git a/linter/lib/utils/TsUtils.ts b/linter/lib/utils/TsUtils.ts index 803de5e59..cfe19066f 100644 --- a/linter/lib/utils/TsUtils.ts +++ b/linter/lib/utils/TsUtils.ts @@ -996,6 +996,11 @@ export class TsUtils { return false; } + isStdMapType(type: ts.Type): boolean { + const sym = type.symbol; + return !!sym && sym.getName() === 'Map' && this.isGlobalSymbol(sym); + } + isStdErrorType(type: ts.Type): boolean { const symbol = type.symbol; if (!symbol) { diff --git a/linter/test/property_access_by_index.ts b/linter/test/property_access_by_index.ts index 0985bb0f3..5593ddcea 100644 --- a/linter/test/property_access_by_index.ts +++ b/linter/test/property_access_by_index.ts @@ -166,3 +166,13 @@ function indexObject(oSmall: object, oBig: Object) { oSmall['fld']; oBig['fld']; } + +class MMap extends Map {} + +let mmap1 = new Map(); +let mmap2 = new Map(); +let mmap3 = new MMap(); + +mmap1[1]; +mmap2['222']; +mmap3["kkr"]; -- Gitee From 7e07b16fd24b6d0871faa6ba602116a5b12d1311 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Tue, 21 Nov 2023 15:10:29 +0300 Subject: [PATCH 46/49] [arkts-linter] fix strict mode error detection Signed-off-by: Nazarov Konstantin --- linter-4.2/src/TypeScriptLinter.ts | 39 ++++++++++++++++++++------ linter/lib/TypeScriptLinter.ts | 44 +++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index aaffb20c4..24dbff615 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -73,6 +73,25 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages = new Set(); } + private initEtsHandlers(): void { + + /* + * some syntax elements are ArkTs-specific and are only implemented inside patched + * compiler, so we initialize those handlers if corresponding properties do exist + */ + const etsComponentExpression: ts.SyntaxKind | undefined = (ts.SyntaxKind as any).EtsComponentExpression; + if (etsComponentExpression) { + this.handlersMap.set(etsComponentExpression, this.handleEtsComponentExpression); + } + } + + private initCounters(): void { + for (let i = 0; i < FaultID.LAST_ID; i++) { + this.nodeCounters[i] = 0; + this.lineCounters[i] = 0; + } + } + constructor( private tsTypeChecker: ts.TypeChecker, private autofixesInfo: AutofixInfoSet, @@ -87,10 +106,8 @@ export class TypeScriptLinter { this.walkedComments = new Set(); this.libraryTypeCallDiagnosticChecker = new LibraryTypeCallDiagnosticChecker(TypeScriptLinter.filteredDiagnosticMessages); - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } + this.initEtsHandlers(); + this.initCounters(); } readonly handlersMap = new Map([ @@ -1690,7 +1707,6 @@ export class TypeScriptLinter { let tsCallExpr = node as ts.CallExpression; const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); - const calleeType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); this.handleImportCall(tsCallExpr); @@ -1709,13 +1725,19 @@ export class TypeScriptLinter { } this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } - this.handleLibraryTypeCall(tsCallExpr, calleeType); + this.handleLibraryTypeCall(tsCallExpr); if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { this.incrementCounters(node, FaultID.EsObjectType); } } + private handleEtsComponentExpression(node: ts.Node): void { + // for all the checks we make EtsComponentExpression is compatible with the CallExpression + const etsComponentExpression = node as ts.CallExpression; + this.handleLibraryTypeCall(etsComponentExpression); + } + private handleImportCall(tsCallExpr: ts.CallExpression) { if (tsCallExpr.expression.kind === ts.SyntaxKind.ImportKeyword) { // relax rule#133 "arkts-no-runtime-import" @@ -1885,8 +1907,9 @@ export class TypeScriptLinter { return result; } - private handleLibraryTypeCall(callExpr: ts.CallExpression, calleeType: ts.Type) { - let inLibCall = this.tsUtils.isLibraryType(calleeType); + private handleLibraryTypeCall(callExpr: ts.CallExpression) { + const calleeType = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); + const inLibCall = this.tsUtils.isLibraryType(calleeType); const diagnosticMessages: Array = [] this.libraryTypeCallDiagnosticChecker.configure(inLibCall, diagnosticMessages); diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index 0a500eee8..21b0bd63e 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -101,10 +101,29 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages = new Set(); } + private initEtsHandlers(): void { + + /* + * some syntax elements are ArkTs-specific and are only implemented inside patched + * compiler, so we initialize those handlers if corresponding properties do exist + */ + const etsComponentExpression: ts.SyntaxKind | undefined = (ts.SyntaxKind as any).EtsComponentExpression; + if (etsComponentExpression) { + this.handlersMap.set(etsComponentExpression, this.handleEtsComponentExpression); + } + } + + private initCounters(): void { + for (let i = 0; i < FaultID.LAST_ID; i++) { + this.nodeCounters[i] = 0; + this.lineCounters[i] = 0; + } + } + constructor( private readonly tsTypeChecker: ts.TypeChecker, private readonly autofixesInfo: AutofixInfoSet, - public strictMode: boolean, + readonly strictMode: boolean, private readonly cancellationToken?: ts.CancellationToken, private readonly incrementalLintInfo?: IncrementalLintInfo, private readonly tscStrictDiagnostics?: Map, @@ -119,10 +138,8 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages ); - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } + this.initEtsHandlers(); + this.initCounters(); } readonly handlersMap = new Map([ @@ -1553,7 +1570,6 @@ export class TypeScriptLinter { const tsCallExpr = node as ts.CallExpression; const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); - const calleeType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); this.handleImportCall(tsCallExpr); @@ -1572,7 +1588,7 @@ export class TypeScriptLinter { } this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } - this.handleLibraryTypeCall(tsCallExpr, calleeType); + this.handleLibraryTypeCall(tsCallExpr); if ( ts.isPropertyAccessExpression(tsCallExpr.expression) && @@ -1582,6 +1598,12 @@ export class TypeScriptLinter { } } + private handleEtsComponentExpression(node: ts.Node): void { + // for all the checks we make EtsComponentExpression is compatible with the CallExpression + const etsComponentExpression = node as ts.CallExpression; + this.handleLibraryTypeCall(etsComponentExpression); + } + private handleImportCall(tsCallExpr: ts.CallExpression): void { if (tsCallExpr.expression.kind === ts.SyntaxKind.ImportKeyword) { // relax rule#133 "arkts-no-runtime-import" @@ -1752,9 +1774,11 @@ export class TypeScriptLinter { return result; } - private handleLibraryTypeCall(callExpr: ts.CallExpression, calleeType: ts.Type): void { + private handleLibraryTypeCall(callExpr: ts.CallExpression): void { + const calleeType = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); const inLibCall = this.tsUtils.isLibraryType(calleeType); const diagnosticMessages: Array = []; + this.libraryTypeCallDiagnosticChecker.configure(inLibCall, diagnosticMessages); const nonFilteringRanges = TypeScriptLinter.findNonFilteringRangesFunctionCalls(callExpr); @@ -1773,10 +1797,10 @@ export class TypeScriptLinter { this.filterStrictDiagnostics( { [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); + return TypeScriptLinter.checkInRange(rangesToFilter, pos); }, [NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); + return TypeScriptLinter.checkInRange(rangesToFilter, pos); }, [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { return TypeScriptLinter.checkInRange(rangesToFilter, pos); -- Gitee From 630cf622afa7506f49d9f6f35b3f0fb379e43b1e Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Tue, 21 Nov 2023 20:22:13 +0300 Subject: [PATCH 47/49] [ArkTS Linter] Fix #14569 Change-Id: Ic89cd771a64eaf73d4b4baf0ead74fb6248416be Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/Utils.ts | 12 +++++++++++ .../test/object_literals_prop_func_type.ts | 10 ++++++++- linter/lib/utils/TsUtils.ts | 21 +++++++++++++++++++ linter/test/object_literals_prop_func_type.ts | 10 ++++++++- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index c56a9541f..46f7e7cca 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -745,6 +745,11 @@ export class TsUtils { return false; } + // #14569: Check for Function type. + if (this.areCompatibleFunctionals(lhsType, rhsType)) { + return false; + } + if (rhsType.isUnion()) { // Each Class/Interface of the RHS union type must be compatible with LHS type. for (const compType of rhsType.types) { @@ -1548,4 +1553,11 @@ export class TsUtils { } return type; } + + private areCompatibleFunctionals(lhsType: ts.Type, rhsType: ts.Type): boolean { + return ( + (this.isStdFunctionType(lhsType) || this.isFunctionalType(lhsType)) && + (this.isStdFunctionType(rhsType) || this.isFunctionalType(rhsType)) + ); + } } diff --git a/linter-4.2/test/object_literals_prop_func_type.ts b/linter-4.2/test/object_literals_prop_func_type.ts index 19ce7f092..51df3217f 100644 --- a/linter-4.2/test/object_literals_prop_func_type.ts +++ b/linter-4.2/test/object_literals_prop_func_type.ts @@ -43,4 +43,12 @@ a = { b: w, c: e, d: r, -} \ No newline at end of file +} + +// #14569 - initialize field with 'Function' object +class B { + f: Function = () => {}; +} +let b: B = { + f: Function +}; \ No newline at end of file diff --git a/linter/lib/utils/TsUtils.ts b/linter/lib/utils/TsUtils.ts index cfe19066f..b3ad9c947 100644 --- a/linter/lib/utils/TsUtils.ts +++ b/linter/lib/utils/TsUtils.ts @@ -566,6 +566,10 @@ export class TsUtils { if (this.isDynamicObjectAssignedToStdType(lhsType, rhsExpr)) { return false; } + // #14569: Check for Function type. + if (this.areCompatibleFunctionals(lhsType, rhsType)) { + return false; + } if (rhsType.isUnion() || lhsType.isUnion()) { return this.needToDeduceStructuralIdentityHandleUnions(lhsType, rhsType, rhsExpr, allowPromotion); } @@ -1356,4 +1360,21 @@ export class TsUtils { } return type; } + + private areCompatibleFunctionals(lhsType: ts.Type, rhsType: ts.Type): boolean { + return ( + (this.isStdFunctionType(lhsType) || TsUtils.isFunctionalType(lhsType)) && + (this.isStdFunctionType(rhsType) || TsUtils.isFunctionalType(rhsType)) + ); + } + + private static isFunctionalType(type: ts.Type): boolean { + const callSigns = type.getCallSignatures(); + return callSigns && callSigns.length > 0; + } + + private isStdFunctionType(type: ts.Type): boolean { + const sym = type.getSymbol(); + return !!sym && sym.getName() === 'Function' && this.isGlobalSymbol(sym); + } } diff --git a/linter/test/object_literals_prop_func_type.ts b/linter/test/object_literals_prop_func_type.ts index 19ce7f092..51df3217f 100644 --- a/linter/test/object_literals_prop_func_type.ts +++ b/linter/test/object_literals_prop_func_type.ts @@ -43,4 +43,12 @@ a = { b: w, c: e, d: r, -} \ No newline at end of file +} + +// #14569 - initialize field with 'Function' object +class B { + f: Function = () => {}; +} +let b: B = { + f: Function +}; \ No newline at end of file -- Gitee From de4813cd6114387dc089c3508cb8f68b2458c5f5 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Wed, 22 Nov 2023 09:36:06 +0000 Subject: [PATCH 48/49] Revert 'Pull Request !60 : [arkts-linter] fix strict mode error filtering' --- linter-4.2/src/TypeScriptLinter.ts | 39 ++++++-------------------- linter/lib/TypeScriptLinter.ts | 44 +++++++----------------------- 2 files changed, 18 insertions(+), 65 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 24dbff615..aaffb20c4 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -73,25 +73,6 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages = new Set(); } - private initEtsHandlers(): void { - - /* - * some syntax elements are ArkTs-specific and are only implemented inside patched - * compiler, so we initialize those handlers if corresponding properties do exist - */ - const etsComponentExpression: ts.SyntaxKind | undefined = (ts.SyntaxKind as any).EtsComponentExpression; - if (etsComponentExpression) { - this.handlersMap.set(etsComponentExpression, this.handleEtsComponentExpression); - } - } - - private initCounters(): void { - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } - } - constructor( private tsTypeChecker: ts.TypeChecker, private autofixesInfo: AutofixInfoSet, @@ -106,8 +87,10 @@ export class TypeScriptLinter { this.walkedComments = new Set(); this.libraryTypeCallDiagnosticChecker = new LibraryTypeCallDiagnosticChecker(TypeScriptLinter.filteredDiagnosticMessages); - this.initEtsHandlers(); - this.initCounters(); + for (let i = 0; i < FaultID.LAST_ID; i++) { + this.nodeCounters[i] = 0; + this.lineCounters[i] = 0; + } } readonly handlersMap = new Map([ @@ -1707,6 +1690,7 @@ export class TypeScriptLinter { let tsCallExpr = node as ts.CallExpression; const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); + const calleeType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); this.handleImportCall(tsCallExpr); @@ -1725,19 +1709,13 @@ export class TypeScriptLinter { } this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } - this.handleLibraryTypeCall(tsCallExpr); + this.handleLibraryTypeCall(tsCallExpr, calleeType); if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { this.incrementCounters(node, FaultID.EsObjectType); } } - private handleEtsComponentExpression(node: ts.Node): void { - // for all the checks we make EtsComponentExpression is compatible with the CallExpression - const etsComponentExpression = node as ts.CallExpression; - this.handleLibraryTypeCall(etsComponentExpression); - } - private handleImportCall(tsCallExpr: ts.CallExpression) { if (tsCallExpr.expression.kind === ts.SyntaxKind.ImportKeyword) { // relax rule#133 "arkts-no-runtime-import" @@ -1907,9 +1885,8 @@ export class TypeScriptLinter { return result; } - private handleLibraryTypeCall(callExpr: ts.CallExpression) { - const calleeType = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); - const inLibCall = this.tsUtils.isLibraryType(calleeType); + private handleLibraryTypeCall(callExpr: ts.CallExpression, calleeType: ts.Type) { + let inLibCall = this.tsUtils.isLibraryType(calleeType); const diagnosticMessages: Array = [] this.libraryTypeCallDiagnosticChecker.configure(inLibCall, diagnosticMessages); diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index 21b0bd63e..0a500eee8 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -101,29 +101,10 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages = new Set(); } - private initEtsHandlers(): void { - - /* - * some syntax elements are ArkTs-specific and are only implemented inside patched - * compiler, so we initialize those handlers if corresponding properties do exist - */ - const etsComponentExpression: ts.SyntaxKind | undefined = (ts.SyntaxKind as any).EtsComponentExpression; - if (etsComponentExpression) { - this.handlersMap.set(etsComponentExpression, this.handleEtsComponentExpression); - } - } - - private initCounters(): void { - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } - } - constructor( private readonly tsTypeChecker: ts.TypeChecker, private readonly autofixesInfo: AutofixInfoSet, - readonly strictMode: boolean, + public strictMode: boolean, private readonly cancellationToken?: ts.CancellationToken, private readonly incrementalLintInfo?: IncrementalLintInfo, private readonly tscStrictDiagnostics?: Map, @@ -138,8 +119,10 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages ); - this.initEtsHandlers(); - this.initCounters(); + for (let i = 0; i < FaultID.LAST_ID; i++) { + this.nodeCounters[i] = 0; + this.lineCounters[i] = 0; + } } readonly handlersMap = new Map([ @@ -1570,6 +1553,7 @@ export class TypeScriptLinter { const tsCallExpr = node as ts.CallExpression; const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); + const calleeType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); this.handleImportCall(tsCallExpr); @@ -1588,7 +1572,7 @@ export class TypeScriptLinter { } this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } - this.handleLibraryTypeCall(tsCallExpr); + this.handleLibraryTypeCall(tsCallExpr, calleeType); if ( ts.isPropertyAccessExpression(tsCallExpr.expression) && @@ -1598,12 +1582,6 @@ export class TypeScriptLinter { } } - private handleEtsComponentExpression(node: ts.Node): void { - // for all the checks we make EtsComponentExpression is compatible with the CallExpression - const etsComponentExpression = node as ts.CallExpression; - this.handleLibraryTypeCall(etsComponentExpression); - } - private handleImportCall(tsCallExpr: ts.CallExpression): void { if (tsCallExpr.expression.kind === ts.SyntaxKind.ImportKeyword) { // relax rule#133 "arkts-no-runtime-import" @@ -1774,11 +1752,9 @@ export class TypeScriptLinter { return result; } - private handleLibraryTypeCall(callExpr: ts.CallExpression): void { - const calleeType = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); + private handleLibraryTypeCall(callExpr: ts.CallExpression, calleeType: ts.Type): void { const inLibCall = this.tsUtils.isLibraryType(calleeType); const diagnosticMessages: Array = []; - this.libraryTypeCallDiagnosticChecker.configure(inLibCall, diagnosticMessages); const nonFilteringRanges = TypeScriptLinter.findNonFilteringRangesFunctionCalls(callExpr); @@ -1797,10 +1773,10 @@ export class TypeScriptLinter { this.filterStrictDiagnostics( { [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange(rangesToFilter, pos); + return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); }, [NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange(rangesToFilter, pos); + return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); }, [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { return TypeScriptLinter.checkInRange(rangesToFilter, pos); -- Gitee From cc3c25985579eb0fab397b1823718834965b0610 Mon Sep 17 00:00:00 2001 From: Nazarov Konstantin Date: Mon, 27 Nov 2023 12:48:04 +0000 Subject: [PATCH 49/49] Revert 'Pull Request !65 : Revert 'Pull Request !60 : [arkts-linter] fix strict mode error filtering' ** it will be fixed in the next release **' --- linter-4.2/src/TypeScriptLinter.ts | 39 ++++++++++++++++++++------ linter/lib/TypeScriptLinter.ts | 44 +++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index aaffb20c4..24dbff615 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -73,6 +73,25 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages = new Set(); } + private initEtsHandlers(): void { + + /* + * some syntax elements are ArkTs-specific and are only implemented inside patched + * compiler, so we initialize those handlers if corresponding properties do exist + */ + const etsComponentExpression: ts.SyntaxKind | undefined = (ts.SyntaxKind as any).EtsComponentExpression; + if (etsComponentExpression) { + this.handlersMap.set(etsComponentExpression, this.handleEtsComponentExpression); + } + } + + private initCounters(): void { + for (let i = 0; i < FaultID.LAST_ID; i++) { + this.nodeCounters[i] = 0; + this.lineCounters[i] = 0; + } + } + constructor( private tsTypeChecker: ts.TypeChecker, private autofixesInfo: AutofixInfoSet, @@ -87,10 +106,8 @@ export class TypeScriptLinter { this.walkedComments = new Set(); this.libraryTypeCallDiagnosticChecker = new LibraryTypeCallDiagnosticChecker(TypeScriptLinter.filteredDiagnosticMessages); - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } + this.initEtsHandlers(); + this.initCounters(); } readonly handlersMap = new Map([ @@ -1690,7 +1707,6 @@ export class TypeScriptLinter { let tsCallExpr = node as ts.CallExpression; const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); - const calleeType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); this.handleImportCall(tsCallExpr); @@ -1709,13 +1725,19 @@ export class TypeScriptLinter { } this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } - this.handleLibraryTypeCall(tsCallExpr, calleeType); + this.handleLibraryTypeCall(tsCallExpr); if (ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression)) { this.incrementCounters(node, FaultID.EsObjectType); } } + private handleEtsComponentExpression(node: ts.Node): void { + // for all the checks we make EtsComponentExpression is compatible with the CallExpression + const etsComponentExpression = node as ts.CallExpression; + this.handleLibraryTypeCall(etsComponentExpression); + } + private handleImportCall(tsCallExpr: ts.CallExpression) { if (tsCallExpr.expression.kind === ts.SyntaxKind.ImportKeyword) { // relax rule#133 "arkts-no-runtime-import" @@ -1885,8 +1907,9 @@ export class TypeScriptLinter { return result; } - private handleLibraryTypeCall(callExpr: ts.CallExpression, calleeType: ts.Type) { - let inLibCall = this.tsUtils.isLibraryType(calleeType); + private handleLibraryTypeCall(callExpr: ts.CallExpression) { + const calleeType = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); + const inLibCall = this.tsUtils.isLibraryType(calleeType); const diagnosticMessages: Array = [] this.libraryTypeCallDiagnosticChecker.configure(inLibCall, diagnosticMessages); diff --git a/linter/lib/TypeScriptLinter.ts b/linter/lib/TypeScriptLinter.ts index 0a500eee8..21b0bd63e 100644 --- a/linter/lib/TypeScriptLinter.ts +++ b/linter/lib/TypeScriptLinter.ts @@ -101,10 +101,29 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages = new Set(); } + private initEtsHandlers(): void { + + /* + * some syntax elements are ArkTs-specific and are only implemented inside patched + * compiler, so we initialize those handlers if corresponding properties do exist + */ + const etsComponentExpression: ts.SyntaxKind | undefined = (ts.SyntaxKind as any).EtsComponentExpression; + if (etsComponentExpression) { + this.handlersMap.set(etsComponentExpression, this.handleEtsComponentExpression); + } + } + + private initCounters(): void { + for (let i = 0; i < FaultID.LAST_ID; i++) { + this.nodeCounters[i] = 0; + this.lineCounters[i] = 0; + } + } + constructor( private readonly tsTypeChecker: ts.TypeChecker, private readonly autofixesInfo: AutofixInfoSet, - public strictMode: boolean, + readonly strictMode: boolean, private readonly cancellationToken?: ts.CancellationToken, private readonly incrementalLintInfo?: IncrementalLintInfo, private readonly tscStrictDiagnostics?: Map, @@ -119,10 +138,8 @@ export class TypeScriptLinter { TypeScriptLinter.filteredDiagnosticMessages ); - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } + this.initEtsHandlers(); + this.initCounters(); } readonly handlersMap = new Map([ @@ -1553,7 +1570,6 @@ export class TypeScriptLinter { const tsCallExpr = node as ts.CallExpression; const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); - const calleeType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); this.handleImportCall(tsCallExpr); @@ -1572,7 +1588,7 @@ export class TypeScriptLinter { } this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); } - this.handleLibraryTypeCall(tsCallExpr, calleeType); + this.handleLibraryTypeCall(tsCallExpr); if ( ts.isPropertyAccessExpression(tsCallExpr.expression) && @@ -1582,6 +1598,12 @@ export class TypeScriptLinter { } } + private handleEtsComponentExpression(node: ts.Node): void { + // for all the checks we make EtsComponentExpression is compatible with the CallExpression + const etsComponentExpression = node as ts.CallExpression; + this.handleLibraryTypeCall(etsComponentExpression); + } + private handleImportCall(tsCallExpr: ts.CallExpression): void { if (tsCallExpr.expression.kind === ts.SyntaxKind.ImportKeyword) { // relax rule#133 "arkts-no-runtime-import" @@ -1752,9 +1774,11 @@ export class TypeScriptLinter { return result; } - private handleLibraryTypeCall(callExpr: ts.CallExpression, calleeType: ts.Type): void { + private handleLibraryTypeCall(callExpr: ts.CallExpression): void { + const calleeType = this.tsTypeChecker.getTypeAtLocation(callExpr.expression); const inLibCall = this.tsUtils.isLibraryType(calleeType); const diagnosticMessages: Array = []; + this.libraryTypeCallDiagnosticChecker.configure(inLibCall, diagnosticMessages); const nonFilteringRanges = TypeScriptLinter.findNonFilteringRangesFunctionCalls(callExpr); @@ -1773,10 +1797,10 @@ export class TypeScriptLinter { this.filterStrictDiagnostics( { [ARGUMENT_OF_TYPE_0_IS_NOT_ASSIGNABLE_TO_PARAMETER_OF_TYPE_1_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); + return TypeScriptLinter.checkInRange(rangesToFilter, pos); }, [NO_OVERLOAD_MATCHES_THIS_CALL_ERROR_CODE]: (pos: number) => { - return TypeScriptLinter.checkInRange([{ begin: callExpr.pos, end: callExpr.end }], pos); + return TypeScriptLinter.checkInRange(rangesToFilter, pos); }, [TYPE_0_IS_NOT_ASSIGNABLE_TO_TYPE_1_ERROR_CODE]: (pos: number) => { return TypeScriptLinter.checkInRange(rangesToFilter, pos); -- Gitee