diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json index 5ffcc059764a1c269ccdc0a2fe0c8c5885d9ebde..611a033828ee351a8d883852ab8fb3785bf19ed0 100644 --- a/ets2panda/linter/rule-config.json +++ b/ets2panda/linter/rule-config.json @@ -14,14 +14,17 @@ "arkts-no-function-return-this", "arkts-limited-stdlib", "arkts-no-class-add-super-prop-with-readonly", + "arkts-var-assignment-before-use", "arkts-no-classes-as-obj", "arkts-obj-literal-props", + "arkts-no-template-string-type", "arkts-obj-literal-key-type", "arkts-optional-methods", "arkts-numeric-semantic", "arkts-incompatible-function-types", "arkts-limited-void-type", "arkts-no-void-operator", + "arkts-no-local-class", "arkts-no-ts-overload", "arkts-limited-literal-types", "arkts-no-exponent-op", diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index 48ef059d6543234443a9e86fbefcc7dd1506e8df..f0b8e41253982f18ac37463e1e3174e0224759f0 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -104,7 +104,7 @@ cookBookTag[73] = ''; cookBookTag[74] = 'Destructuring variable declarations are not supported (arkts-no-destruct-decls)'; cookBookTag[75] = 'Use string-literal keys with Record (arkts-obj-literal-key-type)'; cookBookTag[76] = 'Type of parameter must be defined explicitly (arkts-require-func-arg-type)'; -cookBookTag[77] = ''; +cookBookTag[77] = 'Template string type is not supported (arkts-no-template-string-type)'; cookBookTag[78] = ''; cookBookTag[79] = 'Type annotation in catch clause is not supported (arkts-no-types-in-catch)'; cookBookTag[80] = '"for .. in" is not supported (arkts-no-for-in)'; @@ -267,7 +267,8 @@ cookBookTag[237] = 'Array and tuple are different type(arkts-no-tuples-arrays)'; cookBookTag[238] = 'The static property has no initializer (arkts-class-static-initialization)'; cookBookTag[239] = 'This keyword cannot be used as identifiers (arkts-invalid-identifier)'; cookBookTag[245] = 'JSON files cannot be imported (arkts-no-import-json-file)'; -cookBookTag[249] = 'The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)'; +cookBookTag[249] = + 'The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)'; cookBookTag[251] = '"!!" for bidirectional data binding is not supported (arkui-no-!!-bidirectional-data-binding)'; cookBookTag[252] = '"$$" for bidirectional data binding is not supported (arkui-no-$$-bidirectional-data-binding)'; cookBookTag[253] = '"${variable}" for decorator binding is not supported (arkui-link-decorator-passing)'; @@ -293,12 +294,15 @@ cookBookTag[268] = 'Direct usage of interop JS objects is not supported (arkts-i cookBookTag[269] = 'Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)'; cookBookTag[270] = 'ArkTS1.2 cannot catch a non Error instance thrown from JS code (arkts-interop-js2s-js-exception)'; +cookBookTag[271] = + 'After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)'; cookBookTag[274] = 'The subclass constructor must call the parent class\'s parametered constructor (arkts-subclass-must-call-super-constructor-with-args)'; cookBookTag[275] = 'The Custom component with custom layout capability needs to add the "@CustomLayout" decorator (arkui-custom-layout-need-add-decorator)'; cookBookTag[276] = 'ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)'; +cookBookTag[277] = 'Creating local classes is not supported (arkts-no-local-class)'; cookBookTag[281] = '"@Prop" decorator is not supported (arkui-no-prop-decorator)'; cookBookTag[282] = '"@StorageProp" decorator is not supported (arkui-no-storageprop-decorator)'; cookBookTag[283] = '"@LocalStorageProp" decorator is not supported (arkui-no-localstorageprop-decorator)'; diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index 3b94b8be413c74d7dd7f9c7e8c50fb763bcd1471..8ace468f161fd5f32f2aac72700714920a6452b3 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -66,6 +66,7 @@ faultsAttrs[FaultID.CommaOperator] = new FaultAttributes(71); faultsAttrs[FaultID.DestructuringDeclaration] = new FaultAttributes(74); faultsAttrs[FaultID.ObjectLiteralKeyType] = new FaultAttributes(75); faultsAttrs[FaultID.ParameterType] = new FaultAttributes(76); +faultsAttrs[FaultID.TemplateStringType] = new FaultAttributes(77); faultsAttrs[FaultID.CatchWithUnsupportedType] = new FaultAttributes(79); faultsAttrs[FaultID.ForInStatement] = new FaultAttributes(80); faultsAttrs[FaultID.MappedType] = new FaultAttributes(83); @@ -200,9 +201,11 @@ faultsAttrs[FaultID.InteropJsObjectCallStaticFunc] = new FaultAttributes(267, Pr faultsAttrs[FaultID.InteropJsObjectConditionJudgment] = new FaultAttributes(268); faultsAttrs[FaultID.InteropJsObjectExpandStaticInstance] = new FaultAttributes(269); faultsAttrs[FaultID.InteropJSFunctionInvoke] = new FaultAttributes(270); +faultsAttrs[FaultID.VariableMissingInitializer] = new FaultAttributes(271); faultsAttrs[FaultID.MissingSuperCall] = new FaultAttributes(274); faultsAttrs[FaultID.CustomLayoutNeedAddDecorator] = new FaultAttributes(275); faultsAttrs[FaultID.InterfaceFieldNotImplemented] = new FaultAttributes(276); +faultsAttrs[FaultID.NoLocalClass] = new FaultAttributes(277); faultsAttrs[FaultID.PropDecoratorNotSupported] = new FaultAttributes(281); faultsAttrs[FaultID.StoragePropDecoratorNotSupported] = new FaultAttributes(282); faultsAttrs[FaultID.LocalStoragePropDecoratorNotSupported] = new FaultAttributes(283); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index fa4599cdbea2bfec95c37e3da4845ec89977b527..d812eab32339364d3f430dad380008fcffea5ec2 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -84,6 +84,7 @@ faultDesc[FaultID.ImportAssignment] = 'Import assignments (import = ..)'; faultDesc[FaultID.GenericCallNoTypeArgs] = 'Generic calls without type arguments'; faultDesc[FaultID.ParameterProperties] = 'Parameter properties in constructor'; faultDesc[FaultID.InstanceofUnsupported] = 'Left-hand side of "instanceof" is wrong'; +faultDesc[FaultID.TemplateStringType] = 'Template string type'; faultDesc[FaultID.ShorthandAmbientModuleDecl] = 'Shorthand ambient module declaration'; faultDesc[FaultID.WildcardsInModuleName] = 'Wildcards in module name'; faultDesc[FaultID.UMDModuleDefinition] = 'UMD module definition'; @@ -168,6 +169,7 @@ faultDesc[FaultID.MethodOverridingField] = '"Method overriding field" to keep st faultDesc[FaultID.InteropJsObjectConditionJudgment] = 'Interop JS Object usage in a condition'; faultDesc[FaultID.InteropJsObjectExpandStaticInstance] = 'Interop JS function usage'; faultDesc[FaultID.InteropJSFunctionInvoke] = 'Interop JS function invoke'; +faultDesc[FaultID.VariableMissingInitializer] = 'Value must be assigned to variable'; faultDesc[FaultID.ExplicitFunctionType] = 'Not explicit function type'; faultDesc[FaultID.ClassstaticInitialization] = 'The static properties of a class need to have initial values'; faultDesc[FaultID.AvoidUnionTypes] = 'Union types'; @@ -256,6 +258,7 @@ faultDesc[FaultID.NondecimalBigint] = 'No non decimal'; faultDesc[FaultID.UnsupportOperator] = 'Unsupport operator'; faultDesc[FaultID.CustomLayoutNeedAddDecorator] = 'Custom layout need add decorator'; faultDesc[FaultID.InterfaceFieldNotImplemented] = 'All fields must be implemented'; +faultDesc[FaultID.NoLocalClass] = 'No local classes'; faultDesc[FaultID.PropDecoratorNotSupported] = '"@Prop" decorator is not supported'; faultDesc[FaultID.StoragePropDecoratorNotSupported] = '"@StorageProp" decorator is not supported'; faultDesc[FaultID.LocalStoragePropDecoratorNotSupported] = '"@LocalStorageProp" decorator is not supported'; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index 9cab1b911e55b1442b148a04fd7c85fbe5d765eb..dd700b4ed503bf045a326a84be4b9149e4628771 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -173,6 +173,7 @@ export enum FaultID { TaggedTemplates, IncompationbleFunctionType, InvalidIdentifier, + TemplateStringType, NoImportJsonFile, NoImportNamespaceStarAsVar, ExtendsExpression, @@ -188,6 +189,7 @@ export enum FaultID { InteropDirectAccessToTSTypes, InteropTSFunctionInvoke, InteropJSFunctionInvoke, + VariableMissingInitializer, LimitedVoidTypeFromSdk, EntryAnnotation, SdkAbilityLifecycleMonitor, @@ -256,6 +258,7 @@ export enum FaultID { UnsupportOperator, CustomLayoutNeedAddDecorator, InterfaceFieldNotImplemented, + NoLocalClass, PropDecoratorNotSupported, StoragePropDecoratorNotSupported, LocalStoragePropDecoratorNotSupported, diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index e535b3251aab6811b301845c13b0f97d313a2bc4..09dfdbd33ed3a413df5182477d6563177cca8ae4 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -259,7 +259,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } 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 @@ -403,6 +402,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { [ts.SyntaxKind.TypeAssertionExpression, this.handleTypeAssertionExpression], [ts.SyntaxKind.MethodDeclaration, this.handleMethodDeclaration], [ts.SyntaxKind.TupleType, this.handleTupleType], + [ts.SyntaxKind.TemplateLiteralType, this.handleTemplateType], [ts.SyntaxKind.MethodSignature, this.handleMethodSignature], [ts.SyntaxKind.ClassStaticBlockDeclaration, this.handleClassStaticBlockDeclaration], [ts.SyntaxKind.Identifier, this.handleIdentifier], @@ -477,7 +477,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } 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 @@ -585,7 +584,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { * X.prototype.prototype.prototype = ... */ const baseExprTypeNode = this.tsTypeChecker.typeToTypeNode(baseExprType, undefined, ts.NodeBuilderFlags.None); - return baseExprTypeNode && ts.isFunctionTypeNode(baseExprTypeNode) || TsUtils.isAnyType(baseExprType); + return (baseExprTypeNode && ts.isFunctionTypeNode(baseExprTypeNode)) || TsUtils.isAnyType(baseExprType); } private interfaceInheritanceLint(node: ts.Node, heritageClauses: ts.NodeArray): void { @@ -659,8 +658,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ): boolean { return ( ts.isPropertyAssignment(prop) || - ts.isShorthandPropertyAssignment(prop) && - (ts.isCallExpression(objLitExpr.parent) || ts.isNewExpression(objLitExpr.parent)) + (ts.isShorthandPropertyAssignment(prop) && + (ts.isCallExpression(objLitExpr.parent) || ts.isNewExpression(objLitExpr.parent))) ); } @@ -722,7 +721,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private handleArrayLiteralExpression(node: ts.Node): void { - /* * If array literal is a part of destructuring assignment, then * don't process it further. @@ -920,7 +918,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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 @@ -941,6 +938,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.interfaceInheritanceLint(node, interfaceNode.heritageClauses); } this.countDeclarationsWithDuplicateName(interfaceNode.name, interfaceNode); + this.handleLocalDeclarationOfClassAndIface(interfaceNode); } private handleTryStatement(node: ts.TryStatement): void { @@ -1203,7 +1201,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleImportModule(importDeclNode); if (this.options.arkts2) { const importClause = importDeclNode.importClause; - if (!importClause || !importClause.name && !importClause.namedBindings) { + if (!importClause || (!importClause.name && !importClause.namedBindings)) { const autofix = this.autofixer?.fixSideEffectImport(importDeclNode); this.incrementCounters(node, FaultID.NoSideEffectImport, autofix); } else { @@ -1281,7 +1279,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const modulePath = importDeclNode.moduleSpecifier.getText().slice(1, -1); if (modulePath.startsWith('./') || modulePath.startsWith('../')) { - /* * Reason for this method to check the oh module imports, * We do not use relative paths when importing from OhModules, @@ -1453,9 +1450,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (ts.isBinaryExpression(propertyAccessNode.parent)) { const isAssignment = propertyAccessNode.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken; - const autofix = isAssignment ? - this.autofixer?.fixInteropBinaryExpression(propertyAccessNode.parent) : - this.autofixer?.fixInteropPropertyAccessExpression(propertyAccessNode); + const autofix = isAssignment + ? this.autofixer?.fixInteropBinaryExpression(propertyAccessNode.parent) + : this.autofixer?.fixInteropPropertyAccessExpression(propertyAccessNode); this.incrementCounters( isAssignment ? propertyAccessNode.parent : propertyAccessNode, @@ -1514,9 +1511,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } if ( - baseExprSym && TsUtils.isFunctionSymbol(baseExprSym) || + (baseExprSym && TsUtils.isFunctionSymbol(baseExprSym)) || this.tsUtils.isStdFunctionType(baseExprType) || - TsUtils.isFunctionalType(baseExprType) && TsUtils.isAnonymousType(baseExprType) + (TsUtils.isFunctionalType(baseExprType) && TsUtils.isAnonymousType(baseExprType)) ) { this.incrementCounters(node.expression, FaultID.PropertyDeclOnFunction); } @@ -1551,7 +1548,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return false; } if ( - ts.isTypeAliasDeclaration(decl) && this.checkSpecialTypeNode(decl.type, true) || + (ts.isTypeAliasDeclaration(decl) && this.checkSpecialTypeNode(decl.type, true)) || this.checkSpecialTypeNode(decl, true) ) { return true; @@ -1714,7 +1711,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private static extractKeyofFromString(typeString: string): boolean { - return (/\bkeyof\b/).test(typeString); + return /\bkeyof\b/.test(typeString); } checkUnionTypes(propertyAccessNode: ts.PropertyAccessExpression): void { @@ -1780,7 +1777,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private handleLiteralAsPropertyName(node: ts.PropertyDeclaration | ts.PropertySignature): void { const propName = node.name; - if (!!propName && (ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { + if (!!propName && (ts.isNumericLiteral(propName) || (this.options.arkts2 && ts.isStringLiteral(propName)))) { const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyName(propName); this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); } @@ -1848,7 +1845,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleQuotedHyphenPropsDeprecated(node); this.handleNoDeprecatedApi(node); const propName = node.name; - if (!propName || !(ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { + if (!propName || !(ts.isNumericLiteral(propName) || (this.options.arkts2 && ts.isStringLiteral(propName)))) { return; } @@ -2201,8 +2198,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const tsRetType = this.tsTypeChecker.getReturnTypeOfSignature(tsSignature); if ( !tsRetType || - !this.options.arkts2 && TsUtils.isUnsupportedType(tsRetType) || - this.options.arkts2 && this.tsUtils.isUnsupportedTypeArkts2(tsRetType) + (!this.options.arkts2 && TsUtils.isUnsupportedType(tsRetType)) || + (this.options.arkts2 && this.tsUtils.isUnsupportedTypeArkts2(tsRetType)) ) { hasLimitedRetTypeInference = true; } else if (hasLimitedRetTypeInference) { @@ -2750,7 +2747,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleVariableDeclarationForProp(tsVarDecl); if ( !this.options.useRtLogic || - ts.isVariableDeclarationList(tsVarDecl.parent) && ts.isVariableStatement(tsVarDecl.parent.parent) + (ts.isVariableDeclarationList(tsVarDecl.parent) && ts.isVariableStatement(tsVarDecl.parent.parent)) ) { this.handleDeclarationDestructuring(tsVarDecl); } @@ -2778,6 +2775,42 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handlePropertyDescriptorInScenarios(tsVarDecl); this.handleSdkGlobalApi(tsVarDecl); this.handleNoDeprecatedApi(tsVarDecl); + this.handleMissingInitializer(tsVarDecl); + } + + /** + * Reports an error if a `let`/`const` declaration lacks an initializer. + */ + private handleMissingInitializer(decl: ts.VariableDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const list = decl.parent as ts.VariableDeclarationList; + if (!(list.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const))) { + return; + } + + // Skip for‐of/for‐in loop bindings + const parentStmt = list.parent; + if (ts.isForOfStatement(parentStmt) || ts.isForInStatement(parentStmt)) { + return; + } + + // Skip explicit function‐type declarations (they are more like methods) + if (decl.type && ts.isFunctionTypeNode(decl.type)) { + return; + } + + // Skip variables declared as void—voids are handled by a different rule + if (decl.type && decl.type.kind === ts.SyntaxKind.VoidKeyword) { + return; + } + + // If no initializer, report + if (!decl.initializer) { + this.incrementCounters(decl.name, FaultID.VariableMissingInitializer); + } } private checkTypeFromSdk(type: ts.TypeNode | undefined): void { @@ -2803,9 +2836,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private handleDeclarationDestructuring(decl: ts.VariableDeclaration | ts.ParameterDeclaration): void { const faultId = ts.isVariableDeclaration(decl) ? FaultID.DestructuringDeclaration : FaultID.DestructuringParameter; if (ts.isObjectBindingPattern(decl.name)) { - const autofix = ts.isVariableDeclaration(decl) ? - this.autofixer?.fixObjectBindingPatternDeclarations(decl) : - undefined; + const autofix = ts.isVariableDeclaration(decl) + ? this.autofixer?.fixObjectBindingPatternDeclarations(decl) + : undefined; this.incrementCounters(decl, faultId, autofix); } else if (ts.isArrayBindingPattern(decl.name)) { // Array destructuring is allowed only for Arrays/Tuples and without spread operator. @@ -2822,9 +2855,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { hasNestedObjectDestructuring || TsUtils.destructuringDeclarationHasSpreadOperator(decl.name) ) { - const autofix = ts.isVariableDeclaration(decl) ? - this.autofixer?.fixArrayBindingPatternDeclarations(decl, isArrayOrTuple) : - undefined; + const autofix = ts.isVariableDeclaration(decl) + ? this.autofixer?.fixArrayBindingPatternDeclarations(decl, isArrayOrTuple) + : undefined; this.incrementCounters(decl, faultId, autofix); } } @@ -3283,6 +3316,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleInvalidIdentifier(tsClassDecl); this.handleSdkMethod(tsClassDecl); this.handleNotsLikeSmartType(tsClassDecl); + this.handleLocalDeclarationOfClassAndIface(tsClassDecl); } private static findFinalExpression(typeNode: ts.TypeNode): ts.Node { @@ -3293,7 +3327,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { * Handle comment directive '@ts-nocheck' */ while ((currentNode as any).expression) { - /* * CC-OFFNXT(no_explicit_any) std lib * Handle comment directive '@ts-nocheck' @@ -3309,9 +3342,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { methodName?: string ): boolean { return heritageClause.types.some((type) => { - const parentName = ts.isPropertyAccessExpression(type.expression) ? - type.expression.name.text : - type.expression.getText(); + const parentName = ts.isPropertyAccessExpression(type.expression) + ? type.expression.name.text + : type.expression.getText(); const fullTypeName = TypeScriptLinter.findFinalExpression(type).getText(); const sdkInfos = this.interfaceMap.get(fullTypeName); if (!sdkInfos || sdkInfos.size === 0) { @@ -3496,7 +3529,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private checkClassDeclarationHeritageClause(hClause: ts.HeritageClause, isSendableClass: boolean): void { for (const tsTypeExpr of hClause.types) { - /* * Always resolve type from 'tsTypeExpr' node, not from 'tsTypeExpr.expression' node, * as for the latter, type checker will return incorrect type result for classes in @@ -3627,10 +3659,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const names = new Set(); if ( - ts.isFunctionDeclaration(statement) && statement.name && statement.body || - ts.isClassDeclaration(statement) && statement.name || - ts.isInterfaceDeclaration(statement) && statement.name || - ts.isEnumDeclaration(statement) && statement.name + (ts.isFunctionDeclaration(statement) && statement.name && statement.body) || + (ts.isClassDeclaration(statement) && statement.name) || + (ts.isInterfaceDeclaration(statement) && statement.name) || + (ts.isEnumDeclaration(statement) && statement.name) ) { names.add(statement.name.text); return names; @@ -3692,6 +3724,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private handleTemplateType(node: ts.TemplateLiteralTypeNode): void { + if (!this.options.arkts2) { + return; + } + this.incrementCounters(node, FaultID.TemplateStringType); + } + private handleTupleType(node: ts.TupleTypeNode): void { if (!this.options.arkts2) { return; @@ -3845,24 +3884,31 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private checkMethodType(allBaseTypes: ts.Type[], methodName: string, node: ts.MethodDeclaration, isStatic: boolean = false): void { + private checkMethodType( + allBaseTypes: ts.Type[], + methodName: string, + node: ts.MethodDeclaration, + isStatic: boolean = false + ): void { for (const baseType of allBaseTypes) { let baseMethod: ts.Symbol | undefined; - const symbol = baseType.getSymbol(); + const symbol = baseType.getSymbol(); if (isStatic && symbol) { const constructorType = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, node); - baseMethod = constructorType.getProperty(methodName) || - symbol.members?.get(ts.escapeLeadingUnderscores(methodName)); + baseMethod = + constructorType.getProperty(methodName) || symbol.members?.get(ts.escapeLeadingUnderscores(methodName)); } else { baseMethod = baseType.getProperty(methodName); } if (!baseMethod) { continue; } - const baseMethodDecl = baseMethod.declarations?.find(d => - (ts.isMethodDeclaration(d) || ts.isMethodSignature(d)) && - this.isSameDeclarationType(d.parent, baseType, isStatic) - ) as ts.MethodDeclaration | ts.MethodSignature; + const baseMethodDecl = baseMethod.declarations?.find((d) => { + return ( + (ts.isMethodDeclaration(d) || ts.isMethodSignature(d)) && + this.isSameDeclarationType(d.parent, baseType, isStatic) + ); + }) as ts.MethodDeclaration | ts.MethodSignature; if (!baseMethodDecl) { continue; @@ -4022,7 +4068,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }); } } - return [...resolvedBaseClasses, ...interfaces]; + return [...resolvedBaseClasses, ...interfaces]; } private getStaticAllBaseTypes(classDecl: ts.ClassDeclaration): ts.Type[] | undefined { @@ -4093,7 +4139,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { derivedMethod: ts.MethodDeclaration, baseMethod: ts.MethodDeclaration | ts.MethodSignature ): void { - if(this.shouldSkipTypeParameterCheck(derivedMethod, baseMethod)) { + if (this.shouldSkipTypeParameterCheck(derivedMethod, baseMethod)) { return; } const baseMethodType = this.getActualReturnType(baseMethod); @@ -4144,8 +4190,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ): boolean { const baseMethodType = this.getActualReturnType(baseMethod); const derivedMethodType = this.getActualReturnType(derivedMethod); - - if (baseMethodType && (baseMethodType.flags & ts.TypeFlags.TypeParameter)) { + + if (baseMethodType && baseMethodType.flags & ts.TypeFlags.TypeParameter) { if (derivedMethodType && !(derivedMethodType.flags & ts.TypeFlags.TypeParameter)) { return true; } @@ -4263,7 +4309,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ]; for (const [wrapper, primitive] of typePairs) { - if (typeStr === wrapper && typeSet.has(primitive) || typeStr === primitive && typeSet.has(wrapper)) { + if ((typeStr === wrapper && typeSet.has(primitive)) || (typeStr === primitive && typeSet.has(wrapper))) { return true; } } @@ -4614,7 +4660,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private isStdlibClassVarDecl(ident: ts.Identifier, sym: ts.Symbol): boolean { - /* * Most standard JS classes are defined in TS stdlib as ambient global * variables with interface constructor type and require special check @@ -4665,7 +4710,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } if ( - (tsIdentSym.flags & illegalValues) === 0 && !this.isStdlibClassVarDecl(tsIdentifier, tsIdentSym) || + ((tsIdentSym.flags & illegalValues) === 0 && !this.isStdlibClassVarDecl(tsIdentifier, tsIdentSym)) || isStruct(tsIdentSym) || !identiferUseInValueContext(tsIdentifier, tsIdentSym) ) { @@ -4737,8 +4782,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.tsUtils.isOrDerivedFrom(type, TsUtils.isTuple) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || - !this.options.arkts2 && - (this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdMapType) || TsUtils.isIntrinsicObjectType(type)) || + (!this.options.arkts2 && + (this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdMapType) || TsUtils.isIntrinsicObjectType(type))) || TsUtils.isEnumType(type) || // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType TsUtils.isEsValueType(typeNode) @@ -4791,8 +4836,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.tsUtils.isLibrarySymbol(tsElementAccessExprSymbol) || ts.isArrayLiteralExpression(tsElementAccessExpr.expression) || this.isElementAcessAllowed(tsElemAccessBaseExprType, tsElemAccessArgType) || - this.options.arkts2 && isGetIndexable || - this.options.arkts2 && isSetIndexable + (this.options.arkts2 && isGetIndexable) || + (this.options.arkts2 && isSetIndexable) ) { return; } @@ -5553,7 +5598,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { callLikeExpr: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments, 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 @@ -5584,9 +5628,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (ts.isNewExpression(callLikeExpr) && this.isNonGenericClass(callLikeExpr)) { return; } - const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? - ts.SyntaxKind.Constructor : - ts.SyntaxKind.FunctionDeclaration; + 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, @@ -5604,7 +5648,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const shouldCheck = this.shouldCheckGenericCallExpression(callLikeExpr as ts.CallExpression); if ( this.options.arkts2 && - (ts.isNewExpression(callLikeExpr) || ts.isCallExpression(callLikeExpr) && shouldCheck) + (ts.isNewExpression(callLikeExpr) || (ts.isCallExpression(callLikeExpr) && shouldCheck)) ) { shouldReportError = this.shouldReportGenericTypeArgsError( callLikeExpr, @@ -5701,9 +5745,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { * in ArkTS and already have separate check for it. */ if (typeNode.kind === ts.SyntaxKind.UnknownKeyword) { - const autofix = ts.isCallExpression(callLikeExpr) ? - this.autofixer?.fixGenericCallNoTypeArgsForUnknown(callLikeExpr) : - undefined; + const autofix = ts.isCallExpression(callLikeExpr) + ? this.autofixer?.fixGenericCallNoTypeArgsForUnknown(callLikeExpr) + : undefined; this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs, autofix); break; } @@ -6003,7 +6047,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { expr, this.tsUtils.isLibraryType(this.tsTypeChecker.getTypeAtLocation(expr.expression)), (diagnostic, errorType) => { - /* * When a diagnostic meets the filter criteria, If it happens in an ets file in the 'oh_modules' directory. * the diagnostic is downgraded to warning. For other files, downgraded to nothing. @@ -6203,8 +6246,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const exprType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.expression).getNonNullableType(); // check for rule#65: 'number as Number' and 'boolean as Boolean' are disabled if ( - this.tsUtils.isNumberLikeType(exprType) && this.tsUtils.isStdNumberType(targetType) || - TsUtils.isBooleanLikeType(exprType) && this.tsUtils.isStdBooleanType(targetType) + (this.tsUtils.isNumberLikeType(exprType) && this.tsUtils.isStdNumberType(targetType)) || + (TsUtils.isBooleanLikeType(exprType) && this.tsUtils.isStdBooleanType(targetType)) ) { this.incrementCounters(node, FaultID.TypeAssertion); } @@ -6296,7 +6339,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const isRestrictedPrimitive = restrictedPrimitiveTypes.includes(type.kind); const isRestrictedArrayType = type.kind === ts.SyntaxKind.ArrayType || - ts.isTypeReferenceNode(type) && ts.isIdentifier(type.typeName) && type.typeName.text === 'Array'; + (ts.isTypeReferenceNode(type) && ts.isIdentifier(type.typeName) && type.typeName.text === 'Array'); if (!isRestrictedPrimitive && !isRestrictedArrayType) { return; @@ -6323,7 +6366,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const type = tsAsExpr.type; const isNullAssertion = type.kind === ts.SyntaxKind.NullKeyword || - ts.isLiteralTypeNode(type) && type.literal.kind === ts.SyntaxKind.NullKeyword || + (ts.isLiteralTypeNode(type) && type.literal.kind === ts.SyntaxKind.NullKeyword) || type.getText() === 'null'; if (isNullAssertion) { this.incrementCounters(tsAsExpr, FaultID.InterOpConvertImport); @@ -6556,7 +6599,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private handleSpreadOp(node: ts.Node): void { - /* * spread assignment is disabled * spread element is allowed only for arrays as rest parameter @@ -6651,7 +6693,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration ): boolean | undefined { if ( - (ts.isVariableDeclaration(decl) && ts.isVariableStatement(decl.parent.parent) || + ((ts.isVariableDeclaration(decl) && ts.isVariableStatement(decl.parent.parent)) || ts.isPropertyDeclaration(decl)) && !decl.initializer ) { @@ -6774,7 +6816,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } 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. @@ -6785,7 +6826,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (pragmas && pragmas instanceof Map) { const noCheckPragma = pragmas.get('ts-nocheck'); if (noCheckPragma) { - /* * The value is either a single entry or an array of entries. * Wrap up single entry with array to simplify processing. @@ -6809,9 +6849,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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; + sourceFile.text.slice(range.pos, range.pos + 2) === '/*' + ? ts.SyntaxKind.MultiLineCommentTrivia + : ts.SyntaxKind.SingleLineCommentTrivia; const commentRange: ts.CommentRange = { pos: range.pos, end: range.end, @@ -6960,7 +7000,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const declPosition = decl.getStart(); if ( decl.getSourceFile().fileName !== node.getSourceFile().fileName || - declPosition !== undefined && declPosition >= scope.getStart() && declPosition < scope.getEnd() + (declPosition !== undefined && declPosition >= scope.getStart() && declPosition < scope.getEnd()) ) { return; } @@ -7157,7 +7197,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { rhsType: ts.Type, rhsExpr: ts.Expression ): boolean { - /* * When resolving the contextual type for return expression in async function, the TS compiler * infers 'PromiseLike' type instead of standard 'Promise' (see following link: @@ -7240,8 +7279,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private isSendableDecoratorValid(decl: ts.FunctionDeclaration | ts.TypeAliasDeclaration): boolean { if ( this.compatibleSdkVersion > SENDBALE_FUNCTION_START_VERSION || - this.compatibleSdkVersion === SENDBALE_FUNCTION_START_VERSION && - !SENDABLE_FUNCTION_UNSUPPORTED_STAGES_IN_API12.includes(this.compatibleSdkVersionStage) + (this.compatibleSdkVersion === SENDBALE_FUNCTION_START_VERSION && + !SENDABLE_FUNCTION_UNSUPPORTED_STAGES_IN_API12.includes(this.compatibleSdkVersionStage)) ) { return true; } @@ -7302,7 +7341,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ts.isExpressionStatement(node.parent) || ts.isVoidExpression(node.parent) || ts.isArrowFunction(node.parent) || - ts.isConditionalExpression(node.parent) && ts.isExpressionStatement(node.parent.parent) + (ts.isConditionalExpression(node.parent) && ts.isExpressionStatement(node.parent.parent)) ) { return; } @@ -7411,7 +7450,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return ts.isFunctionDeclaration(name) || ts.isMethodDeclaration(name); }); const isInternalFunction = decl.name && ts.isIdentifier(decl.name) && interanlFunction.includes(decl.name.text); - if (isInternalFunction && filterDecl.length > 2 || !isInternalFunction && filterDecl.length > 1) { + if ((isInternalFunction && filterDecl.length > 2) || (!isInternalFunction && filterDecl.length > 1)) { this.incrementCounters(decl, FaultID.TsOverload); } } else if (ts.isConstructorDeclaration(decl) && decl.getText()) { @@ -7457,8 +7496,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { t.flags & ts.TypeFlags.StringLike || typeText === 'String' || typeText === 'number' || - t.flags & ts.TypeFlags.NumberLike && (/^\d+$/).test(typeText) || - isLiteralInitialized && !hasExplicitTypeAnnotation || + (t.flags & ts.TypeFlags.NumberLike && /^\d+$/.test(typeText)) || + (isLiteralInitialized && !hasExplicitTypeAnnotation) || t.flags & ts.TypeFlags.EnumLike ); }; @@ -7591,7 +7630,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private evaluateNumericValueFromPrefixUnaryExpression(node: ts.PrefixUnaryExpression): number | null { if (node.operator === ts.SyntaxKind.MinusToken) { - if (ts.isNumericLiteral(node.operand) || ts.isIdentifier(node.operand) && node.operand.text === 'Infinity') { + if (ts.isNumericLiteral(node.operand) || (ts.isIdentifier(node.operand) && node.operand.text === 'Infinity')) { return node.operand.text === 'Infinity' ? Number.NEGATIVE_INFINITY : -Number(node.operand.text); } const operandValue = this.evaluateNumericValue(node.operand); @@ -7606,7 +7645,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const typeNode = node.type; if ( typeNode.kind === ts.SyntaxKind.NumberKeyword || - ts.isTypeReferenceNode(typeNode) && typeNode.typeName.getText() === 'Number' + (ts.isTypeReferenceNode(typeNode) && typeNode.typeName.getText() === 'Number') ) { return this.evaluateNumericValue(node.expression); } @@ -7719,10 +7758,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } if ( - this.tsUtils.isOrDerivedFrom(lhsType, this.tsUtils.isArray) && - this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple) || - this.tsUtils.isOrDerivedFrom(rhsType, this.tsUtils.isArray) && - this.tsUtils.isOrDerivedFrom(lhsType, TsUtils.isTuple) + (this.tsUtils.isOrDerivedFrom(lhsType, this.tsUtils.isArray) && + this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple)) || + (this.tsUtils.isOrDerivedFrom(rhsType, this.tsUtils.isArray) && + this.tsUtils.isOrDerivedFrom(lhsType, TsUtils.isTuple)) ) { this.incrementCounters(node, FaultID.NoTuplesArrays); } @@ -7951,7 +7990,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } const text = node.initializer.getText(); - if (!(/^\$.+$/).test(text)) { + if (!/^\$.+$/.test(text)) { return; } @@ -8207,7 +8246,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - /** + /** * Ensures classes fully implement all properties from their interfaces. */ private handleInterfaceFieldImplementation(clause: ts.HeritageClause): void { @@ -9164,7 +9203,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private shouldWarn(symbol: ts.Symbol): boolean { const parentApiName = this.getLocalApiListItemByKey(SdkNameInfo.ParentApiName); - return symbol && this.isHeritageClauseisThirdPartyBySymbol(symbol) || symbol.name === parentApiName; + return (symbol && this.isHeritageClauseisThirdPartyBySymbol(symbol)) || symbol.name === parentApiName; } private getFinalSymOnQuotedHyphenPropsDeprecated(node: ts.Node): ts.Symbol | undefined { @@ -9212,9 +9251,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private getTypeOfVariable(variable: ts.VariableDeclaration): ts.Symbol | undefined { if (variable.type) { - return ts.isArrayTypeNode(variable.type) ? - this.resolveTypeNodeSymbol(variable.type.elementType) : - this.resolveTypeNodeSymbol(variable.type); + return ts.isArrayTypeNode(variable.type) + ? this.resolveTypeNodeSymbol(variable.type.elementType) + : this.resolveTypeNodeSymbol(variable.type); } return variable.initializer ? this.tsTypeChecker.getTypeAtLocation(variable.initializer).getSymbol() : undefined; } @@ -9308,6 +9347,32 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return undefined; } + private handleLocalDeclarationOfClassAndIface(node: ts.ClassDeclaration | ts.InterfaceDeclaration): void { + if (!this.options.arkts2) { + return; + } + this.isLocalClass(node); + } + + private isLocalClass(node: ts.Node): void { + if ( + ts.findAncestor(node, (node) => { + return ( + ts.isArrowFunction(node) || + ts.isFunctionDeclaration(node) || + ts.isMethodDeclaration(node) || + ts.isFunctionExpression(node) || + ts.isConstructorDeclaration(node) || + ts.isGetAccessor(node) || + ts.isSetAccessor(node) || + ts.isBlock(node) + ); + }) + ) { + this.incrementCounters(node, FaultID.NoLocalClass); + } + } + private processPropertyAccessExpression(expression: ts.PropertyAccessExpression): ts.Symbol | undefined { const heritageSymbol = this.tsTypeChecker.getSymbolAtLocation(expression.expression); if (heritageSymbol && expression.name.text === this.getLocalApiListItemByKey(SdkNameInfo.ParentApiName)) { @@ -9631,7 +9696,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return false; } - const propertyName = ts.isIdentifier(decl.expression.name) && decl.expression.name.text || ''; + const propertyName = (ts.isIdentifier(decl.expression.name) && decl.expression.name.text) || ''; if (propertyName !== 'self') { return false; } @@ -9645,13 +9710,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - const importApiName = ts.isIdentifier(decl.expression.expression) && decl.expression.expression.text || ''; + const importApiName = (ts.isIdentifier(decl.expression.expression) && decl.expression.expression.text) || ''; const sdkInfos = importApiName && this.interfaceMap.get(importApiName); if (!sdkInfos) { return; } - const apiName = ts.isIdentifier(decl.name) && decl.name.text || ''; + const apiName = (ts.isIdentifier(decl.name) && decl.name.text) || ''; const matchedApi = [...sdkInfos].find((sdkInfo) => { return sdkInfo.api_name === apiName; }); @@ -9864,7 +9929,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if ( decl && (ts.isFunctionDeclaration(decl) || - ts.isVariableDeclaration(decl) && decl.initializer && ts.isArrowFunction(decl.initializer)) + (ts.isVariableDeclaration(decl) && decl.initializer && ts.isArrowFunction(decl.initializer))) ) { this.incrementCounters(arg, FaultID.InteropJsObjectCallStaticFunc); } @@ -9926,16 +9991,16 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!TypeScriptLinter.isInForLoopBody(elementAccessExpr)) { return; } - const variableDeclaration = ts.isIdentifier(elementAccessExpr.expression) ? - this.tsUtils.findVariableDeclaration(elementAccessExpr.expression) : - undefined; + const variableDeclaration = ts.isIdentifier(elementAccessExpr.expression) + ? this.tsUtils.findVariableDeclaration(elementAccessExpr.expression) + : undefined; if (!variableDeclaration?.initializer) { return; } - const identifier = ts.isPropertyAccessExpression(variableDeclaration.initializer) ? - (variableDeclaration.initializer.expression as ts.Identifier) : - undefined; + const identifier = ts.isPropertyAccessExpression(variableDeclaration.initializer) + ? (variableDeclaration.initializer.expression as ts.Identifier) + : undefined; if (!identifier) { return; } @@ -9964,9 +10029,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2 || !this.useStatic) { return; } - const objectExpr = ts.isNewExpression(propertyAccess.expression) ? - propertyAccess.expression.expression : - propertyAccess.expression; + const objectExpr = ts.isNewExpression(propertyAccess.expression) + ? propertyAccess.expression.expression + : propertyAccess.expression; // Step 1: Must be either setCloneList or setTransferList if (!TypeScriptLinter.isDeprecatedTaskPoolMethodCall(propertyAccess)) { return; @@ -9985,9 +10050,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } const faultId = - propertyAccess.name.text === DEPRECATED_TASKPOOL_METHOD_SETCLONELIST ? - FaultID.SetCloneListDeprecated : - FaultID.SetTransferListDeprecated; + propertyAccess.name.text === DEPRECATED_TASKPOOL_METHOD_SETCLONELIST + ? FaultID.SetCloneListDeprecated + : FaultID.SetTransferListDeprecated; this.incrementCounters(propertyAccess.name, faultId); } @@ -10002,7 +10067,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private isTaskPoolTaskCreation(taskpoolExpr: ts.Expression): boolean { if ( ts.isIdentifier(taskpoolExpr) || - ts.isPropertyAccessExpression(taskpoolExpr) && taskpoolExpr.name.text === STDLIB_TASK_CLASS_NAME + (ts.isPropertyAccessExpression(taskpoolExpr) && taskpoolExpr.name.text === STDLIB_TASK_CLASS_NAME) ) { const objectExpr = ts.isIdentifier(taskpoolExpr) ? taskpoolExpr : taskpoolExpr.expression; return this.isTaskPoolReferenceisTaskPoolImportForTaskPoolDeprecatedUsages(objectExpr); @@ -10265,16 +10330,16 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { */ private isFieldTypeMatchingBetweenDerivedAndBaseClass(derivedType: ts.Type, baseType: ts.Type): boolean { // Split union type strings into trimmed member names - const derivedNames = this.tsTypeChecker. - typeToString(derivedType). - split('|'). - map((s) => { + const derivedNames = this.tsTypeChecker + .typeToString(derivedType) + .split('|') + .map((s) => { return s.trim(); }); - const baseNames = this.tsTypeChecker. - typeToString(baseType). - split('|'). - map((s) => { + const baseNames = this.tsTypeChecker + .typeToString(baseType) + .split('|') + .map((s) => { return s.trim(); }); @@ -10454,7 +10519,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { symbol?.declarations?.some((decl) => { return ( ts.isEnumDeclaration(decl) || - ts.isVariableDeclaration(decl) && decl.initializer && ts.isEnumDeclaration(decl.initializer) + (ts.isVariableDeclaration(decl) && decl.initializer && ts.isEnumDeclaration(decl.initializer)) ); }) ?? false ); @@ -10494,7 +10559,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } if (superCall.arguments.length > 1) { - /* * STD Error Type have two constructors * either empty constructor which is just "Error" message @@ -11031,9 +11095,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - const parentType = node.type ? - this.tsTypeChecker.getTypeAtLocation(node.type) : - this.tsTypeChecker.getTypeAtLocation(node.initializer); + const parentType = node.type + ? this.tsTypeChecker.getTypeAtLocation(node.type) + : this.tsTypeChecker.getTypeAtLocation(node.initializer); this.processNestedObjectLiterals(node.initializer, parentType); } @@ -11676,24 +11740,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { instanceProps: new Map() }; - classDecl.members.forEach((member) => { - if (!ts.isPropertyDeclaration(member)) { - return; - } - - const propName = member.name.getText(); - const propType = this.tsTypeChecker.getTypeAtLocation(member); - const isStatic = member.modifiers?.some((m) => { - return m.kind === ts.SyntaxKind.StaticKeyword; - }); - - if (isStatic) { - result.staticProps.set(propName, propType); - } else { - result.instanceProps.set(propName, propType); - } - }); - + this.tsUtils.collectPropertiesFromClass(classDecl, result); return result; } @@ -11745,7 +11792,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }; const isBigIntAndNumberOperand = - isNumber(leftType) && isBigInt(rightType) || isBigInt(leftType) && isNumber(rightType); + (isNumber(leftType) && isBigInt(rightType)) || (isBigInt(leftType) && isNumber(rightType)); if (isBigIntAndNumberOperand) { this.incrementCounters(node, FaultID.NumericBigintCompare); } @@ -11757,7 +11804,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } const literalText = node.getText(); - if ((/^0[box]/i).test(literalText)) { + if (/^0[box]/i.test(literalText)) { this.incrementCounters(node, FaultID.NondecimalBigint); } } @@ -11854,11 +11901,11 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }; const isStandardFloatFormat = (): boolean => { const text = node.getText(); - return (/\.\d*0+$/).test(text); + return /\.\d*0+$/.test(text); }; const isNoNeedFix = isInElementAccessExpression(node) || - 'name' in node.parent && node.parent.name === node || + ('name' in node.parent && node.parent.name === node) || isStandardFloatFormat(); if (isNoNeedFix) { return; @@ -11866,7 +11913,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const value = parseFloat(node.text); const nodeText = node.getText(); - const hasScientificOrRadixNotation = (/[a-zA-Z]/).test(nodeText); + const hasScientificOrRadixNotation = /[a-zA-Z]/.test(nodeText); const isIntegerWithoutZero = Number.isInteger(value) && !nodeText.endsWith('.0'); if (isIntegerWithoutZero && !hasScientificOrRadixNotation) { const autofix = this.autofixer?.fixNumericLiteralIntToNumber(node); @@ -11935,6 +11982,11 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return true; } } + + if (ts.isNumericLiteral(accessExpr.argumentExpression)) { + return false; + } + if (this.isObjectPropertyAccess(accessExpr)) { return true; } @@ -11951,7 +12003,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } return; } - const { arrayIdent } = arrayAccessInfo; const arraySym = this.tsUtils.trueSymbolAtLocation(arrayIdent); if (!arraySym) { @@ -11961,12 +12012,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.incrementCounters(accessExpr, FaultID.RuntimeArrayCheck); return; } - const arrayDecl = TypeScriptLinter.findArrayDeclaration(arraySym); if (arrayDecl && TypeScriptLinter.isArrayCreatedWithOtherArrayLength(arrayDecl)) { return; } - const indexExpr = accessExpr.argumentExpression; const loopVarName = ts.isIdentifier(indexExpr) ? indexExpr.text : undefined; if (ts.isPrefixUnaryExpression(indexExpr) && indexExpr.operator === ts.SyntaxKind.PlusPlusToken) { @@ -11978,18 +12027,16 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { loopVarName, arraySym ); - if (TypeScriptLinter.isIncrementOrDecrement(indexExpr)) { return; } - if (isInSafeContext) { if (!isValidBoundCheck || isVarModifiedBeforeAccess) { this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); } - } else { - this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); + return; } + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); } static isIncrementOrDecrement(expr: ts.Expression): boolean { @@ -12081,13 +12128,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { loopVarName: string, arraySym: ts.Symbol ): { isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { - const isValidBoundCheck = forNode.condition ? - this.checkBoundCondition(forNode.condition, loopVarName, arraySym) : - false; + const isValidBoundCheck = forNode.condition + ? this.checkBoundCondition(forNode.condition, loopVarName, arraySym) + : false; - const isVarModifiedBeforeAccess = forNode.statement ? - TypeScriptLinter.checkVarModifiedBeforeNode(forNode.statement, accessExpr, loopVarName) : - false; + const isVarModifiedBeforeAccess = forNode.statement + ? TypeScriptLinter.checkVarModifiedBeforeNode(forNode.statement, accessExpr, loopVarName) + : false; return { isValidBoundCheck, isVarModifiedBeforeAccess }; } @@ -12098,13 +12145,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { loopVarName: string, arraySym: ts.Symbol ): { isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { - const isValidBoundCheck = whileNode.expression ? - this.checkBoundCondition(whileNode.expression, loopVarName, arraySym) : - false; + const isValidBoundCheck = whileNode.expression + ? this.checkBoundCondition(whileNode.expression, loopVarName, arraySym) + : false; - const isVarModifiedBeforeAccess = whileNode.statement ? - TypeScriptLinter.checkVarModifiedBeforeNode(whileNode.statement, accessExpr, loopVarName) : - false; + const isVarModifiedBeforeAccess = whileNode.statement + ? TypeScriptLinter.checkVarModifiedBeforeNode(whileNode.statement, accessExpr, loopVarName) + : false; return { isValidBoundCheck, isVarModifiedBeforeAccess }; } @@ -12115,9 +12162,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { loopVarName: string, arraySym: ts.Symbol ): { isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { - const isValidBoundCheck = ifNode.expression ? - this.checkBoundCondition(ifNode.expression, loopVarName, arraySym) : - false; + const isValidBoundCheck = ifNode.expression + ? this.checkBoundCondition(ifNode.expression, loopVarName, arraySym) + : false; let isVarModifiedBeforeAccess = false; const statementBlock = ts.isBlock(ifNode.thenStatement) ? ifNode.thenStatement : undefined; @@ -12165,16 +12212,16 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (ts.isIdentifier(left) && left.text === varName && ts.isNumericLiteral(right)) { const value = parseFloat(right.text); return ( - operatorToken.kind === ts.SyntaxKind.GreaterThanEqualsToken && value <= 0 || - operatorToken.kind === ts.SyntaxKind.GreaterThanToken && value < 0 + (operatorToken.kind === ts.SyntaxKind.GreaterThanEqualsToken && value <= 0) || + (operatorToken.kind === ts.SyntaxKind.GreaterThanToken && value < 0) ); } if (ts.isPropertyAccessExpression(left) && left.name.text === LENGTH_IDENTIFIER && ts.isNumericLiteral(right)) { const constantValue = parseInt(right.text); return ( - operatorToken.kind === ts.SyntaxKind.LessThanToken && constantValue > 0 || - operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken && constantValue >= 0 + (operatorToken.kind === ts.SyntaxKind.LessThanToken && constantValue > 0) || + (operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken && constantValue >= 0) ); } @@ -12345,56 +12392,58 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private getArrayAccessInfo(expr: ts.ElementAccessExpression): false | ArrayAccess { - if (!ts.isIdentifier(expr.expression)) { + let accessedExpression: ts.Node = expr.expression; + if (ts.isPropertyAccessExpression(accessedExpression)) { + accessedExpression = accessedExpression.name; + } + if (!ts.isIdentifier(accessedExpression)) { return false; } - const baseType = this.tsTypeChecker.getTypeAtLocation(expr.expression); - if (!this.tsUtils.isArray(baseType) && !this.isConcatArray(expr.expression)) { + const baseType = this.tsTypeChecker.getTypeAtLocation(accessedExpression); + if (!this.tsUtils.isArray(baseType) && !this.isConcatArray(accessedExpression)) { return false; } - const accessArgument = expr.argumentExpression; + const accessArgument = expr.argumentExpression; if (this.isInstanceOfCheck(expr.parent, expr)) { return false; } - TypeScriptLinter.isFunctionCall(accessArgument); - - const checkNumericType = (node: ts.Node): boolean => { - const argType = this.tsTypeChecker.getTypeAtLocation(node); - return ( - (argType.flags & ts.TypeFlags.NumberLike) !== 0 || - argType.isUnionOrIntersection() && - argType.types.some((t) => { - return t.flags & ts.TypeFlags.NumberLike; - }) - ); - }; - - const isEnumMember = (node: ts.Node): boolean => { - if (ts.isPropertyAccessExpression(node)) { - const symbol = this.tsUtils.trueSymbolAtLocation(node); - return !!symbol && (symbol.flags & ts.SymbolFlags.EnumMember) !== 0; - } - return false; - }; - if (TypeScriptLinter.isFunctionCall(accessArgument)) { return false; } - if (checkNumericType(accessArgument) || isEnumMember(accessArgument)) { + if (this.checkNumericType(accessArgument) || this.isEnumMember(accessArgument)) { return { pos: expr.getEnd(), accessingIdentifier: accessArgument, - arrayIdent: expr.expression + arrayIdent: accessedExpression }; } return false; } + private checkNumericType(node: ts.Node): boolean { + const argType = this.tsTypeChecker.getTypeAtLocation(node); + return ( + (argType.flags & ts.TypeFlags.NumberLike) !== 0 || + (argType.isUnionOrIntersection() && + argType.types.some((t) => { + return t.flags & ts.TypeFlags.NumberLike; + })) + ); + } + + private isEnumMember(node: ts.Node): boolean { + if (ts.isPropertyAccessExpression(node)) { + const symbol = this.tsUtils.trueSymbolAtLocation(node); + return !!symbol && (symbol.flags & ts.SymbolFlags.EnumMember) !== 0; + } + return false; + } + static isArrayCreatedWithOtherArrayLength(decl: ts.VariableDeclaration): boolean { if (!decl.initializer || !ts.isNewExpression(decl.initializer)) { return false; @@ -12540,8 +12589,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const constantValue = parseInt(right.text); return ( - operatorToken.kind === ts.SyntaxKind.LessThanToken && constantValue > 0 || - operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken && constantValue >= 0 + (operatorToken.kind === ts.SyntaxKind.LessThanToken && constantValue > 0) || + (operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken && constantValue >= 0) ); } @@ -12620,7 +12669,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { accessExpr.parent.operatorToken.kind === ts.SyntaxKind.BarBarToken ) { const defaultValue = accessExpr.parent.right; - return ts.isNumericLiteral(defaultValue) || ts.isIdentifier(defaultValue) && defaultValue.text === 'undefined'; + return ts.isNumericLiteral(defaultValue) || (ts.isIdentifier(defaultValue) && defaultValue.text === 'undefined'); } return false; } @@ -12781,11 +12830,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return true; } current = current.expression; - } else if (ts.isPropertyAccessExpression(current)) { + continue; + } + if (ts.isPropertyAccessExpression(current)) { return true; - } else { - break; } + break; } return false; @@ -13483,7 +13533,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return true; } - private handleESObjectUsage(typeRef: ts.TypeReferenceNode): void { + private handleESObjectUsage(typeRef: ts.TypeReferenceNode): void { if (!this.options.arkts2) { return; } diff --git a/ets2panda/linter/src/lib/utils/TsUtils.ts b/ets2panda/linter/src/lib/utils/TsUtils.ts index 738928269d0a778b945d0e0c0b9c49f2cf55b3c8..c7417e2425fac193338fead6af9f50d3c421d8f0 100644 --- a/ets2panda/linter/src/lib/utils/TsUtils.ts +++ b/ets2panda/linter/src/lib/utils/TsUtils.ts @@ -3816,4 +3816,55 @@ export class TsUtils { return false; } + + collectPropertiesFromClass( + classDecl: ts.ClassDeclaration, + result: { + staticProps: Map; + instanceProps: Map; + }, + isBase: boolean = false + ): void { + classDecl.members.forEach((member) => { + if (!ts.isPropertyDeclaration(member) || !member.name || !ts.isIdentifier(member.name)) { + return; + } + + const propName = member.name.text; + + const isPrivate = member.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.PrivateKeyword; + }); + if (isBase && isPrivate) { + return; + } + + const propType = this.tsTypeChecker.getTypeAtLocation(member); + const isStatic = member.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.StaticKeyword; + }); + + if (isStatic) { + result.staticProps.set(propName, propType); + } else { + result.instanceProps.set(propName, propType); + } + }); + + const heritage = classDecl.heritageClauses?.find((h) => { + return h.token === ts.SyntaxKind.ExtendsKeyword; + }); + if (heritage) { + const baseTypeNode = heritage?.types[0]; + if (baseTypeNode) { + const baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeNode); + const baseSymbol = baseType.getSymbol(); + const declarations = baseSymbol?.getDeclarations(); + const baseClassDecl = declarations?.find(ts.isClassDeclaration); + if (baseClassDecl) { + this.collectPropertiesFromClass(baseClassDecl, result, true); + } + } + } + } } diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.arkts2.json index ccc21ad852817e879704bf730636157c56c9016e..7914d892abb23519922e7df936f1a8f038c77890 100755 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.arkts2.json @@ -34,6 +34,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 23, "column": 34, @@ -44,6 +54,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 9, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 27, "column": 34, @@ -53,6 +73,16 @@ "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 9, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" } ] } diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.autofix.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.autofix.json index bb890b9c3b90f345391be21fda2a5eb236ee6799..c6a8280b9c62b15680e5baca0543dbd0a40e48cf 100755 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.autofix.json @@ -56,6 +56,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 23, "column": 34, @@ -77,6 +87,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 9, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 27, "column": 34, @@ -97,6 +117,16 @@ "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 9, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" } ] } diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.migrate.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.migrate.json index 95e6d40d6a3afa83ed578df1b91fe6ad710455e3..d0fa8937d5cf3976f7ea45bf092500e0acfde2b2 100755 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.migrate.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.migrate.json @@ -1,3 +1,48 @@ { - "result": [] -} \ No newline at end of file + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 9, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 9, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json index c390c26562aab76528f553635f51e1d1fd6a142f..c5f506ac66326d2408db0437feeffd0474f6a4ec 100644 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 16, + "column": 5, + "endLine": 16, + "endColumn": 13, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 16, "column": 15, @@ -64,6 +74,16 @@ "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", "severity": "ERROR" }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 16, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 22, "column": 28, diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json index 4eea7766a3ba34154a8dff0dd467b21b54e53e37..a1c3cfb2a25a93631402ff064d8a4dd6358280e8 100644 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 16, + "column": 5, + "endLine": 16, + "endColumn": 13, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 16, "column": 15, @@ -119,6 +129,16 @@ "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", "severity": "ERROR" }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 16, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 22, "column": 28, diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json index 43cb4a27bcc78710d4aa5130c22ee053f66c3fbc..1b71547ad7a096f21a63f5afa3255c679e904fe5 100644 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json @@ -1,3 +1,38 @@ { - "result": [] -} \ No newline at end of file + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 16, + "column": 5, + "endLine": 16, + "endColumn": 13, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 16, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.arkts2.json index c3cf76ae53bf4d3ce63ea49c4c17ed5da474169e..119d080a26d6d2b37ac56922bb8393d54869d216 100755 --- a/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.arkts2.json @@ -104,6 +104,26 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 31, + "column": 52, + "endLine": 31, + "endColumn": 68, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 73, + "endLine": 31, + "endColumn": 89, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 32, "column": 3, @@ -235,4 +255,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/deprecatedapi/sizeType.ets.json b/ets2panda/linter/test/deprecatedapi/sizeType.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..dd03fcf5442488620bcd4b3447f0fcdd89e1905b 100644 --- a/ets2panda/linter/test/deprecatedapi/sizeType.ets.json +++ b/ets2panda/linter/test/deprecatedapi/sizeType.ets.json @@ -1,17 +1,17 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "result": [] -} \ No newline at end of file + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} diff --git a/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json index a169c132ce8a6e17f42b44ad7a53ff65dd6effeb..07c01531937492718419ed42294e57bfe09a8013 100755 --- a/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json @@ -25,14 +25,14 @@ "severity": "ERROR" }, { - "line": 17, - "column": 7, - "endLine": 17, - "endColumn": 11, - "problem": "InterfaceFieldNotImplemented", - "suggest": "", - "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", - "severity": "ERROR" + "line": 17, + "column": 7, + "endLine": 17, + "endColumn": 11, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" }, { "line": 18, diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json index 7fe4087dbb650d0fbaf0a53aa3712ff6f2692c8d..a46dc16c3865eded303fbbd59f9dee7ae1a1ce3c 100644 --- a/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json @@ -134,6 +134,16 @@ "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", "severity": "ERROR" }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 69, "column": 5, @@ -195,4 +205,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/interop/unique_types.ets.arkts2.json b/ets2panda/linter/test/interop/unique_types.ets.arkts2.json index ad93ff0af7b8299c75bcd115e8855c4864cfffb3..afc18ac2cf232bdb1a7f08c2a08a6e917171b8a9 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.arkts2.json +++ b/ets2panda/linter/test/interop/unique_types.ets.arkts2.json @@ -494,6 +494,16 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 323, + "column": 5, + "endLine": 325, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 326, "column": 23, @@ -524,6 +534,16 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 372, + "column": 5, + "endLine": 374, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 375, "column": 23, @@ -575,4 +595,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/interop/unique_types.ets.autofix.json b/ets2panda/linter/test/interop/unique_types.ets.autofix.json index 203ab57067c1c62fe267b24574d87c2363f5f097..bddd995dab96719836c1d50851076ad8099e6ecb 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.autofix.json +++ b/ets2panda/linter/test/interop/unique_types.ets.autofix.json @@ -549,6 +549,16 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 323, + "column": 5, + "endLine": 325, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 326, "column": 23, @@ -590,6 +600,16 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 372, + "column": 5, + "endLine": 374, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 375, "column": 23, @@ -652,4 +672,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/interop/unique_types.ets.migrate.json b/ets2panda/linter/test/interop/unique_types.ets.migrate.json index 3eb75a8fe4df6211f5934d4e04459e0469c9770a..28d850fbfbeed0a1df4c975c1c8ada1b701b39b6 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.migrate.json +++ b/ets2panda/linter/test/interop/unique_types.ets.migrate.json @@ -444,6 +444,16 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 323, + "column": 5, + "endLine": 325, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 357, "column": 7, @@ -464,6 +474,16 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 372, + "column": 5, + "endLine": 374, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 184, "column": 3, @@ -505,4 +525,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/interop/unique_types3.ets.arkts2.json b/ets2panda/linter/test/interop/unique_types3.ets.arkts2.json index aabbdb78be04ab1345c2781a79d78fefb24ae10e..9ec2e4b790fff64e642d1c4147ee1241b3da8c68 100644 --- a/ets2panda/linter/test/interop/unique_types3.ets.arkts2.json +++ b/ets2panda/linter/test/interop/unique_types3.ets.arkts2.json @@ -634,6 +634,16 @@ "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, + { + "line": 195, + "column": 9, + "endLine": 195, + "endColumn": 10, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 195, "column": 13, @@ -674,6 +684,16 @@ "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, + { + "line": 201, + "column": 9, + "endLine": 201, + "endColumn": 10, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 201, "column": 12, @@ -735,4 +755,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json index 74eb906e2fd654a4e341b370d93e0d7d63548e4d..92d0d9b3fde148f071e089da3f51770b9d7cfced 100644 --- a/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json @@ -44,6 +44,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 23, "column": 1, diff --git a/ets2panda/linter/test/main/arkts-no-template-string-type.ets b/ets2panda/linter/test/main/arkts-no-template-string-type.ets new file mode 100644 index 0000000000000000000000000000000000000000..151de4d06d7144f61b1ac0c125d24598b5be77bf --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-template-string-type.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +type Action = "verify"; +type ContentMatch = "match"; +type Outcome = `${Action}_${ContentMatch}`; +type Outcome2 = `${Action}_match`; +type Outcome3 = `verify_${ContentMatch}`; + +type Foo = "Foo"; +type Bar = "Bar"; + +let template: `${Foo}_${Bar}`; +function foo(template: `${Foo}_${Bar}`): `${number}` {} diff --git a/ets2panda/linter/test/main/arkts-no-template-string-type.ets.args.json b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/arkts-no-template-string-type.ets.arkts2.json b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..761207d7879c5a7964ae8d771d7e98b7458e631c --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.arkts2.json @@ -0,0 +1,88 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 18, + "column": 16, + "endLine": 18, + "endColumn": 43, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 17, + "endLine": 19, + "endColumn": 34, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 41, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 13, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 15, + "endLine": 25, + "endColumn": 30, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 24, + "endLine": 26, + "endColumn": 39, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 42, + "endLine": 26, + "endColumn": 53, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-no-template-string-type.ets.json b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} diff --git a/ets2panda/linter/test/main/class_as_object.ets.arkts2.json b/ets2panda/linter/test/main/class_as_object.ets.arkts2.json index 44a60b85bb81f801a67c7fe752b4a1521a07c780..14b04a68c964c875405c35a2633a65ec5812dd4b 100644 --- a/ets2panda/linter/test/main/class_as_object.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_as_object.ets.arkts2.json @@ -324,6 +324,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 98, + "column": 5, + "endLine": 98, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 98, "column": 8, @@ -905,4 +915,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/collections_module.ets.arkts2.json b/ets2panda/linter/test/main/collections_module.ets.arkts2.json index 6fb86f244dfc3ed0b8908ed97460eb09399ffc6b..1bba4e4725cf6a81e3a62a9e4e5816374c46b46c 100644 --- a/ets2panda/linter/test/main/collections_module.ets.arkts2.json +++ b/ets2panda/linter/test/main/collections_module.ets.arkts2.json @@ -84,6 +84,16 @@ "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", "severity": "ERROR" }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 19, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 32, "column": 21, @@ -114,6 +124,16 @@ "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", "severity": "ERROR" }, + { + "line": 36, + "column": 7, + "endLine": 36, + "endColumn": 19, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 40, "column": 22, diff --git a/ets2panda/linter/test/main/collections_module.ets.autofix.json b/ets2panda/linter/test/main/collections_module.ets.autofix.json index 9be897f59e5ec888e5fcf18f65ebcbdab3e3da2b..b09314b3c667efad6a5f3eeec7843e6b7839e5be 100644 --- a/ets2panda/linter/test/main/collections_module.ets.autofix.json +++ b/ets2panda/linter/test/main/collections_module.ets.autofix.json @@ -161,6 +161,16 @@ "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", "severity": "ERROR" }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 19, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 32, "column": 21, @@ -224,6 +234,16 @@ "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", "severity": "ERROR" }, + { + "line": 36, + "column": 7, + "endLine": 36, + "endColumn": 19, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 40, "column": 22, diff --git a/ets2panda/linter/test/main/collections_module.ets.migrate.json b/ets2panda/linter/test/main/collections_module.ets.migrate.json index e3768540dc783f9b6fe11d045ce1217df7aaff07..ad165a2fcbcd0041abbb65ea2032362ac99a168c 100644 --- a/ets2panda/linter/test/main/collections_module.ets.migrate.json +++ b/ets2panda/linter/test/main/collections_module.ets.migrate.json @@ -13,36 +13,56 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - { - "line": 43, - "column": 11, - "endLine": 43, - "endColumn": 38, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 11, - "endLine": 47, - "endColumn": 46, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 27, - "endLine": 47, - "endColumn": 36, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - } - ] + "result": [ + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 19, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 7, + "endLine": 38, + "endColumn": 19, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 11, + "endLine": 43, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 11, + "endLine": 47, + "endColumn": 46, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 27, + "endLine": 47, + "endColumn": 36, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] } diff --git a/ets2panda/linter/test/main/definite_assignment.ets.arkts2.json b/ets2panda/linter/test/main/definite_assignment.ets.arkts2.json index c08c8a3f993b48cdfb95a800c5d53caab98aee9c..4922d60797c257c7c5bbd35ab67a22609007e159 100644 --- a/ets2panda/linter/test/main/definite_assignment.ets.arkts2.json +++ b/ets2panda/linter/test/main/definite_assignment.ets.arkts2.json @@ -24,6 +24,16 @@ "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "ERROR" }, + { + "line": 16, + "column": 5, + "endLine": 16, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 21, "column": 7, @@ -34,6 +44,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 29, "column": 7, @@ -85,4 +105,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/es_object.ets.arkts2.json b/ets2panda/linter/test/main/es_object.ets.arkts2.json index 79c951c0d912a7ac671a4b8f6c39da9ad1a785c4..109f6f3f9f7dbe149c5175442d41a292fa2145c1 100644 --- a/ets2panda/linter/test/main/es_object.ets.arkts2.json +++ b/ets2panda/linter/test/main/es_object.ets.arkts2.json @@ -34,6 +34,26 @@ "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 21, "column": 9, @@ -44,6 +64,16 @@ "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 22, "column": 11, @@ -894,6 +924,16 @@ "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, + { + "line": 148, + "column": 5, + "endLine": 148, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 149, "column": 1, diff --git a/ets2panda/linter/test/main/extends_expression.ets.arkts2.json b/ets2panda/linter/test/main/extends_expression.ets.arkts2.json index 789b06a0ffe191c1ae7660cd7667a0712b4a9274..7dc351bfded2c31854a052b243b342ae15f3b6df 100755 --- a/ets2panda/linter/test/main/extends_expression.ets.arkts2.json +++ b/ets2panda/linter/test/main/extends_expression.ets.arkts2.json @@ -114,6 +114,26 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, + { + "line": 62, + "column": 3, + "endLine": 66, + "endColumn": 4, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 3, + "endLine": 71, + "endColumn": 4, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 73, "column": 12, @@ -155,4 +175,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/func_inferred_type_args.ets.arkts2.json b/ets2panda/linter/test/main/func_inferred_type_args.ets.arkts2.json index eee42f58f0450a05faf2cd75d35139f35e77c1cd..c84d80ce6f32ce61bbc385f09f95c5e6272e4f27 100755 --- a/ets2panda/linter/test/main/func_inferred_type_args.ets.arkts2.json +++ b/ets2panda/linter/test/main/func_inferred_type_args.ets.arkts2.json @@ -124,6 +124,16 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, + { + "line": 56, + "column": 5, + "endLine": 56, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 56, "column": 8, @@ -284,6 +294,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 72, + "column": 7, + "endLine": 72, + "endColumn": 8, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 72, "column": 10, @@ -805,4 +825,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json b/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json index 8bedd487c8ac84dc85fc9728a71faab0de0e2314..bc0673b6ee646e91c180465f1a6fc340de3b815d 100644 --- a/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json +++ b/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json @@ -834,6 +834,16 @@ "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" }, + { + "line": 210, + "column": 9, + "endLine": 210, + "endColumn": 15, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 214, "column": 13, diff --git a/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json b/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json index 77cf362c1527086e6780739896b50bcf4d9fb6dc..f951e4a7708c37d1c980d9be0b53a12f8961b058 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json @@ -1044,6 +1044,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 169, + "column": 5, + "endLine": 169, + "endColumn": 10, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 169, "column": 12, @@ -1054,6 +1064,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 172, + "column": 5, + "endLine": 172, + "endColumn": 10, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 174, "column": 22, @@ -1094,6 +1114,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 200, + "column": 5, + "endLine": 200, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 201, "column": 19, @@ -1825,4 +1855,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/limit_void_type.ets.autofix.json b/ets2panda/linter/test/main/limit_void_type.ets.autofix.json index d80964b3403d86d70caba07f981713790f4387b4..71ebbcfacadf868db5eb962e1f2ca7ebaa7ac8ce 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.autofix.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.autofix.json @@ -1192,6 +1192,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 169, + "column": 5, + "endLine": 169, + "endColumn": 10, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 169, "column": 12, @@ -1202,6 +1212,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 172, + "column": 5, + "endLine": 172, + "endColumn": 10, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 174, "column": 22, @@ -1242,6 +1262,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 200, + "column": 5, + "endLine": 200, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 201, "column": 19, @@ -2510,4 +2540,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/limit_void_type.ets.migrate.json b/ets2panda/linter/test/main/limit_void_type.ets.migrate.json index 45016261114b25295b9fbc45da97c51d76361c93..15e73fe5ec327837f2071ed3942b26821536056b 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.migrate.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.migrate.json @@ -914,6 +914,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 177, + "column": 5, + "endLine": 177, + "endColumn": 10, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 177, "column": 12, @@ -924,6 +934,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 180, + "column": 5, + "endLine": 180, + "endColumn": 10, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 182, "column": 22, @@ -964,6 +984,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 208, + "column": 5, + "endLine": 208, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 209, "column": 19, @@ -1225,4 +1255,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json b/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json index bac768d6989a17a428165cacec894dbafa092f14..c4ce42692d93294214f288ebc60f6e1b44565342 100644 --- a/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json @@ -64,6 +64,26 @@ "rule": "Literal types are restricted(arkts-limited-literal-types)", "severity": "ERROR" }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 23, "column": 14, @@ -114,6 +134,26 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 12, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 39, "column": 5, @@ -194,6 +234,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 8, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 44, "column": 10, @@ -405,4 +455,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json b/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json index ff2491872246f140b2678e500727986e4116540e..c9d8ad036e52826cfdf4c6248996088543d98a98 100644 --- a/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json +++ b/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json @@ -394,6 +394,16 @@ "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", "severity": "ERROR" }, + { + "line": 319, + "column": 9, + "endLine": 319, + "endColumn": 11, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 324, "column": 3, @@ -404,6 +414,16 @@ "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", "severity": "ERROR" }, + { + "line": 325, + "column": 9, + "endLine": 325, + "endColumn": 11, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 330, "column": 3, @@ -414,6 +434,16 @@ "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", "severity": "ERROR" }, + { + "line": 331, + "column": 9, + "endLine": 331, + "endColumn": 11, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 336, "column": 16, @@ -475,4 +505,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.arkts2.json b/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.arkts2.json index f20f5ff07f2064876508be7a1ae60033e62afa66..6281cdd59ea5dcab7b10fcf2a9cb9ecb3c3dc31e 100644 --- a/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.arkts2.json @@ -1,78 +1,78 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "result": [ - { - "line": 32, - "column": 7, - "endLine": 32, - "endColumn": 9, - "problem": "InterfaceFieldNotImplemented", - "suggest": "", - "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 10, - "problem": "InterfaceFieldNotImplemented", - "suggest": "", - "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 7, - "endLine": 45, - "endColumn": 9, - "problem": "InterfaceFieldNotImplemented", - "suggest": "", - "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 7, - "endLine": 65, - "endColumn": 9, - "problem": "InterfaceFieldNotImplemented", - "suggest": "", - "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 7, - "endLine": 68, - "endColumn": 10, - "problem": "InterfaceFieldNotImplemented", - "suggest": "", - "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 7, - "endLine": 79, - "endColumn": 9, - "problem": "InterfaceFieldNotImplemented", - "suggest": "", - "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", - "severity": "ERROR" - } - ] + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 9, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 7, + "endLine": 35, + "endColumn": 10, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 7, + "endLine": 45, + "endColumn": 9, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 7, + "endLine": 65, + "endColumn": 9, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 7, + "endLine": 68, + "endColumn": 10, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 7, + "endLine": 79, + "endColumn": 9, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + } + ] } diff --git a/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.arkts2.json b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.arkts2.json index 1266c69bfca5190fe69b7b4b806747aa9610c8d6..6e0b7d9828c7d6793c4f9a9347c473b160783797 100644 --- a/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.arkts2.json @@ -124,6 +124,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 35, "column": 5, diff --git a/ets2panda/linter/test/main/no_local_class.ets b/ets2panda/linter/test/main/no_local_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..473c36c98ae0a17f8cb6fe9f48ebc42452cce939 --- /dev/null +++ b/ets2panda/linter/test/main/no_local_class.ets @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// VALID: Class/interface can be declared outside of functions +class GlobalClass { } +interface GlobalInterface { } + +// INVALID: Class declared inside a function +function foo() { + class Boo { } +} + +// INVALID: Interface declared inside a function +function a() { + interface B { } +} + +// INVALID: Both class and interface declared inside a function +function b() { + interface C { } + class D { } +} + +// INVALID: Interface declared inside an arrow function +const poo = () => { + interface T { } +} + +// INVALID: Both interface and class declared inside an arrow function +const yoo = () => { + interface L { } + class Zoo { } +} + +// INVALID: Class declared inside an arrow function +const qoo = () => { + class Moo { } +} + +// INVALID: Class declared inside a function expression +const dest = function () { + class Doo { } +} + +// INVALID: Both class and interface declared inside a function expression +const test = function () { + class Koo { } + interface Goo { } +} + +// INVALID: Interface declared inside a function expression +const cast = function () { + interface Pop { } +} + +// INVALID: Class declared inside a top-level block statement +{ + class BlockLocal { } +} + +// INVALID: Interface declared inside a top-level block statement +{ + interface BlockIface { } +} + +// INVALID: Class declared inside an if block +if (true) { + class IfBlockClass { } +} + +// INVALID: Interface declared inside an if block +if (false) { + interface IfBlockIface { } +} + +// INVALID: Class declared inside a for loop block +for (let i = 0; i < 1; i++) { + class ForBlockClass { } +} + +// INVALID: Interface declared inside a for loop block +for (let i = 0; i < 1; i++) { + interface ForBlockIface { } +} + +// INVALID: Class declared inside a while loop block +while (false) { + class WhileBlockClass { } +} + +// INVALID: Interface declared inside a while loop block +while (false) { + interface WhileBlockIface { } +} + +// INVALID: Class declared inside a nested block (block inside block) +{ + { + class NestedBlockClass { } + } +} + +// INVALID: Interface declared inside a nested block (block inside block) +{ + { + interface NestedBlockIface { } + } +} + +// VALID: Type alias at top-level (should NOT warn) +type FooType = number; + +// NESTED CASE: Deeply nested class inside arrow functions +function xyc(): void { + const a1 = () => { + const b2 = () => { + class Abc { + + } + } + } +} + diff --git a/ets2panda/linter/test/main/no_local_class.ets.args.json b/ets2panda/linter/test/main/no_local_class.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d2ef7038fc686415cfc67c9806ba7d19391382df --- /dev/null +++ b/ets2panda/linter/test/main/no_local_class.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2023-2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/no_local_class.ets.arkts2.json b/ets2panda/linter/test/main/no_local_class.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8e76a64ab129700223b65ed1b992372524ac55fe --- /dev/null +++ b/ets2panda/linter/test/main/no_local_class.ets.arkts2.json @@ -0,0 +1,338 @@ +{ + "copyright": [ + "Copyright (c) 2023-2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 20, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 20, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 16, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 20, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 5, + "endLine": 43, + "endColumn": 20, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 14, + "endLine": 55, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 14, + "endLine": 61, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 22, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 14, + "endLine": 66, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 22, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 25, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 29, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 27, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 31, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 10, + "endLine": 89, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 14, + "endLine": 89, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 21, + "endLine": 89, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 5, + "endLine": 90, + "endColumn": 28, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 10, + "endLine": 94, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 14, + "endLine": 94, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 21, + "endLine": 94, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 5, + "endLine": 95, + "endColumn": 32, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 5, + "endLine": 100, + "endColumn": 30, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 34, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 9, + "endLine": 111, + "endColumn": 35, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 9, + "endLine": 118, + "endColumn": 39, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 13, + "endLine": 131, + "endColumn": 14, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/no_local_class.ets.json b/ets2panda/linter/test/main/no_local_class.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8d562d8ee29ccac7c0610636aa5b7cc17b3c0c12 --- /dev/null +++ b/ets2panda/linter/test/main/no_local_class.ets.json @@ -0,0 +1,48 @@ +{ + "copyright": [ + "Copyright (c) 2023-2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 53, + "column": 14, + "endLine": 55, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 14, + "endLine": 61, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 14, + "endLine": 66, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets b/ets2panda/linter/test/main/no_ts_like_smart_type.ets index 7cdff3d524a3211820c8e0ecad1fe4f5692292f3..1c858dc1e1aac2057224f507ae790b707a338f32 100755 --- a/ets2panda/linter/test/main/no_ts_like_smart_type.ets +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets @@ -193,4 +193,42 @@ class A { return this.b //error } } +} + +export class K { + _t:string + constructor(t:string) { + this._t = t; + } +} + +export class P extends K { + constructor(t:string){ + super(t) + } + toString(): string { + return this._t // legal + } +} + +export class H { + protected _t:string + constructor(t:string) { + this._t = t; + } +} + +export class T extends H { + constructor(t:string) { + super(t) + } +} + +export class N extends T { + constructor(t:string){ + super(t) + } + toString(): string { + return this._t // legal + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json b/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json index 35164935cf2df9b2676aa6a0056880d98c390fb6..8dc6aded6f1bbbe46f59cad8402c22c4ee899da2 100644 --- a/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json @@ -204,6 +204,16 @@ "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "ERROR" }, + { + "line": 57, + "column": 5, + "endLine": 57, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 59, "column": 5, diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json b/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json index 99e139c5e9372ec72c4c887a1b7b5adacc4eb835..f9a499a0d28c438117ae92ab18db0594b6155d53 100644 --- a/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json @@ -402,6 +402,16 @@ "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "ERROR" }, + { + "line": 57, + "column": 5, + "endLine": 57, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 59, "column": 5, diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json index ae0621e24de33924117743a1b7bf713ee3b4e9ac..65e6d56f70f0341488c168401b32c29a18be7e4d 100644 --- a/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json @@ -24,6 +24,16 @@ "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "ERROR" }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 117, "column": 27, diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json b/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json index a63a7a849d8ea047a41f71ef2772e7c26c7bb945..57534ac619776325d9e71e9ce70589e7507fcc7a 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json @@ -934,6 +934,16 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 167, + "column": 3, + "endLine": 167, + "endColumn": 37, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 167, "column": 34, @@ -1255,4 +1265,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json b/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json index 432b311d060d6e363d60832bedbeb65972c13771..f650bad3c823282d640d1da0179d1b7a7caa8ec4 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json @@ -1646,6 +1646,16 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 167, + "column": 3, + "endLine": 167, + "endColumn": 37, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 167, "column": 34, @@ -2181,4 +2191,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json index 35c8ec6cd00afdabe9b36d4287d09a6d7d268496..056d7631eb5a91b3b3effa3cf7dea67958b5b78b 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json @@ -194,6 +194,16 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 207, + "column": 3, + "endLine": 210, + "endColumn": 2, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 212, "column": 26, @@ -234,6 +244,16 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 223, + "column": 3, + "endLine": 223, + "endColumn": 39, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 224, "column": 27, @@ -365,4 +385,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets b/ets2panda/linter/test/main/runtime_array_bound.ets index 33c5e11fbfee39878779b70ecd8f61efa7ef0471..6e495cef33dd66ac99f04d97ca86c94df3990aee 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets +++ b/ets2panda/linter/test/main/runtime_array_bound.ets @@ -308,3 +308,15 @@ for (let i = 0; i < concatArray.length; i++) { if (concatArray.length > 10) { concatArray[10] }; + +class DummyClass { + public a1: Array = new Array(); + + foo() { + this.a1[123] = 123; + } +} + +let dc = new DummyClass(); + +dc.a1[123] = 1234; diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json b/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json index eeab471943dea119a5df2506dfe1e2b6cefb3855..6b6a89fb8a5474cbc785c42161a6de69c8c6d10b 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json @@ -2553,6 +2553,46 @@ "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" + }, + { + "line": 316, + "column": 9, + "endLine": 316, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 24, + "endLine": 316, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 322, + "column": 1, + "endLine": 322, + "endColumn": 6, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 322, + "column": 14, + "endLine": 322, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets index 5531ae7190fbacfb0cd23ea1d5aefaab27680da0..eca7e1590197f3c718cccdf9077f706ca3a36c11 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets @@ -308,3 +308,15 @@ for (let i: number = 0.0; i < concatArray.length; i++) { if (concatArray.length > 10.0) { concatArray[10] }; + +class DummyClass { + public a1: Array = new Array(); + + foo() { + this.a1[123] = 123.0; + } +} + +let dc = new DummyClass(); + +dc.a1[123] = 1234.0; diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json index 84420569c7afc81e1a53ff83f2da02c069d5981a..31242ad2a570ddf5e476e4c27a98875912062be9 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json @@ -243,6 +243,26 @@ "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" + }, + { + "line": 316, + "column": 9, + "endLine": 316, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 322, + "column": 1, + "endLine": 322, + "endColumn": 6, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" } ] } diff --git a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json index cadab9b537c3cf72ee3692e146eaf5b553907b1d..a46f1ee37a96dd40d4cfef356637dd35fe2be334 100644 --- a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json +++ b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json @@ -684,6 +684,16 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, + { + "line": 507, + "column": 5, + "endLine": 507, + "endColumn": 7, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 511, "column": 1, @@ -1315,4 +1325,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json index 72f2d82336d0211362673a622b13fd07d4a314fa..d88197ac9bb35b5a9c748421ef142fa0ae8e3898 100644 --- a/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json +++ b/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json @@ -174,6 +174,26 @@ "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", "severity": "ERROR" }, + { + "line": 58, + "column": 5, + "endLine": 58, + "endColumn": 16, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 16, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 73, "column": 1, @@ -215,4 +235,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/var_assignment_before_use.ets b/ets2panda/linter/test/main/var_assignment_before_use.ets new file mode 100644 index 0000000000000000000000000000000000000000..35554385ce240145b93bebf7ac0c1a41ef0a99e7 --- /dev/null +++ b/ets2panda/linter/test/main/var_assignment_before_use.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Positive (should be flagged) +let a: A; // ❌ VariableMissingInitializer +let b: number[]; // ❌ VariableMissingInitializer +let c: A; // ❌ VariableMissingInitializer +const x: X; // ❌ VariableMissingInitializer + +// Negative (should NOT be flagged) +// 1) Initialized declarations +let d: D = new D(); // ✅ OK +const y1: string = "hello"; // ✅ OK + +// 2) Function‐typed declarations are skipped +let add: (a: number, b: number) => number; // ✅ OK +let handler: (e: Event) => void; // ✅ OK + +// 3) Explicit void‐typed declarations are skipped +let v: void; // ✅ OK +const v2: void; // ✅ OK + +// 4) For…of and For…in loop bindings +for (let item of items) { // ✅ OK + console.log(item); +} + +for (let key in record) { // ✅ OK + console.log(key); +} + +// 5) Function declarations / expressions +function foo() { // ✅ OK + return 42; +} + +let bar = function() { // ✅ OK + return "hi"; +}; + +let baz = () => { // ✅ OK + return true; +}; + +// 6) Destructuring with initializer +let { x, y } = point; // ✅ OK diff --git a/ets2panda/linter/test/main/var_assignment_before_use.ets.args.json b/ets2panda/linter/test/main/var_assignment_before_use.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/main/var_assignment_before_use.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/var_assignment_before_use.ets.arkts2.json b/ets2panda/linter/test/main/var_assignment_before_use.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..c022111dcdcc1607fb0cce996a853093638b0fc9 --- /dev/null +++ b/ets2panda/linter/test/main/var_assignment_before_use.ets.arkts2.json @@ -0,0 +1,168 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 6, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 10, + "endLine": 19, + "endColumn": 17, + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 8, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 17, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 8, + "endLine": 32, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 11, + "endLine": 33, + "endColumn": 15, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 10, + "endLine": 36, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 14, + "endLine": 40, + "endColumn": 16, + "problem": "ForInStatement", + "suggest": "", + "rule": "\"for .. in\" is not supported (arkts-no-for-in)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 1, + "endLine": 47, + "endColumn": 2, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 51, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 5, + "endLine": 58, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Event\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/var_assignment_before_use.ets.json b/ets2panda/linter/test/main/var_assignment_before_use.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..687dd6fe1903d7f360bcaa247ec3c6210db5f411 --- /dev/null +++ b/ets2panda/linter/test/main/var_assignment_before_use.ets.json @@ -0,0 +1,68 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 19, + "column": 10, + "endLine": 19, + "endColumn": 17, + "problem": "EsValueType", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "WARNING" + }, + { + "line": 36, + "column": 10, + "endLine": 36, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 14, + "endLine": 40, + "endColumn": 16, + "problem": "ForInStatement", + "suggest": "", + "rule": "\"for .. in\" is not supported (arkts-no-for-in)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 51, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 5, + "endLine": 58, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/worker_module.ets.arkts2.json b/ets2panda/linter/test/main/worker_module.ets.arkts2.json index 535d022afdc58f18c353c35b8ca2d43213f138e0..d01b01f98e49498ef40e0df91bab289d73bf0626 100644 --- a/ets2panda/linter/test/main/worker_module.ets.arkts2.json +++ b/ets2panda/linter/test/main/worker_module.ets.arkts2.json @@ -114,6 +114,16 @@ "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", "severity": "ERROR" }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 14, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 34, "column": 16, @@ -143,6 +153,16 @@ "suggest": "", "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", "severity": "ERROR" + }, + { + "line": 38, + "column": 7, + "endLine": 38, + "endColumn": 14, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.arkts2.json index 76d25532694166291452e1d717bbc7c68b7b324b..8bd1ca80749619654ee3283d673c93d911bac59f 100644 --- a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.arkts2.json @@ -184,6 +184,16 @@ "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", "severity": "ERROR" }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 19, + "problem": "VariableMissingInitializer", + "suggest": "", + "rule": "After a variable is declared, a value must be assigned before using it (arkts-var-assignment-before-use)", + "severity": "ERROR" + }, { "line": 53, "column": 18,