diff --git a/es2panda/lexer/token/tokenType.h b/es2panda/lexer/token/tokenType.h index 6fe7fb0f0ef21bdbfce9999104ec0aa67ec70489..45a23d0ed2344b6d356d119d746c9e442c3ce040 100644 --- a/es2panda/lexer/token/tokenType.h +++ b/es2panda/lexer/token/tokenType.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -142,6 +142,7 @@ enum class TokenType { KEYW_RETURN, KEYW_STRING, KEYW_SUPER, + KEYW_STRUCT, KEYW_SWITCH, KEYW_SYMBOL, KEYW_THIS, diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index f127204827aea3d9a13729dad950d9f49de5a71f..80e75bf31858d7e801a2a4c16327afc8f310ec1a 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1123,6 +1123,12 @@ std::tuple ETSAnalyzer::CheckAssignmentExprOperatorTyp return {sourceType, relationNode}; } +static bool IsPromiseType(checker::Type *type, ETSChecker *checker) +{ + return type->IsETSObjectType() && + type->AsETSObjectType()->GetOriginalBaseType() == checker->GlobalBuiltinPromiseType(); +} + checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const { ETSChecker *checker = GetETSChecker(); @@ -1131,14 +1137,27 @@ checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const } checker::Type *argType = checker->GetApparentType(expr->argument_->Check(checker)); - // Check the argument type of await expression - if (!argType->IsETSObjectType() || - (argType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType())) { - return checker->TypeError(expr, diagnostic::AWAITED_NOT_PROMISE, expr->Argument()->Start()); + ArenaVector awaitedTypes(checker->Allocator()->Adapter()); + + if (argType->IsETSUnionType()) { + for (Type *type : argType->AsETSUnionType()->ConstituentTypes()) { + if (!IsPromiseType(type, checker)) { + return checker->TypeError(expr, diagnostic::AWAITED_NOT_PROMISE, expr->Argument()->Start()); + } + + Type *typeArg = type->AsETSObjectType()->TypeArguments().at(0); + awaitedTypes.push_back(UnwrapPromiseType(typeArg)); + } + } else { + if (!IsPromiseType(argType, checker)) { + return checker->TypeError(expr, diagnostic::AWAITED_NOT_PROMISE, expr->Argument()->Start()); + } + + Type *typeArg = argType->AsETSObjectType()->TypeArguments().at(0); + awaitedTypes.push_back(UnwrapPromiseType(typeArg)); } - Type *type = argType->AsETSObjectType()->TypeArguments().at(0); - expr->SetTsType(UnwrapPromiseType(type)); + expr->SetTsType(argType->IsETSUnionType() ? checker->CreateETSUnionType(std::move(awaitedTypes)) : awaitedTypes[0]); return expr->TsType(); } @@ -2328,7 +2347,8 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const ETSChecker *checker = GetETSChecker(); st->Expr()->Check(checker); - if (!st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { + if (st->GetBaseName()->Variable() == nullptr || + !st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { checker->LogError(diagnostic::NOT_AN_ANNOTATION, {st->GetBaseName()->Name()}, st->GetBaseName()->Start()); return ReturnTypeForStatement(st); } @@ -2829,12 +2849,11 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const flags |= ir::ModifierFlags::OPTIONAL; } - auto *const variableType = checker->CheckVariableDeclaration(ident, ident->TypeAnnotation(), st->Init(), flags); - // Processing possible parser errors if (ident->Variable() == nullptr) { ident->Check(checker); } + auto *const variableType = checker->CheckVariableDeclaration(ident, ident->TypeAnnotation(), st->Init(), flags); // Now try to define the actual type of Identifier so that smart cast can be used in further checker processing // NOTE: T_S and K_o_t_l_i_n don't act in such way, but we can try - why not? :) @@ -3014,8 +3033,19 @@ checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const checker->ReportWarning( {"Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'."}, expr->Expr()->Start()); + + if (expr->expr_->IsIdentifier()) { + ES2PANDA_ASSERT(expr->expr_->AsIdentifier()->Variable() != nullptr); + auto originalType = expr->expr_->AsIdentifier()->Variable()->TsType(); + if (originalType != nullptr) { + expr->SetTsType(checker->GetNonNullishType(originalType)); + } + } + } + + if (expr->TsType() == nullptr) { + expr->SetTsType(checker->GetNonNullishType(exprType)); } - expr->SetTsType(checker->GetNonNullishType(exprType)); expr->SetOriginalType(expr->TsType()); return expr->TsType(); } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index dfc8762e5a6814215b2855ac39cd545cea45a66b..a610a3902db7f59b7124be3c09b26416cef9a6c5 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -411,6 +411,10 @@ public: { return Allocator()->New(*src); } + bool ValidateTypeSubstitution(const ArenaVector &typeParams, Type *ctype, Type *argumentType, + Substitution *substitution); + bool ProcessUntypedParameter(ir::AstNode *declNode, size_t paramIndex, Signature *paramSig, Signature *argSig, + Substitution *substitution); void EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg); [[nodiscard]] bool EnhanceSubstitutionForType(const ArenaVector &typeParams, Type *paramType, Type *argumentType, Substitution *substitution); @@ -459,11 +463,15 @@ public: void SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature *&prevSig, std::tuple info, bool lookForClassType); + void CollectSuitableSignaturesForTypeInference(size_t paramIdx, ArenaVector &signatures, + ArenaMultiMap &bestSignaturesForParameter, + const ArenaVector &arguments); ArenaMultiMap GetSuitableSignaturesForParameter( const std::vector &argTypeInferenceRequired, size_t paramCount, ArenaVector &signatures, - const lexer::SourcePosition &pos); + const ArenaVector &arguments, const lexer::SourcePosition &pos); Signature *ChooseMostSpecificSignature(ArenaVector &signatures, const std::vector &argTypeInferenceRequired, + const ArenaVector &arguments, const lexer::SourcePosition &pos, size_t argumentsSize = ULONG_MAX); Signature *ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpression *callExpr, ArenaVector const &signatures, diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index 7c9a9142ba7166f3d60cf3132387f7c6e2cc3e82..a6a2282f077a6f3fa1baf9bdf153b09d1dfff553 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -189,7 +189,7 @@ void AliveAnalyzer::AnalyzeStat(const ir::AstNode *node) } if (status_ == LivenessStatus::DEAD) { - checker_->LogError(diagnostic::UNREACHABLE_STMT, {}, node->Start()); + checker_->LogError(diagnostic::UNREACHABLE_STMT, node->Start()); return; } diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 94db51adb5953338103874a72eafde28b4e4aa4f..adeea4b940ed1d850b018bb20284a82b3b58659c 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -126,18 +126,26 @@ bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &typeParam return true; } +bool ETSChecker::ValidateTypeSubstitution(const ArenaVector &typeParams, Type *ctype, Type *argumentType, + Substitution *substitution) +{ + if (!EnhanceSubstitutionForType(typeParams, ctype, argumentType, substitution)) { + return false; + } + return !ctype->IsETSTypeParameter() || + (substitution->count(ctype->AsETSTypeParameter()) > 0 && + Relation()->IsAssignableTo(argumentType, substitution->at(ctype->AsETSTypeParameter()))); +} + bool ETSChecker::EnhanceSubstitutionForUnion(const ArenaVector &typeParams, ETSUnionType *paramUn, Type *argumentType, Substitution *substitution) { if (!argumentType->IsETSUnionType()) { - return std::any_of( - paramUn->ConstituentTypes().begin(), paramUn->ConstituentTypes().end(), - [this, typeParams, argumentType, substitution](Type *ctype) { - return EnhanceSubstitutionForType(typeParams, ctype, argumentType, substitution) && - (!ctype->IsETSTypeParameter() || - (substitution->find(ctype->AsETSTypeParameter()) != substitution->end() && - Relation()->IsAssignableTo(argumentType, substitution->at(ctype->AsETSTypeParameter())))); - }); + bool foundValid = false; + for (Type *ctype : paramUn->ConstituentTypes()) { + foundValid |= ValidateTypeSubstitution(typeParams, ctype, argumentType, substitution); + } + return foundValid; } auto *const argUn = argumentType->AsETSUnionType(); @@ -166,6 +174,70 @@ bool ETSChecker::EnhanceSubstitutionForUnion(const ArenaVector &typePara return true; } +bool ETSChecker::ProcessUntypedParameter(ir::AstNode *declNode, size_t paramIndex, Signature *paramSig, + Signature *argSig, Substitution *substitution) +{ + if (!declNode->IsETSParameterExpression() || !HasStatus(CheckerStatus::IN_TYPE_INFER)) { + return false; + } + + auto *paramExpr = declNode->AsETSParameterExpression(); + if (paramExpr->Ident()->TypeAnnotation() != nullptr) { + return false; + } + + Type *paramType = paramSig->Params()[paramIndex]->TsType(); + Type *inferredType = paramType->Substitute(Relation(), substitution); + + varbinder::Variable *argParam = argSig->Params()[paramIndex]; + argParam->SetTsType(inferredType); + paramExpr->Ident()->SetTsType(inferredType); + + return true; +} + +static void RemoveInvalidTypeMarkers(ir::AstNode *node) noexcept +{ + std::function doNode = [&](ir::AstNode *nn) { + if (nn->IsTyped() && !(nn->IsExpression() && nn->AsExpression()->IsTypeNode()) && + nn->AsTyped()->TsType() != nullptr && nn->AsTyped()->TsType()->IsTypeError()) { + nn->AsTyped()->SetTsType(nullptr); + } + if (nn->IsIdentifier() && nn->AsIdentifier()->TsType() != nullptr && + nn->AsIdentifier()->TsType()->IsTypeError()) { + nn->AsIdentifier()->SetVariable(nullptr); + } + if (!nn->IsETSTypeReference()) { + nn->Iterate([&](ir::AstNode *child) { doNode(child); }); + } + }; + + doNode(node); +} + +static void ResetInferredNode(ETSChecker *checker) +{ + auto relation = checker->Relation(); + auto resetFuncState = [](ir::ArrowFunctionExpression *expr) { + auto *func = expr->Function(); + func->SetSignature(nullptr); + func->ReturnStatements().clear(); + expr->SetTsType(nullptr); + }; + + const bool hasValidNode = relation->GetNode() != nullptr && relation->GetNode()->IsArrowFunctionExpression(); + if (!checker->HasStatus(CheckerStatus::IN_TYPE_INFER) || !hasValidNode) { + return; + } + + auto *arrowFunc = relation->GetNode()->AsArrowFunctionExpression(); + relation->SetNode(nullptr); + + RemoveInvalidTypeMarkers(arrowFunc); + resetFuncState(arrowFunc); + arrowFunc->Check(checker); +} + bool ETSChecker::EnhanceSubstitutionForFunction(const ArenaVector &typeParams, ETSFunctionType *paramType, Type *argumentType, Substitution *substitution) { @@ -173,32 +245,36 @@ bool ETSChecker::EnhanceSubstitutionForFunction(const ArenaVector &typeP return EnhanceSubstitutionForType(typeParams, ptype, atype, substitution); }; - if (argumentType->IsETSFunctionType()) { - auto parameterSignature = paramType->ArrowSignature(); - auto argumentSignature = argumentType->AsETSFunctionType()->ArrowSignature(); - // NOTE(gogabr): handle rest parameter for argumentSignature - if (parameterSignature->MinArgCount() < argumentSignature->MinArgCount()) { - return false; - } - bool res = true; - size_t const commonArity = std::min(argumentSignature->ArgCount(), parameterSignature->ArgCount()); - for (size_t idx = 0; idx < commonArity; idx++) { - auto *declNode = argumentSignature->Params()[idx]->Declaration()->Node(); - if (declNode->IsETSParameterExpression() && - declNode->AsETSParameterExpression()->Ident()->TypeAnnotation() == nullptr) { - continue; - } - res &= enhance(parameterSignature->Params()[idx]->TsType(), argumentSignature->Params()[idx]->TsType()); - } + if (!argumentType->IsETSFunctionType()) { + return true; + } + + auto *paramSig = paramType->ArrowSignature(); + auto *argSig = argumentType->AsETSFunctionType()->ArrowSignature(); + + if (paramSig->MinArgCount() < argSig->MinArgCount()) { + return false; + } - if (argumentSignature->HasRestParameter() && parameterSignature->HasRestParameter()) { - res &= enhance(parameterSignature->RestVar()->TsType(), argumentSignature->RestVar()->TsType()); + bool res = true; + const size_t commonArity = std::min(argSig->ArgCount(), paramSig->ArgCount()); + + for (size_t idx = 0; idx < commonArity; idx++) { + auto *declNode = argSig->Params()[idx]->Declaration()->Node(); + if (ProcessUntypedParameter(declNode, idx, paramSig, argSig, substitution)) { + continue; } - res &= enhance(parameterSignature->ReturnType(), argumentSignature->ReturnType()); - return res; + res &= enhance(paramSig->Params()[idx]->TsType(), argSig->Params()[idx]->TsType()); } - return true; + ResetInferredNode(this); + + if (argSig->HasRestParameter() && paramSig->HasRestParameter()) { + res &= enhance(paramSig->RestVar()->TsType(), argSig->RestVar()->TsType()); + } + res &= enhance(paramSig->ReturnType(), argSig->ReturnType()); + + return res; } // Try to find the base type somewhere in object subtypes. Incomplete, yet safe @@ -607,7 +683,8 @@ Signature *ETSChecker::GetMostSpecificSignature(ArenaVector &compat const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags) { std::vector argTypeInferenceRequired = FindTypeInferenceArguments(arguments); - Signature *mostSpecificSignature = ChooseMostSpecificSignature(compatibleSignatures, argTypeInferenceRequired, pos); + Signature *mostSpecificSignature = + ChooseMostSpecificSignature(compatibleSignatures, argTypeInferenceRequired, arguments, pos); if (mostSpecificSignature == nullptr) { LogError(diagnostic::AMBIGUOUS_FUNC_REF, {compatibleSignatures.front()->Function()->Id()->Name()}, pos); @@ -773,9 +850,43 @@ void ETSChecker::SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature } } -static void CollectSuitableSignaturesForTypeInference(size_t paramIdx, ArenaVector &signatures, - ArenaMultiMap &bestSignaturesForParameter) +void ETSChecker::CollectSuitableSignaturesForTypeInference( + size_t paramIdx, ArenaVector &signatures, + ArenaMultiMap &bestSignaturesForParameter, const ArenaVector &arguments) { + // For lambda parameters, attempt to obtain the most matching signature through the number of lambda parameters + ES2PANDA_ASSERT(arguments.at(paramIdx)->IsArrowFunctionExpression()); + [[maybe_unused]] size_t paramCount = + arguments.at(paramIdx)->AsArrowFunctionExpression()->Function()->Params().size(); + size_t minMatchArgCount = SIZE_MAX; + + for (auto *sig : signatures) { + auto *sigParamType = GetNonNullishType(sig->Params().at(paramIdx)->TsType()); + if (!sigParamType->IsETSFunctionType()) { + continue; + } + + auto sigParamArgCount = sigParamType->AsETSFunctionType()->ArrowSignature()->ArgCount(); + ES2PANDA_ASSERT(sigParamArgCount >= paramCount); + + minMatchArgCount = std::min(minMatchArgCount, sigParamArgCount); + } + + for (auto *sig : signatures) { + auto *sigParamType = GetNonNullishType(sig->Params().at(paramIdx)->TsType()); + if (!sigParamType->IsETSFunctionType()) { + continue; + } + + if (sigParamType->AsETSFunctionType()->ArrowSignature()->ArgCount() == minMatchArgCount) { + bestSignaturesForParameter.insert({paramIdx, sig}); + } + } + + if (bestSignaturesForParameter.find(paramIdx) != bestSignaturesForParameter.end()) { + return; + } + for (auto *sig : signatures) { if (paramIdx >= sig->Params().size() || !sig->Params().at(paramIdx)->TsType()->IsETSObjectType() || !sig->Params().at(paramIdx)->TsType()->AsETSObjectType()->IsGlobalETSObjectType()) { @@ -786,7 +897,7 @@ static void CollectSuitableSignaturesForTypeInference(size_t paramIdx, ArenaVect ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter( const std::vector &argTypeInferenceRequired, size_t paramCount, ArenaVector &signatures, - const lexer::SourcePosition &pos) + const ArenaVector &arguments, const lexer::SourcePosition &pos) { // Collect which signatures are most specific for each parameter. ArenaMultiMap bestSignaturesForParameter(Allocator()->Adapter()); @@ -795,8 +906,14 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter TypeRelationFlag::ONLY_CHECK_WIDENING); for (size_t i = 0; i < paramCount; ++i) { - if (i >= argTypeInferenceRequired.size() || argTypeInferenceRequired[i]) { - CollectSuitableSignaturesForTypeInference(i, signatures, bestSignaturesForParameter); + if (i >= argTypeInferenceRequired.size()) { + for (auto *sig : signatures) { + bestSignaturesForParameter.insert({i, sig}); + } + continue; + } + if (argTypeInferenceRequired[i]) { + CollectSuitableSignaturesForTypeInference(i, signatures, bestSignaturesForParameter, arguments); continue; } // 1st step: check which is the most specific parameter type for i. parameter. @@ -823,6 +940,7 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter Signature *ETSChecker::ChooseMostSpecificSignature(ArenaVector &signatures, const std::vector &argTypeInferenceRequired, + const ArenaVector &arguments, const lexer::SourcePosition &pos, size_t argumentsSize) { ES2PANDA_ASSERT(signatures.empty() == false); @@ -861,7 +979,7 @@ Signature *ETSChecker::ChooseMostSpecificSignature(ArenaVector &sig } ArenaMultiMap bestSignaturesForParameter = - GetSuitableSignaturesForParameter(argTypeInferenceRequired, paramCount, signatures, pos); + GetSuitableSignaturesForParameter(argTypeInferenceRequired, paramCount, signatures, arguments, pos); // Find the signature that are most specific for all parameters. Signature *mostSpecificSignature = FindMostSpecificSignature(signatures, bestSignaturesForParameter, paramCount); diff --git a/ets2panda/checker/ets/function_helpers.h b/ets2panda/checker/ets/function_helpers.h index e44d54ffc032cb575ef34b495c7c944419efd55f..1051bb4987d10b76828e144a04417304b9908502 100644 --- a/ets2panda/checker/ets/function_helpers.h +++ b/ets2panda/checker/ets/function_helpers.h @@ -100,6 +100,9 @@ static void InferUntilFail(Signature const *const signature, const ArenaVectorIsArrowFunctionExpression()) { + checker->Relation()->SetNode(arg); + } if (checker->EnhanceSubstitutionForType(sigInfo->typeParams, paramType, argType, substitution)) { inferStatus[ix] = true; diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index d2e28eaec7ad3f00d3d08ee2a3622d1523b28bb2..10699774ace58c5846edbd15eb6fcf0c65e15723 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2633,7 +2633,7 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A auto *paramExpression = AllocNode(paramIdent, false, Allocator()); paramExpression->SetRange(paramIdent->Range()); - auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), paramExpression); + auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), VarBinder(), paramExpression); if (node != nullptr) { VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name()); } @@ -3084,7 +3084,8 @@ checker::ETSFunctionType *ETSChecker::IntersectSignatureSets(const checker::ETSF { auto sameSig = [this](checker::Signature *leftSig, checker::Signature *rightSig) { auto relation = Relation(); - if (leftSig->Flags() != rightSig->Flags()) { + if ((leftSig->Flags() & ~checker::SignatureFlags::FINAL) != + (rightSig->Flags() & ~checker::SignatureFlags::FINAL)) { return false; } return relation->SignatureIsIdenticalTo(rightSig, leftSig); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index eceaf9209b6dcd72be9c2c511995d74dd78018b1..9b36448b0bcfbaeae96b279b35ce235a4e10d262 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -475,8 +475,11 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) if (classDef->IsAbstract()) { classType->AddObjectFlag(checker::ETSObjectFlags::ABSTRACT); } - } else { + } else if (var->TsType()->IsETSObjectType()) { classType = var->TsType()->AsETSObjectType(); + } else { + ES2PANDA_ASSERT(IsAnyError()); + return GlobalTypeError(); } classDef->SetTsType(classType); @@ -1701,7 +1704,7 @@ void ETSChecker::CheckCyclicConstructorCall(Signature *signature) ->Callee() ->IsThisExpression()) { auto *constructorCall = funcBody->Statements()[0]->AsExpressionStatement()->GetExpression()->AsCallExpression(); - if (constructorCall->TsType()->HasTypeFlag(TypeFlag::TYPE_ERROR)) { + if (constructorCall->TsType() == nullptr || constructorCall->TsType()->HasTypeFlag(TypeFlag::TYPE_ERROR)) { LogError(diagnostic::NO_SUCH_CTOR_SIG, {}, constructorCall->Start()); return; } @@ -2291,8 +2294,8 @@ void ETSChecker::CheckProperties(ETSObjectType *classType, ir::ClassDefinition * interfaceFound->GetDeclNode()->Start()); return; } - LogError(diagnostic::INHERITED_CLASS_TYPE_MISMATCH, {classType->SuperType()->Name(), targetType, it->Name()}, - classDef->Super()->Start()); + auto pos = classDef->Super() == nullptr ? classDef->Ident()->Start() : classDef->Super()->Start(); + LogError(diagnostic::INHERITED_CLASS_TYPE_MISMATCH, {classType->SuperType()->Name(), targetType, it->Name()}, pos); } void ETSChecker::CheckReadonlyClassPropertyInImplementedInterface(ETSObjectType *classType, diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 9506cb451de5d413aa82f4b2f6f2b8f333caace3..a077b6024fdc9b925cf610346a53633ee73ebfdb 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -1392,6 +1392,9 @@ bool ETSChecker::CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction { ES2PANDA_ASSERT(param->IsETSParameterExpression()); ir::AstNode *typeAnn = param->AsETSParameterExpression()->Ident()->TypeAnnotation(); + if (typeAnn == nullptr) { + return false; + } if (typeAnn->IsETSTypeReference()) { typeAnn = DerefETSTypeReference(typeAnn); } diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 69ed5cb22c569d29fc1d81fd55c2e6f5b4ef0351..138fe7d21e3f6aae71973d47c1b3ba43b7cc3b9a 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -542,7 +542,7 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co paramExpr->Ident()->SetTsTypeAnnotation(unionType); unionType->SetParent(paramExpr->Ident()); - auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), paramExpr); + auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), VarBinder(), paramExpr); if (node != nullptr) { VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name()); } diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index 593e04c1e295519f6f10a390e0755793c72a5c24..ed71d79e9525a88cf44e20873d0dc89cfffaa9aa 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -125,8 +125,10 @@ void ETSChecker::ValidateAssignmentIdentifier(ir::Identifier *const ident, Type bool ETSChecker::ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, Type *const type) { + auto const resolved = ident->Variable(); const auto *const binaryExpr = ident->Parent()->AsBinaryExpression(); bool isFinished = false; + if (binaryExpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF && binaryExpr->Left() == ident) { if (!IsReferenceType(type)) { std::ignore = @@ -134,6 +136,15 @@ bool ETSChecker::ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, } isFinished = true; } + + if (binaryExpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING || + binaryExpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_OR || + binaryExpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) { + if ((resolved != nullptr) && (!resolved->Declaration()->PossibleTDZ() && !type->IsETSFunctionType())) { + WrongContextErrorClassifyByType(ident); + } + isFinished = true; + } return isFinished; } diff --git a/ets2panda/checker/types/ets/etsEnumType.cpp b/ets2panda/checker/types/ets/etsEnumType.cpp index 6f9d01f6b45d762054a97d76bac60eb47ef19322..61d23b7cbf94ef87d12a88cce69cb24207f4cb97 100644 --- a/ets2panda/checker/types/ets/etsEnumType.cpp +++ b/ets2panda/checker/types/ets/etsEnumType.cpp @@ -27,7 +27,9 @@ bool ETSStringEnumType::AssignmentSource(TypeRelation *relation, Type *target) result = true; } else if (target->IsETSStringType()) { result = true; - relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + if (relation->GetNode() != nullptr) { + relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + } } else if (target->IsETSUnionType()) { auto &unionConstituentTypes = target->AsETSUnionType()->ConstituentTypes(); for (auto *constituentType : unionConstituentTypes) { @@ -72,7 +74,8 @@ bool ETSIntEnumType::AssignmentSource(TypeRelation *relation, Type *target) { bool result = false; if (target->IsETSObjectType()) { - if (target->AsETSObjectType()->IsGlobalETSObjectType()) { + if (target->AsETSObjectType()->IsGlobalETSObjectType() || + target->AsETSObjectType()->Name() == compiler::Signatures::NUMERIC) { result = true; } else if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC)) { result = true; diff --git a/ets2panda/checker/types/ets/etsNeverType.cpp b/ets2panda/checker/types/ets/etsNeverType.cpp index e6fa4f3806db7b714a20035be823f3450bffd459..0b5401c3ba54c9e81c5e0428d85d081a23493238 100644 --- a/ets2panda/checker/types/ets/etsNeverType.cpp +++ b/ets2panda/checker/types/ets/etsNeverType.cpp @@ -22,7 +22,7 @@ namespace ark::es2panda::checker { void ETSNeverType::Identical(TypeRelation *relation, Type *other) { - relation->Result(other->IsNeverType()); + relation->Result(other->IsETSNeverType()); } void ETSNeverType::AssignmentTarget(TypeRelation *relation, Type *source) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index f68e6e9c9ec93455c1030b3618988839fe75f531..5d54c7235bfa01c6cc5825a3c67e5ef2436ad080 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -146,11 +146,18 @@ bool ETSObjectType::IsDescendantOf(const ETSObjectType *ascendant) const return this->SuperType()->IsDescendantOf(ascendant); } +static bool HasAccessor(const PropertySearchFlags &flags, const ETSFunctionType *funcType) +{ + if ((flags & (PropertySearchFlags::IS_GETTER | PropertySearchFlags::IS_SETTER)) != 0) { + return true; + } + return funcType->HasTypeFlag(TypeFlag::GETTER) || funcType->HasTypeFlag(TypeFlag::SETTER); +} + static void UpdateDeclarationForGetterSetter(varbinder::LocalVariable *res, const ETSFunctionType *funcType, const PropertySearchFlags &flags) { - if ((flags & (PropertySearchFlags::IS_GETTER | PropertySearchFlags::IS_SETTER)) == 0 || - res->Declaration() != nullptr) { + if (!HasAccessor(flags, funcType) || res->Declaration() != nullptr) { return; } auto var = funcType->CallSignatures().front()->OwnerVar(); @@ -334,20 +341,40 @@ std::vector ETSObjectType::Fields() const std::vector ETSObjectType::ForeignProperties() const { std::vector foreignProps; - std::unordered_set ownProps; + + // spec 9.3: all names in static and, separately, non-static class declaration scopes must be unique. + std::unordered_set ownInstanceProps; + std::unordered_set ownStaticProps; EnsurePropertiesInstantiated(); - ownProps.reserve(properties_.size()); + ownInstanceProps.reserve(properties_.size()); + ownStaticProps.reserve(properties_.size()); for (const auto *prop : GetAllProperties()) { - ownProps.insert(prop->Name()); + if (prop->HasFlag(varbinder::VariableFlags::STATIC)) { + ownStaticProps.insert(prop->Name()); + } else { + ownInstanceProps.insert(prop->Name()); + } } - std::map allProps {}; - Iterate([&allProps](const varbinder::LocalVariable *var) { allProps.emplace(var->Name(), var); }); + std::map allInstanceProps {}; + std::map allStaticProps {}; + Iterate([&allInstanceProps, &allStaticProps](const varbinder::LocalVariable *var) { + if (var->HasFlag(varbinder::VariableFlags::STATIC)) { + allStaticProps.emplace(var->Name(), var); + } else { + allInstanceProps.emplace(var->Name(), var); + } + }); - for (const auto &[name, var] : allProps) { - if (ownProps.find(name) == ownProps.end()) { + for (const auto &[name, var] : allInstanceProps) { + if (ownInstanceProps.find(name) == ownInstanceProps.end()) { + foreignProps.push_back(var); + } + } + for (const auto &[name, var] : allStaticProps) { + if (ownStaticProps.find(name) == ownStaticProps.end()) { foreignProps.push_back(var); } } diff --git a/ets2panda/checker/types/ets/etsTupleType.cpp b/ets2panda/checker/types/ets/etsTupleType.cpp index fc5c9a9aec9f1bbf639d82f34466ed2f0d9c7d06..7a18c2ab036c33e5b9cafeea7fb4dfb25c704e21 100644 --- a/ets2panda/checker/types/ets/etsTupleType.cpp +++ b/ets2panda/checker/types/ets/etsTupleType.cpp @@ -69,6 +69,20 @@ Type *ETSTupleType::GetTypeAtIndex(const TupleSizeType index) const return GetTupleTypesList().at(index); } +bool ETSTupleType::CheckElementsIdentical(TypeRelation *relation, const ETSTupleType *other) const +{ + if (GetTupleSize() != other->GetTupleSize()) { + return false; + } + + for (TupleSizeType idx = 0; idx < GetTupleSize(); ++idx) { + if (!relation->IsIdenticalTo(GetTypeAtIndex(idx), other->GetTypeAtIndex(idx))) { + return false; + } + } + return true; +} + void ETSTupleType::Identical([[maybe_unused]] TypeRelation *const relation, Type *const other) { if (!other->IsETSTupleType()) { @@ -77,15 +91,14 @@ void ETSTupleType::Identical([[maybe_unused]] TypeRelation *const relation, Type const auto *const otherTuple = other->AsETSTupleType(); - if (GetTupleSize() != otherTuple->GetTupleSize()) { + if (HasTypeFlag(TypeFlag::READONLY) != other->HasTypeFlag(TypeFlag::READONLY)) { + relation->Result(false); return; } - for (TupleSizeType idx = 0; idx < GetTupleSize(); ++idx) { - if (!relation->IsIdenticalTo(GetTypeAtIndex(idx), otherTuple->GetTypeAtIndex(idx))) { - relation->Result(false); - return; - } + if (!CheckElementsIdentical(relation, otherTuple)) { + relation->Result(false); + return; } relation->Result(true); @@ -102,27 +115,9 @@ bool ETSTupleType::AssignmentSource(TypeRelation *const relation, Type *const ta void ETSTupleType::AssignmentTarget(TypeRelation *const relation, Type *const source) { - if (source->HasTypeFlag(TypeFlag::READONLY)) { - relation->Result(false); - return; - } - - if (!source->IsETSTupleType()) { - return; - } - - const auto *const sourceTuple = source->AsETSTupleType(); - if (sourceTuple->GetTupleSize() != GetTupleSize()) { - return; - } - - for (TupleSizeType idx = 0; idx < GetTupleSize(); ++idx) { - if (!relation->IsIdenticalTo(GetTypeAtIndex(idx), sourceTuple->GetTypeAtIndex(idx))) { - return; - } + if (!source->HasTypeFlag(TypeFlag::READONLY) && source->IsETSTupleType()) { + source->AsETSTupleType()->IsSubtypeOf(relation, this); } - - relation->Result(true); } Type *ETSTupleType::Substitute(TypeRelation *relation, const Substitution *substitution) @@ -143,6 +138,11 @@ void ETSTupleType::IsSubtypeOf(TypeRelation *const relation, Type *target) relation->Result(true); return; } + if (target->IsETSTupleType()) { + if (!HasTypeFlag(TypeFlag::READONLY) && CheckElementsIdentical(relation, target->AsETSTupleType())) { + relation->Result(true); + } + } } void ETSTupleType::Cast(TypeRelation *const relation, Type *const target) diff --git a/ets2panda/checker/types/ets/etsTupleType.h b/ets2panda/checker/types/ets/etsTupleType.h index 31aca83175f646508708e02de738e3e69f1aec57..53418a226c933ef7bd6fe24e38d68bfc3ba130f4 100644 --- a/ets2panda/checker/types/ets/etsTupleType.h +++ b/ets2panda/checker/types/ets/etsTupleType.h @@ -70,6 +70,8 @@ public: void ToDebugInfoType(std::stringstream &ss) const override; private: + bool CheckElementsIdentical(TypeRelation *relation, const ETSTupleType *other) const; + const ArenaVector typeList_; ETSObjectType *wrapperType_; }; diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index fc29b8b98bf89d84e7ae688abce1ec1f7798dad9..2bbdf54442f4f6e4e746f7b52b6a3795a33aedc4 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -14,9 +14,10 @@ */ #include +#include "etsObjectType.h" #include "etsUnionType.h" - #include "checker/ets/conversion.h" +#include "checker/types/ets/etsTupleType.h" #include "checker/types/globalTypesHolder.h" #include "checker/ETSchecker.h" @@ -377,6 +378,25 @@ bool ETSUnionType::IsAssignableType(checker::Type *sourceType) const noexcept return false; } +checker::Type *ETSUnionType::HandleNumericPrecedence( + checker::ETSChecker *checker, checker::ETSObjectType *objectType, checker::Type *sourceType, + std::map &numericTypes) const noexcept +{ + auto const sourceId = + (objectType != nullptr) ? ETSObjectType::GetPrecedence(checker, objectType) : Type::GetPrecedence(sourceType); + if (sourceId > 0U) { + for (auto const [id, type] : numericTypes) { + if (id >= sourceId) { + return type; + } + } + if (sourceType->IsConstantType() && !numericTypes.empty()) { + return numericTypes.begin()->second; + } + } + return nullptr; +} + // NOTE! When calling this method we assume that 'AssignmentTarget(...)' check was passes successfully, // thus the required assignable type always exists. checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, checker::Type *sourceType) const noexcept @@ -385,34 +405,37 @@ checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, che return sourceType; } - auto *objectType = sourceType->IsETSObjectType() ? sourceType->AsETSObjectType() : nullptr; - if (objectType != nullptr && (!objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE) || - objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_STRING))) { - // NOTE: here wo don't cast the actual type to possible base type using in the union, but use it as is! - return sourceType; - } - + auto *objectType = sourceType->IsETSObjectType() ? sourceType->AsETSObjectType() + : sourceType->IsETSTupleType() ? sourceType->AsETSTupleType()->GetWrapperType() + : nullptr; std::map numericTypes {}; bool const isBool = objectType != nullptr ? objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN) : sourceType->HasTypeFlag(TypeFlag::ETS_BOOLEAN); bool const isChar = objectType != nullptr ? objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR) : sourceType->HasTypeFlag(TypeFlag::CHAR); + + if (objectType != nullptr) { + if (objectType->IsETSResizableArrayType() || sourceType->IsETSTupleType()) { + checker::Type *assignableType = GetAssignableBuiltinType(checker, objectType, isBool, isChar, numericTypes); + // NOTE: For array and tuple types, they may be readonly, so we cannot simply use the it + if (assignableType != nullptr && assignableType->HasTypeFlag(TypeFlag::READONLY)) { + return assignableType; + } + } + if ((!objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE) || + objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_STRING))) { + // NOTE: here wo don't cast the actual type to possible base type using in the union, but use it as is! + return sourceType; + } + } + if (checker::Type *assignableType = GetAssignableBuiltinType(checker, objectType, isBool, isChar, numericTypes); assignableType != nullptr) { return assignableType; } - if (auto const sourceId = - objectType != nullptr ? ETSObjectType::GetPrecedence(checker, objectType) : Type::GetPrecedence(sourceType); - sourceId > 0U) { - for (auto const [id, type] : numericTypes) { - if (id >= sourceId) { - return type; - } - } - if (sourceType->IsConstantType() && !numericTypes.empty()) { - return numericTypes.begin()->second; - } + if (auto *assignableType = HandleNumericPrecedence(checker, objectType, sourceType, numericTypes)) { + return assignableType; } for (auto *constituentType : constituentTypes_) { @@ -431,11 +454,12 @@ checker::Type *ETSUnionType::GetAssignableBuiltinType( checker::Type *assignableType = nullptr; for (auto *constituentType : constituentTypes_) { - if (!constituentType->IsETSObjectType()) { + if (!constituentType->IsETSObjectType() && !constituentType->IsETSTupleType()) { continue; } - auto *const type = constituentType->AsETSObjectType(); + auto *const type = constituentType->IsETSTupleType() ? constituentType->AsETSTupleType()->GetWrapperType() + : constituentType->AsETSObjectType(); if (type->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN)) { if (isBool) { assignableType = constituentType; diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index d38376a8f827c8faddfbaa7e779b88bcd65226e3..12ae980aec9d686f2561d43f4309aec0d3710229 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -74,6 +74,9 @@ public: return std::all_of(constituentTypes_.cbegin(), constituentTypes_.cend(), p); } + checker::Type *HandleNumericPrecedence(checker::ETSChecker *checker, checker::ETSObjectType *objectType, + checker::Type *sourceType, + std::map &numericTypes) const noexcept; [[nodiscard]] checker::Type *GetAssignableType(ETSChecker *checker, checker::Type *sourceType) const noexcept; [[nodiscard]] std::pair GetComplimentaryType(ETSChecker *checker, checker::Type *sourceType); diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index 5f592559743f774d68753ab09afb721d77d5e545..2a7bf8a2f9be59a6169df8fabe0274e5ba620e28 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -33,6 +33,9 @@ RelationResult TypeRelation::CacheLookup(const Type *source, const Type *target, return result_; } + ES2PANDA_ASSERT(source != nullptr); + ES2PANDA_ASSERT(target != nullptr); + RelationKey relationKey {source->Id(), target->Id()}; auto res = holder.cached.find(relationKey); if (res == holder.cached.end()) { @@ -237,6 +240,10 @@ bool TypeRelation::IsSupertypeOf(Type *super, Type *sub) return Result(true); } + if (sub == nullptr) { + return false; + } + result_ = CacheLookup(super, sub, checker_->SupertypeResults(), RelationType::SUPERTYPE); if (result_ == RelationResult::CACHE_MISS) { if (IsIdenticalTo(super, sub)) { diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index efe0fbb8cb6b7d83ab6029830d8999e0fa0e1edc..2a24c1055fafb7859c77904e16dc5c56115b9e2b 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -776,7 +776,7 @@ void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calle // NOTE: need to refactor: type of member expression object can be obtained via // me->ObjType() or me->Object()->TsType() and they may differ!!!! } else if (me->ObjType() == etsg->Checker()->GlobalETSObjectType() && - me->Object()->TsType()->IsETSUnionType()) { + (etsg->Checker()->GetApparentType(me->Object()->TsType())->IsETSUnionType())) { etsg->CallByName(expr, signature, calleeReg, expr->Arguments()); } else { etsg->CallVirtual(expr, signature, calleeReg, expr->Arguments()); @@ -1426,13 +1426,17 @@ void ETSCompiler::Compile(const ir::ReturnStatement *st) const if (argument->IsCallExpression() && argument->AsCallExpression()->Signature()->ReturnType()->IsETSVoidType()) { argument->Compile(etsg); - if (isAsyncImpl) { - etsg->LoadAccumulatorUndefined(st); + if (etsg->ReturnType()->IsETSVoidType()) { + if (isAsyncImpl) { + etsg->LoadAccumulatorUndefined(st); + etsg->ReturnAcc(st); + } else { + etsg->EmitReturnVoid(st); + } + } else { + etsg->LoadDefaultValue(st, etsg->ReturnType()); etsg->ReturnAcc(st); - return; } - - etsg->EmitReturnVoid(st); return; } diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index 64ae2b8a6a39ff937680ca06d761b2b41adb72e1..0237060a4244f20fe488a4d88a06e246371c1a89 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -176,6 +176,23 @@ void ETSFunctionEmitter::GenVariableSignature(pandasm::debuginfo::LocalVariable variableDebug.signatureType = Signatures::ANY; } +void ETSFunctionEmitter::GenSourceFileDebugInfo(pandasm::Function *func) +{ + func->sourceFile = std::string {Cg()->VarBinder()->Program()->RelativeFilePath()}; + + if (!Cg()->IsDebug()) { + return; + } + + ES2PANDA_ASSERT(Cg()->RootNode()->IsScriptFunction()); + auto *fn = Cg()->RootNode()->AsScriptFunction(); + bool isInitMethod = fn->Id()->Name().Is(compiler::Signatures::INIT_METHOD); + // Write source code of whole file into debug-info of init method + if (isInitMethod) { + func->sourceCode = SourceCode().Utf8(); + } +} + void ETSFunctionEmitter::GenFunctionAnnotations([[maybe_unused]] pandasm::Function *func) {} static pandasm::Function GenExternalFunction(checker::Signature *signature, bool isCtor) diff --git a/ets2panda/compiler/core/ETSemitter.h b/ets2panda/compiler/core/ETSemitter.h index 937d81276a5b1e244daf4eeb49640cfb11dd81ae..f47d2af046eb08142095666debc0994362e22894 100644 --- a/ets2panda/compiler/core/ETSemitter.h +++ b/ets2panda/compiler/core/ETSemitter.h @@ -68,6 +68,7 @@ protected: void GenFunctionAnnotations(pandasm::Function *func) override; void GenVariableSignature(pandasm::debuginfo::LocalVariable &variableDebug, varbinder::LocalVariable *variable) const override; + void GenSourceFileDebugInfo(pandasm::Function *func) override; }; class ETSEmitter : public Emitter { diff --git a/ets2panda/compiler/core/JSemitter.cpp b/ets2panda/compiler/core/JSemitter.cpp index 8c4925497da89abff5d3320b527839018b437938..9be5a0b5c4d1b20eeefcdbfd95e79f88e0f0942a 100644 --- a/ets2panda/compiler/core/JSemitter.cpp +++ b/ets2panda/compiler/core/JSemitter.cpp @@ -51,6 +51,19 @@ void JSFunctionEmitter::GenVariableSignature(pandasm::debuginfo::LocalVariable & variableDebug.signatureType = "any"; } +void JSFunctionEmitter::GenSourceFileDebugInfo(pandasm::Function *func) +{ + func->sourceFile = std::string {Cg()->VarBinder()->Program()->RelativeFilePath()}; + + if (!Cg()->IsDebug()) { + return; + } + + if (Cg()->RootNode()->IsProgram()) { + func->sourceCode = SourceCode().EscapeSymbol(); + } +} + void JSFunctionEmitter::GenFunctionAnnotations(pandasm::Function *func) { pandasm::AnnotationData funcAnnotationData("_ESAnnotation"); diff --git a/ets2panda/compiler/core/JSemitter.h b/ets2panda/compiler/core/JSemitter.h index c49827b99c1de455a9802b656d3205222833bcb5..72b8577c06384450d2f134298b18b955ade8de27 100644 --- a/ets2panda/compiler/core/JSemitter.h +++ b/ets2panda/compiler/core/JSemitter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 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 @@ -38,6 +38,7 @@ protected: void GenFunctionAnnotations(pandasm::Function *func) override; void GenVariableSignature(pandasm::debuginfo::LocalVariable &variableDebug, varbinder::LocalVariable *variable) const override; + void GenSourceFileDebugInfo(pandasm::Function *func) override; }; class JSEmitter : public Emitter { diff --git a/ets2panda/compiler/core/emitter.cpp b/ets2panda/compiler/core/emitter.cpp index 040837e9bd339dad5e853394c3a084006a05fcba..95b7d45aee091ec90d5931fa8cacf7c17d9a676f 100644 --- a/ets2panda/compiler/core/emitter.cpp +++ b/ets2panda/compiler/core/emitter.cpp @@ -280,19 +280,6 @@ void FunctionEmitter::GenFunctionCatchTables(pandasm::Function *func) } } -void FunctionEmitter::GenSourceFileDebugInfo(pandasm::Function *func) -{ - func->sourceFile = std::string {cg_->VarBinder()->Program()->RelativeFilePath()}; - - if (!cg_->IsDebug()) { - return; - } - - if (cg_->RootNode()->IsProgram()) { - func->sourceCode = SourceCode().EscapeSymbol(); - } -} - static void GenLocalVariableInfo(pandasm::debuginfo::LocalVariable &variableDebug, varbinder::Variable *var, std::tuple info, ScriptExtension extension) { diff --git a/ets2panda/compiler/core/emitter.h b/ets2panda/compiler/core/emitter.h index aa196db845f644cc14a4c293ea2489317e68ae0a..84049be833c5801b44ffd519df33a6851417c1d1 100644 --- a/ets2panda/compiler/core/emitter.h +++ b/ets2panda/compiler/core/emitter.h @@ -74,13 +74,13 @@ protected: virtual void GenFunctionAnnotations(pandasm::Function *func) = 0; virtual void GenVariableSignature(pandasm::debuginfo::LocalVariable &variableDebug, varbinder::LocalVariable *variable) const = 0; + virtual void GenSourceFileDebugInfo(pandasm::Function *func) = 0; void GenInstructionDebugInfo(const IRNode *ins, ark::pandasm::Ins *pandaIns); void GenFunctionInstructions(pandasm::Function *func); void GenScopeVariableInfo(pandasm::Function *func, const varbinder::Scope *scope) const; void GenScopeVariableInfoEnd(pandasm::Function *func, const varbinder::Scope *scope, uint32_t count, uint32_t scopeStart, const VariablesStartsMap &starts) const; - void GenSourceFileDebugInfo(pandasm::Function *func); void GenFunctionCatchTables(ark::pandasm::Function *func); void GenVariablesDebugInfo(pandasm::Function *func); util::StringView SourceCode() const; diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index c9a93ad8c7fba0d3dc6f660ea34dfd19b0d013c9..24118c12ed91676da45fba5a322d14cacd3dc270 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -765,12 +765,28 @@ ir::AstNode *ConstantExpressionLowering::FoldMultilineString(ir::TemplateLiteral return result; } +static bool IsEnumMemberInit(ir::AstNode *node) +{ + auto parent = node->Parent(); + if (node->IsMemberExpression()) { + return node->AsMemberExpression()->Object()->IsIdentifier(); + } + + if (node->IsIdentifier()) { + if (parent->IsTSEnumMember()) { + return parent->AsTSEnumMember()->Init() == node; + } + return !parent->IsMemberExpression() && !parent->IsTSEnumDeclaration() && !parent->IsETSTypeReferencePart(); + } + + return false; +} + ir::AstNode *ConstantExpressionLowering::UnFoldEnumMemberExpression(ir::AstNode *constantNode) { ir::NodeTransformer handleUnfoldEnumMember = [this, constantNode](ir::AstNode *const node) { - if (node->IsMemberExpression() && !node->Parent()->IsMemberExpression()) { - auto memExp = node->AsMemberExpression(); - return FindAndReplaceEnumMember(memExp, constantNode); + if (IsEnumMemberInit(node) && constantNode->IsTSEnumDeclaration()) { + return FindAndReplaceEnumMember(node, constantNode); } return node; @@ -788,15 +804,13 @@ ir::AstNode *ConstantExpressionLowering::FindNameInEnumMember(ArenaVectorend()) ? *it : nullptr; } -ir::AstNode *ConstantExpressionLowering::FindAndReplaceEnumMember(ir::MemberExpression *expr, ir::AstNode *node) +ir::AstNode *ConstantExpressionLowering::FindAndReplaceEnumMember(ir::AstNode *const expr, ir::AstNode *constantNode) { - if (!expr->Object()->IsIdentifier()) { - return expr; - } - - auto objectName = expr->Object()->AsIdentifier()->Name(); - auto propertyName = expr->Property()->AsIdentifier()->Name(); - for (auto curScope = node->Scope(); curScope != nullptr; curScope = curScope->Parent()) { + auto objectName = expr->IsMemberExpression() ? expr->AsMemberExpression()->Object()->AsIdentifier()->Name() + : constantNode->AsTSEnumDeclaration()->Key()->AsIdentifier()->Name(); + auto propertyName = expr->IsMemberExpression() ? expr->AsMemberExpression()->Property()->AsIdentifier()->Name() + : expr->AsIdentifier()->Name(); + for (auto curScope = constantNode->Scope(); curScope != nullptr; curScope = curScope->Parent()) { auto *foundDecl = curScope->FindDecl(objectName); if (foundDecl == nullptr || !foundDecl->Node()->IsTSEnumDeclaration()) { continue; @@ -810,7 +824,7 @@ ir::AstNode *ConstantExpressionLowering::FindAndReplaceEnumMember(ir::MemberExpr return expr; } - auto clonedInit = transformedInit->Clone(context_->allocator, transformedInit->Parent()); + auto clonedInit = transformedInit->Clone(context_->allocator, expr->Parent()); clonedInit->SetRange(expr->Range()); return UnFoldEnumMemberExpression(clonedInit); } diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.h b/ets2panda/compiler/lowering/ets/constantExpressionLowering.h index ded999e2f82ce143995c6950da339b8a36ad5a32..06567902075de46a93aa73fff5d85d58e900cbb0 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.h +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.h @@ -106,7 +106,7 @@ private: ir::AstNode *FindNameInEnumMember(ArenaVector *members, util::StringView targetName); - ir::AstNode *FindAndReplaceEnumMember(ir::MemberExpression *expr, ir::AstNode *node); + ir::AstNode *FindAndReplaceEnumMember(ir::AstNode *expr, ir::AstNode *constantNode); ir::AstNode *UnfoldConstIdentifiers(ir::AstNode *constantNode); diff --git a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp index 4b5ff91757bb9add7804e2b5afd3815bfaf3e23e..b430e9b49fd846836ac21c3afa115025bf84a919 100644 --- a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp @@ -179,16 +179,18 @@ static void FillClassBody(public_lib::Context *ctx, ArenaVector * } } +// CC-OFFNXT(G.FUN.01-CPP) solid logic static void FillAnonClassBody(public_lib::Context *ctx, ArenaVector *classBody, ir::TSInterfaceDeclaration *ifaceNode, ir::ObjectExpression *objExpr, - ArenaVector &readonlyFields) + ArenaVector &readonlyFields, + checker::ETSObjectType *interfaceType = nullptr) { for (auto *extendedIface : ifaceNode->TsType()->AsETSObjectType()->Interfaces()) { - auto extendedIfaceBody = extendedIface->GetDeclNode()->AsTSInterfaceDeclaration()->Body()->Body(); - FillClassBody(ctx, classBody, extendedIfaceBody, objExpr, readonlyFields, extendedIface); + FillAnonClassBody(ctx, classBody, extendedIface->GetDeclNode()->AsTSInterfaceDeclaration(), objExpr, + readonlyFields, extendedIface); } - FillClassBody(ctx, classBody, ifaceNode->Body()->Body(), objExpr, readonlyFields); + FillClassBody(ctx, classBody, ifaceNode->Body()->Body(), objExpr, readonlyFields, interfaceType); } static checker::Type *GenerateAnonClassTypeFromInterface(public_lib::Context *ctx, diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index 01327be62a53b810db50636c2cbb203878a36a72..f9b848d9a14c5a46f4dc92a326606a96ff2be082 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -87,7 +87,7 @@ ir::FunctionSignature InterfacePropertyDeclarationsPhase::GenerateGetterOrSetter auto *const paramExpression = checker->AllocNode(paramIdent, false, checker->Allocator()); paramExpression->SetRange(paramIdent->Range()); - auto [paramVar, node] = paramScope->AddParamDecl(checker->Allocator(), paramExpression); + auto [paramVar, node] = paramScope->AddParamDecl(checker->Allocator(), varbinder, paramExpression); if (node != nullptr) { varbinder->ThrowRedeclaration(node->Start(), paramVar->Name()); } diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 1f4fc3dedb684f2fbcb6bf4d05353cf99e309363..4ea83a9a6e196649dfa3ad3591233c4d4118dd9e 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -996,6 +996,7 @@ static ir::AstNode *ConvertFunctionReference(public_lib::Context *ctx, ir::Expre var = mexpr->Object()->TsType()->AsETSObjectType()->GetProperty( mexpr->Property()->AsIdentifier()->Name(), checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | checker::PropertySearchFlags::SEARCH_STATIC_METHOD | + checker::PropertySearchFlags::SEARCH_IN_BASE | checker::PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION); ES2PANDA_ASSERT(var != nullptr); } @@ -1037,7 +1038,7 @@ static bool IsVariableOriginalAccessor(const varbinder::Variable *var) return checker::ETSChecker::IsVariableGetterSetter(var) && !(checker::ETSChecker::IsVariableExtensionAccessor(var)); } -static bool IsFunctionOrMethodCall(ir::CallExpression const *node) +static bool IsFunctionOrMethodCall(checker::ETSChecker *checker, ir::CallExpression const *node) { auto const *callee = node->Callee(); if (callee->TsType() != nullptr && callee->TsType()->IsETSExtensionFuncHelperType()) { @@ -1048,7 +1049,7 @@ static bool IsFunctionOrMethodCall(ir::CallExpression const *node) // Not skip if invoke pattern Union.() where field is of ETSArrowType if (callee->IsMemberExpression()) { auto me = callee->AsMemberExpression(); - if (me->Object()->TsType() != nullptr && me->Object()->TsType()->IsETSUnionType() && + if (me->Object()->TsType() != nullptr && checker->GetApparentType(me->Object()->TsType())->IsETSUnionType() && me->TsType()->IsETSMethodType()) { return true; } @@ -1165,7 +1166,7 @@ static ir::AstNode *BuildLambdaClassWhenNeeded(public_lib::Context *ctx, ir::Ast auto *var = mexpr->Object()->TsType()->AsETSObjectType()->GetProperty( mexpr->Property()->AsIdentifier()->Name(), checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | - checker::PropertySearchFlags::SEARCH_STATIC_METHOD | + checker::PropertySearchFlags::SEARCH_STATIC_METHOD | checker::PropertySearchFlags::SEARCH_IN_BASE | checker::PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION); if (IsValidFunctionDeclVar(var) && !IsInCalleePosition(mexpr)) { return ConvertFunctionReference(ctx, mexpr); @@ -1214,7 +1215,8 @@ bool LambdaConversionPhase::PerformForModule(public_lib::Context *ctx, parser::P [ctx](ir::AstNode *node) { return LowerTypeNodeIfNeeded(ctx, node); }, Name()); auto insertInvokeIfNeeded = [ctx](ir::AstNode *node) { - if (node->IsCallExpression() && !IsFunctionOrMethodCall(node->AsCallExpression()) && + if (node->IsCallExpression() && + !IsFunctionOrMethodCall(ctx->checker->AsETSChecker(), node->AsCallExpression()) && !IsRedirectingConstructorCall(node->AsCallExpression())) { return InsertInvokeCall(ctx, node->AsCallExpression()); } diff --git a/ets2panda/compiler/lowering/ets/opAssignment.cpp b/ets2panda/compiler/lowering/ets/opAssignment.cpp index c56811b38705b5c263e4121c8fe2a1b883490452..38a9d0b4c13f82f50d7c8633a9e218d513842af6 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.cpp +++ b/ets2panda/compiler/lowering/ets/opAssignment.cpp @@ -196,7 +196,23 @@ static std::tuple> GenerateNestedMemb return {newAssignmentStatements, newAssignmentExpressions}; } -static ir::Expression *GenerateStringForLoweredAssignment( +static std::tuple> GenerateStringForAssignment( + const lexer::TokenType opEqual, ir::MemberExpression *expr, ArenaAllocator *const allocator, size_t counter) +{ + // Note: Handle "A `opAssign` B" to "A = (A `operation` B) as T" + // opAssign is the operation like: "+=", "-=", "*=", "/=", etc., + // operation is the operation like: "+", "-", "*", "/", etc. + auto [retStr, retVec] = GenerateNestedMemberAccess(expr, allocator, counter); + counter += retVec.size(); + auto result = GenerateNestedMemberAccess(expr, allocator, counter); + counter += std::get<1>(result).size(); + retStr += " = ( " + std::get<0>(result) + ' ' + std::string {lexer::TokenToString(CombinedOpToOp(opEqual))} + + " (@@E" + std::to_string(counter) + ")) as @@T" + std::to_string(counter + 1); + retVec.insert(retVec.end(), std::get<1>(result).begin(), std::get<1>(result).end()); + return {retStr, retVec}; +} + +static ir::Expression *GenerateLoweredResultForLoweredAssignment( const lexer::TokenType opEqual, ir::MemberExpression *expr, ArenaAllocator *const allocator, parser::ETSParser *parser, const std::array additionalAssignmentExpressions) { @@ -206,14 +222,29 @@ static ir::Expression *GenerateStringForLoweredAssignment( // `operation` is the operation of the assignment like: "+", "-", "*", "/", etc., // B is the right hand side of the assignment // T is the type of the left hand side of the assignment - size_t counter = 1; - auto [retStr, retVec] = GenerateNestedMemberAccess(expr, allocator, counter); - counter += retVec.size(); - auto result = GenerateNestedMemberAccess(expr, allocator, counter); - counter += std::get<1>(result).size(); - retStr += " = ( " + std::get<0>(result) + ' ' + std::string {lexer::TokenToString(CombinedOpToOp(opEqual))} + - " (@@E" + std::to_string(counter) + ")) as @@T" + std::to_string(counter + 1); - retVec.insert(retVec.end(), std::get<1>(result).begin(), std::get<1>(result).end()); + if (expr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS && !expr->Property()->IsLiteral()) { + // Note: support such a situation could be okay: `a[idx++] += someExpr`. + // It should be lowered as: `let dummyIdx = (lower result of `idx++`); a[dummyIdx] = a[dummyIdx] + someExpr`; + ArenaVector dummyIndexDeclExpression(allocator->Adapter()); + std::string dummyIndexDeclStr = "let @@I1 = @@E2;\n"; + auto dummyIndex = Gensym(allocator); + dummyIndexDeclExpression.emplace_back(dummyIndex); + dummyIndexDeclExpression.emplace_back(expr->Property()->Clone(allocator, nullptr)->AsExpression()); + ClearTypesVariablesAndScopes(dummyIndexDeclExpression[1]); + + // Note: Drop the old property, substitute it with dummyIdx. + expr->Property()->SetParent(nullptr); + expr->SetProperty(dummyIndex->Clone(allocator, expr)); + auto [retStr, retVec] = + GenerateStringForAssignment(opEqual, expr, allocator, dummyIndexDeclExpression.size() + 1); + retVec.push_back(additionalAssignmentExpressions[0]); + retVec.push_back(additionalAssignmentExpressions[1]); + retVec.insert(retVec.begin(), dummyIndexDeclExpression.begin(), dummyIndexDeclExpression.end()); + retStr = dummyIndexDeclStr + retStr; + return parser->CreateFormattedExpression(retStr, retVec); + } + + auto [retStr, retVec] = GenerateStringForAssignment(opEqual, expr, allocator, 1); retVec.push_back(additionalAssignmentExpressions[0]); retVec.push_back(additionalAssignmentExpressions[1]); return parser->CreateFormattedExpression(retStr, retVec); @@ -242,8 +273,8 @@ static ir::Expression *ConstructOpAssignmentResult(public_lib::Context *ctx, ir: GetClone(allocator, left->AsIdentifier()), right, exprType); } else if (left->IsMemberExpression()) { // Generate ArkTS code string for new lowered assignment expression: - retVal = GenerateStringForLoweredAssignment(opEqual, left->AsMemberExpression(), allocator, parser, - {right, exprType}); + retVal = GenerateLoweredResultForLoweredAssignment(opEqual, left->AsMemberExpression(), allocator, parser, + {right, exprType}); } else { ES2PANDA_UNREACHABLE(); } diff --git a/ets2panda/compiler/lowering/ets/packageImplicitImport.cpp b/ets2panda/compiler/lowering/ets/packageImplicitImport.cpp index 0f1f93533706c5d7e0247c7294efdc8929f4ebac..104d9083acb8e3f5f24af5f42694b0aeea709c08 100644 --- a/ets2panda/compiler/lowering/ets/packageImplicitImport.cpp +++ b/ets2panda/compiler/lowering/ets/packageImplicitImport.cpp @@ -46,7 +46,8 @@ static void ValidateFolderContainOnlySamePackageFiles(const public_lib::Context return; } - if ((prog1->ModuleName() != prog2->ModuleName()) && (prog1->SourceFileFolder() == prog2->SourceFileFolder())) { + if ((prog1->ModuleName() != prog2->ModuleName()) && + (prog1->SourceFile().GetAbsoluteParentFolder() == prog2->SourceFile().GetAbsoluteParentFolder())) { // There exist 2 files in the same folder, with different package names // // Showing the full path would be more informative, but it also leaks it to the stdout, which is diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index 8b94066abc4b3066510708c306752c44274da83b..537de9bed0fa1dcc7a6f0811eb20c4f7a28981a4 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -77,7 +77,8 @@ static ir::ClassDefinition *GetUnionAccessClass(checker::ETSChecker *checker, va } static std::tuple CreateNamedAccessMethod( - checker::ETSChecker *checker, varbinder::VarBinder *varbinder, ir::MemberExpression *expr) + checker::ETSChecker *checker, varbinder::VarBinder *varbinder, ir::MemberExpression *expr, + checker::Signature *signature) { auto allocator = checker->Allocator(); auto unionType = checker->GetApparentType(checker->GetNonNullishType(expr->Object()->TsType()))->AsETSUnionType(); @@ -87,14 +88,11 @@ static std::tuple CreateNamedA // Create method name for synthetic class auto *methodIdent = checker->AllocNode(methodName, allocator); - // Create the synthetic function node - auto *sig = expr->Parent()->AsCallExpression()->Signature(); - ArenaVector params {allocator->Adapter()}; - for (auto param : sig->Function()->Params()) { + for (auto param : signature->Function()->Params()) { params.emplace_back(param->Clone(allocator, nullptr)->AsETSParameterExpression()); } - auto returnTypeAnno = checker->AllocNode(sig->ReturnType(), allocator); + auto returnTypeAnno = checker->AllocNode(signature->ReturnType(), allocator); auto *func = checker->AllocNode( allocator, ir::ScriptFunction::ScriptFunctionData { @@ -174,14 +172,10 @@ static varbinder::LocalVariable *CreateNamedAccess(checker::ETSChecker *checker, // arrow type fields should be processed as property access not method invocation if (type->IsETSMethodType() && !type->IsETSArrowType()) { - if (type->AsETSFunctionType()->CallSignatures().size() != 1) { - checker->LogError(diagnostic::UNION_METHOD_SIGNATURE, {}, expr->Start()); - } - auto parent = expr->Parent(); - ES2PANDA_ASSERT(parent->IsCallExpression() && parent->AsCallExpression()->Callee() == expr && - parent->AsCallExpression()->Signature()->HasFunction()); - auto [var, sig] = CreateNamedAccessMethod(checker, varbinder, expr); - ES2PANDA_ASSERT(parent->IsCallExpression()); + auto parent = expr->Parent()->AsCallExpression(); + ES2PANDA_ASSERT(parent->Callee() == expr && parent->Signature()->HasFunction()); + + auto [var, sig] = CreateNamedAccessMethod(checker, varbinder, expr, parent->Signature()); parent->AsCallExpression()->SetSignature(sig); return var; } diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index a177e3b7790a00b0a9f7abc84f9d69ec105af1db..4d386ae30be6f0a5da0bef32d1780020182a0182 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -233,7 +233,7 @@ void ScopesInitPhase::VisitCatchClause(ir::CatchClause *catchClause) void ScopesInitPhase::VisitVariableDeclarator(ir::VariableDeclarator *varDecl) { auto init = varDecl->Id(); - std::vector bindings = util::Helpers::CollectBindingNames(init); + std::vector bindings = util::Helpers::CollectBindingNames(VarBinder(), init); for (auto *binding : bindings) { auto [decl, var] = AddOrGetVarDecl(varDecl->Flag(), binding); BindVarDecl(binding, init, decl, var); diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index ffc327cc477de14ac8bdd526bdf26d4ff64dae47..df42c1787c3cf8dd68335b33481d183d789bb7fd 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -170,6 +170,36 @@ defines: ref: BUILTIN_RETENTION - name: 'Symbol' ref: SYMBOL + - name: 'escompat.Array' + ref: ESCOMPAT_ARRAY + - name: 'ByteType.VAL' + ref: BYTETYPE_VAL + - name: 'IntType.VAL' + ref: INTTYPE_VAL + - name: 'LongType.VAL' + ref: LONGTYPE_VAL + - name: 'ShortType.VAL' + ref: SHORTTYPE_VAL + - name: 'FloatType.VAL' + ref: FLOATTYPE_VAL + - name: 'DoubleType.VAL' + ref: DOUBLETYPE_VAL + - name: 'BooleanType.VAL' + ref: BOOLEANTYPE_VAL + - name: 'CharType.VAL' + ref: CHARTYPE_VAL + - name: 'VoidType.VAL' + ref: VOIDTYPE_VAL + - name: 'UndefinedType.REF' + ref: UNDEFINEDTYPE_REF + - name: 'NullType.REF' + ref: NULLTYPE_REF + - name: 'Type' + ref: TYPE + - name: 'from' + ref: FROM + - name: 'Numeric' + ref: NUMERIC packages: - name: 'std.core' diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp index 8cdf9344ac6f8983bfa5191b1718d5c17167ebb6..6255e84e5cc1982ffaa1b40b724d6a5158077b14 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp @@ -106,32 +106,37 @@ void TSDeclGen::ProcessTypeAliasDependencies(const ir::TSTypeAliasDeclaration *t void TSDeclGen::ProcessTypeAnnotationDependencies(const ir::TypeNode *typeAnnotation) { - if (!typeAnnotation->IsETSTypeReference() || - !typeAnnotation->AsETSTypeReference()->Part()->Name()->IsIdentifier()) { - return; - } - - const auto part = typeAnnotation->AsETSTypeReference()->Part(); - const auto partParams = part->TypeParams(); - if (partParams == nullptr) { + if (typeAnnotation->IsETSTypeReference()) { + ProcessETSTypeReferenceDependencies(typeAnnotation->AsETSTypeReference()); return; + } else if (typeAnnotation->IsETSUnionType()) { + GenSeparated( + typeAnnotation->AsETSUnionType()->Types(), + [this](ir::TypeNode *arg) { ProcessTypeAnnotationDependencies(arg); }, ""); } +} - const auto typeParams = partParams->AsTSTypeParameterInstantiation(); - if (typeParams == nullptr) { +void TSDeclGen::ProcessETSTypeReferenceDependencies(const ir::ETSTypeReference *typeReference) +{ + const auto part = typeReference->Part(); + auto partName = part->GetIdent()->Name().Mutf8(); + if (part->TypeParams() != nullptr && part->TypeParams()->IsTSTypeParameterInstantiation()) { + indirectDependencyObjects_.insert(partName); + GenSeparated( + part->TypeParams()->Params(), [this](ir::TypeNode *param) { ProcessTypeAnnotationDependencies(param); }, + ""); return; + } else if (part->Name()->IsTSQualifiedName() && part->Name()->AsTSQualifiedName()->Name() != nullptr) { + const auto qualifiedName = part->Name()->AsTSQualifiedName()->Name().Mutf8(); + std::istringstream stream(qualifiedName.data()); + std::string firstSegment; + if (std::getline(stream, firstSegment, '.')) { + importSet_.insert(firstSegment); + indirectDependencyObjects_.insert(firstSegment); + } + } else { + indirectDependencyObjects_.insert(partName); } - - GenSeparated( - typeParams->Params(), - [this](ir::TypeNode *param) { - if (param->IsETSTypeReference() && param->AsETSTypeReference()->Part()->Name()->IsIdentifier()) { - const auto paramName = param->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Name().Mutf8(); - importSet_.insert(paramName); - indirectDependencyObjects_.insert(paramName); - } - }, - ""); } void TSDeclGen::ProcessClassDependencies(const ir::ClassDeclaration *classDecl) @@ -163,21 +168,38 @@ void TSDeclGen::ProcessClassDependencies(const ir::ClassDeclaration *classDecl) ""); } - GenSeparated( - classDef->Body(), [this](ir::AstNode *prop) { ProcessClassPropDependencies(prop); }, ""); + ProcessClassPropDependencies(classDef); } -void TSDeclGen::ProcessClassPropDependencies(const ir::AstNode *prop) +void TSDeclGen::ProcessClassPropDependencies(const ir::ClassDefinition *classDef) { - if (prop->IsClassProperty() && prop->AsClassProperty()->Value() != nullptr) { - AddSuperType(prop->AsClassProperty()->Value()); - } else if (prop->IsMethodDefinition()) { - ProcessClassMethodDependencies(prop->AsMethodDefinition()); + for (const auto *prop : classDef->Body()) { + if (prop->IsClassProperty()) { + auto value = prop->AsClassProperty()->Value(); + if (value != nullptr && value->IsETSNewClassInstanceExpression() && + value->AsETSNewClassInstanceExpression()->GetTypeRef() != nullptr && + value->AsETSNewClassInstanceExpression()->GetTypeRef()->IsETSTypeReference()) { + auto typeReference = value->AsETSNewClassInstanceExpression()->GetTypeRef()->AsETSTypeReference(); + ProcessETSTypeReferenceDependencies(typeReference); + continue; + } + if (prop->AsClassProperty()->TypeAnnotation() != nullptr) { + ProcessTypeAnnotationDependencies(prop->AsClassProperty()->TypeAnnotation()); + continue; + } + } else if (prop->IsMethodDefinition()) { + ProcessClassMethodDependencies(prop->AsMethodDefinition()); + } else if (prop->IsClassDeclaration() && classDef->IsNamespaceTransformed()) { + ProcessClassDependencies(prop->AsClassDeclaration()); + } } } void TSDeclGen::ProcessClassMethodDependencies(const ir::MethodDefinition *methodDef) { + if (!methodDef->IsExported() && !methodDef->IsExportedType() && !methodDef->IsDefaultExported()) { + return; + } auto sig = methodDef->Function()->Signature(); GenSeparated( sig->Params(), [this](varbinder::LocalVariable *param) { AddSuperType(param->TsType()); }, ""); @@ -508,17 +530,32 @@ const checker::Signature *TSDeclGen::GetFuncSignature(const checker::ETSFunction return etsFunctionType->CallSignatures()[0]; } -void TSDeclGen::ProcessFuncParameter(varbinder::LocalVariable *param) +void TSDeclGen::ProcessParameterName(varbinder::LocalVariable *param) { - if (std::string(param->Name()).find("") != std::string::npos) { - return; - } + const auto *paramDeclNode = param->Declaration()->Node(); + const std::string prefix = "gensym%%_"; + if (!paramDefaultMap_.empty() && paramDefaultMap_.find(param->Name()) != paramDefaultMap_.end()) { OutDts(paramDefaultMap_[param->Name()]); paramDefaultMap_.erase(param->Name()); + } else if (param->Name().Is("=t")) { + OutDts("this"); + } else if (paramDeclNode->IsETSParameterExpression() && paramDeclNode->AsETSParameterExpression()->IsOptional() && + paramDeclNode->AsETSParameterExpression()->Name().StartsWith(prefix)) { + OutDts("arg", param->Name().Mutf8().substr(prefix.size())); } else { - OutDts(param->Name().Is("=t") ? "this" : param->Name()); + OutDts(param->Name()); } +} + +void TSDeclGen::ProcessFuncParameter(varbinder::LocalVariable *param) +{ + if (std::string(param->Name()).find("") != std::string::npos) { + return; + } + + ProcessParameterName(param); + const auto *paramType = param->TsType(); const auto *paramDeclNode = param->Declaration()->Node(); @@ -536,15 +573,15 @@ void TSDeclGen::ProcessFuncParameter(varbinder::LocalVariable *param) OutDts(": "); const auto *typeAnnotation = expr->TypeAnnotation(); - if (typeAnnotation == nullptr) { - GenType(paramType); - return; - } - if (expr->IsOptional()) { - GenType(typeAnnotation->TsType()); + if (typeAnnotation != nullptr) { + if (expr->IsOptional()) { + ProcessTypeAnnotationType(typeAnnotation); + return; + } + ProcessTypeAnnotationType(typeAnnotation, paramType); return; } - ProcessTypeAnnotationType(typeAnnotation, paramType); + OutDts("any"); } void TSDeclGen::ProcessFuncParameters(const checker::Signature *sig) @@ -609,13 +646,18 @@ void TSDeclGen::ProcessFunctionReturnType(const checker::Signature *sig) return; } - const auto param = sig->Function()->Params(); - if (!param.empty() && param.size() == 1 && param.at(0)->IsETSParameterExpression() && - param.at(0)->AsETSParameterExpression()->Ident()->TypeAnnotation() != nullptr && - sig->HasSignatureFlag(checker::SignatureFlags::SETTER)) { - ProcessTypeAnnotationType(param.at(0)->AsETSParameterExpression()->Ident()->TypeAnnotation(), - sig->Params()[0]->TsType()); - return; + if (sig->HasSignatureFlag(checker::SignatureFlags::SETTER)) { + const auto param = sig->Function()->Params(); + if (!param.empty() && param.size() == 1 && param.at(0)->IsETSParameterExpression() && + param.at(0)->AsETSParameterExpression()->Ident()->TypeAnnotation() != nullptr) { + ProcessTypeAnnotationType(param.at(0)->AsETSParameterExpression()->Ident()->TypeAnnotation(), + sig->Params()[0]->TsType()); + return; + } + if (!sig->Params().empty() && sig->Params().size() == 1) { + GenType(sig->Params()[0]->TsType()); + return; + } } GenType(sig->ReturnType()); } @@ -812,6 +854,9 @@ bool TSDeclGen::ShouldEmitDeclarationSymbol(const ir::Identifier *symbol) if (symbol->Parent()->IsExported() || symbol->Parent()->IsExportedType() || symbol->Parent()->IsDefaultExported()) { return true; } + if (state_.isDeclareNamespace) { + return true; + } if (indirectDependencyObjects_.find(symbol->Name().Mutf8()) != indirectDependencyObjects_.end()) { classNode_.isIndirect = true; return true; @@ -870,6 +915,9 @@ void TSDeclGen::GenAnnotations(const T *node) if (annotationList_.count(anno->GetBaseName()->Name().Mutf8()) == 0U) { return; } + if (!state_.inGlobalClass && (state_.inClass || state_.inInterface)) { + ProcessIndent(); + } OutDts("@", anno->GetBaseName()->Name()); GenAnnotationProperties(anno); OutEndlDts(); @@ -1084,12 +1132,30 @@ std::string TSDeclGen::ReplaceETSGLOBAL(const std::string &typeName) return globalDesc_; } +bool TSDeclGen::ProcessTSQualifiedName(const ir::ETSTypeReference *typeReference) +{ + if (typeReference->Part()->Name()->IsTSQualifiedName() && + typeReference->Part()->Name()->AsTSQualifiedName()->Name() != nullptr) { + const auto qualifiedName = typeReference->Part()->Name()->AsTSQualifiedName()->Name().Mutf8(); + std::istringstream stream(qualifiedName.data()); + std::string segment; + while (std::getline(stream, segment, '.')) { + importSet_.insert(segment); + indirectDependencyObjects_.insert(segment); + } + OutDts(qualifiedName); + return true; + } + return false; +} + void TSDeclGen::ProcessETSTypeReferenceType(const ir::ETSTypeReference *typeReference, const checker::Type *checkerType) { auto typePart = typeReference->Part(); auto partName = typePart->GetIdent()->Name().Mutf8(); importSet_.insert(partName); if (typePart->TypeParams() != nullptr && typePart->TypeParams()->IsTSTypeParameterInstantiation()) { + indirectDependencyObjects_.insert(partName); if (partName == "FixedArray") { GenSeparated(typePart->TypeParams()->Params(), [this](ir::TypeNode *param) { ProcessTypeAnnotationType(param, param->GetType(checker_)); }); @@ -1101,15 +1167,8 @@ void TSDeclGen::ProcessETSTypeReferenceType(const ir::ETSTypeReference *typeRefe GenSeparated(typePart->TypeParams()->Params(), [this](ir::TypeNode *param) { ProcessTypeAnnotationType(param, param->GetType(checker_)); }); OutDts(">"); - } else if (typePart->Name()->IsTSQualifiedName() && typePart->Name()->AsTSQualifiedName()->Name() != nullptr) { - const auto qualifiedName = typePart->Name()->AsTSQualifiedName()->Name().Mutf8(); - std::istringstream stream(qualifiedName.data()); - std::string segment; - while (std::getline(stream, segment, '.')) { - importSet_.insert(segment); - indirectDependencyObjects_.insert(segment); - } - OutDts(qualifiedName); + } else if (ProcessTSQualifiedName(typeReference)) { + return; } else if (checkerType != nullptr && checkerType->IsETSFunctionType()) { indirectDependencyObjects_.insert(partName); OutDts(partName); @@ -1127,6 +1186,7 @@ bool TSDeclGen::ProcessTypeAnnotationSpecificTypes(const checker::Type *checkerT } importSet_.insert(checkerType->ToString()); + indirectDependencyObjects_.insert(checkerType->ToString()); if (HandleBasicTypes(checkerType)) { return true; } @@ -1187,6 +1247,9 @@ void TSDeclGen::ProcessTypeAnnotationType(const ir::TypeNode *typeAnnotation, co void TSDeclGen::ProcessETSTypeReference(const ir::TypeNode *typeAnnotation, const checker::Type *checkerType) { + if (ProcessTSQualifiedName(typeAnnotation->AsETSTypeReference())) { + return; + } if (ProcessTypeAnnotationSpecificTypes(checkerType)) { return; } @@ -1237,6 +1300,11 @@ void TSDeclGen::GenTypeAliasDeclaration(const ir::TSTypeAliasDeclaration *typeAl if (!ShouldEmitDeclarationSymbol(typeAlias->Id())) { return; } + if (state_.inClass) { + auto indent = GetIndent(); + OutDts(indent); + OutTs(indent); + } GenAnnotations(typeAlias); if (classNode_.isIndirect || state_.inNamespace || typeAlias->IsDefaultExported()) { OutDts("type ", name); @@ -1295,7 +1363,6 @@ void TSDeclGen::GenEnumDeclaration(const ir::ClassProperty *enumMember) void TSDeclGen::GenInterfaceDeclaration(const ir::TSInterfaceDeclaration *interfaceDecl) { - state_.inInterface = true; const auto interfaceName = interfaceDecl->Id()->Name().Mutf8(); DebugPrint("GenInterfaceDeclaration: " + interfaceName); if (interfaceName.find("$partial") != std::string::npos) { @@ -1305,6 +1372,7 @@ void TSDeclGen::GenInterfaceDeclaration(const ir::TSInterfaceDeclaration *interf return; } GenAnnotations(interfaceDecl); + state_.inInterface = true; if (classNode_.isIndirect) { OutDts(state_.isInterfaceInNamespace ? "interface " : "declare interface ", interfaceName); } else if (!interfaceDecl->IsDefaultExported()) { @@ -1314,10 +1382,22 @@ void TSDeclGen::GenInterfaceDeclaration(const ir::TSInterfaceDeclaration *interf } GenTypeParameters(interfaceDecl->TypeParams()); + if (!interfaceDecl->Extends().empty()) { + OutDts(" extends "); + GenSeparated(interfaceDecl->Extends(), [this](ir::TSInterfaceHeritage *param) { + if (param->Expr()->IsETSTypeReference()) { + ProcessETSTypeReferenceType(param->Expr()->AsETSTypeReference()); + } + }); + } OutDts(" {"); OutEndlDts(); ProcessInterfaceBody(interfaceDecl->Body()); + if (state_.isInterfaceInNamespace) { + classNode_.indentLevel--; + OutDts(GetIndent()); + } OutDts("}"); OutEndlDts(); } @@ -1343,8 +1423,8 @@ void TSDeclGen::ProcessMethodDefinition(const ir::MethodDefinition *methodDef, } if (methodDef->IsGetter() || methodDef->IsSetter()) { GenMethodDeclaration(methodDef); + processedMethods.insert(methodName); } - processedMethods.insert(methodName); if (!methodDef->Overloads().empty()) { for (const auto *overloadMethd : methodDef->Overloads()) { if (overloadMethd->IsGetter() || overloadMethd->IsSetter()) { @@ -1355,6 +1435,7 @@ void TSDeclGen::ProcessMethodDefinition(const ir::MethodDefinition *methodDef, } if (!methodDef->IsGetter() && !methodDef->IsSetter()) { GenMethodDeclaration(methodDef); + processedMethods.insert(methodName); } } @@ -1367,6 +1448,7 @@ void TSDeclGen::PrepareClassDeclaration(const ir::ClassDefinition *classDef) if (classDef->IsNamespaceTransformed()) { state_.inNamespace = true; state_.isClassInNamespace = false; + state_.isDeclareNamespace = classDef->IsDeclare(); } else { state_.isClassInNamespace = true; } @@ -1380,40 +1462,32 @@ bool TSDeclGen::ShouldSkipClassDeclaration(const std::string_view &className) co className == compiler::Signatures::JSCALL_CLASS || (className.find("$partial") != std::string::npos); } +void TSDeclGen::EmitDeclarationPrefix(const ir::ClassDefinition *classDef, const std::string &typeName, + const std::string_view &className) +{ + if (classDef->IsDefaultExported()) { + OutDts(classNode_.indentLevel > 1 ? typeName : "declare " + typeName, className); + } else if (classDef->IsExported() || declgenOptions_.exportAll) { + OutDts(classNode_.indentLevel > 1 ? typeName : "export declare " + typeName, className); + } else { + OutDts(classNode_.indentLevel > 1 ? typeName : "declare " + typeName, className); + } +} + void TSDeclGen::EmitClassDeclaration(const ir::ClassDefinition *classDef, const std::string_view &className) { if (classDef->IsNamespaceTransformed()) { - if (classDef->IsDefaultExported()) { - OutDts("declare namespace ", className); - } else { - OutDts(classNode_.indentLevel > 1 ? "namespace " : "export declare namespace ", className); - } + EmitDeclarationPrefix(classDef, "namespace ", className); OutTs("export namespace ", className, " {"); } else if (classDef->IsEnumTransformed()) { - if (classDef->IsDefaultExported()) { - OutDts("declare enum ", className); - } else { - OutDts(classNode_.indentLevel > 1 ? "enum " : "export declare enum ", className); - } + EmitDeclarationPrefix(classDef, "enum ", className); OutTs("export const enum ", className, " {"); } else if (classDef->IsFromStruct()) { - if (classDef->IsDefaultExported()) { - OutDts("declare struct ", className); - } else { - OutDts(classNode_.indentLevel > 1 ? "struct " : "export declare struct ", className); - } - } else if (classNode_.isIndirect) { - OutDts("declare class ", className); + EmitDeclarationPrefix(classDef, "struct ", className); } else if (classDef->IsAbstract()) { - if (classDef->IsDefaultExported()) { - OutDts("export default abstract class ", className); - } else { - OutDts("export declare abstract class ", className); - } - } else if (classDef->IsDefaultExported()) { - OutDts("export default class ", className); + EmitDeclarationPrefix(classDef, "abstract class ", className); } else { - OutDts(classNode_.indentLevel > 1 ? "class " : "export declare class ", className); + EmitDeclarationPrefix(classDef, "class ", className); } OutEndlTs(); } @@ -1442,7 +1516,9 @@ void TSDeclGen::GenPartName(std::string &partName) void TSDeclGen::ProcessIndent() { - if (classNode_.hasNestedClass || state_.inNamespace || state_.inEnum) { + if (state_.isInterfaceInNamespace) { + OutDts(GetIndent()); + } else if (classNode_.hasNestedClass || state_.inNamespace || state_.inEnum) { auto indent = GetIndent(); OutDts(indent); OutTs(indent); @@ -1453,10 +1529,15 @@ void TSDeclGen::ProcessIndent() void TSDeclGen::HandleClassDeclarationTypeInfo(const ir::ClassDefinition *classDef, const std::string_view &className) { - if (!ShouldEmitDeclarationSymbol(classDef->Ident())) { - return; + if (classNode_.hasNestedClass) { + classNode_.indentLevel--; + ES2PANDA_ASSERT(classNode_.indentLevel != static_cast(-1)); } GenAnnotations(classDef); + if (classNode_.hasNestedClass) { + OutDts(GetIndent()); + classNode_.indentLevel++; + } EmitClassDeclaration(classDef, className); GenTypeParameters(classDef->TypeParams()); @@ -1505,8 +1586,26 @@ void TSDeclGen::EmitClassGlueCode(const ir::ClassDefinition *classDef, const std } } +void TSDeclGen::ProcessMethodsFromInterfaces(const std::unordered_set &processedMethods, + const ir::ClassDefinition *classDef) +{ + const auto &interfaces = classDef->TsType()->AsETSObjectType()->Interfaces(); + for (const auto &interface : interfaces) { + auto methods = interface->Methods(); + for (const auto &method : methods) { + if ((method->Flags() & (varbinder::VariableFlags::PUBLIC)) != 0U && + (method->Flags() & (varbinder::VariableFlags::STATIC)) == 0U && + processedMethods.find(method->Name().Mutf8()) == processedMethods.end()) { + GenMethodDeclaration( + method->AsLocalVariable()->Declaration()->AsFunctionDecl()->Node()->AsMethodDefinition()); + } + } + } +} + void TSDeclGen::ProcessClassBody(const ir::ClassDefinition *classDef) { + state_.inClass = true; std::unordered_set processedMethods; for (const auto *prop : classDef->Body()) { if (classDef->IsEnumTransformed()) { @@ -1517,11 +1616,11 @@ void TSDeclGen::ProcessClassBody(const ir::ClassDefinition *classDef) } else if (prop->IsTSInterfaceDeclaration()) { state_.isInterfaceInNamespace = true; OutDts(GetIndent()); + classNode_.indentLevel++; GenInterfaceDeclaration(prop->AsTSInterfaceDeclaration()); + state_.inInterface = false; state_.isInterfaceInNamespace = false; } else if (prop->IsTSTypeAliasDeclaration()) { - OutDts(GetIndent()); - OutTs(GetIndent()); GenTypeAliasDeclaration(prop->AsTSTypeAliasDeclaration()); } else if (prop->IsMethodDefinition()) { ProcessMethodDefinition(prop->AsMethodDefinition(), processedMethods); @@ -1534,9 +1633,7 @@ void TSDeclGen::ProcessClassBody(const ir::ClassDefinition *classDef) GenPropDeclaration(classProp); } else if (prop->IsClassDeclaration() && classDef->IsNamespaceTransformed()) { classNode_.hasNestedClass = true; - auto indent = GetIndent(); - OutDts(indent); - OutTs(indent); + OutTs(GetIndent()); classNode_.indentLevel++; GenClassDeclaration(prop->AsClassDeclaration()); state_.isClassInNamespace = false; @@ -1544,6 +1641,7 @@ void TSDeclGen::ProcessClassBody(const ir::ClassDefinition *classDef) GenClassDeclaration(prop->AsClassDeclaration()); } } + ProcessMethodsFromInterfaces(processedMethods, classDef); } void TSDeclGen::CloseClassBlock(const bool isDts) @@ -1593,8 +1691,7 @@ void TSDeclGen::GenClassDeclaration(const ir::ClassDeclaration *classDecl) CloseClassBlock(false); } } - if ((classDef->IsNamespaceTransformed() || classDef->IsEnumTransformed() || classDef->IsFromStruct()) && - classDef->IsDefaultExported()) { + if (classDef->IsDefaultExported()) { OutDts("export default ", className, ";"); OutEndlDts(); } @@ -1659,6 +1756,11 @@ void TSDeclGen::GenMethodDeclaration(const ir::MethodDefinition *methodDef) OutDts(";"); OutEndlDts(); + + if (methodDef->IsDefaultExported()) { + OutDts("export default ", methodName, ";"); + OutEndlDts(); + } } bool TSDeclGen::GenMethodDeclarationPrefix(const ir::MethodDefinition *methodDef, const ir::Identifier *methodIdent, @@ -1669,13 +1771,16 @@ bool TSDeclGen::GenMethodDeclarationPrefix(const ir::MethodDefinition *methodDef return true; } if (methodDef->IsDefaultExported()) { - OutDts("export default function "); + OutDts("declare function "); } else { OutDts("export declare function "); } } else { + if (state_.inNamespace && !state_.isClassInNamespace && !state_.isInterfaceInNamespace && + !ShouldEmitDeclarationSymbol(methodIdent) && !methodDef->IsConstructor()) { + return true; + } if (!methodDef->Function()->Annotations().empty()) { - ProcessIndent(); GenAnnotations(methodDef->Function()); } ProcessIndent(); @@ -1709,11 +1814,7 @@ void TSDeclGen::GenMethodSignature(const ir::MethodDefinition *methodDef, const OutDts(")"); } else { DebugPrint(" GenMethodDeclaration: " + methodName); - if (methodName.find("$_iterator") != std::string::npos) { - OutDts("[Symbol.iterator]"); - } else { - OutDts(methodName); - } + OutDts(methodName); if (methodDef->TsType() == nullptr) { LogWarning(diagnostic::UNTYPED_METHOD, {methodName}, methodIdent->Start()); @@ -1794,18 +1895,16 @@ void TSDeclGen::GenPropDeclaration(const ir::ClassProperty *classProp) void TSDeclGen::ProcessClassPropDeclaration(const ir::ClassProperty *classProp) { - ProcessIndent(); if (!state_.inInterface && (!state_.inNamespace || state_.isClassInNamespace) && !classNode_.isStruct) { GenPropAccessor(classProp, "get "); if (!classProp->IsReadonly()) { - ProcessIndent(); GenPropAccessor(classProp, "set "); } } else { if (!classProp->Annotations().empty()) { GenAnnotations(classProp); - ProcessIndent(); } + ProcessIndent(); if (!classNode_.isStruct) { GenModifier(classProp, true); } @@ -1829,8 +1928,8 @@ void TSDeclGen::GenPropAccessor(const ir::ClassProperty *classProp, const std::s } if (!classProp->Annotations().empty()) { GenAnnotations(classProp); - ProcessIndent(); } + ProcessIndent(); GenModifier(classProp); const auto propName = GetKeyIdent(classProp->Key())->Name().Mutf8(); diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.h b/ets2panda/declgen_ets2ts/declgenEts2Ts.h index 005c75ce3e5bd83c9299d46a322dc5766b85ac53..72ea50e805b8dedd9c3b6bd6a65a30c0509ed36a 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.h +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.h @@ -97,6 +97,7 @@ private: void GenType(const checker::Type *checkerType); void GenFunctionType(const checker::ETSFunctionType *functionType, const ir::MethodDefinition *methodDef = nullptr); void ProcessFunctionReturnType(const checker::Signature *sig); + bool ProcessTSQualifiedName(const ir::ETSTypeReference *typeReference); void ProcessETSTypeReferenceType(const ir::ETSTypeReference *typeReference, const checker::Type *checkerType = nullptr); bool ProcessTypeAnnotationSpecificTypes(const checker::Type *checkerType); @@ -160,6 +161,7 @@ private: void HandleClassInherit(const ir::Expression *expr); void ProcessClassBody(const ir::ClassDefinition *classDef); void ProcessParamDefaultToMap(const ir::Statement *stmt); + void ProcessParameterName(varbinder::LocalVariable *param); void ProcessFuncParameter(varbinder::LocalVariable *param); void ProcessFuncParameters(const checker::Signature *sig); void ProcessClassPropertyType(const ir::ClassProperty *classProp); @@ -175,8 +177,9 @@ private: void ProcessTypeAliasDependencies(const ir::TSTypeAliasDeclaration *typeAliasDecl); void ProcessTypeAnnotationDependencies(const ir::TypeNode *typeAnnotation); void ProcessClassDependencies(const ir::ClassDeclaration *classDecl); - void ProcessClassPropDependencies(const ir::AstNode *prop); + void ProcessClassPropDependencies(const ir::ClassDefinition *classDef); void ProcessClassMethodDependencies(const ir::MethodDefinition *methodDef); + void ProcessETSTypeReferenceDependencies(const ir::ETSTypeReference *typeReference); void AddSuperType(const ir::Expression *super); void AddSuperType(const checker::Type *tsType); void ProcessInterfacesDependencies(const ArenaVector &interfaces); @@ -184,6 +187,8 @@ private: void GenDeclarations(); void CloseClassBlock(const bool isDts); + void EmitDeclarationPrefix(const ir::ClassDefinition *classDef, const std::string &typeName, + const std::string_view &className); void EmitClassDeclaration(const ir::ClassDefinition *classDef, const std::string_view &className); void EmitClassGlueCode(const ir::ClassDefinition *classDef, const std::string &className); void EmitMethodGlueCode(const std::string &methodName, const ir::Identifier *methodIdentifier); @@ -201,6 +206,9 @@ private: void ProcessMethodDefinition(const ir::MethodDefinition *methodDef, std::unordered_set &processedMethods); + void ProcessMethodsFromInterfaces(const std::unordered_set &processedMethods, + const ir::ClassDefinition *classDef); + void OutDts() {} template @@ -244,10 +252,12 @@ private: const ir::Expression *super {nullptr}; bool inInterface {false}; bool inGlobalClass {false}; + bool inClass {false}; bool inNamespace {false}; bool inEnum {false}; bool isClassInNamespace {false}; bool isInterfaceInNamespace {false}; + bool isDeclareNamespace {false}; std::string currentClassDescriptor {}; std::stack inUnionBodyStack {}; std::string currentTypeAliasName; diff --git a/ets2panda/driver/build_system/src/build/base_mode.ts b/ets2panda/driver/build_system/src/build/base_mode.ts index 20ab3bd4bf06661fef8b670a6d881c9dab76dd73..bbb32e53320220c6c8e92198658a0985a54ced81 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -491,6 +491,31 @@ export abstract class BaseMode { } } + public async generateDeclarationParallell(): Promise { + this.generateModuleInfos(); + this.generateArkTSConfigForModules(); + + if (!cluster.isPrimary) { + return; + } + + try { + this.setupCluster(cluster, { + clearExitListeners: true, + execPath: path.resolve(__dirname, 'declgen_worker.js'), + }); + await this.dispatchTasks(); + this.logger.printInfo('All declaration generation tasks complete.'); + } catch (error) { + this.logger.printError(LogDataFactory.newInstance( + ErrorCode.BUILDSYSTEM_DECLGEN_FAIL, + 'Generate declaration files failed.' + )); + } finally { + this.terminateAllWorkers(); + } + } + private async dispatchTasks(): Promise { const numCPUs = os.cpus().length; const taskQueue = Array.from(this.compileFiles.values()); @@ -512,12 +537,14 @@ export abstract class BaseMode { const serializableConfig = this.getSerializableConfig(); const workerExitPromises: Promise[] = []; + const moduleInfosArray = Array.from(this.moduleInfos.entries()); + for (let i = 0; i < maxWorkers; i++) { const taskChunk = taskQueue.slice(i * chunkSize, (i + 1) * chunkSize); const worker = cluster.fork(); this.setupWorkerMessageHandler(worker); - worker.send({ taskList: taskChunk, buildConfig: serializableConfig }); + worker.send({ taskList: taskChunk, buildConfig: serializableConfig, moduleInfos: moduleInfosArray}); const exitPromise = new Promise((resolve, reject) => { worker.on('exit', (status) => status === 0 ? resolve() : reject()); @@ -547,7 +574,6 @@ export abstract class BaseMode { }); } - private getSerializableConfig(): Object { const ignoreList = [ 'compileFiles', @@ -566,6 +592,7 @@ export abstract class BaseMode { }); return JSON.parse(jsonStr); } + setupCluster(cluster: Cluster, options: SetupClusterOptions): void { const { clearExitListeners, diff --git a/ets2panda/driver/build_system/src/build/build_mode.ts b/ets2panda/driver/build_system/src/build/build_mode.ts index 4c797a308a7e1f6f67bcee059b1dbfe484d2c7dc..59bdb759ab010c12b508de796c7b775b504e83d1 100644 --- a/ets2panda/driver/build_system/src/build/build_mode.ts +++ b/ets2panda/driver/build_system/src/build/build_mode.ts @@ -22,7 +22,7 @@ export class BuildMode extends BaseMode { } public async generateDeclaration(): Promise { - super.generateDeclaration(); + await super.generateDeclarationParallell(); } public async run(): Promise { diff --git a/ets2panda/driver/build_system/src/build/compile_worker.ts b/ets2panda/driver/build_system/src/build/compile_worker.ts index 4c69a0c8a4faae66408c2ff6fccc77fc57dc22ea..38a1fcdb596325139a0fe145d26194643394950b 100644 --- a/ets2panda/driver/build_system/src/build/compile_worker.ts +++ b/ets2panda/driver/build_system/src/build/compile_worker.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { CompileFileInfo } from '../types'; +import { CompileFileInfo, ModuleInfo } from '../types'; import * as fs from 'fs'; import * as path from 'path'; import { ensurePathExists } from '../utils'; @@ -32,15 +32,15 @@ import { } from '../logger'; import { ErrorCode } from '../error_code'; - process.on('message', (message: { taskList: CompileFileInfo[]; buildConfig: BuildConfig; + moduleInfos: Array<[string, ModuleInfo]>; }) => { if (!process.send) { throw new Error('process.send is undefined. This worker must be run as a forked process.'); } - const { taskList, buildConfig } = message; + const { taskList, buildConfig, moduleInfos } = message; const isDebug = buildConfig.buildMode === BUILD_MODE.DEBUG; Logger.getInstance(buildConfig); diff --git a/ets2panda/driver/build_system/src/build/declgen_worker.ts b/ets2panda/driver/build_system/src/build/declgen_worker.ts new file mode 100644 index 0000000000000000000000000000000000000000..2d25e9704d485b7561a6842f3fd81cdeaf405e74 --- /dev/null +++ b/ets2panda/driver/build_system/src/build/declgen_worker.ts @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CompileFileInfo, ModuleInfo } from '../types'; +import { BuildConfig } from '../types'; +import { LogData, LogDataFactory, Logger } from '../logger'; +import { ErrorCode } from '../error_code'; +import * as fs from 'fs'; +import * as path from 'path'; +import { changeFileExtension, ensurePathExists } from '../utils'; +import { + DECL_ETS_SUFFIX, + TS_SUFFIX, + KOALA_WRAPPER_PATH_FROM_SDK +} from '../pre_define'; +import { PluginDriver, PluginHook } from '../plugins/plugins_driver'; + +process.on('message', (message: { + taskList: CompileFileInfo[]; + buildConfig: BuildConfig; + moduleInfos: Array<[string, ModuleInfo]>; +}) => { + if (!process.send) { + throw new Error('process.send is undefined. This worker must be run as a forked process.'); + } + const { taskList, buildConfig, moduleInfos } = message; + const moduleInfosMap = new Map(moduleInfos); + + const logger = Logger.getInstance(buildConfig); + const pluginDriver = PluginDriver.getInstance(); + pluginDriver.initPlugins(buildConfig); + + const koalaWrapperPath = path.resolve(buildConfig.buildSdkPath, KOALA_WRAPPER_PATH_FROM_SDK); + let { arkts, arktsGlobal } = require(koalaWrapperPath); + + for (const fileInfo of taskList) { + let errorStatus = false; + try { + const source = fs.readFileSync(fileInfo.filePath, 'utf8'); + let moduleInfo = moduleInfosMap.get(fileInfo.packageName)!; + let filePathFromModuleRoot: string = path.relative(moduleInfo.moduleRootPath, fileInfo.filePath); + let declEtsOutputPath: string = path.join( + moduleInfo.declgenV1OutPath as string, + moduleInfo.packageName, + filePathFromModuleRoot + ); + declEtsOutputPath = changeFileExtension(declEtsOutputPath, DECL_ETS_SUFFIX); + let etsOutputPath: string = path.join( + moduleInfo.declgenBridgeCodePath as string, + moduleInfo.packageName, + filePathFromModuleRoot + ); + etsOutputPath = changeFileExtension(etsOutputPath, TS_SUFFIX); + + ensurePathExists(declEtsOutputPath); + ensurePathExists(etsOutputPath); + + arktsGlobal.filePath = fileInfo.filePath; + arktsGlobal.config = arkts.Config.create([ + '_', + '--extension', + 'ets', + '--arktsconfig', + fileInfo.arktsConfigFile, + fileInfo.filePath + ]).peer; + arktsGlobal.compilerContext = arkts.Context.createFromString(source); + pluginDriver.getPluginContext().setArkTSProgram(arktsGlobal.compilerContext.program); + + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, true); + + let ast = arkts.EtsScript.fromContext(); + pluginDriver.getPluginContext().setArkTSAst(ast); + pluginDriver.runPluginHook(PluginHook.PARSED); + + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, true); + + ast = arkts.EtsScript.fromContext(); + pluginDriver.getPluginContext().setArkTSAst(ast); + pluginDriver.runPluginHook(PluginHook.CHECKED); + + arkts.generateTsDeclarationsFromContext( + declEtsOutputPath, + etsOutputPath, + false + ); // Generate 1.0 declaration files & 1.0 glue code + logger.printInfo('declaration files generated'); + + process.send({ success: true, filePath: fileInfo.filePath }); + } catch (error) { + errorStatus = true; + if (error instanceof Error) { + const logData: LogData = LogDataFactory.newInstance( + ErrorCode.BUILDSYSTEM_DECLGEN_FAIL, + 'Generate declaration files failed in worker.', + error.message + ); + logger.printError(logData); + } + process.send({ + success: false, + filePath: fileInfo.filePath, + error: 'Generate declaration files failed in worker.' + }); + } finally { + if (!errorStatus) { + // when error occur,wrapper will destroy context. + arktsGlobal.es2panda._DestroyContext(arktsGlobal.compilerContext.peer); + } + arkts.destroyConfig(arktsGlobal.config); + } + } + process.exit(0); +}); \ No newline at end of file diff --git a/ets2panda/driver/build_system/src/entry.ts b/ets2panda/driver/build_system/src/entry.ts index 5d70b509d0278ddb18ba907684efff63aacdb2a4..6f0a52f9bbb54b649558c305df1acfe5208b1095 100644 --- a/ets2panda/driver/build_system/src/entry.ts +++ b/ets2panda/driver/build_system/src/entry.ts @@ -30,7 +30,7 @@ export async function build(projectConfig: BuildConfig): Promise { if (projectConfig.enableDeclgenEts2Ts === true) { let buildMode: BuildMode = new BuildMode(buildConfig); - buildMode.generateDeclaration(); + await buildMode.generateDeclaration(); } else if (projectConfig.buildType === BUILD_TYPE_BUILD) { let buildMode: BuildMode = new BuildMode(buildConfig); await buildMode.run(); diff --git a/ets2panda/ir/statements/emptyStatement.cpp b/ets2panda/ir/statements/emptyStatement.cpp index 5159ef56e3d3cef77804b6a3cdc187b43a5d11c4..f3f541464bf2c7a90b5b6113cfd5fb4a5ebaf870 100644 --- a/ets2panda/ir/statements/emptyStatement.cpp +++ b/ets2panda/ir/statements/emptyStatement.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -58,4 +58,15 @@ checker::VerifiedType EmptyStatement::Check(checker::ETSChecker *checker) { return {this, checker->GetAnalyzer()->Check(this)}; } + +[[nodiscard]] EmptyStatement *EmptyStatement::Clone(ArenaAllocator *allocator, AstNode *parent) +{ + EmptyStatement *stmt = allocator->New(); + if (stmt != nullptr) { + stmt->SetParent(parent); + stmt->SetRange(Range()); + } + + return stmt; +} } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/statements/emptyStatement.h b/ets2panda/ir/statements/emptyStatement.h index bba6f5958a2beda90f765734e6799426eb56fe84..22c56bfb405db4301f29cabb59b4b06d2829912a 100644 --- a/ets2panda/ir/statements/emptyStatement.h +++ b/ets2panda/ir/statements/emptyStatement.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -31,6 +31,7 @@ public: void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; checker::VerifiedType Check(checker::ETSChecker *checker) override; + [[nodiscard]] EmptyStatement *Clone(ArenaAllocator *allocator, AstNode *parent) override; void Accept(ASTVisitorT *v) override { diff --git a/ets2panda/lexer/scripts/keywords.yaml b/ets2panda/lexer/scripts/keywords.yaml index 5d1af9132941f6a2bdb8c3b165bc2c39e7212277..48f97e770067e30f77ff2ec4e9c027ad67994a0f 100644 --- a/ets2panda/lexer/scripts/keywords.yaml +++ b/ets2panda/lexer/scripts/keywords.yaml @@ -72,7 +72,8 @@ keywords: - name: 'boolean' token: KEYW_BOOLEAN - keyword_like: [ets, js, ts] + keyword: [ets] + keyword_like: [js, ts] flags: [reserved_type_name, definable_type_name] - name: 'Boolean' @@ -87,7 +88,7 @@ keywords: - name: 'byte' token: KEYW_BYTE - keyword_like: [ets] + keyword: [ets] flags: [reserved_type_name, definable_type_name] - name: 'Byte' @@ -107,7 +108,7 @@ keywords: - name: 'char' token: KEYW_CHAR - keyword_like: [ets] + keyword: [ets] flags: [reserved_type_name, definable_type_name] - name: 'Char' @@ -161,7 +162,7 @@ keywords: - name: 'double' token: KEYW_DOUBLE - keyword_like: [ets] + keyword: [ets] flags: [reserved_type_name, definable_type_name] - name: 'Double' @@ -222,7 +223,7 @@ keywords: - name: 'float' token: KEYW_FLOAT - keyword_like: [ets] + keyword: [ets] flags: [reserved_type_name, definable_type_name] - name: 'Float' @@ -307,7 +308,7 @@ keywords: - name: 'int' token: KEYW_INT - keyword_like: [ets] + keyword: [ets] flags: [reserved_type_name, definable_type_name] - name: 'Int' @@ -342,7 +343,7 @@ keywords: - name: 'long' token: KEYW_LONG - keyword_like: [ets] + keyword: [ets] flags: [reserved_type_name, definable_type_name] - name: 'Long' @@ -461,7 +462,7 @@ keywords: - name: 'short' token: KEYW_SHORT - keyword_like: [ets] + keyword: [ets] flags: [reserved_type_name, definable_type_name] - name: 'Short' @@ -575,8 +576,7 @@ keywords: - name: 'void' token: KEYW_VOID - keyword: [as, js, ts] - keyword_like: [ets] + keyword: [as, ets, js, ts] flags: [unary, reserved_type_name, definable_type_name] - name: 'while' diff --git a/ets2panda/linter/.prettierignore b/ets2panda/linter/.prettierignore index fd9022d71ad8aa2ae992be269d5c22012a9975d8..3bde64241c0fd532207ef32db1d296c3d50b148e 100644 --- a/ets2panda/linter/.prettierignore +++ b/ets2panda/linter/.prettierignore @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2024 Huawei Device Co., Ltd. +# 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 @@ -22,5 +22,7 @@ /scripts/** /test/** /third_party/** +/arkanalyzer/** +/homecheck/** **.json **.js diff --git a/ets2panda/linter/BUILD.gn b/ets2panda/linter/BUILD.gn index 724e7ced23e0a9e86c1a8589aafbc6042e2ffaa0..e2071e83da50d1aea5e4ed95523f23fd66a9743a 100644 --- a/ets2panda/linter/BUILD.gn +++ b/ets2panda/linter/BUILD.gn @@ -22,13 +22,11 @@ action("build_linter") { sources = [ "./package.json", "./src/cli/CommandLineParser.ts", - "./src/cli/Compiler.ts", "./src/cli/ConsoleLogger.ts", "./src/cli/LinterCLI.ts", "./src/cli/LoggerImpl.ts", "./src/cli/main.ts", - "./src/cli/ts-compiler/FormTscOptions.ts", - "./src/cli/ts-compiler/ResolveSdks.ts", + "./src/lib/BaseTypeScriptLinter.ts", "./src/lib/CommandLineOptions.ts", "./src/lib/CookBookMsg.ts", "./src/lib/FaultAttrs.ts", @@ -49,8 +47,16 @@ action("build_linter") { "./src/lib/TypeScriptLinterConfig.ts", "./src/lib/autofixes/AutofixTitles.ts", "./src/lib/autofixes/Autofixer.ts", + "./src/lib/autofixes/QuasiEditor.ts", "./src/lib/autofixes/ReportAutofixCallback.ts", "./src/lib/autofixes/SymbolCache.ts", + "./src/lib/statistics/FileProblemStatistics.ts", + "./src/lib/statistics/FileStatistics.ts", + "./src/lib/statistics/ProjectStatistics.ts", + "./src/lib/statistics/StatisticsLogger.ts", + "./src/lib/ts-compiler/Compiler.ts", + "./src/lib/ts-compiler/FormTscOptions.ts", + "./src/lib/ts-compiler/ResolveSdks.ts", "./src/lib/ts-diagnostics/GetTscDiagnostics.ts", "./src/lib/ts-diagnostics/TSCCompiledProgram.ts", "./src/lib/ts-diagnostics/TransformTscDiagnostics.ts", diff --git a/ets2panda/linter/arkanalyzer/.prettierrc b/ets2panda/linter/arkanalyzer/.prettierrc index 2e3d95a2a6c31ed99f60caff76da5fa6a94f07b3..4d939fa56def97340e6af8a8784c51b3db3d77af 100644 --- a/ets2panda/linter/arkanalyzer/.prettierrc +++ b/ets2panda/linter/arkanalyzer/.prettierrc @@ -4,7 +4,8 @@ "useTabs": false, "semi": true, "singleQuote": true, - "printWidth": 120, + "printWidth": 160, "quoteProps": "as-needed", - "arrowParens": "always" + "arrowParens": "avoid", + "bracketSpacing": true } \ No newline at end of file diff --git a/ets2panda/linter/arkanalyzer/README.en.md b/ets2panda/linter/arkanalyzer/README.en.md new file mode 100644 index 0000000000000000000000000000000000000000..2c336a4d1b80dd3bc051c7105b4226d1cf6728c5 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/README.en.md @@ -0,0 +1,96 @@ +# sig_programanalysis + +English | [简体中文](./README.md) + +## SIG Group Work Objectives and Scope + +### Work Objectives + +* Sig_programanalysis aims to carry out program analysis technology exploration, key technology identification, and competitiveness building for OpenHarmony systems and apps, striving to become the gathering place for OpenHarmony system and app analysis capabilities and an incubation place for related engineering tools. + +* Sig_programanalysis will build a basic program analysis framework for OpenHarmony apps, and subsequently based on it to provide application developers with out-of-the-box defect scanning and analysis tools, making it possible to automatically vet code for scenarios such as IDE, CI/CD pipelines, etc. + +### Work Scope + +* Responsible for building and maintaining the key technology map of program analysis, as well as the decomposition of functional modules in the field, interface definition, and maintenance management. + +* Responsible for the architecture design, open source development, and project maintenance of projects related to program analysis. + + +### Projects + +Sig_programanalysis currently incubates the following projects. Everyone is welcome to participate (you can apply to participate in the co-construction of existing projects, or you can apply to create a new program analysis project). + + +* ArkAnalyzer: +The Static Analysis Framework for ArkTS-based OpenHarmony Apps. + +* ArkCheck: +Checking OpenHarmony Apps for Potential Code-level Defects + + +## SIG Members + + +### Leader + +- [lilicoding](https://gitee.com/lilicoding) + + +### Committers +- [kubigao](https://gitee.com/kubigao) +- [yifei-xue](https://gitee.com/yifei_xue) +- [kubrick-hjh](https://gitee.com/kubrick-hjh) +- [speed9](https://gitee.com/speeds) +- [bbsun](https://gitee.com/bbsun) +- [chn](https://gitee.com/chn) +- [Elouan](https://gitee.com/Elouan) +- [Rnine](https://gitee.com/Rnine) +- [workspace_cb](https://gitee.com/workspace_cb) +- [longyuC](https://gitee.com/longyuC) +- [xyji95](https://gitee.com/xyji95) +- [xulingyun-red](https://gitee.com/xulingyun-red) + + +### Meetings + - Meeting Time: Bi-weekly meeting, Thursday 19:30 Beijing time + - Meeting Application:[Link](https://shimo.im/forms/B1Awd60W7bU51g3m/fill) + - Meeting Link: Welink or Others + - Meeting Notification: [Subscribe to](https://lists.openatom.io/postorius/lists/dev.openharmony.io) mailing list dev@openharmony.io for the meeting link + - Meeting Summary: [Archive link address](https://gitee.com/openharmony-sig/sig-content) + +### Contact + +- Mailing list: [dev@openharmony.io](https://lists.openatom.io/postorius/lists/dev@openharmony.io/) + +*** +# ArkAnalyzer: Static Program Analysis Framework for the ArkTS Language +## Develope environment setup +1. [Download Visual Studio Code](https://code.visualstudio.com/download) or other IDEA; +2. +3. Install Typescript via npm: +```shell +npm install -g typescript +``` +4. Install dependency libraries +```shell +cd arkanalyzer +npm install +``` +5. [Optional] Generate the latest API documentation, which will be created at docs/api_docs. +```shell +npm run gendoc +``` + +## Docmentations + +1. ArkAnalyzer API docmentations,refer to the [link](https://gitcode.com/openharmony-sig/arkanalyzer/wiki/globals.md). + +## Commit codes +Follow the code repository standards of Openharmony-Sig, refer to the [link](docs/HowToCreatePR.md#english) + +## Debug +Modify the `args` parameter array in the debug configuration file `.vscode/launch.json` to the path of the test file you want to debug, and then start the debugging process. + +## Add test cases +Place all new test codes in the `tests` directory. Corresponding sample code and other resource files should be placed in the ``tests\resources` directory, and create different folders for each testing scenario. \ No newline at end of file diff --git a/ets2panda/linter/arkanalyzer/README.md b/ets2panda/linter/arkanalyzer/README.md new file mode 100644 index 0000000000000000000000000000000000000000..068993e9ab9304610b2a13cb19dfbe5b73dd526b --- /dev/null +++ b/ets2panda/linter/arkanalyzer/README.md @@ -0,0 +1,107 @@ +# sig_programanalysis + +简体中文 | [English](./README.en.md) + +说明:本SIG的内容遵循OpenHarmony的PMC管理章程 [README](../../zh/pmc.md)中描述的约定。 + + +## SIG组工作目标和范围 + + + +### 工作目标 + +* 程序分析-SIG(Sig_programanalysis) 旨在面向OpenHarmony系统和原生应用开展程序分析技术洞察、关键技术识别和竞争力构建,同时成为OpenHarmony系统和应用程序分析能力的聚集地和相关工程工具的孵化地。 + +* 程序分析-SIG(Sig_programanalysis)将面向OpenHarmony应用构建基础程序分析框架并基于此为应用开发者提供开箱即用的缺陷扫描分析工具,面向IDE、流水线门禁、应用市场上架审核等场景,打造自动化工具看护能力。 + +### 工作范围 + +* 负责程序分析子领域关键根技术梳理,以及领域内功能模块分解、接口定义与维护管理等工作。 + +* 负责程序分析子领域相关项目的架构设计、开源开发和项目维护等工作。 + + +### 项目孵化 + +程序分析-SIG(Sig_programanalysis)正积极孵化如下项目,欢迎大家参与共享共建(可申请参与已有项目的共建,也可申请创建新的程序分析项目并联合社区启动开源共建)。 + + +* 方舟分析器(ArkAnalyzer): + 面向ArkTS的OpenHarmony应用程序分析框架。 + +* 方舟检测器(ArkCheck): + 面向OpenHarmony应用开发提供代码级缺陷自动检测(I期聚焦高性能编码规则的自动化检测) + + + +## SIG组成员 + + +### Leader + +- [lilicoding](https://gitcode.com/lilicoding) + + +### Committers列表 +- [kubigao](https://gitcode.com/kubigao) +- [yifei-xue](https://gitcode.com/yifei-xue) +- [kubrick-hjh](https://gitcode.com/kubrick-hjh) +- [speed9](https://gitee.com/speeds) +- [bbsun](https://gitcode.com/bbsun) +- [chn](https://gitcode.com/chn) +- [Elouan](https://gitcode.com/Elouan) +- [Rnine](https://gitcode.com/Rnine1) +- [workspace_cb](https://gitee.com/workspace_cb) +- [longyuC](https://gitee.com/longyuC) +- [xyji95](https://gitcode.com/xyji95) +- [xulingyun](https://gitcode.com/muya318) + + +### 会议 + - 会议时间:双周例会,周四晚上19:00, UTC+8 + - 会议申报:[申报链接](https://shimo.im/forms/B1Awd60W7bU51g3m/fill) + - 会议链接: + - 会议通知:请[订阅](https://lists.openatom.io/postorius/lists/dev.openharmony.io)邮件列表 dev@openharmony.io 获取会议链接 + - 会议纪要:[归档链接地址](https://gitee.com/openharmony-sig/sig-content) + + +### Contact (optional) + +- 邮件列表:[dev@openharmony.io](https://lists.openatom.io/postorius/lists/dev@openharmony.io/) + +*** + +# 方舟分析器:面向ArkTS语言的静态程序分析框架 +## ArkAnalyzer 环境配置 +1. 从[Download Visual Studio Code](https://code.visualstudio.com/download)下载vscode并安装,或安装其他IDE。 +2. +3. 通过npm安装TypeScript编译器,命令行输入 +```shell +npm install -g typescript +``` +4. 安装依赖库 +```shell +npm install +``` +5. 【可选】生成新API文档,文档生成在 docs/api_docs。 +```shell +npm run gendoc +``` + +## ArkAnalyzer 文档 + +1. ArkAnalyzer 快速入门文档,请参考:[链接](https://gitcode.com/openharmony-sig/arkanalyzer/wiki/ArkAnalyzer%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97.md)。 +2. ArkAnalyzer API文档,请参考:[链接](https://gitcode.com/openharmony-sig/arkanalyzer/wiki/globals.md)。 + +## ArkAnalyzer 代码上库 +遵守openharmony-sig代码上库规范, 操作方法请参考:[链接](docs/HowToCreatePR.md#中文) + +## ArkAnalyzer 调试 +将调试配置文件`.vscode/launch.json`中`args`参数数组修改为想要调试的文件路径,然后启动调试。 + +## 添加自验证测试用例 +新增测试代码统一放至`tests`目录下,对应的样例代码和资源文件统一放至`tests\resources`,按测试场景创建不同文件夹。 + +## ArkAnalyzer Issues +请参考[连接](docs/HowToHandleIssues.md)提交Issues。 diff --git a/ets2panda/linter/arkanalyzer/config/arkanalyzer.json b/ets2panda/linter/arkanalyzer/config/arkanalyzer.json index 26c5953b478e06b72bcfb7a51ff28be3b86c147b..fe0c60bdc46c6a41afedd532ca45aed9128f4e1e 100644 --- a/ets2panda/linter/arkanalyzer/config/arkanalyzer.json +++ b/ets2panda/linter/arkanalyzer/config/arkanalyzer.json @@ -2,6 +2,7 @@ "supportFileExts": [ ".ets", ".ts", + ".js", ".d.ets", ".d.ts" ], @@ -9,12 +10,12 @@ "ignoreFileNames": [ "oh_modules", "node_modules", - "hvigorfile.ts", - "build-tools" + "build-tools", + "hvigorfile.ts" ], "sdkGlobalFolders": [ "component", "@internal" ], "tsconfig": "tsconfig.json" -} +} \ No newline at end of file diff --git a/ets2panda/linter/arkanalyzer/package.json b/ets2panda/linter/arkanalyzer/package.json index 902be5d33d8a30f00d0fce26990e1f4695216133..a9d42adc134be6b785c43dd3406c9ee216d35ef9 100644 --- a/ets2panda/linter/arkanalyzer/package.json +++ b/ets2panda/linter/arkanalyzer/package.json @@ -18,16 +18,8 @@ "copyCollectionDefintion": "ts-node script/typescriptCollectionDefinitionCopy.ts" }, "dependencies": { - "commander": "11.0.0", - "log4js": "6.7.1" - }, - "bundleDependencies": [ - "ohos-typescript" - ], - "devDependencies": { - "@vitest/coverage-v8": "^1.5.0", - "ts-node": "^10.9.1", - "typedoc": "^0.25.13", - "vitest": "^1.5.0" + "commander": "^9.4.0", + "log4js": "^6.4.0", + "json5": "2.2.3" } } diff --git a/ets2panda/linter/arkanalyzer/script/typescriptCollectionDefinitionCopy.ts b/ets2panda/linter/arkanalyzer/script/typescriptCollectionDefinitionCopy.ts index eb4d3476e3e6134e032f312ae7d0159591dc9af6..f44aa17f8ac0e8df88e534328399b3db2a4872d8 100644 --- a/ets2panda/linter/arkanalyzer/script/typescriptCollectionDefinitionCopy.ts +++ b/ets2panda/linter/arkanalyzer/script/typescriptCollectionDefinitionCopy.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 diff --git a/ets2panda/linter/arkanalyzer/src/Config.ts b/ets2panda/linter/arkanalyzer/src/Config.ts index 24178d2b5b5498e89f214cb415254e16312bc42a..bff8ddf474ca034ddd0a8478c982dbdff0b2e6a5 100644 --- a/ets2panda/linter/arkanalyzer/src/Config.ts +++ b/ets2panda/linter/arkanalyzer/src/Config.ts @@ -35,7 +35,6 @@ export interface TsConfig { [key: string]: string[]; }; }; - } export type SceneOptionsValue = string | number | boolean | (string | number)[] | string[] | null | undefined; @@ -43,7 +42,7 @@ export interface SceneOptions { supportFileExts?: string[]; ignoreFileNames?: string[]; enableLeadingComments?: boolean; - enableTrailingComments?:boolean + enableTrailingComments?: boolean; tsconfig?: string; isScanAbc?: boolean; sdkGlobalFolders?: string[]; @@ -84,12 +83,7 @@ export class SceneConfig { * @param sdks - sdks used in this scene. * @param fullFilePath - the full file path. */ - public buildConfig( - targetProjectName: string, - targetProjectDirectory: string, - sdks: Sdk[], - fullFilePath?: string[] - ) { + public buildConfig(targetProjectName: string, targetProjectDirectory: string, sdks: Sdk[], fullFilePath?: string[]): void { this.targetProjectName = targetProjectName; this.targetProjectDirectory = targetProjectDirectory; this.sdksObj = sdks; @@ -111,18 +105,19 @@ export class SceneConfig { sceneConfig.buildFromProjectDir(projectDir); ``` */ - public buildFromProjectDir(targetProjectDirectory: string) { + public buildFromProjectDir(targetProjectDirectory: string): void { this.targetProjectDirectory = targetProjectDirectory; this.targetProjectName = path.basename(targetProjectDirectory); - this.projectFiles = getAllFiles( - targetProjectDirectory, - this.options.supportFileExts!, - this.options.ignoreFileNames - ); + this.projectFiles = getAllFiles(targetProjectDirectory, this.options.supportFileExts!, this.options.ignoreFileNames); } - public buildFromProjectFiles(projectName: string, projectDir: string, filesAndDirectorys: string[], sdks?: Sdk[], - languageTags?: Map): void { + public buildFromProjectFiles( + projectName: string, + projectDir: string, + filesAndDirectorys: string[], + sdks?: Sdk[], + languageTags?: Map + ): void { if (sdks) { this.sdksObj = sdks; } @@ -140,13 +135,13 @@ export class SceneConfig { private processFilePaths(fileOrDirectory: string, projectDir: string): void { let absoluteFilePath = ''; - if (fileOrDirectory.includes(projectDir)) { + if (path.isAbsolute(fileOrDirectory)) { absoluteFilePath = fileOrDirectory; } else { absoluteFilePath = path.join(projectDir, fileOrDirectory); } if (fs.statSync(absoluteFilePath).isDirectory()) { - getAllFiles(absoluteFilePath, this.getOptions().supportFileExts!, this.options.ignoreFileNames).forEach((filePath) => { + getAllFiles(absoluteFilePath, this.getOptions().supportFileExts!, this.options.ignoreFileNames).forEach(filePath => { if (!this.projectFiles.includes(filePath)) { this.projectFiles.push(filePath); } @@ -158,22 +153,21 @@ export class SceneConfig { private setLanguageTagForFiles(fileOrDirectory: string, projectDir: string, languageTag: Language): void { let absoluteFilePath = ''; - if (fileOrDirectory.includes(projectDir)) { + if (path.isAbsolute(fileOrDirectory)) { absoluteFilePath = fileOrDirectory; } else { absoluteFilePath = path.join(projectDir, fileOrDirectory); } if (fs.statSync(absoluteFilePath).isDirectory()) { - getAllFiles(absoluteFilePath, this.getOptions().supportFileExts!, this.options.ignoreFileNames) - .forEach((filePath) => { - this.fileLanguages.set(filePath, languageTag); - }); + getAllFiles(absoluteFilePath, this.getOptions().supportFileExts!, this.options.ignoreFileNames).forEach(filePath => { + this.fileLanguages.set(filePath, languageTag); + }); } else { this.fileLanguages.set(absoluteFilePath, languageTag); } } - public buildFromJson(configJsonPath: string) { + public buildFromJson(configJsonPath: string): void { if (fs.existsSync(configJsonPath)) { let configurationsText: string; try { @@ -193,9 +187,7 @@ export class SceneConfig { } const targetProjectName: string = configurations.targetProjectName ? configurations.targetProjectName : ''; - const targetProjectDirectory: string = configurations.targetProjectDirectory - ? configurations.targetProjectDirectory - : ''; + const targetProjectDirectory: string = configurations.targetProjectDirectory ? configurations.targetProjectDirectory : ''; const sdks: Sdk[] = configurations.sdks ? configurations.sdks : []; if (configurations.options) { @@ -208,15 +200,15 @@ export class SceneConfig { } } - public getTargetProjectName() { + public getTargetProjectName(): string { return this.targetProjectName; } - public getTargetProjectDirectory() { + public getTargetProjectDirectory(): string { return this.targetProjectDirectory; } - public getProjectFiles() { + public getProjectFiles(): string[] { return this.projectFiles; } @@ -224,19 +216,19 @@ export class SceneConfig { return this.fileLanguages; } - public getSdkFiles() { + public getSdkFiles(): string[] { return this.sdkFiles; } - public getSdkFilesMap() { + public getSdkFilesMap(): Map { return this.sdkFilesMap; } - public getEtsSdkPath() { + public getEtsSdkPath(): string { return this.etsSdkPath; } - public getSdksObj() { + public getSdksObj(): Sdk[] { return this.sdksObj; } diff --git a/ets2panda/linter/arkanalyzer/src/Scene.ts b/ets2panda/linter/arkanalyzer/src/Scene.ts index 02e26abc4633a84180d01d084c89c4798fc64e40..72c782822638b95a35109c472eeaa37aaaf1e76f 100644 --- a/ets2panda/linter/arkanalyzer/src/Scene.ts +++ b/ets2panda/linter/arkanalyzer/src/Scene.ts @@ -51,8 +51,8 @@ enum SceneBuildStage { CLASS_COLLECTED, METHOD_COLLECTED, SDK_INFERRED, - TYPE_INFERRED -}; + TYPE_INFERRED, +} /** * The Scene class includes everything in the analyzed project. @@ -85,7 +85,7 @@ export class Scene { private ohPkgContent: { [k: string]: unknown } = {}; private overRides: Map = new Map(); private overRideDependencyMap: Map = new Map(); - private globalModule2PathMapping?: { [k: string]: string[]; } | undefined; + private globalModule2PathMapping?: { [k: string]: string[] } | undefined; private baseUrl?: string | undefined; private buildStage: SceneBuildStage = SceneBuildStage.BUILD_INIT; @@ -97,8 +97,7 @@ export class Scene { private unhandledFilePaths: string[] = []; private unhandledSdkFilePaths: string[] = []; - constructor() { - } + constructor() {} public getOptions(): SceneOptions { return this.options; @@ -155,7 +154,7 @@ export class Scene { scene.buildSceneFromProjectDir(sceneConfig); ``` */ - public buildSceneFromProjectDir(sceneConfig: SceneConfig) { + public buildSceneFromProjectDir(sceneConfig: SceneConfig): void { this.buildBasicInfo(sceneConfig); this.genArkFiles(); } @@ -195,7 +194,7 @@ export class Scene { } // handle sdks - sceneConfig.getSdksObj()?.forEach((sdk) => { + sceneConfig.getSdksObj()?.forEach(sdk => { if (!sdk.moduleName) { this.buildSdk(sdk.name, sdk.path); this.projectSdkMap.set(sdk.name, sdk); @@ -225,7 +224,7 @@ export class Scene { const buildProfileJson = parseJsonText(configurationsText); const modules = buildProfileJson.modules; if (modules instanceof Array) { - modules.forEach((module) => { + modules.forEach(module => { this.modulePath2NameMap.set(path.resolve(this.realProjectDir, path.join(module.srcPath)), module.name); }); } @@ -253,7 +252,6 @@ export class Scene { this.overRideDependencyMap.set(key, globalDependency); } } - } else { logger.warn('This project has no oh-package.json5!'); } @@ -298,28 +296,37 @@ export class Scene { private buildAllMethodBody(): void { this.buildStage = SceneBuildStage.CLASS_DONE; + const methods: ArkMethod[] = []; for (const file of this.getFiles()) { for (const cls of file.getClasses()) { for (const method of cls.getMethods(true)) { - method.buildBody(); - method.freeBodyBuilder(); + methods.push(method); } } } for (const namespace of this.getNamespacesMap().values()) { for (const cls of namespace.getClasses()) { for (const method of cls.getMethods(true)) { - method.buildBody(); - method.freeBodyBuilder(); + methods.push(method); } } } + for (const method of methods) { + try { + method.buildBody(); + } catch (error) { + logger.error('Error building body:', method.getSignature(), error); + } finally { + method.freeBodyBuilder(); + } + } + this.buildStage = SceneBuildStage.METHOD_DONE; } - private genArkFiles() { - this.projectFiles.forEach((file) => { + private genArkFiles(): void { + this.projectFiles.forEach(file => { logger.info('=== parse file:', file); try { const arkFile: ArkFile = new ArkFile(FileUtils.getFileLanguage(file, this.fileLanguages)); @@ -426,7 +433,7 @@ export class Scene { private findDependenciesByTsConfig(from: string, arkFile: ArkFile): void { if (this.globalModule2PathMapping) { const paths: { [k: string]: string[] } = this.globalModule2PathMapping; - Object.keys(paths).forEach((key) => this.parseTsConfigParms(paths, key, from, arkFile)); + Object.keys(paths).forEach(key => this.parseTsConfigParms(paths, key, from, arkFile)); } } @@ -436,7 +443,7 @@ export class Scene { this.processFuzzyMapping(key, from, module2pathMapping, arkFile); } else if (from.startsWith(key)) { let tail = from.substring(key.length, from.length); - module2pathMapping.forEach((pathMapping) => { + module2pathMapping.forEach(pathMapping => { let originPath = path.join(this.getRealProjectDir(), pathMapping, tail); if (this.baseUrl) { originPath = path.resolve(this.baseUrl, originPath); @@ -450,7 +457,7 @@ export class Scene { key = key.substring(0, key.indexOf(ALL) - 1); if (from.substring(0, key.indexOf(ALL) - 1) === key) { let tail = from.substring(key.indexOf(ALL) - 1, from.length); - module2pathMapping.forEach((pathMapping) => { + module2pathMapping.forEach(pathMapping => { pathMapping = pathMapping.substring(0, pathMapping.indexOf(ALL) - 1); let originPath = path.join(this.getRealProjectDir(), pathMapping, tail); if (this.baseUrl) { @@ -462,7 +469,7 @@ export class Scene { } private findDependenciesByRule(originPath: string, arkFile: ArkFile): void { - const extNameArray = ['.ets', '.ts', '.d.ets', '.d.ts']; + const extNameArray = ['.ets', '.ts', '.d.ets', '.d.ts', '.js']; if (!this.findFilesByPathArray(originPath, this.indexPathArray, arkFile) && !this.findFilesByExtNameArray(originPath, extNameArray, arkFile)) { logger.info(originPath + 'module mapperInfo is not found!'); } @@ -490,11 +497,10 @@ export class Scene { return false; } - private findRelativeDependenciesByOhPkg(from: string, arkFile: ArkFile): void { //relative path ../from ./from //order - //1. ../from/oh-package.json5 -> [[name]] -> overRides/overRideDependencyMap? -> + //1. ../from/oh-package.json5 -> [[name]] -> overRides/overRideDependencyMap? -> //[[main]] -> file path ->dependencies(priority)+devDependencies? dynamicDependencies(not support) -> //key overRides/overRideDependencyMap? //2. ../from/index.ets(ts) @@ -511,9 +517,14 @@ export class Scene { this.findDependenciesByRule(originPath, arkFile); } - private findDependenciesByOhPkg(ohPkgContentPath: string, ohPkgContentInfo: { - [k: string]: unknown - }, from: string, arkFile: ArkFile): void { + private findDependenciesByOhPkg( + ohPkgContentPath: string, + ohPkgContentInfo: { + [k: string]: unknown; + }, + from: string, + arkFile: ArkFile + ): void { //module name @ohos/from const ohPkgContent: { [k: string]: unknown } | undefined = ohPkgContentInfo; //module main name is must be @@ -560,9 +571,9 @@ export class Scene { this.filesMap.set(arkFile.getFileSignature().toMapKey(), arkFile); } - private buildSdk(sdkName: string, sdkPath: string) { + private buildSdk(sdkName: string, sdkPath: string): void { const allFiles = getAllFiles(sdkPath, this.options.supportFileExts!, this.options.ignoreFileNames); - allFiles.forEach((file) => { + allFiles.forEach(file => { logger.info('=== parse sdk file:', file); try { const arkFile: ArkFile = new ArkFile(FileUtils.getFileLanguage(file, this.fileLanguages)); @@ -574,6 +585,7 @@ export class Scene { }); const fileSig = arkFile.getFileSignature().toMapKey(); this.sdkArkFilesMap.set(fileSig, arkFile); + SdkUtils.buildSdkImportMap(arkFile); SdkUtils.buildGlobalMap(arkFile, this.sdkGlobalMap); } catch (error) { logger.error('Error parsing file:', file, error); @@ -588,7 +600,7 @@ export class Scene { * dependencies from this file. Next, build a `ModuleScene` for this project to generate {@link ArkFile}. Finally, * it build bodies of all methods, generate extended classes, and add DefaultConstructors. */ - public buildScene4HarmonyProject() { + public buildScene4HarmonyProject(): void { this.buildOhPkgContentMap(); this.modulePath2NameMap.forEach((value, key) => { let moduleScene = new ModuleScene(this); @@ -610,7 +622,7 @@ export class Scene { }); } - public buildModuleScene(moduleName: string, modulePath: string, supportFileExts: string[]) { + public buildModuleScene(moduleName: string, modulePath: string, supportFileExts: string[]): void { if (this.moduleScenesMap.get(moduleName)) { return; } @@ -642,7 +654,7 @@ export class Scene { private processModuleOhPkgContent(dependencies: Object, moduleOhPkgFilePath: string, supportFileExts: string[]): void { Object.entries(dependencies).forEach(([k, v]) => { const pattern = new RegExp('^(\\.\\.\\/\|\\.\\/)'); - if (typeof (v) === 'string') { + if (typeof v === 'string') { let dependencyModulePath: string = ''; if (pattern.test(v)) { dependencyModulePath = path.join(moduleOhPkgFilePath, v); @@ -680,7 +692,7 @@ export class Scene { return this.projectName; } - public getProjectFiles() { + public getProjectFiles(): string[] { return this.projectFiles; } @@ -744,7 +756,7 @@ export class Scene { * @example * 1. In inferSimpleTypes() to check arkClass and arkMethod. * ```typescript - * public inferSimpleTypes() { + * public inferSimpleTypes(): void { * for (let arkFile of this.getFiles()) { * for (let arkClass of arkFile.getClasses()) { * for (let arkMethod of arkClass.getMethods()) { @@ -777,11 +789,11 @@ export class Scene { return Array.from(this.sdkArkFilesMap.values()); } - public getModuleSdkMap() { + public getModuleSdkMap(): Map { return this.moduleSdkMap; } - public getProjectSdkMap() { + public getProjectSdkMap(): Map { return this.projectSdkMap; } @@ -815,7 +827,7 @@ export class Scene { private getNamespacesMap(): Map { if (this.buildStage === SceneBuildStage.CLASS_DONE) { for (const file of this.getFiles()) { - ModelUtils.getAllNamespacesInFile(file).forEach((namespace) => { + ModelUtils.getAllNamespacesInFile(file).forEach(namespace => { this.namespacesMap.set(namespace.getNamespaceSignature().toMapKey(), namespace); }); } @@ -963,7 +975,7 @@ export class Scene { } //Get the set of entry points that are used to build the call graph. - public getEntryPoints() { + public getEntryPoints(): MethodSignature[] { return []; } @@ -972,15 +984,15 @@ export class Scene { return this.visibleValue; } - public getOhPkgContent() { + public getOhPkgContent(): { [p: string]: unknown } { return this.ohPkgContent; } - public getOhPkgContentMap() { + public getOhPkgContentMap(): Map { return this.ohPkgContentMap; } - public getOhPkgFilePath() { + public getOhPkgFilePath(): string { return this.ohPkgFilePath; } @@ -1010,12 +1022,24 @@ export class Scene { scene.inferTypes(); ``` */ - public inferTypes() { + public inferTypes(): void { if (this.buildStage < SceneBuildStage.SDK_INFERRED) { - this.sdkArkFilesMap.forEach(file => IRInference.inferFile(file)); + this.sdkArkFilesMap.forEach(file => { + try { + IRInference.inferFile(file); + } catch (error) { + logger.error('Error inferring types of sdk file:', file.getFileSignature(), error); + } + }); this.buildStage = SceneBuildStage.SDK_INFERRED; } - this.filesMap.forEach(file => IRInference.inferFile(file)); + this.filesMap.forEach(file => { + try { + IRInference.inferFile(file); + } catch (error) { + logger.error('Error inferring types of project file:', file.getFileSignature(), error); + } + }); if (this.buildStage < SceneBuildStage.TYPE_INFERRED) { this.getMethodsMap(true); this.buildStage = SceneBuildStage.TYPE_INFERRED; @@ -1036,8 +1060,7 @@ export class Scene { scene.inferSimpleTypes(); ``` */ - public inferSimpleTypes() { - + public inferSimpleTypes(): void { for (let arkFile of this.getFiles()) { for (let arkClass of arkFile.getClasses()) { for (let arkMethod of arkClass.getMethods()) { @@ -1047,9 +1070,12 @@ export class Scene { } } - private addNSClasses(namespaceStack: ArkNamespace[], finalNamespaces: ArkNamespace[], - classMap: Map, - parentMap: Map): void { + private addNSClasses( + namespaceStack: ArkNamespace[], + finalNamespaces: ArkNamespace[], + classMap: Map, + parentMap: Map + ): void { while (namespaceStack.length > 0) { const ns = namespaceStack.shift()!; const nsClass: ArkClass[] = []; @@ -1068,9 +1094,11 @@ export class Scene { } } - private addNSExportedClasses(finalNamespaces: ArkNamespace[], - classMap: Map, - parentMap: Map): void { + private addNSExportedClasses( + finalNamespaces: ArkNamespace[], + classMap: Map, + parentMap: Map + ): void { while (finalNamespaces.length > 0) { const finalNS = finalNamespaces.shift()!; const exportClass = []; @@ -1117,9 +1145,7 @@ export class Scene { // 遗留问题:只统计了项目文件的namespace,没统计sdk文件内部的引入 const importNameSpaceClasses = classMap.get(importNameSpace.getNamespaceSignature())!; importClasses.push(...importNameSpaceClasses.filter(c => !importClasses.includes(c) && c.getName() !== DEFAULT_ARK_CLASS_NAME)); - } catch { - } - + } catch {} } } const fileClasses = classMap.get(file.getFileSignature())!; @@ -1171,17 +1197,25 @@ export class Scene { return classMap; } - private addNSLocals(namespaceStack: ArkNamespace[], finalNamespaces: ArkNamespace[], - parentMap: Map, - globalVariableMap: Map): void { + private addNSLocals( + namespaceStack: ArkNamespace[], + finalNamespaces: ArkNamespace[], + parentMap: Map, + globalVariableMap: Map + ): void { while (namespaceStack.length > 0) { const ns = namespaceStack.shift()!; const nsGlobalLocals: Local[] = []; - ns.getDefaultClass().getDefaultArkMethod()!.getBody()?.getLocals().forEach(local => { - if (local.getDeclaringStmt() && local.getName() !== 'this' && local.getName()[0] !== '$') { - nsGlobalLocals.push(local); - } - }); + ns + .getDefaultClass() + .getDefaultArkMethod()! + .getBody() + ?.getLocals() + .forEach(local => { + if (local.getDeclaringStmt() && local.getName() !== 'this' && local.getName()[0] !== '$') { + nsGlobalLocals.push(local); + } + }); globalVariableMap.set(ns.getNamespaceSignature(), nsGlobalLocals); if (ns.getNamespaces().length === 0) { finalNamespaces.push(ns); @@ -1194,9 +1228,11 @@ export class Scene { } } - private addNSExportedLocals(finalNamespaces: ArkNamespace[], - globalVariableMap: Map, - parentMap: Map): void { + private addNSExportedLocals( + finalNamespaces: ArkNamespace[], + globalVariableMap: Map, + parentMap: Map + ): void { while (finalNamespaces.length > 0) { const finalNS = finalNamespaces.shift()!; const exportLocal = []; @@ -1242,9 +1278,7 @@ export class Scene { // 遗留问题:只统计了项目文件,没统计sdk文件内部的引入 const importNameSpaceClasses = globalVariableMap.get(importNameSpace.getNamespaceSignature())!; importLocals.push(...importNameSpaceClasses.filter(c => !importLocals.includes(c) && c.getName() !== DEFAULT_ARK_CLASS_NAME)); - } catch { - } - + } catch {} } } const fileLocals = globalVariableMap.get(file.getFileSignature())!; @@ -1270,8 +1304,7 @@ export class Scene { } } - private handleNestedNSLocals(nsns: ArkNamespace, nsLocals: Local[], - globalVariableMap: Map): void { + private handleNestedNSLocals(nsns: ArkNamespace, nsLocals: Local[], globalVariableMap: Map): void { const nsnsLocals = globalVariableMap.get(nsns.getNamespaceSignature())!; const nsnsLocalNameSet = new Set(nsnsLocals.map(item => item.getName())); for (const local of nsLocals) { @@ -1288,11 +1321,16 @@ export class Scene { const parentMap: Map = new Map(); const finalNamespaces: ArkNamespace[] = []; const globalLocals: Local[] = []; - file.getDefaultClass()?.getDefaultArkMethod()!.getBody()?.getLocals().forEach(local => { - if (local.getDeclaringStmt() && local.getName() !== 'this' && local.getName()[0] !== '$') { - globalLocals.push(local); - } - }); + file + .getDefaultClass() + ?.getDefaultArkMethod()! + .getBody() + ?.getLocals() + .forEach(local => { + if (local.getDeclaringStmt() && local.getName() !== 'this' && local.getName()[0] !== '$') { + globalLocals.push(local); + } + }); globalVariableMap.set(file.getFileSignature(), globalLocals); for (const ns of file.getNamespaces()) { namespaceStack.push(ns); @@ -1326,7 +1364,7 @@ export class Scene { return this.buildStage >= SceneBuildStage.CLASS_DONE; } - public getModuleScene(moduleName: string) { + public getModuleScene(moduleName: string): ModuleScene | undefined { return this.moduleScenesMap.get(moduleName); } @@ -1334,7 +1372,7 @@ export class Scene { return this.moduleScenesMap; } - public getGlobalModule2PathMapping(): { [k: string]: string[]; } | undefined { + public getGlobalModule2PathMapping(): { [k: string]: string[] } | undefined { return this.globalModule2PathMapping; } @@ -1383,7 +1421,7 @@ export class ModuleScene { /** * get oh-package.json5 */ - private getModuleOhPkgFilePath() { + private getModuleOhPkgFilePath(): void { const moduleOhPkgFilePath = path.resolve(this.projectScene.getRealProjectDir(), path.join(this.modulePath, OH_PACKAGE_JSON5)); if (fs.existsSync(moduleOhPkgFilePath)) { this.moduleOhPkgFilePath = moduleOhPkgFilePath; @@ -1402,11 +1440,11 @@ export class ModuleScene { return this.modulePath; } - public getOhPkgFilePath() { + public getOhPkgFilePath(): string { return this.moduleOhPkgFilePath; } - public getOhPkgContent() { + public getOhPkgContent(): { [p: string]: unknown } { return this.ohPkgContent; } @@ -1418,15 +1456,14 @@ export class ModuleScene { this.moduleFileMap.set(arkFile.getFileSignature().toMapKey(), arkFile); } - private genArkFiles(supportFileExts: string[]) { - getAllFiles(this.modulePath, supportFileExts, this.projectScene.getOptions().ignoreFileNames).forEach((file) => { + private genArkFiles(supportFileExts: string[]): void { + getAllFiles(this.modulePath, supportFileExts, this.projectScene.getOptions().ignoreFileNames).forEach(file => { logger.info('=== parse file:', file); try { const arkFile: ArkFile = new ArkFile(FileUtils.getFileLanguage(file, this.projectScene.getFileLanguages())); arkFile.setScene(this.projectScene); arkFile.setModuleScene(this); - buildArkFileFromFile(file, this.projectScene.getRealProjectDir(), arkFile, - this.projectScene.getProjectName()); + buildArkFileFromFile(file, this.projectScene.getRealProjectDir(), arkFile, this.projectScene.getProjectName()); this.projectScene.setFile(arkFile); } catch (error) { logger.error('Error parsing file:', file, error); @@ -1435,4 +1472,4 @@ export class ModuleScene { } }); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/VFG/DVFG.ts b/ets2panda/linter/arkanalyzer/src/VFG/DVFG.ts index cdf1b3ee10d5e0c68d7d9b514b2109c7a8c4876c..feca7e2286c6ecf34020be9bd0dd930bf92589e2 100644 --- a/ets2panda/linter/arkanalyzer/src/VFG/DVFG.ts +++ b/ets2panda/linter/arkanalyzer/src/VFG/DVFG.ts @@ -85,8 +85,19 @@ export class DVFG extends BaseExplicitGraph { } export enum DVFGNodeKind { - assign, copy, write, load, addr, if, actualParm, formalParm, actualRet, - formalRet, unary, binary, normal + assign, + copy, + write, + load, + addr, + if, + actualParm, + formalParm, + actualRet, + formalRet, + unary, + binary, + normal, } export class DVFGNode extends BaseNode { @@ -108,4 +119,4 @@ export class DVFGNode extends BaseNode { } } -export class DVFGEdge extends BaseEdge {} \ No newline at end of file +export class DVFGEdge extends BaseEdge {} diff --git a/ets2panda/linter/arkanalyzer/src/VFG/builder/DVFGBuilder.ts b/ets2panda/linter/arkanalyzer/src/VFG/builder/DVFGBuilder.ts index 51bb4fb007eadeb87d6db769d70b4e1fea122691..f6169f1cf49829f85065849711227f763990ca3e 100644 --- a/ets2panda/linter/arkanalyzer/src/VFG/builder/DVFGBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/VFG/builder/DVFGBuilder.ts @@ -24,7 +24,7 @@ import { NodeID } from '../../core/graph/BaseExplicitGraph'; import { ArkMethod } from '../../core/model/ArkMethod'; import { FieldSignature } from '../../core/model/ArkSignature'; import { Scene } from '../../Scene'; -import { DVFG } from '../DVFG'; +import { DVFG, DVFGNode } from '../DVFG'; export class DVFGBuilder { private dvfg: DVFG; @@ -35,27 +35,33 @@ export class DVFGBuilder { this.scene = s; } - public build() { - this.scene.getMethods().forEach(m => { if (m.getCfg()) { this.buildForSingleMethod(m) } }); + public build(): void { + this.scene.getMethods().forEach(m => { + if (m.getCfg()) { + this.buildForSingleMethod(m); + } + }); } - public buildForSingleMethod(m: ArkMethod) { + public buildForSingleMethod(m: ArkMethod): void { let problem = new ReachingDefProblem(m); let solver = new MFPDataFlowSolver(); let solution = solver.calculateMopSolutionForwards(problem); let defMap = new Map>(); - m.getCfg()!.getStmts().forEach((s) => { - let def: Value | FieldSignature | null = s.getDef(); - if (def != null) { - if (def instanceof AbstractFieldRef) { - def = def.getFieldSignature(); + m.getCfg()! + .getStmts() + .forEach(s => { + let def: Value | FieldSignature | null = s.getDef(); + if (def != null) { + if (def instanceof AbstractFieldRef) { + def = def.getFieldSignature(); + } + let defStmts = defMap.get(def) ?? new Set(); + defStmts.add(s); + defMap.set(def, defStmts); } - let defStmts = defMap.get(def) ?? new Set(); - defStmts.add(s); - defMap.set(def, defStmts); - } - }); + }); solution.in.forEach((defs, reach) => { let addNewNodes = (defId: NodeID, def: Stmt, reach: Stmt): void => { @@ -72,7 +78,7 @@ export class DVFGBuilder { if (target instanceof AbstractFieldRef) { target = target.getFieldSignature(); } - defMap.get(target)?.forEach((defStmt) => { + defMap.get(target)?.forEach(defStmt => { let defId = problem.flowGraph.getNodeID(defStmt); addNewNodes(defId, defStmt, reachStmt); }); @@ -101,9 +107,13 @@ export class DVFGBuilder { private getUsedValues(val: Value): Value[] { if (val instanceof AbstractExpr) { if (val instanceof AbstractInvokeExpr) { - return val.getArgs().flatMap((current) => { return this.getUsedValues(current) }, []); + return val.getArgs().flatMap(current => { + return this.getUsedValues(current); + }, []); } else { - return val.getUses().flatMap((current) => { return this.getUsedValues(current) }, []); + return val.getUses().flatMap(current => { + return this.getUsedValues(current); + }, []); } } if (val instanceof Constant) { @@ -112,11 +122,11 @@ export class DVFGBuilder { return [val]; } - public getOrNewDVFGNode(stmt: Stmt) { + public getOrNewDVFGNode(stmt: Stmt): DVFGNode { return this.dvfg.getOrNewDVFGNode(stmt); } - public addDVFGNodes(): void { } + public addDVFGNodes(): void {} - public addDVFGEdges(): void { } -} \ No newline at end of file + public addDVFGEdges(): void {} +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/AbstractAnalysis.ts b/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/AbstractAnalysis.ts index 5c543b1c49b8059dca241b68f2c81d4ae812945b..4fb8a6f7b7185608987af0b265e98a098ee24047 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/AbstractAnalysis.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/AbstractAnalysis.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -24,6 +24,7 @@ import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; import { NodeID } from '../../core/graph/BaseExplicitGraph'; import { CallGraph, FuncID, CallSite, CallGraphNode } from '../model/CallGraph'; import { CallGraphBuilder } from '../model/builder/CallGraphBuilder'; +import { createPtsCollectionCtor, IPtsCollection, PtsCollectionType } from '../pointerAnalysis/PtsDS'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'CG'); @@ -32,7 +33,7 @@ export abstract class AbstractAnalysis { protected cg!: CallGraph; protected cgBuilder!: CallGraphBuilder; protected workList: FuncID[] = []; - protected processedMethod!: Set; + protected processedMethod!: IPtsCollection; constructor(s: Scene) { this.scene = s; @@ -54,6 +55,7 @@ export abstract class AbstractAnalysis { if (method != null) { return method; } + return undefined; } public getClassHierarchy(arkClass: ArkClass): ArkClass[] { @@ -78,35 +80,63 @@ export abstract class AbstractAnalysis { const method = this.workList.shift() as FuncID; const cgNode = this.cg.getNode(method) as CallGraphNode; - if (this.processedMethod.has(method) || cgNode.isSdkMethod()) { + if (this.processedMethod.contains(method) || cgNode.isSdkMethod()) { continue; } // pre process for RTA only this.preProcessMethod(method).forEach((cs: CallSite) => { this.workList.push(cs.calleeFuncID); - }) + }); this.processMethod(method).forEach((cs: CallSite) => { - let me = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + this.processCallSite(method, cs, displayGeneratedMethod); + }); + } + } + + public projectStart(displayGeneratedMethod: boolean): void { + this.scene.getMethods().forEach((method) => { + let cgNode = this.cg.getCallGraphNodeByMethod(method.getSignature()) as CallGraphNode; + + if (cgNode.isSdkMethod()) { + return; + } + + this.preProcessMethod(cgNode.getID()); - this.addCallGraphEdge(method, me, cs, displayGeneratedMethod); + this.processMethod(cgNode.getID()).forEach((cs: CallSite) => { + this.processCallSite(cgNode.getID(), cs, displayGeneratedMethod, true); + }); + }); + } - if (!this.processedMethod.has(cs.calleeFuncID)) { - this.workList.push(cs.calleeFuncID); - logger.info(`New workList item ${cs.calleeFuncID}: ${this.cg.getArkMethodByFuncID(cs.calleeFuncID)?.getSignature().toString()}`); + private processCallSite(method: FuncID, cs: CallSite, displayGeneratedMethod: boolean, isProject: boolean = false): void { + let me = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + let meNode = this.cg.getNode(cs.calleeFuncID) as CallGraphNode; + this.addCallGraphEdge(method, me, cs, displayGeneratedMethod); - this.processedMethod.add(cs.callerFuncID); - } - }) + if (isProject) { + return; + } + + this.processedMethod.insert(cs.callerFuncID); + + if (this.processedMethod.contains(cs.calleeFuncID) || meNode.isSdkMethod()) { + return; + } + + if (displayGeneratedMethod || !me?.isGenerated()) { + this.workList.push(cs.calleeFuncID); + logger.info(`New workList item ${cs.calleeFuncID}: ${this.cg.getArkMethodByFuncID(cs.calleeFuncID)?.getSignature().toString()}`); } } protected init(): void { - this.processedMethod = new Set(); - this.cg.getEntries().forEach((entryFunc) => { + this.processedMethod = new (createPtsCollectionCtor(PtsCollectionType.BitVector))(); + this.cg.getEntries().forEach(entryFunc => { this.workList.push(entryFunc); - }) + }); } protected processMethod(methodID: FuncID): CallSite[] { @@ -115,22 +145,22 @@ export abstract class AbstractAnalysis { let calleeMethods: CallSite[] = []; if (!arkMethod) { - throw new Error("can not find method"); + throw new Error('can not find method'); } const cfg = arkMethod.getCfg(); if (!cfg) { return []; } - cfg.getStmts().forEach((stmt) => { + cfg.getStmts().forEach(stmt => { if (stmt.containsInvokeExpr()) { - this.resolveCall(cgNode.getID(), stmt).forEach((callSite) => { + this.resolveCall(cgNode.getID(), stmt).forEach(callSite => { calleeMethods.push(callSite); this.cg.addStmtToCallSiteMap(stmt, callSite); this.cg.addMethodToCallSiteMap(callSite.calleeFuncID, callSite); }); } - }) + }); return calleeMethods; } @@ -138,7 +168,7 @@ export abstract class AbstractAnalysis { protected getParamAnonymousMethod(invokeExpr: AbstractInvokeExpr): MethodSignature[] { let paramMethod: MethodSignature[] = []; - invokeExpr.getArgs().forEach((args) => { + invokeExpr.getArgs().forEach(args => { let argsType = args.getType(); if (argsType instanceof FunctionType) { paramMethod.push(argsType.getMethodSignature()); @@ -153,9 +183,9 @@ export abstract class AbstractAnalysis { if (!callee) { logger.error(`FuncID has no method ${cs.calleeFuncID}`); } else { - if (displayGeneratedMethod || !(callee?.isGenerated())) { + if (displayGeneratedMethod || !callee?.isGenerated()) { this.cg.addDynamicCallEdge(caller, cs.calleeFuncID, cs.callStmt); } } } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/ClassHierarchyAnalysis.ts b/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/ClassHierarchyAnalysis.ts index f086c8267df53e759fee7345713dfa7bf5d7121a..029d85541ea8172eeeaf5b3bb1cd21b0aa67df9e 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/ClassHierarchyAnalysis.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/ClassHierarchyAnalysis.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -22,7 +22,6 @@ import { CallGraph, CallSite } from '../model/CallGraph'; import { AbstractAnalysis } from './AbstractAnalysis'; export class ClassHierarchyAnalysis extends AbstractAnalysis { - constructor(scene: Scene, cg: CallGraph) { super(scene); this.cg = cg; @@ -38,11 +37,7 @@ export class ClassHierarchyAnalysis extends AbstractAnalysis { // process anonymous method call this.getParamAnonymousMethod(invokeExpr).forEach(method => { - resolveResult.push( - new CallSite(invokeStmt, undefined, - this.cg.getCallGraphNodeByMethod(method).getID(), callerMethod - ) - ); + resolveResult.push(new CallSite(invokeStmt, undefined, this.cg.getCallGraphNodeByMethod(method).getID(), callerMethod)); }); let calleeMethod = this.resolveInvokeExpr(invokeExpr); @@ -51,9 +46,7 @@ export class ClassHierarchyAnalysis extends AbstractAnalysis { } if (invokeExpr instanceof ArkStaticInvokeExpr) { // get specific method - resolveResult.push(new CallSite(invokeStmt, undefined, - this.cg.getCallGraphNodeByMethod(calleeMethod!.getSignature()).getID(), - callerMethod!)); + resolveResult.push(new CallSite(invokeStmt, undefined, this.cg.getCallGraphNodeByMethod(calleeMethod!.getSignature()).getID(), callerMethod!)); } else { let declareClass = calleeMethod.getDeclaringArkClass(); // TODO: super class method should be placed at the end @@ -64,18 +57,18 @@ export class ClassHierarchyAnalysis extends AbstractAnalysis { let possibleCalleeMethod = arkClass.getMethodWithName(calleeMethod!.getName()); - if (possibleCalleeMethod && possibleCalleeMethod.isGenerated() && - arkClass.getSignature().toString() !== declareClass.getSignature().toString()) { + if ( + possibleCalleeMethod && + possibleCalleeMethod.isGenerated() && + arkClass.getSignature().toString() !== declareClass.getSignature().toString() + ) { // remove the generated method in extended classes return; } if (possibleCalleeMethod && !possibleCalleeMethod.isAbstract()) { resolveResult.push( - new CallSite(invokeStmt, undefined, - this.cg.getCallGraphNodeByMethod(possibleCalleeMethod.getSignature()).getID(), - callerMethod - ) + new CallSite(invokeStmt, undefined, this.cg.getCallGraphNodeByMethod(possibleCalleeMethod.getSignature()).getID(), callerMethod) ); } }); @@ -88,4 +81,4 @@ export class ClassHierarchyAnalysis extends AbstractAnalysis { // do nothing return []; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/RapidTypeAnalysis.ts b/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/RapidTypeAnalysis.ts index 1e447e6dccc90cab969d32b06b8c5ac0c1e32c13..b4ecc267ac48cc1ed19e38c685663ef8195fa732 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/RapidTypeAnalysis.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/algorithm/RapidTypeAnalysis.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -30,7 +30,7 @@ export class RapidTypeAnalysis extends AbstractAnalysis { // TODO: signature duplicated check private instancedClasses: Set = new Set(); // TODO: Set duplicated check - private ignoredCalls: Map> = new Map(); + private ignoredCalls: Map> = new Map(); constructor(scene: Scene, cg: CallGraph) { super(scene); @@ -47,9 +47,7 @@ export class RapidTypeAnalysis extends AbstractAnalysis { // process anonymous method call this.getParamAnonymousMethod(invokeExpr).forEach(method => { - resolveResult.push(new CallSite(invokeStmt, undefined, - this.cg.getCallGraphNodeByMethod(method).getID(), callerMethod) - ); + resolveResult.push(new CallSite(invokeStmt, undefined, this.cg.getCallGraphNodeByMethod(method).getID(), callerMethod)); }); let calleeMethod = this.resolveInvokeExpr(invokeExpr); @@ -59,9 +57,7 @@ export class RapidTypeAnalysis extends AbstractAnalysis { if (invokeExpr instanceof ArkStaticInvokeExpr) { // get specific method - resolveResult.push(new CallSite(invokeStmt, undefined, - this.cg.getCallGraphNodeByMethod(calleeMethod.getSignature()).getID(), callerMethod) - ); + resolveResult.push(new CallSite(invokeStmt, undefined, this.cg.getCallGraphNodeByMethod(calleeMethod.getSignature()).getID(), callerMethod)); } else { let declareClass = calleeMethod!.getDeclaringArkClass(); // TODO: super class method should be placed at the end @@ -72,8 +68,11 @@ export class RapidTypeAnalysis extends AbstractAnalysis { let possibleCalleeMethod = arkClass.getMethodWithName(calleeMethod!.getName()); - if (possibleCalleeMethod && possibleCalleeMethod.isGenerated() && - arkClass.getSignature().toString() !== declareClass.getSignature().toString()) { + if ( + possibleCalleeMethod && + possibleCalleeMethod.isGenerated() && + arkClass.getSignature().toString() !== declareClass.getSignature().toString() + ) { // remove the generated method in extended classes return; } @@ -83,14 +82,15 @@ export class RapidTypeAnalysis extends AbstractAnalysis { } if (!this.instancedClasses.has(arkClass.getSignature())) { - this.addIgnoredCalls(arkClass.getSignature(), callerMethod, + this.addIgnoredCalls( + arkClass.getSignature(), + callerMethod, this.cg.getCallGraphNodeByMethod(possibleCalleeMethod.getSignature()).getID(), invokeStmt ); } else { - resolveResult.push(new CallSite(invokeStmt, undefined, - this.cg.getCallGraphNodeByMethod(possibleCalleeMethod.getSignature()).getID(), - callerMethod) + resolveResult.push( + new CallSite(invokeStmt, undefined, this.cg.getCallGraphNodeByMethod(possibleCalleeMethod.getSignature()).getID(), callerMethod) ); } }); @@ -102,14 +102,12 @@ export class RapidTypeAnalysis extends AbstractAnalysis { protected preProcessMethod(funcID: FuncID): CallSite[] { let newCallSites: CallSite[] = []; let instancedClasses: Set = this.collectInstancedClassesInMethod(funcID); - let newlyInstancedClasses = new Set( - Array.from(instancedClasses).filter(item => !this.instancedClasses.has(item)) - ); + let newlyInstancedClasses = new Set(Array.from(instancedClasses).filter(item => !this.instancedClasses.has(item))); newlyInstancedClasses.forEach(sig => { - let ignoredCalls = this.ignoredCalls.get(sig) + let ignoredCalls = this.ignoredCalls.get(sig); if (ignoredCalls) { - ignoredCalls.forEach((call) => { + ignoredCalls.forEach(call => { this.cg.addDynamicCallEdge(call.caller, call.callee, call.callStmt); newCallSites.push(new CallSite(call.callStmt, undefined, call.callee, call.caller)); }); @@ -120,7 +118,7 @@ export class RapidTypeAnalysis extends AbstractAnalysis { return newCallSites; } - private collectInstancedClassesInMethod(funcID: FuncID) { + private collectInstancedClassesInMethod(funcID: FuncID): Set { let instancedClasses: Set = new Set(); let arkMethod = this.cg.getArkMethodByFuncID(funcID); @@ -148,9 +146,9 @@ export class RapidTypeAnalysis extends AbstractAnalysis { return instancedClasses; } - public addIgnoredCalls(arkClass: ClassSignature, callerID: FuncID, calleeID: FuncID, invokeStmt: Stmt) { + public addIgnoredCalls(arkClass: ClassSignature, callerID: FuncID, calleeID: FuncID, invokeStmt: Stmt): void { let classMap = this.ignoredCalls.get(arkClass) ?? new Set(); classMap.add({ caller: callerID, callee: calleeID, callStmt: invokeStmt }); this.ignoredCalls.set(arkClass, classMap); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/common/Statistics.ts b/ets2panda/linter/arkanalyzer/src/callgraph/common/Statistics.ts index e3b41aeaa9b65b37661126c66fe983e5a55c85ae..61246908adb1ecf0ba1446fa8a77d7860d0fb458 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/common/Statistics.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/common/Statistics.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,15 +13,19 @@ * limitations under the License. */ -import { ArkAssignStmt, Stmt } from "../../core/base/Stmt"; -import { UnknownType } from "../../core/base/Type"; -import { CallGraphNode, CallGraphNodeKind } from "../model/CallGraph"; -import { PointerAnalysis } from "../pointerAnalysis/PointerAnalysis"; -import Logger, { LOG_MODULE_TYPE } from "../../utils/logger"; +import { ArkAssignStmt, Stmt } from '../../core/base/Stmt'; +import { UnknownType } from '../../core/base/Type'; +import { CallGraphNode, CallGraphNodeKind } from '../model/CallGraph'; +import { PointerAnalysis } from '../pointerAnalysis/PointerAnalysis'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'PTA'); abstract class StatTraits { + TotalTime: number = 0; + startTime: number = 0; + endTime: number = 0; + public getStat(): string { return ''; } @@ -31,7 +35,7 @@ abstract class StatTraits { } } -export class PTAStat implements StatTraits { +export class PTAStat extends StatTraits { pta: PointerAnalysis; numProcessedAddr: number = 0; numProcessedCopy: number = 0; @@ -56,10 +60,6 @@ export class PTAStat implements StatTraits { numUnhandledFunc: number = 0; iterTimes: number = 0; - TotalTime: number = 0; - - startTime: number = 0; - endTime: number = 0; startMemUsage: any; endMemUsage: any; @@ -67,6 +67,7 @@ export class PTAStat implements StatTraits { heapUsed: number = 0; constructor(pta: PointerAnalysis) { + super(); this.pta = pta; } @@ -121,7 +122,10 @@ export class PTAStat implements StatTraits { let cg = this.pta.getCallGraph(); this.pta.getHandledFuncs().forEach(funcID => { let f = cg.getArkMethodByFuncID(funcID); - f?.getCfg()?.getStmts().forEach(s => stmtStat(s)); + f + ?.getCfg() + ?.getStmts() + .forEach(s => stmtStat(s)); }); } @@ -143,23 +147,22 @@ export class PTAStat implements StatTraits { public getStat(): string { // TODO: get PAG stat and CG stat let output: string; - output = '==== Pointer analysis Statictics: ====\n' - output = output + `Processed address\t${this.numProcessedAddr}\n` - output = output + `Processed copy\t\t${this.numProcessedCopy}\n` - output = output + `Processed load\t\t${this.numProcessedLoad}\n` - output = output + `Processed write\t\t${this.numProcessedWrite}\n` - output = output + `Real write\t\t${this.numRealWrite}\n` - output = output + `Real load\t\t${this.numRealLoad}\n` - output = output + `Processed This\t\t${this.numProcessedThis}\n\n` - output = output + `Unhandled function\t${this.numUnhandledFun}\n` - output = output + `Total values in visited function\t${this.totalValuesInVisitedFunc}\n` - output = output + `Infered Value unknown+different type\t${this.numInferedUnknownValue}+${this.numInferedDiffTypeValue}\n\n` - output = output + `Total Time\t\t${this.TotalTime} S\n` - output = output + `Total iterator Times\t${this.iterTimes}\n` - output = output + `RSS used\t\t${this.rssUsed.toFixed(3)} Mb\n` - output = output + `Heap used\t\t${this.heapUsed.toFixed(3)} Mb\n` + output = '==== Pointer analysis Statictics: ====\n'; + output = output + `Processed address\t${this.numProcessedAddr}\n`; + output = output + `Processed copy\t\t${this.numProcessedCopy}\n`; + output = output + `Processed load\t\t${this.numProcessedLoad}\n`; + output = output + `Processed write\t\t${this.numProcessedWrite}\n`; + output = output + `Real write\t\t${this.numRealWrite}\n`; + output = output + `Real load\t\t${this.numRealLoad}\n`; + output = output + `Processed This\t\t${this.numProcessedThis}\n\n`; + output = output + `Unhandled function\t${this.numUnhandledFun}\n`; + output = output + `Total values in visited function\t${this.totalValuesInVisitedFunc}\n`; + output = output + `Infered Value unknown+different type\t${this.numInferedUnknownValue}+${this.numInferedDiffTypeValue}\n\n`; + output = output + `Total Time\t\t${this.TotalTime} S\n`; + output = output + `Total iterator Times\t${this.iterTimes}\n`; + output = output + `RSS used\t\t${this.rssUsed.toFixed(3)} Mb\n`; + output = output + `Heap used\t\t${this.heapUsed.toFixed(3)} Mb\n`; return output; - } public printStat(): void { @@ -167,17 +170,17 @@ export class PTAStat implements StatTraits { } } -export class PAGStat implements StatTraits { +export class PAGStat extends StatTraits { numDynamicCall: number = 0; numTotalFunction: number = 0; numTotalNode: number = 0; public getStat(): string { let output: string; - output = '==== PAG Statictics: ====\n' - output = output + `Dynamic call\t\t${this.numDynamicCall}\n` - output = output + `Total function handled\t${this.numTotalFunction}\n` - output = output + `Total PAG Nodes\t\t${this.numTotalNode}\n` + output = '==== PAG Statictics: ====\n'; + output = output + `Dynamic call\t\t${this.numDynamicCall}\n`; + output = output + `Total function handled\t${this.numTotalFunction}\n`; + output = output + `Total PAG Nodes\t\t${this.numTotalNode}\n`; return output; } @@ -194,8 +197,17 @@ export class CGStat extends StatTraits { numIntrinsic: number = 0; numConstructor: number = 0; + public startStat(): void { + this.startTime = new Date().getTime(); + } + + public endStat(): void { + this.endTime = new Date().getTime(); + this.TotalTime = (this.endTime - this.startTime) / 1000; + } + public addNodeStat(kind: CallGraphNodeKind): void { - switch(kind) { + switch (kind) { case CallGraphNodeKind.real: this.numReal++; break; @@ -215,12 +227,13 @@ export class CGStat extends StatTraits { public getStat(): string { let output: string; - output = '==== CG Statictics: ====\n' - output = output + `Real function\t\t${this.numReal}\n` - output = output + `Intrinsic function\t${this.numIntrinsic}\n` - output = output + `Constructor function\t${this.numConstructor}\n` - output = output + `Blank function\t\t${this.numVirtual}\n` - output = output + `Total\t\t\t${this.numTotalNode}\n` + output = '==== CG Statictics: ====\n'; + output = output + `CG construction Total Time\t\t${this.TotalTime} S\n`; + output = output + `Real function\t\t${this.numReal}\n`; + output = output + `Intrinsic function\t${this.numIntrinsic}\n`; + output = output + `Constructor function\t${this.numConstructor}\n`; + output = output + `Blank function\t\t${this.numVirtual}\n`; + output = output + `Total\t\t\t${this.numTotalNode}\n`; return output; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/model/CallGraph.ts b/ets2panda/linter/arkanalyzer/src/callgraph/model/CallGraph.ts index 78b28920881ce40100b4c6a81526d7e2eb76ce8e..954f47804a2413dbdba1747ea31f02b19edc1cd6 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/model/CallGraph.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/model/CallGraph.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,9 +13,9 @@ * limitations under the License. */ -import { MethodSignature } from '../../core/model/ArkSignature' -import { Stmt } from '../../core/base/Stmt' -import { Value } from '../../core/base/Value' +import { MethodSignature } from '../../core/model/ArkSignature'; +import { Stmt } from '../../core/base/Stmt'; +import { Value } from '../../core/base/Value'; import { Scene } from '../../Scene'; import { ArkMethod } from '../../core/model/ArkMethod'; import { GraphPrinter } from '../../save/GraphPrinter'; @@ -31,7 +31,10 @@ export type FuncID = number; type StmtSet = Set; export enum CallGraphNodeKind { - real, vitual, intrinsic, constructor + real, + vitual, + intrinsic, + constructor, } export class CallSite { @@ -81,15 +84,15 @@ export class CallGraphEdge extends BaseEdge { super(src, dst, 0); } - public addDirectCallSite(stmt: Stmt) { + public addDirectCallSite(stmt: Stmt): void { this.directCalls.add(stmt); } - public addSpecialCallSite(stmt: Stmt) { + public addSpecialCallSite(stmt: Stmt): void { this.specialCalls.add(stmt); } - public addInDirectCallSite(stmt: Stmt) { + public addInDirectCallSite(stmt: Stmt): void { this.indirectCalls.add(stmt); } @@ -98,17 +101,17 @@ export class CallGraphEdge extends BaseEdge { const directCallNums: number = this.directCalls.size; const specialCallNums: number = this.specialCalls.size; if ([CallGraphNodeKind.intrinsic, CallGraphNodeKind.constructor].includes(this.getDstNode().getKind())) { - return '' + return ''; } if (indirectCallNums !== 0 && directCallNums === 0) { - return "color=red"; + return 'color=red'; } else if (specialCallNums !== 0) { - return "color=yellow"; + return 'color=yellow'; } else if (indirectCallNums === 0 && directCallNums !== 0) { - return "color=black"; + return 'color=black'; } else { - return "color=black"; + return 'color=black'; } } } @@ -132,7 +135,7 @@ export class CallGraphNode extends BaseNode { } public isSdkMethod(): boolean { - return this.ifSdkMethod + return this.ifSdkMethod; } public get isBlankMethod(): boolean { @@ -190,9 +193,7 @@ export class CallGraph extends BaseExplicitGraph { let id: NodeID = this.nodeNum; let cgNode = new CallGraphNode(id, method, kind); // check if sdk method - cgNode.setSdkMethod(this.scene.hasSdkFile( - method.getDeclaringClassSignature().getDeclaringFileSignature() - )); + cgNode.setSdkMethod(this.scene.hasSdkFile(method.getDeclaringClassSignature().getDeclaringFileSignature())); let arkMethod = this.scene.getMethod(method); if (!arkMethod || !arkMethod.getCfg()) { @@ -205,7 +206,7 @@ export class CallGraph extends BaseExplicitGraph { return cgNode; } - public removeCallGraphNode(nodeID: NodeID) { + public removeCallGraphNode(nodeID: NodeID): void { // remove edge relate to node first this.removeCallGraphEdge(nodeID); let node = this.getNode(nodeID) as CallGraphNode; @@ -264,7 +265,7 @@ export class CallGraph extends BaseExplicitGraph { } } - public removeCallGraphEdge(nodeID: NodeID) { + public removeCallGraphEdge(nodeID: NodeID): void { let node = this.getNode(nodeID) as CallGraphNode; for (const inEdge of node.getIncomingEdge()) { @@ -284,11 +285,11 @@ export class CallGraph extends BaseExplicitGraph { } let args = callStmt.getInvokeExpr()?.getArgs(); - let cs = new DynCallSite(callerNode.getID(), callStmt, args, calleeNode?.getID()) + let cs = new DynCallSite(callerNode.getID(), callStmt, args, calleeNode?.getID()); this.stmtToDynCallSitemap.set(callStmt, cs); } - public addDynamicCallEdge(callerID: NodeID, calleeID: NodeID, callStmt: Stmt) { + public addDynamicCallEdge(callerID: NodeID, calleeID: NodeID, callStmt: Stmt): void { let callerNode = this.getNode(callerID) as CallGraphNode; let calleeNode = this.getNode(calleeID) as CallGraphNode; @@ -342,7 +343,7 @@ export class CallGraph extends BaseExplicitGraph { public getInvokeStmtByMethod(func: FuncID | MethodSignature): Stmt[] { let callSites = this.getCallSitesByMethod(func); let invokeStmts: Stmt[] = []; - callSites.forEach((cs) => { + callSites.forEach(cs => { invokeStmts.push(cs.callStmt); }); @@ -372,7 +373,6 @@ export class CallGraph extends BaseExplicitGraph { if (node !== undefined) { return (node as CallGraphNode).getMethod(); } - //return undefined; return null; } @@ -428,6 +428,14 @@ export class CallGraph extends BaseExplicitGraph { return false; } + public startStat(): void { + this.cgStat.startStat(); + } + + public endStat(): void { + this.cgStat.endStat(); + } + public printStat(): void { this.cgStat.printStat(); } diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/model/builder/CallGraphBuilder.ts b/ets2panda/linter/arkanalyzer/src/callgraph/model/builder/CallGraphBuilder.ts index 88076a8eaf829a1a11a5e3f42d962f423b5b455c..c631c4333fc41b233ee3fba8988fb5f0ebb530b3 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/model/builder/CallGraphBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/model/builder/CallGraphBuilder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -15,7 +15,7 @@ import { CallGraph, CallGraphNode, CallGraphNodeKind, Method } from '../CallGraph'; import { Scene } from '../../../Scene'; -import { AbstractInvokeExpr, ArkInstanceInvokeExpr, ArkStaticInvokeExpr } from "../../../core/base/Expr"; +import { AbstractInvokeExpr, ArkInstanceInvokeExpr, ArkStaticInvokeExpr } from '../../../core/base/Expr'; import { NodeID } from '../../../core/graph/BaseExplicitGraph'; import { ClassHierarchyAnalysis } from '../../algorithm/ClassHierarchyAnalysis'; import { RapidTypeAnalysis } from '../../algorithm/RapidTypeAnalysis'; @@ -30,7 +30,6 @@ export class CallGraphBuilder { this.scene = s; } - public buildDirectCallGraphForScene(): void { const methods = this.scene.getMethods(); this.buildDirectCallGraph(methods); @@ -70,8 +69,11 @@ export class CallGraphBuilder { // abstract method will also be added into direct cg if (callee && invokeExpr instanceof ArkStaticInvokeExpr) { this.cg.addDirectOrSpecialCallEdge(method.getSignature(), callee, stmt); - } else if (callee && (invokeExpr instanceof ArkInstanceInvokeExpr && ( - this.isConstructor(callee) || this.scene.getMethod(callee)?.isGenerated()))) { + } else if ( + callee && + invokeExpr instanceof ArkInstanceInvokeExpr && + (this.isConstructor(callee) || this.scene.getMethod(callee)?.isGenerated()) + ) { this.cg.addDirectOrSpecialCallEdge(method.getSignature(), callee, stmt, false); } else { this.cg.addDynamicCallInfo(stmt, method.getSignature(), callee); @@ -84,18 +86,23 @@ export class CallGraphBuilder { let cgEntries: NodeID[] = []; entries.forEach((entry: Method) => { cgEntries.push(this.cg.getCallGraphNodeByMethod(entry).getID()); - }) + }); this.cg.setEntries(cgEntries); let classHierarchyAnalysis: ClassHierarchyAnalysis = new ClassHierarchyAnalysis(this.scene, this.cg); classHierarchyAnalysis.start(displayGeneratedMethod); } + public buildCHA4WholeProject(displayGeneratedMethod: boolean = false): void { + let classHierarchyAnalysis: ClassHierarchyAnalysis = new ClassHierarchyAnalysis(this.scene, this.cg); + classHierarchyAnalysis.projectStart(displayGeneratedMethod); + } + public buildRapidTypeCallGraph(entries: Method[], displayGeneratedMethod: boolean = false): void { let cgEntries: NodeID[] = []; entries.forEach((entry: Method) => { cgEntries.push(this.cg.getCallGraphNodeByMethod(entry).getID()); - }) + }); this.cg.setEntries(cgEntries); let rapidTypeAnalysis: RapidTypeAnalysis = new RapidTypeAnalysis(this.scene, this.cg); @@ -114,8 +121,7 @@ export class CallGraphBuilder { public setEntries(): void { let nodesIter = this.cg.getNodesIter(); let entries = Array.from(nodesIter) - .filter(node => !node.hasIncomingEdges() && node.getKind() === CallGraphNodeKind.real - && !(node as CallGraphNode).isBlankMethod) + .filter(node => !node.hasIncomingEdges() && node.getKind() === CallGraphNodeKind.real && !(node as CallGraphNode).isBlankMethod) .map(node => node.getID()); this.cg.setEntries(entries); } diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/Context.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/Context.ts index e8affe8adbf7f9909fdebbfe5e1ab002c2d4b4d3..71b00b5b9bb49bbad9d14aae5f9ed207a65d182a 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/Context.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/Context.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,10 +13,10 @@ * limitations under the License. */ -import {FuncID} from '../model/CallGraph' +import { FuncID } from '../model/CallGraph'; -export type ContextID = number -export const DUMMY_CID = 0 +export type ContextID = number; +export const DUMMY_CID = 0; class Context { private contextElems: number[]; @@ -34,7 +34,7 @@ class Context { return new Context(contextElems); } - // use old context and a new element to create a new k-limited Context + // use old context and a new element to create a new k-limited Context static newKLimitedContext(oldCtx: Context, elem: number, k: number): Context { let elems: number[] = []; if (k > 0) { @@ -48,7 +48,7 @@ class Context { return new Context(elems); } - static kLimitedContext(ctx: Context, k:number): Context { + static kLimitedContext(ctx: Context, k: number): Context { if (ctx.length() <= k) { return new Context(ctx.contextElems); } else { @@ -69,7 +69,7 @@ class Context { } public toString(): String { - return this.contextElems.join('-') + return this.contextElems.join('-'); } } @@ -96,7 +96,7 @@ class ContextCache { } public updateContext(id: ContextID, newContext: Context, oldContext: Context): boolean { - if(this.contextList.length < id) { + if (this.contextList.length < id) { return false; } this.contextList[id] = newContext; @@ -143,11 +143,11 @@ export class KLimitedContextSensitive { return new Context([]); } - public getEmptyContextID(): ContextID{ + public getEmptyContextID(): ContextID { return this.getContextID(Context.newEmpty()); } - public getContextID(context: Context): ContextID{ + public getContextID(context: Context): ContextID { return this.ctxCache.getOrNewContextID(context); } @@ -156,7 +156,7 @@ export class KLimitedContextSensitive { } public getNewContextID(callerFuncId: FuncID): ContextID { - return this.ctxCache.getOrNewContextID(Context.new([callerFuncId])); + return this.ctxCache.getOrNewContextID(Context.new([callerFuncId])); } public getOrNewContext(callerCid: ContextID, calleeFuncId: FuncID, findCalleeAsTop: boolean = false): ContextID { @@ -166,7 +166,7 @@ export class KLimitedContextSensitive { } const calleeNewCtx = Context.newKLimitedContext(callerCtx, calleeFuncId, this.k); - if (findCalleeAsTop){ + if (findCalleeAsTop) { const calleeAsTopCtx = Context.newKLimitedContext(Context.sEmptyCtx, calleeFuncId, this.k); let topID = this.ctxCache.getContextID(calleeAsTopCtx); if (topID) { @@ -178,4 +178,4 @@ export class KLimitedContextSensitive { const calleeCid = this.ctxCache.getOrNewContextID(calleeNewCtx); return calleeCid; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/DummyCallCreator.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/DummyCallCreator.ts index 3708605bdf6378fd11cba86de5c7178b2bc9482c..0595926cc48756961aba6249e0973103c1577743 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/DummyCallCreator.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/DummyCallCreator.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,7 +13,6 @@ * limitations under the License. */ - import { ArkInstanceInvokeExpr } from '../../core/base/Expr'; import { Local } from '../../core/base/Local'; import { Stmt, ArkInvokeStmt } from '../../core/base/Stmt'; @@ -31,7 +30,7 @@ const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'Dummy Call'); export class DummyCallCreator { private scene: Scene; private pageMap; - // TODO: classSig -> str ? + // TODO: classSig -> str ? private componentMap: Map>; constructor(scene: Scene) { @@ -86,7 +85,9 @@ export class DummyCallCreator { let callStmts: Stmt[] = []; // filter callback method - componentClass.getMethods().filter(method => COMPONENT_LIFECYCLE_METHOD_NAME.includes(method.getName())) + componentClass + .getMethods() + .filter(method => COMPONENT_LIFECYCLE_METHOD_NAME.includes(method.getName())) .forEach((method: ArkMethod) => { // TODO: args pointer ? if (method.getParameters().length === 0) { @@ -98,4 +99,4 @@ export class DummyCallCreator { return callStmts; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PTAUtils.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PTAUtils.ts index 04b07551c96c9933534c0533c340b2b379ab5d67..a8940d5d3c21b561450e4ac051f3684fa728fb7e 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PTAUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PTAUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -16,30 +16,44 @@ import { ClassSignature, MethodSignature } from '../../core/model/ArkSignature'; export function IsCollectionClass(classSignature: ClassSignature): boolean { - if (classSignature.toString().endsWith('lib.es2015.collection.d.ts: Set') || - classSignature.toString().endsWith('lib.es2015.collection.d.ts: Map')) { + if (classSignature.toString().endsWith('lib.es2015.collection.d.ts: Set') || classSignature.toString().endsWith('lib.es2015.collection.d.ts: Map')) { return true; } return false; } -export function IsCollectionAPI(method: MethodSignature): boolean { - if (IsCollectionSetAdd(method) || IsCollectionMapSet(method)) { - return true; - } - return false; +export enum BuiltApiType { + SetAdd, + MapSet, + FunctionCall, + FunctionApply, + FunctionBind, + NotBuiltIn, } -export function IsCollectionSetAdd(method: MethodSignature): boolean { - if (method.toString().endsWith('lib.es2015.collection.d.ts: Set.add(T)')) { - return true; - } - return false; -} +export function getBuiltInApiType(method: MethodSignature): BuiltApiType { + let methodSigStr = method.toString(); -export function IsCollectionMapSet(method: MethodSignature): boolean { - if (method.toString().endsWith('lib.es2015.collection.d.ts: Map.set(K, V)')) { - return true; + const regex = /lib\.es5\.d\.ts: Function\.(call|apply|bind)\(/; + + if (methodSigStr.endsWith('lib.es2015.collection.d.ts: Set.add(T)')) { + return BuiltApiType.SetAdd; + } else if (methodSigStr.endsWith('lib.es2015.collection.d.ts: Map.set(K, V)')) { + return BuiltApiType.MapSet; + } else { + const match = methodSigStr.match(regex); + if (match) { + const functionName = match[1]; + switch (functionName) { + case 'call': + return BuiltApiType.FunctionCall; + case 'apply': + return BuiltApiType.FunctionApply; + case 'bind': + return BuiltApiType.FunctionBind; + } + } } - return false; -} \ No newline at end of file + + return BuiltApiType.NotBuiltIn; +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/Pag.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/Pag.ts index 6da4c6c9ac66900f58d7263c75759b12780f9188..b04e4cc1ec55a4f69211c66a8c2f1c3b3bc2dcc7 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/Pag.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/Pag.ts @@ -29,7 +29,7 @@ import { ContextID } from './Context'; import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; import { GLOBAL_THIS_NAME } from '../../core/common/TSConst'; import { ExportInfo } from '../../core/model/ArkExport'; -import { IsCollectionClass } from './PTAUtils'; +import { BuiltApiType, getBuiltInApiType, IsCollectionClass } from './PTAUtils'; import { IPtsCollection } from './PtsDS'; import { PointerAnalysisConfig } from './PointerAnalysisConfig'; @@ -40,20 +40,28 @@ export type PagNodeType = Value; * Implementation of pointer-to assignment graph for pointer analysis */ -const DUMMY_PAG_NODE_ID = -1 +const DUMMY_PAG_NODE_ID = -1; export enum PagEdgeKind { - Address, Copy, Load, Write, This, Unknown, InterProceduralCopy -}; + Address, + Copy, + Load, + Write, + This, + Unknown, + InterProceduralCopy, +} export enum StorageType { - APP_STORAGE, LOCAL_STORAGE, Undefined -}; + APP_STORAGE, + LOCAL_STORAGE, + Undefined, +} export enum StorageLinkEdgeType { Property2Local, Local2Property, - TwoWay + TwoWay, } export class PagEdge extends BaseEdge { @@ -62,27 +70,27 @@ export class PagEdge extends BaseEdge { constructor(n: PagNode, d: PagNode, k: PagEdgeKind, s?: Stmt) { super(n, d, k); this.stmt = s; - }; + } public getDotAttr(): string { switch (this.getKind()) { case PagEdgeKind.Address: - return "color=green"; + return 'color=green'; case PagEdgeKind.Copy: if (this.stmt?.getInvokeExpr() !== undefined || this.stmt instanceof ArkReturnStmt) { - return "color=black,style=dotted"; + return 'color=black,style=dotted'; } - return "color=black"; + return 'color=black'; case PagEdgeKind.Load: - return "color=red"; + return 'color=red'; case PagEdgeKind.Write: - return "color=blue" + return 'color=blue'; case PagEdgeKind.This: - return "color=orange" + return 'color=orange'; case PagEdgeKind.InterProceduralCopy: - return "color=purple,style=dashed"; + return 'color=purple,style=dashed'; default: - return "color=black"; + return 'color=black'; } } } @@ -90,36 +98,46 @@ export class PagEdge extends BaseEdge { export class AddrPagEdge extends PagEdge { constructor(n: PagNode, d: PagNode, s: Stmt) { super(n, d, PagEdgeKind.Address, s); - }; + } } export class CopyPagEdge extends PagEdge { constructor(n: PagNode, d: PagNode, s: Stmt) { super(n, d, PagEdgeKind.Copy, s); - }; + } } export class LoadPagEdge extends PagEdge { constructor(n: PagNode, d: PagNode, s: Stmt) { super(n, d, PagEdgeKind.Copy, s); - }; + } } export class WritePagEdge extends PagEdge { constructor(n: PagNode, d: PagNode, s: Stmt) { super(n, d, PagEdgeKind.Write, s); - }; + } } export class ThisPagEdge extends PagEdge { constructor(n: PagNode, d: PagNode, s: Stmt) { super(n, d, PagEdgeKind.This, s); - }; + } } type PagEdgeSet = Set; -export enum PagNodeKind { HeapObj, LocalVar, RefVar, Param, ThisRef, Function, GlobalThis, ExportInfo } +export enum PagNodeKind { + HeapObj, + LocalVar, + RefVar, + Param, + ThisRef, + Function, + GlobalThis, + ExportInfo, +} + export class PagNode extends BaseNode { private cid: ContextID | undefined; private value: Value; @@ -156,22 +174,22 @@ export class PagNode extends BaseNode { return this.basePt; } - public setBasePt(pt: NodeID) { + public setBasePt(pt: NodeID): void { this.basePt = pt; } public getCid(): ContextID { if (this.cid === undefined) { - throw new Error('cid is undefine') + throw new Error('cid is undefine'); } return this.cid; } - public setCid(cid: ContextID) { + public setCid(cid: ContextID): void { this.cid = cid; } - public setStmt(s: Stmt) { + public setStmt(s: Stmt): void { this.stmt = s; } @@ -180,7 +198,7 @@ export class PagNode extends BaseNode { } public hasOutgoingCopyEdge(): boolean { - return (this.copyOutEdges.size !== 0); + return this.copyOutEdges.size !== 0; } public getOutgoingCopyEdges(): PagEdgeSet { @@ -212,38 +230,38 @@ export class PagNode extends BaseNode { } public addAddressInEdge(e: AddrPagEdge): void { - this.addressInEdges === undefined ? this.addressInEdges = new Set() : undefined; + this.addressInEdges === undefined ? (this.addressInEdges = new Set()) : undefined; this.addressInEdges.add(e); this.addIncomingEdge(e); } public addAddressOutEdge(e: AddrPagEdge): void { - this.addressOutEdges === undefined ? this.addressOutEdges = new Set() : undefined; + this.addressOutEdges === undefined ? (this.addressOutEdges = new Set()) : undefined; this.addressOutEdges.add(e); this.addOutgoingEdge(e); } public addCopyInEdge(e: CopyPagEdge): void { - this.copyInEdges === undefined ? this.copyInEdges = new Set() : undefined; + this.copyInEdges === undefined ? (this.copyInEdges = new Set()) : undefined; this.copyInEdges.add(e); this.addIncomingEdge(e); } public addCopyOutEdge(e: CopyPagEdge): void { - this.copyOutEdges === undefined ? this.copyOutEdges = new Set() : undefined; + this.copyOutEdges === undefined ? (this.copyOutEdges = new Set()) : undefined; this.copyOutEdges.add(e); this.addOutgoingEdge(e); } public addLoadInEdge(e: LoadPagEdge): void { - this.loadInEdges === undefined ? this.loadInEdges = new Set() : undefined; + this.loadInEdges === undefined ? (this.loadInEdges = new Set()) : undefined; this.loadInEdges.add(e); this.addIncomingEdge(e); } public addLoadOutEdge(e: LoadPagEdge): void { - this.loadOutEdges === undefined ? this.loadOutEdges = new Set() : undefined; + this.loadOutEdges === undefined ? (this.loadOutEdges = new Set()) : undefined; this.loadOutEdges.add(e); this.addOutgoingEdge(e); } @@ -280,7 +298,7 @@ export class PagNode extends BaseNode { return this.pointTo; } - public addPointToElement(node: NodeID) { + public addPointToElement(node: NodeID): void { this.pointTo.insert(node); } @@ -288,13 +306,18 @@ export class PagNode extends BaseNode { this.pointTo = pts; } - public getOutEdges() { + public getOutEdges(): { + AddressEdge: PagEdgeSet; + CopyEdge: PagEdgeSet; + LoadEdge: PagEdgeSet; + WriteEdge: PagEdgeSet; + } { return { AddressEdge: this.addressOutEdges, CopyEdge: this.copyOutEdges, LoadEdge: this.loadOutEdges, - WriteEdge: this.writeOutEdges - } + WriteEdge: this.writeOutEdges, + }; } public getClonedFrom(): NodeID { @@ -320,7 +343,7 @@ export class PagNode extends BaseNode { case PagNodeKind.ExportInfo: return 'shape=tab,color=purple'; case PagNodeKind.ThisRef: - return 'shape=box,color=orange' + return 'shape=box,color=orange'; default: return 'shape=box'; } @@ -335,7 +358,7 @@ export class PagNode extends BaseNode { if (this.basePt) { label = label + ` base:{${this.basePt}}`; } - label = label + ` pts:{${Array.from(this.pointTo).join(',')}}` + label = label + ` pts:{${Array.from(this.pointTo).join(',')}}`; if (this.getKind() === PagNodeKind.Param) { param = this.value as ArkParameterRef; @@ -346,6 +369,10 @@ export class PagNode extends BaseNode { label = label + `\n${(this.value as ArkThisRef).toString()}`; } + if (this.getKind() === PagNodeKind.Function) { + label = label + ` thisPt:{${(this as unknown as PagFuncNode).getThisPt()}}`; + } + if (this.stmt) { label = label + `\n${this.stmt.toString()}`; let method = this.stmt.getCfg()?.getDeclaringMethod().getSubSignature().toString(); @@ -371,20 +398,20 @@ export class PagLocalNode extends PagNode { private sdkParam: boolean = false; constructor(id: NodeID, cid: ContextID | undefined = undefined, value: Local, stmt?: Stmt) { - super(id, cid, value, PagNodeKind.LocalVar, stmt) + super(id, cid, value, PagNodeKind.LocalVar, stmt); } - public addRelatedDynCallSite(cs: DynCallSite) { - this.relatedDynamicCallSite = this.relatedDynamicCallSite ?? new Set() + public addRelatedDynCallSite(cs: DynCallSite): void { + this.relatedDynamicCallSite = this.relatedDynamicCallSite ?? new Set(); - this.relatedDynamicCallSite.add(cs) + this.relatedDynamicCallSite.add(cs); } public getRelatedDynCallSites(): Set { return this.relatedDynamicCallSite ?? new Set(); } - public addRelatedUnknownCallSite(cs: CallSite) { + public addRelatedUnknownCallSite(cs: CallSite): void { this.relatedUnknownCallSite = this.relatedUnknownCallSite ?? new Set(); this.relatedUnknownCallSite.add(cs); @@ -400,10 +427,10 @@ export class PagLocalNode extends PagNode { this.propertyName = propertyName; } - public getStorage(): { StorageType: StorageType, PropertyName: string } { + public getStorage(): { StorageType: StorageType; PropertyName: string } { return { StorageType: this.storageType!, - PropertyName: this.propertyName! + PropertyName: this.propertyName!, }; } @@ -422,14 +449,13 @@ export class PagLocalNode extends PagNode { export class PagInstanceFieldNode extends PagNode { constructor(id: NodeID, cid: ContextID | undefined = undefined, instanceFieldRef: ArkInstanceFieldRef, stmt?: Stmt) { - super(id, cid, instanceFieldRef, PagNodeKind.RefVar, stmt) + super(id, cid, instanceFieldRef, PagNodeKind.RefVar, stmt); } - } export class PagStaticFieldNode extends PagNode { constructor(id: NodeID, cid: ContextID | undefined = undefined, staticFieldRef: ArkStaticFieldRef, stmt?: Stmt) { - super(id, cid, staticFieldRef, PagNodeKind.RefVar, stmt) + super(id, cid, staticFieldRef, PagNodeKind.RefVar, stmt); } } @@ -444,8 +470,8 @@ export class PagThisRefNode extends PagNode { return this.pointToNode; } - public addPTNode(ptNode: NodeID) { - this.pointToNode.push(ptNode) + public addPTNode(ptNode: NodeID): void { + this.pointToNode.push(ptNode); } } @@ -458,41 +484,40 @@ export class PagArrayNode extends PagNode { } } - /** * below is heapObj like Node */ export class PagNewExprNode extends PagNode { // store the cloned field node - fieldNodes!: Map + fieldNodes!: Map; constructor(id: NodeID, cid: ContextID | undefined = undefined, expr: AbstractExpr, stmt?: Stmt) { - super(id, cid, expr, PagNodeKind.HeapObj, stmt) + super(id, cid, expr, PagNodeKind.HeapObj, stmt); } public addFieldNode(fieldSignature: AbstractFieldRef, nodeID: NodeID): boolean { if (!this.fieldNodes) { - this.fieldNodes = new Map() + this.fieldNodes = new Map(); } if (this.fieldNodes.has(fieldSignature.getFieldSignature().toString())) { - return false + return false; } this.fieldNodes.set(fieldSignature.getFieldSignature().toString(), nodeID); - return true + return true; } public getFieldNode(fieldSignature: AbstractFieldRef): NodeID | undefined { if (!this.fieldNodes) { - return undefined + return undefined; } - return this.fieldNodes.get(fieldSignature.getFieldSignature().toString()) + return this.fieldNodes.get(fieldSignature.getFieldSignature().toString()); } public getFieldNodes(): Map | undefined { if (!this.fieldNodes) { - return undefined + return undefined; } - return this.fieldNodes + return this.fieldNodes; } } @@ -522,27 +547,75 @@ export class PagNewContainerExprNode extends PagNode { export class PagParamNode extends PagNode { constructor(id: NodeID, cid: ContextID | undefined = undefined, r: ArkParameterRef, stmt?: Stmt) { - super(id, cid, r, PagNodeKind.Param, stmt) + super(id, cid, r, PagNodeKind.Param, stmt); } } export class PagFuncNode extends PagNode { - private methodSignature!: MethodSignature + private methodSignature!: MethodSignature; + private thisPt!: NodeID; + private methodType!: BuiltApiType; + // for Function.bind, store the original call message and caller cid + private originCallSite!: CallSite; + private argsOffset: number = 0; + private originCid!: ContextID; // TODO: may add obj interface - constructor(id: NodeID, cid: ContextID | undefined = undefined, r: Value, stmt?: Stmt, method?: MethodSignature) { - super(id, cid, r, PagNodeKind.Function, stmt) + constructor(id: NodeID, cid: ContextID | undefined = undefined, r: Value, stmt?: Stmt, method?: MethodSignature, thisInstanceID?: NodeID) { + super(id, cid, r, PagNodeKind.Function, stmt); if (method) { this.methodSignature = method; + this.methodType = getBuiltInApiType(method); + } + + if (thisInstanceID) { + this.thisPt = thisInstanceID; } } - public setMethod(method: MethodSignature) { - this.methodSignature = method + public setMethod(method: MethodSignature): void { + this.methodSignature = method; + this.methodType = getBuiltInApiType(method); } public getMethod(): MethodSignature { - return this.methodSignature + return this.methodSignature; + } + + public setThisPt(thisPt: NodeID): void { + this.thisPt = thisPt; + } + + public getThisPt(): NodeID { + return this.thisPt; + } + + public setCS(callsite: CallSite): void { + this.originCallSite = callsite; + } + + public getCS(): CallSite { + return this.originCallSite; + } + + public setArgsOffset(offset: number): void { + this.argsOffset = offset; + } + + public getArgsOffset(): number { + return this.argsOffset; + } + + public getMethodType(): BuiltApiType { + return this.methodType; + } + + public setOriginCid(cid: ContextID): void { + this.originCid = cid; + } + + public getOriginCid(): ContextID { + return this.originCid; } } @@ -550,32 +623,31 @@ export class PagFuncNode extends PagNode { * almost same as PagNewExprNode, used only for globalThis and its field reference */ export class PagGlobalThisNode extends PagNode { - fieldNodes: Map + fieldNodes: Map; constructor(id: NodeID, cid: ContextID | undefined = undefined, r: Value, stmt?: Stmt) { - super(id, cid, r, PagNodeKind.GlobalThis, stmt) - this.fieldNodes = new Map() + super(id, cid, r, PagNodeKind.GlobalThis, stmt); + this.fieldNodes = new Map(); } public addFieldNode(fieldSignature: AbstractFieldRef, nodeID: NodeID): boolean { if (this.fieldNodes.has(fieldSignature.getFieldSignature().toString())) { - return false + return false; } this.fieldNodes.set(fieldSignature.getFieldSignature().toString(), nodeID); - return true + return true; } public getFieldNode(fieldSignature: AbstractFieldRef): NodeID | undefined { - return this.fieldNodes.get(fieldSignature.getFieldSignature().toString()) + return this.fieldNodes.get(fieldSignature.getFieldSignature().toString()); } public getFieldNodes(): Map | undefined { - return this.fieldNodes + return this.fieldNodes; } } export class Pag extends BaseExplicitGraph { - private cg!: CallGraph; private contextValueToIdMap: Map> = new Map(); private ExportInfoToIdMap?: Map; @@ -612,27 +684,27 @@ export class Pag extends BaseExplicitGraph { } // Not found - let cloneNode = this.addPagNode(src.getCid(), src.getValue(), src.getStmt(), false) + let cloneNode = this.addPagNode(src.getCid(), src.getValue(), src.getStmt(), false); cloneNode.setClonedFrom(src.getID()); cloneSet.set(basePt, cloneNode.getID()); return cloneNode; } public getOrClonePagFieldNode(src: PagInstanceFieldNode, basePt: NodeID): PagInstanceFieldNode | undefined { - let baseNode = this.getNode(basePt) + let baseNode = this.getNode(basePt); if (baseNode instanceof PagNewExprNode || baseNode instanceof PagGlobalThisNode) { // check if real field node has been created with basePT, using FieldSignature as key - let existedNode = baseNode.getFieldNode(src.getValue() as ArkInstanceFieldRef) + let existedNode = baseNode.getFieldNode(src.getValue() as ArkInstanceFieldRef); if (existedNode) { - return this.getNode(existedNode) as PagInstanceFieldNode + return this.getNode(existedNode) as PagInstanceFieldNode; } - let fieldNode = this.getOrClonePagNode(src, basePt) - baseNode.addFieldNode(src.getValue() as ArkInstanceFieldRef, fieldNode.getID()) - fieldNode.setBasePt(basePt) - return fieldNode + let fieldNode = this.getOrClonePagNode(src, basePt); + baseNode.addFieldNode(src.getValue() as ArkInstanceFieldRef, fieldNode.getID()); + fieldNode.setBasePt(basePt); + return fieldNode; } else { - logger.error(`Error clone field node ${src.getValue()}`) + logger.error(`Error clone field node ${src.getValue()}`); return undefined; } } @@ -650,12 +722,15 @@ export class Pag extends BaseExplicitGraph { if (src) { fieldNode = this.getOrClonePagNode(src, basePt); } else if (base) { - const containerFieldSignature = new FieldSignature('field', + const containerFieldSignature = new FieldSignature( + 'field', new ClassSignature('container', new FileSignature('container', 'lib.es2015.collection.d.ts')), - new UnclearReferenceType('')); + new UnclearReferenceType('') + ); fieldNode = this.getOrClonePagNode( // TODO: cid check - this.addPagNode(0, new ArkInstanceFieldRef(base, containerFieldSignature)), basePt + this.addPagNode(0, new ArkInstanceFieldRef(base, containerFieldSignature)), + basePt ); } @@ -675,6 +750,17 @@ export class Pag extends BaseExplicitGraph { return undefined; } + public getOrClonePagFuncNode(basePt: NodeID): PagFuncNode | undefined { + let baseNode = this.getNode(basePt) as PagNode; + if (baseNode instanceof PagFuncNode) { + let clonedFuncNode = this.getOrClonePagNode(baseNode, basePt) as PagFuncNode; + return clonedFuncNode; + } else { + logger.error(`Error clone func node ${baseNode.getValue()}`); + return undefined; + } + } + public addPagNode(cid: ContextID, value: PagNodeType, stmt?: Stmt, refresh: boolean = true): PagNode { let id: NodeID = this.nodeNum + 1; let pagNode: PagNode; @@ -741,8 +827,7 @@ export class Pag extends BaseExplicitGraph { } } - private addContextOrExportInfoMap(refresh: boolean, cid: ContextID, id: NodeID, - value: PagNodeType, pagNode: PagNode, stmt?: Stmt): void { + private addContextOrExportInfoMap(refresh: boolean, cid: ContextID, id: NodeID, value: PagNodeType, pagNode: PagNode, stmt?: Stmt): void { if (!(value instanceof ExportInfo)) { this.addContextMap(refresh, cid, id, value, stmt!, pagNode!); } else { @@ -774,9 +859,11 @@ export class Pag extends BaseExplicitGraph { let base = value.getBase(); //TODO: remove below once this Local is not uniq in %instInit is fix if (base instanceof Local && base.getName() === 'this') { - stmt?.getCfg() ?.getStmts() .forEach((s) => { - if (s instanceof ArkAssignStmt && s.getLeftOp() instanceof Local && - (s.getLeftOp() as Local).getName() === 'this') { + stmt + ?.getCfg() + ?.getStmts() + .forEach(s => { + if (s instanceof ArkAssignStmt && s.getLeftOp() instanceof Local && (s.getLeftOp() as Local).getName() === 'this') { base = s.getLeftOp() as Local; return; } @@ -820,11 +907,11 @@ export class Pag extends BaseExplicitGraph { public getOrNewThisRefNode(thisRefNodeID: NodeID, value: ArkThisRef): PagNode { if (thisRefNodeID !== -1) { - return this.getNode(thisRefNodeID) as PagNode + return this.getNode(thisRefNodeID) as PagNode; } - let thisRefNode = this.addPagThisRefNode(value) - return thisRefNode + let thisRefNode = this.addPagThisRefNode(value); + return thisRefNode; } public getOrNewThisLocalNode(cid: ContextID, ptNode: NodeID, value: Local, s?: Stmt): PagNode { @@ -904,11 +991,7 @@ export class Pag extends BaseExplicitGraph { case PagEdgeKind.InterProceduralCopy: src.addCopyOutEdge(edge); dst.addCopyInEdge(edge); - if (src instanceof PagFuncNode || - src instanceof PagGlobalThisNode || - src instanceof PagNewExprNode || - src instanceof PagNewContainerExprNode - ) { + if (src instanceof PagFuncNode || src instanceof PagGlobalThisNode || src instanceof PagNewExprNode || src instanceof PagNewContainerExprNode) { this.addrEdge.add(edge); this.stashAddrEdge.add(edge); } @@ -932,7 +1015,6 @@ export class Pag extends BaseExplicitGraph { dst.addThisInEdge(edge); break; default: - ; } return true; } @@ -941,7 +1023,7 @@ export class Pag extends BaseExplicitGraph { return this.stashAddrEdge; } - public resetAddrEdges() { + public resetAddrEdges(): void { this.stashAddrEdge.clear(); } @@ -956,8 +1038,17 @@ export class Pag extends BaseExplicitGraph { } export type InterProceduralSrcType = Local; -export type IntraProceduralEdge = { src: Value, dst: Value, kind: PagEdgeKind, stmt: Stmt } -export type InterProceduralEdge = { src: InterProceduralSrcType, dst: Value, kind: PagEdgeKind } +export type IntraProceduralEdge = { + src: Value; + dst: Value; + kind: PagEdgeKind; + stmt: Stmt; +}; +export type InterProceduralEdge = { + src: InterProceduralSrcType; + dst: Value; + kind: PagEdgeKind; +}; export class FuncPag { private internalEdges!: Set; @@ -1000,7 +1091,7 @@ export class FuncPag { } public addInternalEdge(stmt: ArkAssignStmt, k: PagEdgeKind): boolean { - this.internalEdges === undefined ? this.internalEdges = new Set() : undefined; + this.internalEdges === undefined ? (this.internalEdges = new Set()) : undefined; let lhOp = stmt.getLeftOp(); let rhOp = stmt.getRightOp(); @@ -1008,7 +1099,12 @@ export class FuncPag { return false; } - let iEdge: IntraProceduralEdge = { src: rhOp, dst: lhOp, kind: k, stmt: stmt }; + let iEdge: IntraProceduralEdge = { + src: rhOp, + dst: lhOp, + kind: k, + stmt: stmt, + }; this.internalEdges.add(iEdge); return true; @@ -1029,4 +1125,4 @@ export class InterFuncPag { public addToInterProceduralEdgeSet(e: InterProceduralEdge): void { this.interFuncEdges.add(e); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PagBuilder.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PagBuilder.ts index 98abe7e58423829187e58b8d146f926a87a35176..bd3917b09083d00bd5fdf67ae0129a69b8630daa 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PagBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PagBuilder.ts @@ -14,8 +14,8 @@ */ import { CallGraph, CallGraphNode, CallGraphNodeKind, CallSite, DynCallSite, FuncID } from '../model/CallGraph'; -import { Scene } from '../../Scene' -import { ArkAssignStmt, ArkInvokeStmt, ArkReturnStmt, Stmt } from '../../core/base/Stmt' +import { Scene } from '../../Scene'; +import { ArkAssignStmt, ArkInvokeStmt, ArkReturnStmt, Stmt } from '../../core/base/Stmt'; import { AbstractExpr, AbstractInvokeExpr, @@ -23,25 +23,18 @@ import { ArkNewArrayExpr, ArkNewExpr, ArkPtrInvokeExpr, - ArkStaticInvokeExpr + ArkStaticInvokeExpr, } from '../../core/base/Expr'; -import { - AbstractFieldRef, - ArkArrayRef, - ArkInstanceFieldRef, - ArkParameterRef, - ArkStaticFieldRef, - ArkThisRef -} from '../../core/base/Ref'; +import { AbstractFieldRef, ArkArrayRef, ArkInstanceFieldRef, ArkParameterRef, ArkStaticFieldRef, ArkThisRef } from '../../core/base/Ref'; import { Value } from '../../core/base/Value'; import { ArkMethod } from '../../core/model/ArkMethod'; -import Logger, { LOG_MODULE_TYPE } from "../../utils/logger"; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; import { Local } from '../../core/base/Local'; import { NodeID } from '../../core/graph/BaseExplicitGraph'; import { ClassSignature } from '../../core/model/ArkSignature'; import { ArkClass } from '../../core/model/ArkClass'; -import { ClassType, FunctionType, StringType } from '../../core/base/Type'; -import { Constant } from '../../core/base/Constant'; +import { ArrayType, ClassType, FunctionType, StringType } from '../../core/base/Type'; +import { Constant, NullConstant } from '../../core/base/Constant'; import { PAGStat } from '../common/Statistics'; import { ContextID, DUMMY_CID, KLimitedContextSensitive } from './Context'; import { @@ -59,12 +52,12 @@ import { PagNodeType, PagThisRefNode, StorageLinkEdgeType, - StorageType + StorageType, } from './Pag'; import { GLOBAL_THIS_NAME } from '../../core/common/TSConst'; import { IPtsCollection } from './PtsDS'; import { UNKNOWN_FILE_NAME } from '../../core/common/Const'; -import { IsCollectionAPI, IsCollectionMapSet, IsCollectionSetAdd } from './PTAUtils'; +import { BuiltApiType, getBuiltInApiType } from './PTAUtils'; import { PointerAnalysisConfig, PtaAnalysisScale } from './PointerAnalysisConfig'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'PTA'); @@ -85,7 +78,7 @@ export class PagBuilder { private scale: PtaAnalysisScale; private funcPags: Map; private interFuncPags?: Map; - private handledFunc: Set = new Set() + private handledFunc: Set = new Set(); private ctx: KLimitedContextSensitive; private scene: Scene; private worklist: CSFuncID[] = []; @@ -99,20 +92,21 @@ export class PagBuilder { private sdkMethodReturnValueMap: Map> = new Map(); // record the SDK API param, and create fake Values private methodParamValueMap: Map> = new Map(); - private fakeSdkMethodParamDeclaringStmt: Stmt = new ArkAssignStmt(new Local(""), new Local("")); + private fakeSdkMethodParamDeclaringStmt: Stmt = new ArkAssignStmt(new Local(''), new Local('')); private funcHandledThisRound: Set = new Set(); - private updatedNodesThisRound: Map> = new Map() + private updatedNodesThisRound: Map> = new Map(); private singletonFuncMap: Map = new Map(); private globalThisValue: Local = new Local(GLOBAL_THIS_NAME); private globalThisPagNode?: PagGlobalThisNode; private storagePropertyMap: Map> = new Map(); private externalScopeVariableMap: Map = new Map(); + private retriggerNodesList: Set = new Set(); constructor(p: Pag, cg: CallGraph, s: Scene, kLimit: number, scale: PtaAnalysisScale) { this.pag = p; this.cg = cg; this.scale = scale; - this.funcPags = new Map; + this.funcPags = new Map(); this.ctx = new KLimitedContextSensitive(kLimit); this.scene = s; this.pagStat = new PAGStat(); @@ -129,15 +123,15 @@ export class PagBuilder { } this.worklist.push(cs); - return cs + return cs; } - private addToFuncHandledListThisRound(id: FuncID) { + private addToFuncHandledListThisRound(id: FuncID): void { if (this.funcHandledThisRound.has(id)) { return; } - this.funcHandledThisRound.add(id) + this.funcHandledThisRound.add(id); } public buildForEntries(funcIDs: FuncID[]): void { @@ -188,20 +182,18 @@ export class PagBuilder { return false; } - let cfg = arkMethod.getCfg() + let cfg = arkMethod.getCfg(); if (!cfg) { this.buildSDKFuncPag(funcID); - return false + return false; } - logger.trace(`[build FuncPag] ${arkMethod.getSignature().toString()}`) + logger.trace(`[build FuncPag] ${arkMethod.getSignature().toString()}`); let fpag = new FuncPag(); for (let stmt of cfg.getStmts()) { if (stmt instanceof ArkAssignStmt) { - stmt.getRightOp().getUses().forEach((v) => { - this.handleValueFromExternalScope(v, funcID); - }); + this.processExternalScopeValue(stmt.getRightOp(), funcID); // Add non-call edges let kind = this.getEdgeKindForAssignStmt(stmt); if (kind !== PagEdgeKind.Unknown) { @@ -212,6 +204,7 @@ export class PagBuilder { // handle call this.buildInvokeExprInAssignStmt(stmt, fpag); } else if (stmt instanceof ArkInvokeStmt && this.scale === PtaAnalysisScale.WholeProgram) { + this.processExternalScopeValue(stmt.getInvokeExpr(), funcID); this.buildInvokeExprInInvokeStmt(stmt, fpag); } else { // TODO: need handle other type of stmt? @@ -230,7 +223,7 @@ export class PagBuilder { if (callSites.length !== 0) { // direct call is already existing in CG // TODO: API Invoke stmt has anonymous method param, how to add these param into callee - callSites.forEach((cs) => { + callSites.forEach(cs => { this.addFuncPagCallSite(fpag, cs, ivkExpr); }); } else { @@ -246,8 +239,7 @@ export class PagBuilder { private addFuncPagCallSite(fpag: FuncPag, cs: CallSite, ivkExpr: AbstractInvokeExpr): void { if (ivkExpr instanceof ArkStaticInvokeExpr) { - if (ivkExpr.getMethodSignature().getDeclaringClassSignature() - .getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME) { + if (ivkExpr.getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME) { fpag.addUnknownCallSite(cs); } else { fpag.addNormalCallSite(cs); @@ -263,7 +255,7 @@ export class PagBuilder { // direct call or constructor call is already existing in CG // TODO: some ptr invoke stmt is recognized as Static invoke in tests/resources/callgraph/funPtrTest1/fnPtrTest4.ts // TODO: instance invoke(ptr invoke) - callSites.forEach((cs) => { + callSites.forEach(cs => { if (this.cg.isUnknownMethod(cs.calleeFuncID)) { fpag.addUnknownCallSite(cs); } else { @@ -282,6 +274,21 @@ export class PagBuilder { } } + private processExternalScopeValue(value: Value, funcID: FuncID): void { + let dummyMainFuncID = this.cg.getDummyMainFuncID(); + if (dummyMainFuncID && funcID === dummyMainFuncID) { + return; + } + + if (value instanceof Local) { + this.handleValueFromExternalScope(value, funcID); + } else if (value instanceof ArkInstanceInvokeExpr) { + value.getUses().forEach(v => { + this.handleValueFromExternalScope(v, funcID); + }); + } + } + /** * will not create real funcPag, only create param values */ @@ -348,7 +355,7 @@ export class PagBuilder { return paramPagNodes; } - public buildPagFromFuncPag(funcID: FuncID, cid: ContextID) { + public buildPagFromFuncPag(funcID: FuncID, cid: ContextID): void { let funcPag = this.funcPags.get(funcID); if (funcPag === undefined) { return; @@ -364,7 +371,7 @@ export class PagBuilder { } this.addCallsEdgesFromFuncPag(funcPag, cid); - this.addDynamicCallSite(funcPag, funcID); + this.addDynamicCallSite(funcPag, funcID, cid); this.addUnknownCallSite(funcPag, funcID); this.handledFunc.add(`${cid}-${funcID}`); } @@ -394,7 +401,7 @@ export class PagBuilder { // for demand-driven analysis, add fake parameter heapObj nodes if (e.src instanceof ArkParameterRef && this.scale === PtaAnalysisScale.MethodLevel) { - let paramObjNodeID = paramNodes?.get(paramRefIndex ++); + let paramObjNodeID = paramNodes?.get(paramRefIndex++); if (!paramObjNodeID) { continue; } @@ -425,14 +432,13 @@ export class PagBuilder { } // Add edge to thisRef for special calls - if (calleeCGNode.getKind() === CallGraphNodeKind.constructor || - calleeCGNode.getKind() === CallGraphNodeKind.intrinsic) { - let callee = this.scene.getMethod(this.cg.getMethodByFuncID(cs.calleeFuncID)!)! + if (calleeCGNode.getKind() === CallGraphNodeKind.constructor || calleeCGNode.getKind() === CallGraphNodeKind.intrinsic) { + let callee = this.scene.getMethod(this.cg.getMethodByFuncID(cs.calleeFuncID)!)!; if (ivkExpr instanceof ArkInstanceInvokeExpr) { - let baseNode = this.getOrNewPagNode(cid, ivkExpr.getBase()) + let baseNode = this.getOrNewPagNode(cid, ivkExpr.getBase()); let baseNodeID = baseNode.getID(); - this.addThisRefCallEdge(baseNodeID, cid, ivkExpr, callee, calleeCid, cs.callerFuncID); + this.addThisRefCallEdge(baseNodeID, cid, ivkExpr.getBase(), callee, calleeCid, cs.callerFuncID); } else { logger.error(`constructor or intrinsic func is static ${ivkExpr!.toString()}`); } @@ -442,146 +448,7 @@ export class PagBuilder { return true; } - /** - * process Storage API - * @returns boolean: check if the cs represent a Storage API, no matter the API will success or fail - */ - private processStorage(cs: CallSite | DynCallSite, calleeCGNode: CallGraphNode, cid: ContextID): boolean { - let storageName = calleeCGNode.getMethod().getDeclaringClassSignature().getClassName(); - let storageType: StorageType = this.getStorageType(storageName, cs, cid); - - // TODO: add other storages - if (storageType === StorageType.APP_STORAGE) { - let calleeName = calleeCGNode.getMethod().getMethodSubSignature().getMethodName(); - - // TODO: complete AppStorage API - if (calleeName === 'setOrCreate') { - this.processStorageSetOrCreate(cs, cid); - } else if (calleeName === 'link') { - this.processStorageLink(cs, cid); - } else if (calleeName === 'prop') { - this.processStorageProp(cs, cid); - } else if (calleeName === 'set') { - this.processStorageSet(cs, cid); - } else if (calleeName === 'get') { - this.processStorageGet(cs, cid); - } - return true; - } else if (storageType === StorageType.LOCAL_STORAGE) { - // TODO: LocalStorage is not Static - } - - return false; - } - - private processStorageSetOrCreate(cs: CallSite | DynCallSite, cid: ContextID): void { - let propertyStr = this.getPropertyName(cs.args![0]); - if (!propertyStr) { - return; - } - - let propertyName = propertyStr; - let propertyNode = this.getOrNewPropertyNode(StorageType.APP_STORAGE, propertyName, cs.callStmt); - let storageObj = cs.args![1]; - - this.addPropertyLinkEdge(propertyNode, storageObj, cid, cs.callStmt, StorageLinkEdgeType.Local2Property); - } - - private processStorageLink(cs: CallSite | DynCallSite, cid: ContextID): void { - let propertyStr = this.getPropertyName(cs.args![0]); - if (!propertyStr) { - return; - } - - let propertyName = propertyStr; - let propertyNode = this.getOrNewPropertyNode(StorageType.APP_STORAGE, propertyName, cs.callStmt); - let leftOp = (cs.callStmt as ArkAssignStmt).getLeftOp() as Local; - let linkedOpNode = this.pag.getOrNewNode(cid, leftOp) as PagNode; - if (linkedOpNode instanceof PagLocalNode) { - linkedOpNode.setStorageLink(StorageType.APP_STORAGE, propertyName); - } - - this.pag.addPagEdge(propertyNode, linkedOpNode, PagEdgeKind.Copy); - this.pag.addPagEdge(linkedOpNode, propertyNode, PagEdgeKind.Copy); - } - - private processStorageProp(cs: CallSite | DynCallSite, cid: ContextID): void { - let propertyStr = this.getPropertyName(cs.args![0]); - if (!propertyStr) { - return; - } - - let propertyName = propertyStr; - let propertyNode = this.getOrNewPropertyNode(StorageType.APP_STORAGE, propertyName, cs.callStmt); - let leftOp = (cs.callStmt as ArkAssignStmt).getLeftOp() as Local; - let linkedOpNode = this.pag.getOrNewNode(cid, leftOp) as PagNode; - if (linkedOpNode instanceof PagLocalNode) { - linkedOpNode.setStorageLink(StorageType.APP_STORAGE, propertyName); - } - - this.pag.addPagEdge(propertyNode, linkedOpNode, PagEdgeKind.Copy); - } - - private processStorageSet(cs: CallSite | DynCallSite, cid: ContextID): void { - let ivkExpr: AbstractInvokeExpr = cs.callStmt.getInvokeExpr()!; - if (ivkExpr instanceof ArkInstanceInvokeExpr) { - let base = ivkExpr.getBase(); - let baseNode = this.pag.getOrNewNode(cid, base) as PagLocalNode; - - if (baseNode.isStorageLinked()) { - let argsNode = this.pag.getOrNewNode(cid, cs.args![0]) as PagNode; - - this.pag.addPagEdge(argsNode, baseNode, PagEdgeKind.Copy); - } - } else if (ivkExpr instanceof ArkStaticInvokeExpr) { - // TODO: process AppStorage.set() - } - } - - private processStorageGet(cs: CallSite | DynCallSite, cid: ContextID): void { - if (!(cs.callStmt instanceof ArkAssignStmt)) { - return; - } - let leftOp = (cs.callStmt as ArkAssignStmt).getLeftOp() as Local; - let ivkExpr = cs.callStmt.getInvokeExpr(); - let propertyName!: string; - if (ivkExpr instanceof ArkStaticInvokeExpr) { - let propertyStr = this.getPropertyName(cs.args![0]); - if (propertyStr) { - propertyName = propertyStr; - } - } else if (ivkExpr instanceof ArkInstanceInvokeExpr) { - let baseNode = this.pag.getOrNewNode(cid, ivkExpr.getBase()) as PagLocalNode; - if (baseNode.isStorageLinked()) { - propertyName = baseNode.getStorage().PropertyName!; - } - } - - let propertyNode = this.getPropertyNode(StorageType.APP_STORAGE, propertyName, cs.callStmt); - if (!propertyNode) { - return; - } - - this.pag.addPagEdge( - propertyNode, this.pag.getOrNewNode(cid, leftOp, cs.callStmt), - PagEdgeKind.Copy, cs.callStmt - ); - } - - private getPropertyName(value: Value): string | undefined { - if (value instanceof Local) { - let type = value.getType(); - if (type instanceof StringType) { - return type.getName(); - } - } else if (value instanceof Constant) { - return value.getValue(); - } - - return undefined; - } - - public addDynamicCallSite(funcPag: FuncPag, funcID: FuncID) { + public addDynamicCallSite(funcPag: FuncPag, funcID: FuncID, cid: ContextID): void { // add dyn callsite in funcpag to base node for (let cs of funcPag.getDynamicCallSites()) { let invokeExpr: AbstractInvokeExpr = cs.callStmt.getInvokeExpr()!; @@ -590,6 +457,13 @@ export class PagBuilder { base = invokeExpr.getBase(); } else if (invokeExpr instanceof ArkPtrInvokeExpr && invokeExpr.getFuncPtrLocal() instanceof Local) { base = invokeExpr.getFuncPtrLocal() as Local; + } else if (invokeExpr instanceof ArkPtrInvokeExpr && invokeExpr.getFuncPtrLocal() instanceof AbstractFieldRef) { + /** + * TODO: wait for IR change + * throw error in ptrInvoke with field ref + * this.field() // field is lambda expression + */ + continue; } // TODO: check base under different cid let baseNodeIDs = this.pag.getNodesByValue(base); @@ -614,6 +488,10 @@ export class PagBuilder { node.addRelatedDynCallSite(cs); } + + if (cs.callStmt instanceof ArkAssignStmt) { + this.getOrNewPagNode(cid, cs.callStmt.getLeftOp(), cs.callStmt); + } } } @@ -626,9 +504,8 @@ export class PagBuilder { let locals = method.getBody()?.getLocals()!; - funcPag.getUnknownCallSites().forEach((unknownCallSite) => { - let calleeName = unknownCallSite.callStmt.getInvokeExpr()?.getMethodSignature() - .getMethodSubSignature().getMethodName()!; + funcPag.getUnknownCallSites().forEach(unknownCallSite => { + let calleeName = unknownCallSite.callStmt.getInvokeExpr()?.getMethodSignature().getMethodSubSignature().getMethodName()!; let base = locals.get(calleeName); if (!base) { @@ -647,7 +524,7 @@ export class PagBuilder { node.addRelatedUnknownCallSite(unknownCallSite); } - }) + }); } public addDynamicCallEdge(cs: DynCallSite | CallSite, baseClassPTNode: NodeID, cid: ContextID): NodeID[] { @@ -666,33 +543,40 @@ export class PagBuilder { let dstCGNode = this.cg.getCallGraphNodeByMethod(callee.getSignature()); let callerNode = this.cg.getNode(cs.callerFuncID) as CallGraphNode; if (!callerNode) { - throw new Error("Can not get caller method node"); + throw new Error('Can not get caller method node'); } // update call graph // TODO: movo to cgbuilder + this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt); - if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) { - let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true); - let staticCS = new CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID); - if (this.scale === PtaAnalysisScale.MethodLevel) { - srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS, baseClassPTNode, calleeCid)); - continue; - } - srcNodes.push(...this.processContainerPagCallEdge(staticCS, cid, baseClassPTNode)); - srcNodes.push(...this.addStaticPagCallEdge(staticCS, cid, calleeCid)); + if (this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) { + return srcNodes; + } - // Pass base's pts to callee's this pointer - if (!dstCGNode.isSdkMethod() && ivkExpr instanceof ArkInstanceInvokeExpr) { - let srcBaseNode = this.addThisRefCallEdge(baseClassPTNode, cid, ivkExpr, callee!, calleeCid, cs.callerFuncID); - srcNodes.push(srcBaseNode); - } + let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true); + let staticCS = new CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID); + + if (this.scale === PtaAnalysisScale.MethodLevel) { + srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS, baseClassPTNode, calleeCid)); + continue; + } + + if (getBuiltInApiType(ivkExpr?.getMethodSignature()!) === BuiltApiType.NotBuiltIn) { + srcNodes.push(...this.processNormalMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode)); + } else { + // special SDK call: Container API, Function API + srcNodes.push(...this.processBuiltInMethodPagCallEdge(staticCS, cid, calleeCid, baseClassPTNode)); } } return srcNodes; } + /** + * all possible callee methods of a dynamic call site + * handle both PtrInvokeExpr and InstanceInvokeExpr + */ private getDynamicCallee(ptNode: PagNode, value: Value, ivkExpr: AbstractInvokeExpr, cs: DynCallSite | CallSite): ArkMethod[] { let callee: ArkMethod[] = []; @@ -750,29 +634,196 @@ export class PagBuilder { return callee; } - public addUpdatedNode(nodeID: NodeID, diffPT: IPtsCollection) { - let ptaConfig = PointerAnalysisConfig.getInstance(); - let updatedNode = this.updatedNodesThisRound.get(nodeID) ?? new ptaConfig.ptsCollectionCtor(); - updatedNode.union(diffPT); - this.updatedNodesThisRound.set(nodeID, updatedNode); + public processNormalMethodPagCallEdge(staticCS: CallSite, cid: ContextID, calleeCid: ContextID, baseClassPTNode: NodeID): NodeID[] { + let srcNodes: NodeID[] = []; + let ivkExpr = staticCS.callStmt.getInvokeExpr()!; + let ptNode = this.pag.getNode(baseClassPTNode) as PagNode; + let dstCGNode = this.cg.getNode(staticCS.calleeFuncID) as CallGraphNode; + let callee = this.cg.getArkMethodByFuncID(staticCS.calleeFuncID); + // Dynamic call, Ptr call, normal SDK call + srcNodes.push(...this.addStaticPagCallEdge(staticCS, cid, calleeCid, ptNode)); + + // Pass base's pts to callee's this pointer + if (!dstCGNode.isSdkMethod() && ivkExpr instanceof ArkInstanceInvokeExpr) { + let srcBaseNode = this.addThisRefCallEdge(baseClassPTNode, cid, ivkExpr.getBase(), callee!, calleeCid, staticCS.callerFuncID); + srcNodes.push(srcBaseNode); + } else if (!dstCGNode.isSdkMethod() && ivkExpr instanceof ArkPtrInvokeExpr) { + let originCS = (ptNode as PagFuncNode).getCS(); + if (!originCS) { + return srcNodes; + } + + let thisValue = originCS.args![0]; + + if (!(thisValue instanceof Local)) { + return srcNodes; + } + this.addThisRefCallEdge(baseClassPTNode, (ptNode as PagFuncNode).getOriginCid(), thisValue, callee!, calleeCid, staticCS.callerFuncID); + } + + return srcNodes; } - public getUpdatedNodes() { - return this.updatedNodesThisRound; + /** + * include container API, Function API + */ + public processBuiltInMethodPagCallEdge(staticCS: CallSite, cid: ContextID, calleeCid: ContextID, baseClassPTNode: NodeID): NodeID[] { + let srcNodes: NodeID[] = []; + let ivkExpr = staticCS.callStmt.getInvokeExpr()!; + let callee = this.scene.getMethod(ivkExpr.getMethodSignature()); + let realCallee = this.cg.getArkMethodByFuncID(staticCS.calleeFuncID); + if (!callee) { + return srcNodes; + } + + let builtInType = getBuiltInApiType(callee.getSignature()); + + if (builtInType === BuiltApiType.NotBuiltIn || !realCallee) { + return srcNodes; + } + + switch (builtInType) { + case BuiltApiType.SetAdd: + case BuiltApiType.MapSet: + this.processContainerPagCallEdge(staticCS, cid, baseClassPTNode, builtInType); + break; + + case BuiltApiType.FunctionCall: + /** + * set this and param + * function.call(thisArg, arg1, arg2, ...) + */ + this.handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode); + break; + + case BuiltApiType.FunctionApply: + /** + * set this, resolve array param + * function.apply(thisArg, [argsArray]) + */ + this.handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode); + break; + + case BuiltApiType.FunctionBind: + /** + * clone the function node and add the this pointer, origin callsite, args offset to it + * let f = function.bind(thisArg, arg1, arg2, ...) + * f(); + */ + this.handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes); + break; + } + + return srcNodes; } - public resetUpdatedNodes() { - this.updatedNodesThisRound.clear(); + private processContainerPagCallEdge(cs: CallSite, cid: ContextID, baseClassPTNode: NodeID, type: BuiltApiType): NodeID[] { + let srcNodes: NodeID[] = []; + let calleeNode = this.cg.getNode(cs.calleeFuncID) as CallGraphNode; + let calleeMethod: ArkMethod | null = this.scene.getMethod(calleeNode.getMethod()); + let ptNode = this.pag.getNode(baseClassPTNode) as PagNode; + + if (!calleeMethod || !(ptNode instanceof PagNewContainerExprNode)) { + return srcNodes; + } + + let containerValue = (cs.callStmt.getInvokeExpr() as ArkInstanceInvokeExpr).getBase(); + + const containerValueProcess = (argIndex: number): void => { + let srcNode = this.pag.getOrNewNode(cid, cs.args![argIndex], cs.callStmt); + let realContainerFieldPagNode = this.pag.getOrClonePagContainerFieldNode(baseClassPTNode, undefined, containerValue); + + if (realContainerFieldPagNode) { + // In some cases, the value of a variable of array type may not be an explicit array object, + // and the value of `realContainerFieldPagNode` will be undefined. + this.pag.addPagEdge(srcNode, realContainerFieldPagNode, PagEdgeKind.Copy, cs.callStmt); + srcNodes.push(srcNode.getID()); + } + }; + + if (type === BuiltApiType.SetAdd) { + containerValueProcess(0); + } else if (type === BuiltApiType.MapSet) { + containerValueProcess(1); + } + + return srcNodes; + } + + private handleFunctionCall( + staticCS: CallSite, + cid: ContextID, + calleeCid: ContextID, + realCallee: ArkMethod, + srcNodes: NodeID[], + baseClassPTNode: NodeID + ): void { + this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID)); + srcNodes.push(...this.addCallParamPagEdge(realCallee, staticCS.args!, staticCS.callStmt, cid, calleeCid, 1)); + this.addThisEdge(staticCS, cid, realCallee, srcNodes, baseClassPTNode, calleeCid); + } + + private handleFunctionApply( + staticCS: CallSite, + cid: ContextID, + calleeCid: ContextID, + realCallee: ArkMethod, + srcNodes: NodeID[], + baseClassPTNode: NodeID + ): void { + this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID)); + let callerMethod = this.cg.getArkMethodByFuncID(staticCS.callerFuncID); + if (!callerMethod) { + throw new Error('Cannot get caller method'); + } + let argsRealValues = this.transferArrayValues(callerMethod, staticCS.args![1]); + srcNodes.push(...this.addCallParamPagEdge(realCallee, argsRealValues, staticCS.callStmt, cid, calleeCid, 0)); + this.addThisEdge(staticCS, cid, realCallee, srcNodes, baseClassPTNode, calleeCid); + } + + private handleFunctionBind(staticCS: CallSite, cid: ContextID, baseClassPTNode: NodeID, srcNodes: NodeID[]): void { + let srcNode = this.pag.getOrClonePagFuncNode(baseClassPTNode); + if (!srcNode) { + return; + } + this.setFunctionThisPt(staticCS, srcNode, cid); + + let dstNode = this.getOrNewPagNode(cid, (staticCS.callStmt as ArkAssignStmt).getLeftOp() as Local); + this.pag.addPagEdge(srcNode, dstNode, PagEdgeKind.Copy, staticCS.callStmt); + srcNodes.push(srcNode.getID()); + + srcNode.setCS(staticCS); + srcNode.setArgsOffset(1); + srcNode.setOriginCid(cid); + } + + private addThisEdge(staticCS: CallSite, cid: ContextID, realCallee: ArkMethod, srcNodes: NodeID[], baseClassPTNode: NodeID, calleeCid: ContextID): void { + if (!(staticCS.args![0] instanceof NullConstant) && !realCallee.isStatic()) { + srcNodes.push(this.addThisRefCallEdge(baseClassPTNode, cid, staticCS.args![0] as Local, realCallee, calleeCid, staticCS.callerFuncID)); + } + } + + private setFunctionThisPt(staticCS: CallSite, srcNode: PagFuncNode, cid: ContextID): void { + let thisLocal = staticCS.args![0]; + if (!(thisLocal instanceof Local)) { + return; + } + + let thisInstanceLocal = this.getRealThisLocal(thisLocal, staticCS.callerFuncID); + let baseThisNode = this.pag.getOrNewNode(cid, thisInstanceLocal); + + for (let pt of baseThisNode.getPointTo()) { + srcNode.setThisPt(pt); + } } public handleUnkownDynamicCall(cs: DynCallSite, cid: ContextID): NodeID[] { let srcNodes: NodeID[] = []; let callerNode = this.cg.getNode(cs.callerFuncID) as CallGraphNode; let ivkExpr = cs.callStmt.getInvokeExpr() as AbstractInvokeExpr; - logger.warn("Handling unknown dyn call site : \n " + callerNode.getMethod().toString() - + '\n --> ' + ivkExpr.toString() + '\n CID: ' + cid); + logger.warn('Handling unknown dyn call site : \n ' + callerNode.getMethod().toString() + '\n --> ' + ivkExpr.toString() + '\n CID: ' + cid); - let callees: ArkMethod[] = [] + let callees: ArkMethod[] = []; let callee: ArkMethod | null = null; callee = this.scene.getMethod(ivkExpr.getMethodSignature()); if (!callee) { @@ -785,7 +836,7 @@ export class PagBuilder { if (callee) { callees.push(callee); } - }) + }); } else { callees.push(callee); } @@ -797,7 +848,7 @@ export class PagBuilder { callees.forEach(callee => { let dstCGNode = this.cg.getCallGraphNodeByMethod(callee.getSignature()); if (!callerNode) { - throw new Error("Can not get caller method node"); + throw new Error('Can not get caller method node'); } if (this.processStorage(cs, dstCGNode, cid)) { @@ -808,7 +859,7 @@ export class PagBuilder { } } - logger.warn(`\tAdd call edge of unknown call ${callee.getSignature().toString()}`) + logger.warn(`\tAdd call edge of unknown call ${callee.getSignature().toString()}`); this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt); if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) { let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true); @@ -816,22 +867,22 @@ export class PagBuilder { let staticSrcNodes = this.addStaticPagCallEdge(staticCS, cid, calleeCid); srcNodes.push(...staticSrcNodes); } - }) + }); return srcNodes; } public handleUnprocessedCallSites(processedCallSites: Set): NodeID[] { let reAnalyzeNodes: NodeID[] = []; for (let funcID of this.funcHandledThisRound) { - let funcPag = this.funcPags.get(funcID) + let funcPag = this.funcPags.get(funcID); if (!funcPag) { - logger.error(`can not find funcPag of handled func ${funcID}`) - continue + logger.error(`can not find funcPag of handled func ${funcID}`); + continue; } - let callSites = funcPag.getDynamicCallSites() + let callSites = funcPag.getDynamicCallSites(); - const diffCallSites = new Set(Array.from(callSites).filter(item => !processedCallSites.has(item))) - diffCallSites.forEach((cs) => { + const diffCallSites = new Set(Array.from(callSites).filter(item => !processedCallSites.has(item))); + diffCallSites.forEach(cs => { let ivkExpr = cs.callStmt.getInvokeExpr(); if (!(ivkExpr instanceof ArkInstanceInvokeExpr)) { return; @@ -839,7 +890,7 @@ export class PagBuilder { // Get local of base class let base = ivkExpr.getBase(); // TODO: remove this after multiple this local fixed - base = this.getRealThisLocal(base, cs.callerFuncID) + base = this.getRealThisLocal(base, cs.callerFuncID); // Get PAG nodes for this base's local let ctx2NdMap = this.pag.getNodesByValue(base); if (!ctx2NdMap) { @@ -849,31 +900,23 @@ export class PagBuilder { for (let [cid] of ctx2NdMap.entries()) { reAnalyzeNodes.push(...this.handleUnkownDynamicCall(cs, cid)); } - }) + }); } return reAnalyzeNodes; } - private addThisRefCallEdge(baseClassPTNode: NodeID, cid: ContextID, - ivkExpr: ArkInstanceInvokeExpr, callee: ArkMethod, calleeCid: ContextID, callerFunID: FuncID): NodeID { - - if (!callee || !callee.getCfg()) { - logger.error(`callee is null`); - return -1; - } - let thisAssignStmt = callee.getCfg()?.getStmts().filter(s => - s instanceof ArkAssignStmt && s.getRightOp() instanceof ArkThisRef); - let thisPtr = (thisAssignStmt?.at(0) as ArkAssignStmt).getRightOp() as ArkThisRef; - if (!thisPtr) { - throw new Error('Can not get this ptr'); - } - - // IMPORTANT: set cid 2 base Pt info firstly - this.cid2ThisRefPtMap.set(calleeCid, baseClassPTNode); - let thisRefNode = this.getOrNewThisRefNode(calleeCid, thisPtr) as PagThisRefNode; - thisRefNode.addPTNode(baseClassPTNode); - let srcBaseLocal = ivkExpr.getBase(); + private addThisRefCallEdge( + baseClassPTNode: NodeID, + cid: ContextID, + baseLocal: Local, + callee: ArkMethod, + calleeCid: ContextID, + callerFunID: FuncID + ): NodeID { + let thisRefNodeID = this.recordThisRefNode(baseClassPTNode, callee, calleeCid); + let thisRefNode = this.pag.getNode(thisRefNodeID) as PagThisRefNode; + let srcBaseLocal = baseLocal; srcBaseLocal = this.getRealThisLocal(srcBaseLocal, callerFunID); let srcNodeId = this.pag.hasCtxNode(cid, srcBaseLocal); if (!srcNodeId) { @@ -893,17 +936,39 @@ export class PagBuilder { return srcNodeId; } + private recordThisRefNode(baseClassPTNode: NodeID, callee: ArkMethod, calleeCid: ContextID): NodeID { + if (!callee || !callee.getCfg()) { + logger.error(`callee is null`); + return -1; + } + let thisAssignStmt = callee + .getCfg() + ?.getStmts() + .filter(s => s instanceof ArkAssignStmt && s.getRightOp() instanceof ArkThisRef); + let thisPtr = (thisAssignStmt?.at(0) as ArkAssignStmt).getRightOp() as ArkThisRef; + if (!thisPtr) { + throw new Error('Can not get this ptr'); + } + + // IMPORTANT: set cid 2 base Pt info firstly + this.cid2ThisRefPtMap.set(calleeCid, baseClassPTNode); + let thisRefNode = this.getOrNewThisRefNode(calleeCid, thisPtr) as PagThisRefNode; + thisRefNode.addPTNode(baseClassPTNode); + + return thisRefNode.getID(); + } + /* * Add copy edges from arguments to parameters * ret edges from return values to callsite * Return src node */ - public addStaticPagCallEdge(cs: CallSite, callerCid: ContextID, calleeCid?: ContextID): NodeID[] { + public addStaticPagCallEdge(cs: CallSite, callerCid: ContextID, calleeCid?: ContextID, ptNode?: PagNode): NodeID[] { if (!calleeCid) { calleeCid = this.ctx.getOrNewContext(callerCid, cs.calleeFuncID, true); } - let srcNodes: NodeID[] = [] + let srcNodes: NodeID[] = []; // Add reachable let calleeNode = this.cg.getNode(cs.calleeFuncID) as CallGraphNode; @@ -917,32 +982,127 @@ export class PagBuilder { return srcNodes; } - if (!calleeMethod.getCfg()) { - // method have no cfg body + if (!calleeMethod.getCfg()) { + // method have no cfg body + return srcNodes; + } + + let calleeCS = this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, cs.calleeFuncID)); + // callee cid will updated if callee is singleton + calleeCid = calleeCS.cid; + + let realArgs: Value[] = cs.args ?? []; + let argsOffset: number = 0; + if (ptNode && ptNode instanceof PagFuncNode && ptNode.getCS()) { + // for ptr invoke cloned by Function.bind() + realArgs = ptNode.getCS().args ?? []; + argsOffset = ptNode.getArgsOffset() ?? 0; + callerCid = ptNode.getOriginCid() ?? callerCid; + } + + srcNodes.push(...this.addCallParamPagEdge(calleeMethod, realArgs, cs.callStmt, callerCid, calleeCid, argsOffset)); + srcNodes.push(...this.addCallReturnPagEdge(calleeMethod, cs.callStmt, callerCid, calleeCid)); + + return srcNodes; + } + + /** + * only process the param PAG edge for invoke stmt + */ + private addCallParamPagEdge(calleeMethod: ArkMethod, args: Value[], callStmt: Stmt, callerCid: ContextID, calleeCid: ContextID, offset: number): NodeID[] { + let params = calleeMethod + .getCfg()! + .getStmts() + .filter(stmt => stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof ArkParameterRef) + .map(stmt => (stmt as ArkAssignStmt).getRightOp()); + + let srcNodes: NodeID[] = []; + + /** + * process foreach situation + * e.g. arr.forEach((item) => { ... }) + * cs.args is anonymous method local, will have only 1 parameter + * but inside foreach will have >= 1 parameters + */ + if (callStmt.getInvokeExpr()?.getMethodSignature().getMethodSubSignature().getMethodName() === 'forEach') { + srcNodes.push(...this.addForeachParamPagEdge(callerCid, calleeCid, callStmt, params)); + return srcNodes; + } + + // add args to parameters edges + for (let i = offset; i <= args.length; i++) { + let arg = args.at(i); + let param = params.at(i - offset); + if (!arg || !param) { + return srcNodes; + } + + if (arg instanceof Constant || arg instanceof AbstractExpr) { + // TODO: handle AbstractExpr + continue; + } + + // Get or create new PAG node for argument and parameter + let srcPagNode = this.getOrNewPagNode(callerCid, arg, callStmt); + let dstPagNode = this.getOrNewPagNode(calleeCid, param, callStmt); + + this.pag.addPagEdge(srcPagNode, dstPagNode, PagEdgeKind.Copy, callStmt); + srcNodes.push(srcPagNode.getID()); + // TODO: handle other types of parmeters + } + + return srcNodes; + } + + /** + * temporary solution for foreach + * deprecate when foreach is handled by built-in method + * connect the element node with the value inside foreach + */ + private addForeachParamPagEdge(callerCid: ContextID, calleeCid: ContextID, callStmt: Stmt, params: Value[]): NodeID[] { + // container value is the base value of callstmt, its points-to is PagNewContainerExprNode + let srcNodes: NodeID[] = []; + let containerValue = (callStmt.getInvokeExpr() as ArkInstanceInvokeExpr).getBase(); + let param = params.at(0); + if (!containerValue || !param) { return srcNodes; } - let calleeCS = this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, cs.calleeFuncID)); - // callee cid will updated if callee is singleton - calleeCid = calleeCS.cid + let basePagNode = this.getOrNewPagNode(callerCid, containerValue, callStmt); + let dstPagNode = this.getOrNewPagNode(calleeCid, param, callStmt); - // TODO: getParameterInstances's performance is not good. Need to refactor - let params = calleeMethod.getCfg()!.getStmts() - .filter(stmt => stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof ArkParameterRef) - .map(stmt => (stmt as ArkAssignStmt).getRightOp()); + for (let pt of basePagNode.getPointTo()) { + let newContainerExprPagNode = this.pag.getNode(pt) as PagNewContainerExprNode; + + // PagNewContainerExprNode's points-to is the element node + if (!newContainerExprPagNode || !newContainerExprPagNode.getElementNode()) { + continue; + } + let srcPagNode = this.pag.getNode(newContainerExprPagNode.getElementNode()!) as PagNode; + + // connect the element node with the value inside foreach + this.pag.addPagEdge(srcPagNode, dstPagNode, PagEdgeKind.Copy, callStmt); + srcNodes.push(srcPagNode.getID()); + } - srcNodes.push(...this.addCallParamPagEdge(params, cs, callerCid, calleeCid)); + return srcNodes; + } + /** + * process the return value PAG edge for invoke stmt + */ + public addCallReturnPagEdge(calleeMethod: ArkMethod, callStmt: Stmt, callerCid: ContextID, calleeCid: ContextID): NodeID[] { + let srcNodes: NodeID[] = []; // add ret to caller edges let retStmts = calleeMethod.getReturnStmt(); // TODO: call statement must be a assignment state - if (cs.callStmt instanceof ArkAssignStmt) { - let retDst = cs.callStmt.getLeftOp(); + if (callStmt instanceof ArkAssignStmt) { + let retDst = callStmt.getLeftOp(); for (let retStmt of retStmts) { let retValue = (retStmt as ArkReturnStmt).getOp(); if (retValue instanceof Local) { let srcPagNode = this.getOrNewPagNode(calleeCid, retValue, retStmt); - let dstPagNode = this.getOrNewPagNode(callerCid, retDst, cs.callStmt); + let dstPagNode = this.getOrNewPagNode(callerCid, retDst, callStmt); this.pag.addPagEdge(srcPagNode, dstPagNode, PagEdgeKind.Copy, retStmt); } else if (retValue instanceof Constant) { @@ -951,7 +1111,7 @@ export class PagBuilder { logger.debug(retValue); continue; } else { - throw new Error('return dst not a local or constant, but: ' + retValue.getType().toString()) + throw new Error('return dst not a local or constant, but: ' + retValue.getType().toString()); } } } @@ -977,68 +1137,6 @@ export class PagBuilder { return srcNodes; } - public addCallParamPagEdge(params: Value[], cs: CallSite, callerCid: ContextID, calleeCid: ContextID): NodeID[] { - let srcNodes: NodeID[] = []; - let argNum = cs.args?.length; - if (argNum === params.length) { - // add args to parameters edges - for (let i = 0; i < argNum; i++) { - let arg = cs.args?.at(i); - let param = params.at(i); - if (!arg || !param) { - return srcNodes; - } - - if (arg instanceof Constant || arg instanceof AbstractExpr) { - // TODO: handle AbstractExpr - continue; - } - - // Get or create new PAG node for argument and parameter - let srcPagNode = this.getOrNewPagNode(callerCid, arg, cs.callStmt); - let dstPagNode = this.getOrNewPagNode(calleeCid, param, cs.callStmt); - - this.pag.addPagEdge(srcPagNode, dstPagNode, PagEdgeKind.Copy, cs.callStmt); - srcNodes.push(srcPagNode.getID()); - // TODO: handle other types of parmeters - } - } else { - /** - * process foreach situation - * e.g. arr.forEach((item) => { ... }) - * cs.args is anonymous method local, will have only 1 parameter - * but inside foreach will have >= 1 parameters - */ - if (!(cs.callStmt.getInvokeExpr()?.getMethodSignature().getMethodSubSignature().getMethodName() === 'forEach')) { - return srcNodes; - } - // container value is the base value of callstmt, its points-to is PagNewContainerExprNode - let containerValue = (cs.callStmt.getInvokeExpr() as ArkInstanceInvokeExpr).getBase(); - let param = params.at(0); - if (!containerValue || !param) { - return srcNodes; - } - - let basePagNode = this.getOrNewPagNode(callerCid, containerValue, cs.callStmt); - let dstPagNode = this.getOrNewPagNode(calleeCid, param, cs.callStmt); - - for (let pt of basePagNode.getPointTo()) { - let newContainerExprPagNode = this.pag.getNode(pt) as PagNewContainerExprNode; - - // PagNewContainerExprNode's points-to is the element node - if (!newContainerExprPagNode || !newContainerExprPagNode.getElementNode()) { - continue; - } - let srcPagNode = this.pag.getNode(newContainerExprPagNode.getElementNode()!) as PagNode; - - // connect the element node with the value inside foreach - this.pag.addPagEdge(srcPagNode, dstPagNode, PagEdgeKind.Copy, cs.callStmt); - srcNodes.push(srcPagNode.getID()); - } - } - return srcNodes; - } - private addSDKMethodPagCallEdge(cs: CallSite, callerCid: ContextID, calleeCid: ContextID): NodeID[] { let srcNodes: NodeID[] = []; let calleeNode = this.cg.getNode(cs.calleeFuncID) as CallGraphNode; @@ -1047,9 +1145,10 @@ export class PagBuilder { if (!calleeMethod) { return srcNodes; } + let methodType = getBuiltInApiType(calleeMethod.getSignature()); // block the container SDK - if (IsCollectionAPI(calleeMethod.getSignature())) { + if (methodType === BuiltApiType.SetAdd || BuiltApiType.MapSet) { return srcNodes; } @@ -1059,7 +1158,7 @@ export class PagBuilder { srcNodes.push(...this.addSDKMethodReturnPagEdge(cs, callerCid, calleeCid, calleeMethod)); srcNodes.push(...this.addSDKMethodParamPagEdge(cs, callerCid, calleeCid, calleeNode.getID())); - return srcNodes + return srcNodes; } private addSDKMethodReturnPagEdge(cs: CallSite, callerCid: ContextID, calleeCid: ContextID, calleeMethod: ArkMethod): NodeID[] { @@ -1070,20 +1169,20 @@ export class PagBuilder { } // check fake heap object exists or not - let cidMap = this.sdkMethodReturnValueMap.get(calleeMethod) + let cidMap = this.sdkMethodReturnValueMap.get(calleeMethod); if (!cidMap) { - cidMap = new Map() + cidMap = new Map(); } - let newExpr = cidMap.get(calleeCid) + let newExpr = cidMap.get(calleeCid); if (!newExpr) { if (returnType instanceof ClassType) { - newExpr = new ArkNewExpr(returnType) + newExpr = new ArkNewExpr(returnType); } } - cidMap.set(calleeCid, newExpr!) - this.sdkMethodReturnValueMap.set(calleeMethod, cidMap) + cidMap.set(calleeCid, newExpr!); + this.sdkMethodReturnValueMap.set(calleeMethod, cidMap); - let srcPagNode = this.getOrNewPagNode(calleeCid, newExpr!) + let srcPagNode = this.getOrNewPagNode(calleeCid, newExpr!); let dstPagNode = this.getOrNewPagNode(callerCid, cs.callStmt.getLeftOp(), cs.callStmt); this.pag.addPagEdge(srcPagNode, dstPagNode, PagEdgeKind.Address, cs.callStmt); @@ -1131,9 +1230,7 @@ export class PagBuilder { * when this API is called, the anonymous method pointer will not be able to pass into the fake Value PagNode */ dstPagNode.setSdkParam(); - let sdkParamInvokeStmt = new ArkInvokeStmt( - new ArkPtrInvokeExpr((arg.getType() as FunctionType).getMethodSignature(), paramValue as Local, []) - ); + let sdkParamInvokeStmt = new ArkInvokeStmt(new ArkPtrInvokeExpr((arg.getType() as FunctionType).getMethodSignature(), paramValue as Local, [])); // create new DynCallSite let sdkParamCallSite = new DynCallSite(funcID, sdkParamInvokeStmt, undefined, undefined); @@ -1147,39 +1244,6 @@ export class PagBuilder { return srcNodes; } - private processContainerPagCallEdge(cs: CallSite, cid: ContextID, baseClassPTNode: NodeID): NodeID[] { - let srcNodes: NodeID[] = []; - let calleeNode = this.cg.getNode(cs.calleeFuncID) as CallGraphNode; - let calleeMethod: ArkMethod | null = this.scene.getMethod(calleeNode.getMethod()); - let ptNode = this.pag.getNode(baseClassPTNode) as PagNode; - - if (!calleeMethod || !(ptNode instanceof PagNewContainerExprNode)) { - return srcNodes; - } - - let containerValue = (cs.callStmt.getInvokeExpr() as ArkInstanceInvokeExpr).getBase(); - - const containerValueProcess = (argIndex: number): void => { - let srcNode = this.pag.getOrNewNode(cid, cs.args![argIndex], cs.callStmt); - let realContainerFieldPagNode = this.pag.getOrClonePagContainerFieldNode(baseClassPTNode, undefined, containerValue); - - if (realContainerFieldPagNode) { - // In some cases, the value of a variable of array type may not be an explicit array object, - // and the value of `realContainerFieldPagNode` will be undefined. - this.pag.addPagEdge(srcNode, realContainerFieldPagNode, PagEdgeKind.Copy, cs.callStmt); - srcNodes.push(srcNode.getID()); - } - }; - - if (IsCollectionSetAdd(calleeMethod.getSignature())) { - containerValueProcess(0); - } else if (IsCollectionMapSet(calleeMethod.getSignature())) { - containerValueProcess(1); - } - - return srcNodes; - } - public getOrNewPagNode(cid: ContextID, v: PagNodeType, s?: Stmt): PagNode { if (v instanceof ArkThisRef) { return this.getOrNewThisRefNode(cid, v as ArkThisRef); @@ -1190,11 +1254,11 @@ export class PagBuilder { // globalThis process can not be removed while all `globalThis` ref is the same Value if (v instanceof Local) { - if (v.getName() === "this") { + if (v.getName() === 'this') { return this.getOrNewThisLoalNode(cid, v as Local, s); } else if (v.getName() === GLOBAL_THIS_NAME && v.getDeclaringStmt() == null) { // globalThis node has no cid - return this.getOrNewGlobalThisNode(-1) + return this.getOrNewGlobalThisNode(-1); } } @@ -1210,19 +1274,19 @@ export class PagBuilder { * @param cid: current contextID */ public getOrNewThisRefNode(cid: ContextID, v: ArkThisRef): PagNode { - let thisRefNodeID = this.cid2ThisRefMap.get(cid) + let thisRefNodeID = this.cid2ThisRefMap.get(cid); if (!thisRefNodeID) { thisRefNodeID = -1; } - let thisRefNode = this.pag.getOrNewThisRefNode(thisRefNodeID, v) - this.cid2ThisRefMap.set(cid, thisRefNode.getID()) - return thisRefNode + let thisRefNode = this.pag.getOrNewThisRefNode(thisRefNodeID, v); + this.cid2ThisRefMap.set(cid, thisRefNode.getID()); + return thisRefNode; } // TODO: remove it once this local not uniq issue is fixed public getOrNewThisLoalNode(cid: ContextID, v: Local, s?: Stmt): PagNode { - let thisLocalNodeID = this.cid2ThisLocalMap.get(cid) + let thisLocalNodeID = this.cid2ThisLocalMap.get(cid); if (thisLocalNodeID) { return this.pag.getNode(thisLocalNodeID) as PagNode; } @@ -1274,7 +1338,6 @@ export class PagBuilder { propertyLocal = storageMap.get(propertyName)!; } - if (propertyLocal) { return this.getOrNewPagNode(-1, propertyLocal, stmt); } @@ -1309,9 +1372,9 @@ export class PagBuilder { /* * In ArkIR, ArkField has multiple instances for each stmt which use it * But the unique one is needed for pointer analysis - * This is a temp solution to use a ArkField->(first instance) + * This is a temp solution to use a ArkField->(first instance) * as the unique instance - * + * * node merge condition: * instance field: value and ArkField * static field: ArkField @@ -1322,18 +1385,18 @@ export class PagBuilder { } let sig = v.getFieldSignature(); - let sigStr = sig.toString() + let sigStr = sig.toString(); let base: Local; let real: Value | undefined; if (v instanceof ArkInstanceFieldRef) { - base = (v as ArkInstanceFieldRef).getBase() + base = (v as ArkInstanceFieldRef).getBase(); if (base instanceof Local && base.getName() === GLOBAL_THIS_NAME && base.getDeclaringStmt() == null) { // replace the base in fieldRef base = this.getGlobalThisValue(); - (v as ArkInstanceFieldRef).setBase(base as Local) + (v as ArkInstanceFieldRef).setBase(base as Local); } - let key = `${base.getSignature()}-${sigStr}` + let key = `${base.getSignature()}-${sigStr}`; real = this.instanceField2UniqInstanceMap.get(key); if (!real) { @@ -1371,9 +1434,7 @@ export class PagBuilder { } let funcPag = this.funcPags.get(funcID)!; - let heapObjects = [...funcPag.getInternalEdges()!] - .filter(edge => edge.kind === PagEdgeKind.Address) - .map(edge => edge.dst); + let heapObjects = [...funcPag.getInternalEdges()!].filter(edge => edge.kind === PagEdgeKind.Address).map(edge => edge.dst); let returnValues = arkMethod.getReturnValues(); @@ -1428,8 +1489,7 @@ export class PagBuilder { return false; } - private funcPagDfs(graph: Map, visited: Set, currentNode: Value, targetNode: Value, - staticFieldFound: boolean): boolean { + private funcPagDfs(graph: Map, visited: Set, currentNode: Value, targetNode: Value, staticFieldFound: boolean): boolean { if (currentNode === targetNode) { return staticFieldFound; } @@ -1478,6 +1538,142 @@ export class PagBuilder { return PagEdgeKind.Unknown; } + /** + * process Storage API + * @returns boolean: check if the cs represent a Storage API, no matter the API will success or fail + */ + private processStorage(cs: CallSite | DynCallSite, calleeCGNode: CallGraphNode, cid: ContextID): boolean { + let storageName = calleeCGNode.getMethod().getDeclaringClassSignature().getClassName(); + let storageType: StorageType = this.getStorageType(storageName, cs, cid); + + // TODO: add other storages + if (storageType === StorageType.APP_STORAGE) { + let calleeName = calleeCGNode.getMethod().getMethodSubSignature().getMethodName(); + + // TODO: complete AppStorage API + if (calleeName === 'setOrCreate') { + this.processStorageSetOrCreate(cs, cid); + } else if (calleeName === 'link') { + this.processStorageLink(cs, cid); + } else if (calleeName === 'prop') { + this.processStorageProp(cs, cid); + } else if (calleeName === 'set') { + this.processStorageSet(cs, cid); + } else if (calleeName === 'get') { + this.processStorageGet(cs, cid); + } + return true; + } else if (storageType === StorageType.LOCAL_STORAGE) { + // TODO: LocalStorage is not Static + } + + return false; + } + + private processStorageSetOrCreate(cs: CallSite | DynCallSite, cid: ContextID): void { + let propertyStr = this.getPropertyName(cs.args![0]); + if (!propertyStr) { + return; + } + + let propertyName = propertyStr; + let propertyNode = this.getOrNewPropertyNode(StorageType.APP_STORAGE, propertyName, cs.callStmt); + let storageObj = cs.args![1]; + + this.addPropertyLinkEdge(propertyNode, storageObj, cid, cs.callStmt, StorageLinkEdgeType.Local2Property); + } + + private processStorageLink(cs: CallSite | DynCallSite, cid: ContextID): void { + let propertyStr = this.getPropertyName(cs.args![0]); + if (!propertyStr) { + return; + } + + let propertyName = propertyStr; + let propertyNode = this.getOrNewPropertyNode(StorageType.APP_STORAGE, propertyName, cs.callStmt); + let leftOp = (cs.callStmt as ArkAssignStmt).getLeftOp() as Local; + let linkedOpNode = this.pag.getOrNewNode(cid, leftOp) as PagNode; + if (linkedOpNode instanceof PagLocalNode) { + linkedOpNode.setStorageLink(StorageType.APP_STORAGE, propertyName); + } + + this.pag.addPagEdge(propertyNode, linkedOpNode, PagEdgeKind.Copy); + this.pag.addPagEdge(linkedOpNode, propertyNode, PagEdgeKind.Copy); + } + + private processStorageProp(cs: CallSite | DynCallSite, cid: ContextID): void { + let propertyStr = this.getPropertyName(cs.args![0]); + if (!propertyStr) { + return; + } + + let propertyName = propertyStr; + let propertyNode = this.getOrNewPropertyNode(StorageType.APP_STORAGE, propertyName, cs.callStmt); + let leftOp = (cs.callStmt as ArkAssignStmt).getLeftOp() as Local; + let linkedOpNode = this.pag.getOrNewNode(cid, leftOp) as PagNode; + if (linkedOpNode instanceof PagLocalNode) { + linkedOpNode.setStorageLink(StorageType.APP_STORAGE, propertyName); + } + + this.pag.addPagEdge(propertyNode, linkedOpNode, PagEdgeKind.Copy); + } + + private processStorageSet(cs: CallSite | DynCallSite, cid: ContextID): void { + let ivkExpr: AbstractInvokeExpr = cs.callStmt.getInvokeExpr()!; + if (ivkExpr instanceof ArkInstanceInvokeExpr) { + let base = ivkExpr.getBase(); + let baseNode = this.pag.getOrNewNode(cid, base) as PagLocalNode; + + if (baseNode.isStorageLinked()) { + let argsNode = this.pag.getOrNewNode(cid, cs.args![0]) as PagNode; + + this.pag.addPagEdge(argsNode, baseNode, PagEdgeKind.Copy); + } + } else if (ivkExpr instanceof ArkStaticInvokeExpr) { + // TODO: process AppStorage.set() + } + } + + private processStorageGet(cs: CallSite | DynCallSite, cid: ContextID): void { + if (!(cs.callStmt instanceof ArkAssignStmt)) { + return; + } + let leftOp = (cs.callStmt as ArkAssignStmt).getLeftOp() as Local; + let ivkExpr = cs.callStmt.getInvokeExpr(); + let propertyName!: string; + if (ivkExpr instanceof ArkStaticInvokeExpr) { + let propertyStr = this.getPropertyName(cs.args![0]); + if (propertyStr) { + propertyName = propertyStr; + } + } else if (ivkExpr instanceof ArkInstanceInvokeExpr) { + let baseNode = this.pag.getOrNewNode(cid, ivkExpr.getBase()) as PagLocalNode; + if (baseNode.isStorageLinked()) { + propertyName = baseNode.getStorage().PropertyName!; + } + } + + let propertyNode = this.getPropertyNode(StorageType.APP_STORAGE, propertyName, cs.callStmt); + if (!propertyNode) { + return; + } + + this.pag.addPagEdge(propertyNode, this.pag.getOrNewNode(cid, leftOp, cs.callStmt), PagEdgeKind.Copy, cs.callStmt); + } + + private getPropertyName(value: Value): string | undefined { + if (value instanceof Local) { + let type = value.getType(); + if (type instanceof StringType) { + return type.getName(); + } + } else if (value instanceof Constant) { + return value.getValue(); + } + + return undefined; + } + /** * get storageType enum with method's Declaring ClassName * @@ -1515,11 +1711,12 @@ export class PagBuilder { private stmtIsCreateAddressObj(stmt: ArkAssignStmt): boolean { let lhOp = stmt.getLeftOp(); let rhOp = stmt.getRightOp(); - if ((rhOp instanceof ArkNewExpr || rhOp instanceof ArkNewArrayExpr) || - (lhOp instanceof Local && ( - (rhOp instanceof Local && rhOp.getType() instanceof FunctionType && - rhOp.getDeclaringStmt() === null) || - (rhOp instanceof AbstractFieldRef && rhOp.getType() instanceof FunctionType))) || + if ( + rhOp instanceof ArkNewExpr || + rhOp instanceof ArkNewArrayExpr || + (lhOp instanceof Local && + ((rhOp instanceof Local && rhOp.getType() instanceof FunctionType && rhOp.getDeclaringStmt() === null) || + (rhOp instanceof AbstractFieldRef && rhOp.getType() instanceof FunctionType))) || (rhOp instanceof Local && rhOp.getName() === GLOBAL_THIS_NAME && rhOp.getDeclaringStmt() == null) ) { return true; @@ -1535,10 +1732,9 @@ export class PagBuilder { let rhOp = stmt.getRightOp(); let condition: boolean = - (lhOp instanceof Local && ( - rhOp instanceof Local || rhOp instanceof ArkParameterRef || - rhOp instanceof ArkThisRef || rhOp instanceof ArkStaticFieldRef)) || - (lhOp instanceof ArkStaticFieldRef && rhOp instanceof Local) + (lhOp instanceof Local && + (rhOp instanceof Local || rhOp instanceof ArkParameterRef || rhOp instanceof ArkThisRef || rhOp instanceof ArkStaticFieldRef)) || + (lhOp instanceof ArkStaticFieldRef && rhOp instanceof Local); if (condition) { return true; @@ -1550,8 +1746,7 @@ export class PagBuilder { let lhOp = stmt.getLeftOp(); let rhOp = stmt.getRightOp(); - if (rhOp instanceof Local && - (lhOp instanceof ArkInstanceFieldRef || lhOp instanceof ArkArrayRef)) { + if (rhOp instanceof Local && (lhOp instanceof ArkInstanceFieldRef || lhOp instanceof ArkArrayRef)) { return true; } return false; @@ -1561,8 +1756,7 @@ export class PagBuilder { let lhOp = stmt.getLeftOp(); let rhOp = stmt.getRightOp(); - if (lhOp instanceof Local && - (rhOp instanceof ArkInstanceFieldRef || rhOp instanceof ArkArrayRef)) { + if (lhOp instanceof Local && (rhOp instanceof ArkInstanceFieldRef || rhOp instanceof ArkArrayRef)) { return true; } return false; @@ -1572,7 +1766,7 @@ export class PagBuilder { funcPag.addDynamicCallSite(cs); this.pagStat.numDynamicCall++; - logger.trace("[add dynamic callsite] " + cs.callStmt.toString() + ": " + cs.callStmt.getCfg()?.getDeclaringMethod().getSignature().toString()); + logger.trace('[add dynamic callsite] ' + cs.callStmt.toString() + ': ' + cs.callStmt.getCfg()?.getDeclaringMethod().getSignature().toString()); } public setPtForNode(node: NodeID, pts: IPtsCollection | undefined): void { @@ -1584,19 +1778,23 @@ export class PagBuilder { } public getRealThisLocal(input: Local, funcId: FuncID): Local { - if (input.getName() !== 'this') + if (input.getName() !== 'this') { return input; + } let real = input; let f = this.cg.getArkMethodByFuncID(funcId); - f?.getCfg()?.getStmts().forEach(s => { - if (s instanceof ArkAssignStmt && s.getLeftOp() instanceof Local) { - if ((s.getLeftOp() as Local).getName() === 'this') { - real = s.getLeftOp() as Local; - return; + f + ?.getCfg() + ?.getStmts() + .forEach(s => { + if (s instanceof ArkAssignStmt && s.getLeftOp() instanceof Local) { + if ((s.getLeftOp() as Local).getName() === 'this') { + real = s.getLeftOp() as Local; + return; + } } - } - }) + }); return real; } @@ -1632,7 +1830,7 @@ export class PagBuilder { */ private handleValueFromExternalScope(value: Value, funcID: FuncID, originValue?: Value): void { if (value instanceof Local) { - if (value.getDeclaringStmt()) { + if (value.getDeclaringStmt() || value.getName() === 'this') { // not from external scope return; } @@ -1661,7 +1859,11 @@ export class PagBuilder { // Export a local // Add a InterProcedural edge if (dst instanceof Local) { - let e: InterProceduralEdge = { src: src, dst: dst, kind: PagEdgeKind.InterProceduralCopy }; + let e: InterProceduralEdge = { + src: src, + dst: dst, + kind: PagEdgeKind.InterProceduralCopy, + }; interFuncPag.addToInterProceduralEdgeSet(e); this.addExportVariableMap(src, dst as Local); } else if (dst instanceof ArkInstanceFieldRef) { @@ -1683,7 +1885,7 @@ export class PagBuilder { private getSourceValueFromExternalScope(value: Local, funcID: FuncID): Local | undefined { let sourceValue; - // TODO: first from default method + sourceValue = this.getDefaultMethodSourceValue(value, funcID); if (!sourceValue) { sourceValue = this.getExportSourceValue(value, funcID); @@ -1696,13 +1898,12 @@ export class PagBuilder { // namespace check let arkMethod = this.cg.getArkMethodByFuncID(funcID); if (!arkMethod) { - return; + return undefined; } let declaringNameSpace = arkMethod.getDeclaringArkClass().getDeclaringArkNamespace(); while (declaringNameSpace) { - let nameSpaceLocals = declaringNameSpace.getDefaultClass() - .getDefaultArkMethod()?.getBody()?.getLocals() ?? new Map(); + let nameSpaceLocals = declaringNameSpace.getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals() ?? new Map(); if (nameSpaceLocals.has(value.getName())) { return nameSpaceLocals.get(value.getName()); } @@ -1712,10 +1913,9 @@ export class PagBuilder { // file check let declaringFile = arkMethod.getDeclaringArkFile(); - let fileLocals = declaringFile.getDefaultClass() - .getDefaultArkMethod()?.getBody()?.getLocals() ?? new Map(); + let fileLocals = declaringFile.getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals() ?? new Map(); if (!fileLocals.has(value.getName())) { - return; + return undefined; } return fileLocals.get(value.getName()); @@ -1724,24 +1924,25 @@ export class PagBuilder { private getExportSourceValue(value: Local, funcID: FuncID): Local | undefined { let curMethod = this.cg.getArkMethodByFuncID(funcID); if (!curMethod) { - return; + return undefined; } let curFile = curMethod.getDeclaringArkFile(); let impInfo = curFile.getImportInfoBy(value.getName()); if (!impInfo) { - return; + return undefined; } let exportSource = impInfo.getLazyExportInfo(); if (!exportSource) { - return; + return undefined; } let exportSouceValue = exportSource.getArkExport(); if (exportSouceValue instanceof Local) { return exportSouceValue; } + return undefined; } private addExportVariableMap(src: Local, dst: Local): void { @@ -1772,9 +1973,53 @@ export class PagBuilder { let existingNodes = this.pag.getNodesByValue(exportLocal); existingNodes?.forEach(n => { this.pag.addPagEdge(this.pag.getNode(n)! as PagNode, dstPagNode, e.kind); + this.retriggerNodesList.add(n); }); } return true; } + + public getRetriggerNodes(): NodeID[] { + let retriggerNodes = Array.from(this.retriggerNodesList); + this.retriggerNodesList.clear(); + return retriggerNodes; + } + + public addUpdatedNode(nodeID: NodeID, diffPT: IPtsCollection): void { + let ptaConfig = PointerAnalysisConfig.getInstance(); + let updatedNode = this.updatedNodesThisRound.get(nodeID) ?? new ptaConfig.ptsCollectionCtor(); + updatedNode.union(diffPT); + this.updatedNodesThisRound.set(nodeID, updatedNode); + } + + public getUpdatedNodes(): Map> { + return this.updatedNodesThisRound; + } + + public resetUpdatedNodes(): void { + this.updatedNodesThisRound.clear(); + } + + private transferArrayValues(method: ArkMethod, arrayLocal: Value): Local[] { + if (!(arrayLocal instanceof Local) || !(arrayLocal.getType() instanceof ArrayType)) { + return []; + } + + /** + * TODO: get array element values + * need to resolve multi dimension array + */ + const usedValuesInArray = arrayLocal.getUsedStmts().flatMap(stmt => { + if (stmt instanceof ArkAssignStmt) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local) { + return rightOp; + } + } + return []; + }); + + return usedValuesInArray; + } } diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysis.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysis.ts index 9dca84f6381f8c7ef3b08f563800d11225357016..902a05b902faa419cf511850bd2ccc1871a915fc 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysis.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysis.ts @@ -47,7 +47,7 @@ export class PointerAnalysis extends AbstractAnalysis { private config: PointerAnalysisConfig; constructor(p: Pag, cg: CallGraph, s: Scene, config: PointerAnalysisConfig) { - super(s) + super(s); this.pag = p; this.cg = cg; this.ptd = new DiffPTData>(config.ptsCollectionCtor); @@ -96,7 +96,7 @@ export class PointerAnalysis extends AbstractAnalysis { return pta; } - protected init() { + protected init(): void { logger.warn(`========== Init Pointer Analysis ==========`); // start statistics this.ptaStat.startStat(); @@ -108,13 +108,13 @@ export class PointerAnalysis extends AbstractAnalysis { } } - public start() { + public start(): void { this.init(); this.solveConstraint(); this.postProcess(); } - private postProcess() { + private postProcess(): void { this.ptaStat.endStat(); this.pagBuilder.doStat(); this.cg.printStat(); @@ -147,11 +147,11 @@ export class PointerAnalysis extends AbstractAnalysis { return []; } - public setEntries(fIds: FuncID[]) { + public setEntries(fIds: FuncID[]): void { this.entries = fIds; } - private solveConstraint() { + private solveConstraint(): void { this.worklist = []; logger.warn(`========== Pointer Analysis Start ==========`); this.initWorklist(); @@ -164,7 +164,7 @@ export class PointerAnalysis extends AbstractAnalysis { // do pointer transfer this.solveWorklist(); // process dynamic call - if (this.config.analysisScale === PtaAnalysisScale.WholeProgram || this.ptaStat.iterTimes === 1 ) { + if (this.config.analysisScale === PtaAnalysisScale.WholeProgram || this.ptaStat.iterTimes === 1) { reanalyzer = this.onTheFlyDynamicCallSolve(); } else { reanalyzer = false; @@ -180,6 +180,7 @@ export class PointerAnalysis extends AbstractAnalysis { */ private initWorklist(): boolean { let changed: boolean = false; + this.addToReanalyze(this.pagBuilder.getRetriggerNodes()); for (let e of this.pag.getAddrEdges()) { this.ptaStat.numProcessedAddr++; @@ -241,10 +242,10 @@ export class PointerAnalysis extends AbstractAnalysis { let intraProceduralFieldNodeMap = new Map(); if (nodeValue instanceof Local) { - this.pagBuilder.getExportVariableMap(nodeValue).forEach((dst) => { + this.pagBuilder.getExportVariableMap(nodeValue).forEach(dst => { let temp = this.pag.getNodesByBaseValue(dst) ?? new Map(); intraProceduralFieldNodeMap = this.mergeInstanceFieldMap(instanceFieldNodeMap, temp); - }) + }); } instanceFieldNodeMap!.forEach((nodeIDs, cid) => { @@ -260,25 +261,25 @@ export class PointerAnalysis extends AbstractAnalysis { this.handleFieldInEdges(fieldNode, diffPts!); this.handleFieldOutEdges(fieldNode, diffPts!); - }) - }) + }); + }); // without cid check, because closure and export is under different cid - intraProceduralFieldNodeMap!.forEach((nodeIDs) => { + intraProceduralFieldNodeMap!.forEach(nodeIDs => { nodeIDs.forEach((nodeID: number) => { // get abstract field node let fieldNode = this.pag.getNode(nodeID) as PagNode; this.handleFieldInEdges(fieldNode, diffPts!); this.handleFieldOutEdges(fieldNode, diffPts!); - }) - }) + }); + }); return true; } private handleFieldInEdges(fieldNode: PagNode, diffPts: IPtsCollection): void { - fieldNode.getIncomingEdge().forEach((edge) => { + fieldNode.getIncomingEdge().forEach(edge => { if (edge.getKind() !== PagEdgeKind.Write) { return; } @@ -307,7 +308,7 @@ export class PointerAnalysis extends AbstractAnalysis { } private handleFieldOutEdges(fieldNode: PagNode, diffPts: IPtsCollection): void { - fieldNode.getOutgoingEdges().forEach((edge) => { + fieldNode.getOutgoingEdges().forEach(edge => { if (edge.getKind() !== PagEdgeKind.Load) { return; } @@ -347,7 +348,7 @@ export class PointerAnalysis extends AbstractAnalysis { return true; } - private handlePt(nodeID: NodeID) { + private handlePt(nodeID: NodeID): void { let realDiff = this.ptd.calculateDiff(nodeID, nodeID); if (realDiff.count() !== 0) { @@ -396,7 +397,7 @@ export class PointerAnalysis extends AbstractAnalysis { changed = this.processDynCallSite(node, pts, processedCallSites) || changed; changed = this.processUnknownCallSite(node, pts) || changed; - }) + }); this.pagBuilder.resetUpdatedNodes(); let srcNodes = this.pagBuilder.handleUnprocessedCallSites(processedCallSites); changed = this.addToReanalyze(srcNodes) || changed; @@ -416,13 +417,13 @@ export class PointerAnalysis extends AbstractAnalysis { } logger.info(`[process dynamic callsite] node ${node.getID()}`); - dynCallSites.forEach((dynCallsite) => { + dynCallSites.forEach(dynCallsite => { for (let pt of pts) { let srcNodes = this.pagBuilder.addDynamicCallEdge(dynCallsite, pt, node.getCid()); changed = this.addToReanalyze(srcNodes) || changed; } processedCallSites.add(dynCallsite); - }) + }); return changed; } @@ -437,12 +438,12 @@ export class PointerAnalysis extends AbstractAnalysis { } logger.info(`[process unknown callsite] node ${node.getID()}`); - unknownCallSites.forEach((unknownCallSite) => { + unknownCallSites.forEach(unknownCallSite => { for (let pt of pts) { let srcNodes = this.pagBuilder.addDynamicCallEdge(unknownCallSite, pt, node.getCid()); changed = this.addToReanalyze(srcNodes) || changed; } - }) + }); return changed; } @@ -524,7 +525,7 @@ export class PointerAnalysis extends AbstractAnalysis { processedNodes.forEach(nodeID => { let valueNode = this.pag.getNode(nodeID) as PagNode; relatedAllNodes.add(valueNode.getValue()); - }) + }); return relatedAllNodes; } @@ -541,7 +542,7 @@ export class PointerAnalysis extends AbstractAnalysis { private addIncomingEdgesToWorkList(valueNode: PagNode, workListNodes: NodeID[], processedNodes: Set): void { let inCopyEdges = valueNode.getIncomingCopyEdges(); let inThisEdges = valueNode.getIncomingThisEdges(); - let combinedEdges = new Set([...inCopyEdges ?? [], ...inThisEdges ?? []]); + let combinedEdges = new Set([...(inCopyEdges ?? []), ...(inThisEdges ?? [])]); if (combinedEdges) { combinedEdges.forEach(edge => { let srcID = edge.getSrcID(); @@ -555,7 +556,7 @@ export class PointerAnalysis extends AbstractAnalysis { private addOutgoingEdgesToWorkList(valueNode: PagNode, workListNodes: NodeID[], processedNodes: Set): void { let outCopyEdges = valueNode.getOutgoingCopyEdges(); let outThisEdges = valueNode.getOutgoingThisEdges(); - let combinedEdges = new Set([...outCopyEdges ?? [], ...outThisEdges ?? []]); + let combinedEdges = new Set([...(outCopyEdges ?? []), ...(outThisEdges ?? [])]); if (combinedEdges) { combinedEdges.forEach(edge => { let dstID = edge.getDstID(); @@ -601,7 +602,7 @@ export class PointerAnalysis extends AbstractAnalysis { } } - // If find pts to original type, + // If find pts to original type, // need add original type back since it is a correct type let diffSet = this.typeDiffMap.get(value); if (diffSet && findSameType) { @@ -631,9 +632,9 @@ export class PointerAnalysis extends AbstractAnalysis { private dumpUnhandledFunctions(): void { const filePath = path.join(this.config.outputDirectory, 'PtaUnhandledFunctionList.txt'); - fs.access(filePath, fs.constants.F_OK, (err) => { + fs.access(filePath, fs.constants.F_OK, err => { if (!err) { - fs.truncate(filePath, 0, (err) => { + fs.truncate(filePath, 0, err => { err && logger.error('Error to truncate file ', err); }); } @@ -651,7 +652,7 @@ export class PointerAnalysis extends AbstractAnalysis { } }); - fs.writeFile(filePath, updatedContent, 'utf8', (err) => { + fs.writeFile(filePath, updatedContent, 'utf8', err => { if (err) { logger.error('Error to write file', err); } @@ -669,4 +670,4 @@ export class PointerAnalysis extends AbstractAnalysis { }); return src; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts index 9dcde376dd255c8026d85f72e5e29d852e017f46..1e68c981db8221514da887c76692e267a90cbe2f 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts @@ -19,7 +19,7 @@ import { NodeID } from '../../core/graph/BaseExplicitGraph'; export enum PtaAnalysisScale { WholeProgram = 0, - MethodLevel = 1 + MethodLevel = 1, } export class PointerAnalysisConfig { @@ -36,11 +36,17 @@ export class PointerAnalysisConfig { /* * Note: DO NOT use `new PointerAnalysisConfig` to initialize ptaconfig - * Use PointerAnalysisConfig.create() for singleton pattern + * Use PointerAnalysisConfig.create() for singleton pattern */ - constructor(kLimit: number, outputDirectory: string, detectTypeDiff: boolean = false, - dotDump: boolean = false, unhandledFuncDump: boolean = false, - analysisScale: PtaAnalysisScale = PtaAnalysisScale.WholeProgram, ptsCoType = PtsCollectionType.Set) { + constructor( + kLimit: number, + outputDirectory: string, + detectTypeDiff: boolean = false, + dotDump: boolean = false, + unhandledFuncDump: boolean = false, + analysisScale: PtaAnalysisScale = PtaAnalysisScale.WholeProgram, + ptsCoType = PtsCollectionType.Set + ) { if (kLimit > 5) { throw new Error('K Limit too large'); } @@ -58,16 +64,27 @@ export class PointerAnalysisConfig { } } - /* * Create Singleton instance * The instance can be created multi-times and be overwrited */ - public static create(kLimit: number, outputDirectory: string, detectTypeDiff: boolean = false, - dotDump: boolean = false, unhandledFuncDump: boolean = false, - analysisScale: PtaAnalysisScale = PtaAnalysisScale.WholeProgram, ptsCoType = PtsCollectionType.Set): PointerAnalysisConfig { + public static create( + kLimit: number, + outputDirectory: string, + detectTypeDiff: boolean = false, + dotDump: boolean = false, + unhandledFuncDump: boolean = false, + analysisScale: PtaAnalysisScale = PtaAnalysisScale.WholeProgram, + ptsCoType = PtsCollectionType.Set + ): PointerAnalysisConfig { PointerAnalysisConfig.instance = new PointerAnalysisConfig( - kLimit, outputDirectory, detectTypeDiff, dotDump, unhandledFuncDump, analysisScale, ptsCoType + kLimit, + outputDirectory, + detectTypeDiff, + dotDump, + unhandledFuncDump, + analysisScale, + ptsCoType ); return PointerAnalysisConfig.instance; } @@ -81,4 +98,4 @@ export class PointerAnalysisConfig { } return PointerAnalysisConfig.instance; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PtsDS.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PtsDS.ts index 3b7c3baf81f36493328a1e9abe164f6bcd975fad..492d6c99ecd407b1955cb8ba6e2acd80cabf95c3 100644 --- a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PtsDS.ts +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PtsDS.ts @@ -215,12 +215,15 @@ export class PtsBV implements IPtsCollection { } } -export enum PtsCollectionType { Set, BitVector }; +export enum PtsCollectionType { + Set, + BitVector, +} export class DiffPTData> { private diffPtsMap: Map; private propaPtsMap: Map; - constructor(private DSCreator: (new () => DS)) { + constructor(private DSCreator: new () => DS) { this.diffPtsMap = new Map(); this.propaPtsMap = new Map(); } @@ -323,7 +326,9 @@ export class DiffPTData> { } flush(v: K): void { - if (!this.diffPtsMap.has(v)) return; + if (!this.diffPtsMap.has(v)) { + return; + } let diff = this.diffPtsMap.get(v)!; let propa = this.getPropaPtsMut(v); // do not clear origin propa, only copy the pt and add it to diff @@ -333,19 +338,27 @@ export class DiffPTData> { clearPts(v: K): void { let diff = this.diffPtsMap.get(v); - if (diff) diff.clear(); + if (diff) { + diff.clear(); + } let propa = this.propaPtsMap.get(v); - if (propa) propa.clear(); + if (propa) { + propa.clear(); + } } clearDiffPts(v: K): void { let diff = this.diffPtsMap.get(v); - if (diff) diff.clear(); + if (diff) { + diff.clear(); + } } clearPropaPts(v: K): void { let propa = this.propaPtsMap.get(v); - if (propa) propa.clear(); + if (propa) { + propa.clear(); + } } calculateDiff(src: K, dst: K): DS { @@ -360,4 +373,4 @@ export class DiffPTData> { result.subtract(dstPropa); return result; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Constant.ts b/ets2panda/linter/arkanalyzer/src/core/base/Constant.ts index d6541f1cb1bb0bed267d7f8b18b2f8e9ff7883d5..cc7da1df70180d6a6d9b7df638fde0c7dedb7e7e 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Constant.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Constant.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -56,7 +56,7 @@ export class Constant implements Value { public toString(): string { let str = ''; if (this.type instanceof StringType) { - str = '\'' + this.value + '\''; + str = "'" + this.value + "'"; } else { str = this.value; } diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Decorator.ts b/ets2panda/linter/arkanalyzer/src/core/base/Decorator.ts index 8c98790ff944f127715afbf1d7ec7ad58a98da35..f53d1f78bd00abdcf67027620245b4d449be8312 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Decorator.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Decorator.ts @@ -41,4 +41,4 @@ export class Decorator { public toString(): string { return `@${this.content}`; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/DefUseChain.ts b/ets2panda/linter/arkanalyzer/src/core/base/DefUseChain.ts index 669bc74f2768d5ed3b2af523840a7a0d2cc2b3ae..8c4bd3ce97560ddde6183f16408d8a445e33d3e3 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/DefUseChain.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/DefUseChain.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -16,13 +16,13 @@ import { Value } from './Value'; import { Stmt } from './Stmt'; -export class DefUseChain{ - value:Value; - def:Stmt; - use:Stmt; - constructor(value:Value,def:Stmt,use:Stmt){ - this.value=value; - this.def=def; - this.use=use; +export class DefUseChain { + value: Value; + def: Stmt; + use: Stmt; + constructor(value: Value, def: Stmt, use: Stmt) { + this.value = value; + this.def = def; + this.use = use; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Expr.ts b/ets2panda/linter/arkanalyzer/src/core/base/Expr.ts index 96a499d5a58f0619feb90012e776b99626561c4b..dcf4695331ac437403e3d04b0ce248b533806264 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Expr.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Expr.ts @@ -19,7 +19,8 @@ import { MethodSignature } from '../model/ArkSignature'; import { Local } from './Local'; import { AliasType, - ArrayType, BigIntType, + ArrayType, + BigIntType, BooleanType, ClassType, FunctionType, @@ -60,7 +61,7 @@ export abstract class AbstractExpr implements Value { export abstract class AbstractInvokeExpr extends AbstractExpr { private methodSignature: MethodSignature; private args: Value[]; - private realGenericTypes?: Type[];//新增 + private realGenericTypes?: Type[]; //新增 constructor(methodSignature: MethodSignature, args: Value[], realGenericTypes?: Type[]) { super(); @@ -216,7 +217,6 @@ export class ArkInstanceInvokeExpr extends AbstractInvokeExpr { public inferType(arkMethod: ArkMethod): AbstractInvokeExpr { return IRInference.inferInstanceInvokeExpr(this, arkMethod); } - } export class ArkStaticInvokeExpr extends AbstractInvokeExpr { @@ -243,7 +243,6 @@ export class ArkStaticInvokeExpr extends AbstractInvokeExpr { public inferType(arkMethod: ArkMethod): AbstractInvokeExpr { return IRInference.inferStaticInvokeExpr(this, arkMethod); } - } /** @@ -439,7 +438,6 @@ export class ArkDeleteExpr extends AbstractExpr { public toString(): string { return 'delete ' + this.field; } - } export class ArkAwaitExpr extends AbstractExpr { @@ -640,13 +638,13 @@ export abstract class AbstractBinopExpr extends AbstractExpr { return this.op1 + ' ' + this.operator + ' ' + this.op2; } - protected inferOpType(op: Value, arkMethod: ArkMethod) { + protected inferOpType(op: Value, arkMethod: ArkMethod): void { if (op instanceof AbstractExpr || op instanceof AbstractRef) { TypeInference.inferValueType(op, arkMethod); } } - protected setType() { + protected setType(): void { let op1Type = this.op1.getType(); let op2Type = this.op2.getType(); if (op1Type instanceof UnionType) { @@ -706,15 +704,13 @@ export abstract class AbstractBinopExpr extends AbstractExpr { } break; case '??': - if (op1Type === UnknownType.getInstance() || op1Type === UndefinedType.getInstance() - || op1Type === NullType.getInstance()) { + if (op1Type === UnknownType.getInstance() || op1Type === UndefinedType.getInstance() || op1Type === NullType.getInstance()) { type = op2Type; } else { type = op1Type; } break; default: - ; } this.type = type; } @@ -945,7 +941,7 @@ export class ArkPhiExpr extends AbstractExpr { export enum UnaryOperator { Neg = '-', BitwiseNot = '~', - LogicalNot = '!' + LogicalNot = '!', } // unary operation expression @@ -1124,17 +1120,19 @@ export class AliasTypeExpr extends AbstractExpr { const genericTypes = this.getRealGenericTypes()!.join(','); res = res.replace('(', `<${genericTypes}>(`).replace(/\([^)]*\)/g, `(${genericTypes})`); } - return res + return res; } return `${typeOf}${typeObject.getName()}`; } public static isAliasTypeOriginalModel(object: any): object is AliasTypeOriginalModel { - return object instanceof Type || + return ( + object instanceof Type || object instanceof ImportInfo || object instanceof Local || object instanceof ArkClass || object instanceof ArkMethod || - object instanceof ArkField; + object instanceof ArkField + ); } } diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Local.ts b/ets2panda/linter/arkanalyzer/src/core/base/Local.ts index b018725ccb0feafa2de38088d68d46c719fa095c..aa4fbebdf0597b1972cea69e7fcdb70bba21b64b 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Local.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Local.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -14,7 +14,7 @@ */ import { Stmt } from './Stmt'; -import { Type, UnknownType } from './Type'; +import { ClassType, Type, UnknownType } from './Type'; import { Value } from './Value'; import { TypeInference } from '../common/TypeInference'; import { ArkExport, ExportType } from '../model/ArkExport'; @@ -24,6 +24,7 @@ import { UNKNOWN_METHOD_NAME } from '../common/Const'; import { ModifierType } from '../model/ArkBaseModel'; import { ArkMethod } from '../model/ArkMethod'; import { ModelUtils } from '../common/ModelUtils'; +import { THIS_NAME } from '../common/TSConst'; /** * @category core/base @@ -49,9 +50,11 @@ export class Local implements Value, ArkExport { } public inferType(arkMethod: ArkMethod): Local { - if (TypeInference.isUnclearType(this.type)) { - const type = TypeInference.inferUnclearRefName(this.name, arkMethod.getDeclaringArkClass()) ?? - ModelUtils.findDeclaredLocal(this, arkMethod)?.getType(); + if (this.name === THIS_NAME && this.type instanceof UnknownType) { + const declaringArkClass = arkMethod.getDeclaringArkClass(); + this.type = new ClassType(declaringArkClass.getSignature(), declaringArkClass.getRealTypes()); + } else if (TypeInference.isUnclearType(this.type)) { + const type = TypeInference.inferBaseType(this.name, arkMethod.getDeclaringArkClass()) ?? ModelUtils.findDeclaredLocal(this, arkMethod)?.getType(); if (type) { this.type = type; } @@ -127,7 +130,7 @@ export class Local implements Value, ArkExport { return this.declaringStmt; } - public setDeclaringStmt(declaringStmt: Stmt) { + public setDeclaringStmt(declaringStmt: Stmt): void { this.declaringStmt = declaringStmt; } @@ -139,7 +142,7 @@ export class Local implements Value, ArkExport { return []; } - public addUsedStmt(usedStmt: Stmt) { + public addUsedStmt(usedStmt: Stmt): void { this.usedStmts.push(usedStmt); } @@ -187,8 +190,13 @@ export class Local implements Value, ArkExport { } public getSignature(): LocalSignature { - return this.signature ?? new LocalSignature(this.name, new MethodSignature(ClassSignature.DEFAULT, - ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(UNKNOWN_METHOD_NAME))); + return ( + this.signature ?? + new LocalSignature( + this.name, + new MethodSignature(ClassSignature.DEFAULT, ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(UNKNOWN_METHOD_NAME)) + ) + ); } public setSignature(signature: LocalSignature): void { @@ -205,4 +213,4 @@ export class Local implements Value, ArkExport { public setConstFlag(newConstFlag: boolean): void { this.constFlag = newConstFlag; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Position.ts b/ets2panda/linter/arkanalyzer/src/core/base/Position.ts index 9ae747dac992509f4edbcad944b352c3f32ebfdd..2e1087b4cd50e2cc45a1de95c66e9f2948f2738d 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Position.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Position.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -94,7 +94,7 @@ export class LineColPosition { return getColNo(this.lineCol); } - public static buildFromNode(node: ts.Node, sourceFile: ts.SourceFile) { + public static buildFromNode(node: ts.Node, sourceFile: ts.SourceFile): LineColPosition { let { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)); // line start from 1. return new LineColPosition(line + 1, character + 1); @@ -129,10 +129,7 @@ export class FullPosition { } public static buildFromNode(node: ts.Node, sourceFile: ts.SourceFile): FullPosition { - const { line: startLine, character: startCharacter } = ts.getLineAndCharacterOfPosition( - sourceFile, - node.getStart(sourceFile) - ); + const { line: startLine, character: startCharacter } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)); const { line: endLine, character: endCharacter } = ts.getLineAndCharacterOfPosition(sourceFile, node.getEnd()); // line start from 1 diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Ref.ts b/ets2panda/linter/arkanalyzer/src/core/base/Ref.ts index 612b0e3371ee5b953c99ff4c391ef29940d07d94..66e13f6d9066fb175a34c775831b846cc07591c8 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Ref.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Ref.ts @@ -39,7 +39,7 @@ export abstract class AbstractRef implements Value { } export class ArkArrayRef extends AbstractRef { - private base: Local; // 数组变量 + private base: Local; // 数组变量 private index: Value; // 索引 constructor(base: Local, index: Value) { @@ -167,7 +167,7 @@ export abstract class AbstractFieldRef extends AbstractRef { } export class ArkInstanceFieldRef extends AbstractFieldRef { - private base: Local; // which obj this field belong to + private base: Local; // which obj this field belong to constructor(base: Local, fieldSignature: FieldSignature) { super(fieldSignature); @@ -216,7 +216,6 @@ export class ArkInstanceFieldRef extends AbstractFieldRef { public inferType(arkMethod: ArkMethod): AbstractRef { return IRInference.inferFieldRef(this, arkMethod); } - } export class ArkStaticFieldRef extends AbstractFieldRef { @@ -272,7 +271,6 @@ export class ArkParameterRef extends AbstractRef { } } - export class ArkThisRef extends AbstractRef { private type: ClassType; @@ -400,7 +398,10 @@ export class ClosureFieldRef extends AbstractRef { if (TypeInference.isUnclearType(this.type)) { let type: Type | undefined = this.base.getType(); if (type instanceof LexicalEnvType) { - type = type.getClosures().find(c => c.getName() === this.fieldName)?.getType(); + type = type + .getClosures() + .find(c => c.getName() === this.fieldName) + ?.getType(); } if (type && !TypeInference.isUnclearType(type)) { this.type = type; @@ -408,4 +409,4 @@ export class ClosureFieldRef extends AbstractRef { } return this; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Stmt.ts b/ets2panda/linter/arkanalyzer/src/core/base/Stmt.ts index 914bf730438f6e45dc5072619ea20a00fd153068..6d792a826efa2f61369902bcb3473b8594914f86 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Stmt.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Stmt.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -30,12 +30,12 @@ import { AbstractTypeExpr } from './TypeExpr'; * @category core/base/stmt */ export abstract class Stmt { - protected text?: string; // just for debug + protected text?: string; // just for debug protected originalText?: string; protected originalPosition: LineColPosition = LineColPosition.DEFAULT; protected cfg!: Cfg; protected operandOriginalPositions?: FullPosition[]; // operandOriginalPositions correspond with - // def and uses one by one + // def and uses one by one metadata?: ArkMetadata; public getMetadata(kind: ArkMetadataKind): ArkMetadataType | undefined { @@ -48,7 +48,7 @@ export abstract class Stmt { } return this.metadata?.setMetadata(kind, value); } - + /** Return a list of values which are uesd in this statement */ public getUses(): Value[] { return []; @@ -274,7 +274,7 @@ export abstract class Stmt { return this.originalPosition; } - abstract toString(): string ; + abstract toString(): string; public setText(text: string): void { this.text = text; @@ -290,14 +290,14 @@ export abstract class Stmt { public setOperandOriginalPositions(operandOriginalPositions: FullPosition[]): void { this.operandOriginalPositions = operandOriginalPositions; - }; + } public getOperandOriginalPositions(): FullPosition[] | undefined { return this.operandOriginalPositions; - }; + } public getOperandOriginalPosition(indexOrOperand: number | Value): FullPosition | null { - let index:number = -1; + let index: number = -1; if (typeof indexOrOperand !== 'number') { index = IRUtils.findOperandIdx(this, indexOrOperand); } else { @@ -308,7 +308,7 @@ export abstract class Stmt { return null; } return this.operandOriginalPositions[index]; - }; + } } export class ArkAssignStmt extends Stmt { @@ -322,7 +322,7 @@ export class ArkAssignStmt extends Stmt { } /** - * Returns the left operand of the assigning statement. + * Returns the left operand of the assigning statement. * @returns The left operand of the assigning statement. * @example * 1. If the statement is `a=b;`, the right operand is `a`; if the statement is `dd = cc + 5;`, the right operand @@ -381,11 +381,11 @@ export class ArkInvokeStmt extends Stmt { this.invokeExpr = invokeExpr; } - public replaceInvokeExpr(newExpr: AbstractInvokeExpr) { + public replaceInvokeExpr(newExpr: AbstractInvokeExpr): void { this.invokeExpr = newExpr; } - public getInvokeExpr() { + public getInvokeExpr(): AbstractInvokeExpr { return this.invokeExpr; } @@ -600,4 +600,4 @@ export class ArkAliasTypeDefineStmt extends Stmt { } return []; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Trap.ts b/ets2panda/linter/arkanalyzer/src/core/base/Trap.ts index b5e22d759414acb5f3e90f7a55089c65187e2a6c..62237fe0e906615939e38d3fcfa1c67ef3d3bc59 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Trap.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Trap.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -31,4 +31,4 @@ export class Trap { public getCatchBlocks(): BasicBlock[] { return this.catchBlocks; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Type.ts b/ets2panda/linter/arkanalyzer/src/core/base/Type.ts index 18a85c32fccc2e78bd7c10ebecb8f5acc0eeed0d..16987467749ac00a493ec3f00132d789c8f123b2 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Type.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Type.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { AliasTypeSignature, ClassSignature, MethodSignature, NamespaceSignature, } from '../model/ArkSignature'; +import { AliasTypeSignature, ClassSignature, FieldSignature, MethodSignature, NamespaceSignature } from '../model/ArkSignature'; import { ArkExport, ExportType } from '../model/ArkExport'; import { MODIFIER_TYPE_MASK, ModifierType } from '../model/ArkBaseModel'; import { @@ -29,6 +29,7 @@ import { VOID_KEYWORD, } from '../common/TSConst'; import { Local } from './Local'; +import { Constant } from './Constant'; /** * @category core/base/type @@ -95,7 +96,7 @@ export class UnclearReferenceType extends Type { this.genericTypes = genericTypes; } - public getName() { + public getName(): string { return this.name; } @@ -124,7 +125,7 @@ export abstract class PrimitiveType extends Type { this.name = name; } - public getName() { + public getName(): string { return this.name; } @@ -140,7 +141,7 @@ export class BooleanType extends PrimitiveType { super(BOOLEAN_KEYWORD); } - public static getInstance() { + public static getInstance(): BooleanType { return this.INSTANCE; } } @@ -152,7 +153,7 @@ export class NumberType extends PrimitiveType { super(NUMBER_KEYWORD); } - public static getInstance() { + public static getInstance(): NumberType { return this.INSTANCE; } } @@ -168,7 +169,7 @@ export class BigIntType extends PrimitiveType { super(BIGINT_KEYWORD); } - public static getInstance() { + public static getInstance(): BigIntType { return this.INSTANCE; } } @@ -180,7 +181,7 @@ export class StringType extends PrimitiveType { super(STRING_KEYWORD); } - public static getInstance() { + public static getInstance(): StringType { return this.INSTANCE; } } @@ -247,7 +248,7 @@ export class LiteralType extends PrimitiveType { */ export class UnionType extends Type { private types: Type[]; - private currType: Type; // The true type of the value at this time + private currType: Type; // The true type of the value at this time constructor(types: Type[], currType: Type = UnknownType.getInstance()) { super(); this.types = [...types]; @@ -268,7 +269,7 @@ export class UnionType extends Type { public getTypeString(): string { let typesString: string[] = []; - this.getTypes().forEach((t) => { + this.getTypes().forEach(t => { if (t instanceof UnionType || t instanceof IntersectionType) { typesString.push(`(${t.toString()})`); } else { @@ -310,7 +311,7 @@ export class IntersectionType extends Type { public getTypeString(): string { let typesString: string[] = []; - this.getTypes().forEach((t) => { + this.getTypes().forEach(t => { if (t instanceof UnionType || t instanceof IntersectionType) { typesString.push(`(${t.toString()})`); } else { @@ -697,7 +698,7 @@ export class GenericType extends Type { this.constraint = type; } - public setIndex(index: number) { + public setIndex(index: number): void { this.index = index; } @@ -792,3 +793,26 @@ export class LexicalEnvType extends Type { return `[${this.getClosures().join(', ')}]`; } } + +export class EnumValueType extends Type { + private signature: FieldSignature; + private constant?: Constant; + + constructor(signature: FieldSignature, constant?: Constant) { + super(); + this.signature = signature; + this.constant = constant; + } + + public getFieldSignature(): FieldSignature { + return this.signature; + } + + public getConstant(): Constant | undefined { + return this.constant; + } + + public getTypeString(): string { + return this.signature.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/TypeExpr.ts b/ets2panda/linter/arkanalyzer/src/core/base/TypeExpr.ts index c390f3ce5b6ebb708bc91a49ce855a788e3f4f4a..8995083feb1acc7689742832e041f1cd7a9408f7 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/TypeExpr.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/TypeExpr.ts @@ -175,4 +175,4 @@ export class KeyofTypeExpr extends AbstractTypeExpr { public inferType(arkMethod: ArkMethod): void { IRInference.inferKeyofTypeExpr(this, arkMethod); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Value.ts b/ets2panda/linter/arkanalyzer/src/core/base/Value.ts index 89ed31ee5185ff7b156bf472d896cf29db3ae5a3..abeb8acba8897d3c8e364559b317bed16918a77e 100644 --- a/ets2panda/linter/arkanalyzer/src/core/base/Value.ts +++ b/ets2panda/linter/arkanalyzer/src/core/base/Value.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -19,11 +19,11 @@ import { Type } from './Type'; * @category core/base */ export interface Value { - /** + /** * Return a list of values which are contained in this {@link Value}. - * Value is a core interface in ArkAnalyzer, which may represent any value or expression. + * Value is a core interface in ArkAnalyzer, which may represent any value or expression. * @returns An **array** of values used by this value. - */ + */ getUses(): Value[]; /** @@ -45,5 +45,5 @@ export interface Value { } ``` */ - getType():Type; -} \ No newline at end of file + getType(): Type; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ArkError.ts b/ets2panda/linter/arkanalyzer/src/core/common/ArkError.ts index be9fa839a17db23ed837a593cacf96dd75fdd659..effb281a6e4f22c55a634c735e4dffefd1801ba0 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/ArkError.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/ArkError.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ArkIRTransformer.ts b/ets2panda/linter/arkanalyzer/src/core/common/ArkIRTransformer.ts index ab15671794831dd86dc8d1252ccf6830ef6d073d..31f9ecf635744368612a3a08b551ecca62c1b4a5 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/ArkIRTransformer.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/ArkIRTransformer.ts @@ -29,37 +29,16 @@ import { ArkCaughtExceptionRef, ArkInstanceFieldRef, ArkParameterRef, ArkThisRef import { Value } from '../base/Value'; import * as ts from 'ohos-typescript'; import { Local } from '../base/Local'; -import { - ArkAliasTypeDefineStmt, - ArkAssignStmt, - ArkIfStmt, - ArkInvokeStmt, - ArkReturnStmt, - ArkReturnVoidStmt, - ArkThrowStmt, - Stmt, -} from '../base/Stmt'; +import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, ArkThrowStmt, Stmt } from '../base/Stmt'; import { AliasType, BooleanType, ClassType, Type, UnclearReferenceType, UnknownType, VoidType } from '../base/Type'; import { ValueUtil } from './ValueUtil'; -import { - AliasTypeSignature, - ClassSignature, - FieldSignature, - MethodSignature, - MethodSubSignature, -} from '../model/ArkSignature'; +import { AliasTypeSignature, ClassSignature, FieldSignature, MethodSignature, MethodSubSignature } from '../model/ArkSignature'; import { IRUtils } from './IRUtils'; import { ArkMethod } from '../model/ArkMethod'; import { buildArkMethodFromArkClass } from '../model/builder/ArkMethodBuilder'; import { ArkSignatureBuilder } from '../model/builder/ArkSignatureBuilder'; -import { - COMPONENT_BRANCH_FUNCTION, - COMPONENT_CREATE_FUNCTION, - COMPONENT_IF, - COMPONENT_POP_FUNCTION, - COMPONENT_REPEAT, -} from './EtsConst'; +import { COMPONENT_BRANCH_FUNCTION, COMPONENT_CREATE_FUNCTION, COMPONENT_IF, COMPONENT_POP_FUNCTION, COMPONENT_REPEAT } from './EtsConst'; import { FullPosition, LineColPosition } from '../base/Position'; import { ModelUtils } from './ModelUtils'; import { Builtin } from './Builtin'; @@ -74,9 +53,9 @@ import { ArkClass } from '../model/ArkClass'; import { ModifierType } from '../model/ArkBaseModel'; export type ValueAndStmts = { - value: Value, - valueOriginalPositions: FullPosition[], // original positions of value and its uses - stmts: Stmt[] + value: Value; + valueOriginalPositions: FullPosition[]; // original positions of value and its uses + stmts: Stmt[]; }; export class DummyStmt extends Stmt { @@ -132,9 +111,7 @@ export class ArkIRTransformer { let index = 0; for (const methodParameter of this.declaringMethod.getParameters()) { const parameterRef = new ArkParameterRef(index, methodParameter.getType()); - stmts.push(new ArkAssignStmt( - this.arkValueTransformer.addNewLocal(methodParameter.getName(), parameterRef.getType()), - parameterRef)); + stmts.push(new ArkAssignStmt(this.arkValueTransformer.addNewLocal(methodParameter.getName(), parameterRef.getType()), parameterRef)); index++; } @@ -216,18 +193,10 @@ export class ArkIRTransformer { private returnStatementToStmts(returnStatement: ts.ReturnStatement): Stmt[] { const stmts: Stmt[] = []; if (returnStatement.expression) { - let { - value: exprValue, - valueOriginalPositions: exprPositions, - stmts: exprStmts, - } = this.tsNodeToValueAndStmts(returnStatement.expression); + let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(returnStatement.expression); exprStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(exprValue)) { - ({ - value: exprValue, - valueOriginalPositions: exprPositions, - stmts: exprStmts, - } = this.generateAssignStmtForValue(exprValue, exprPositions)); + ({ value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.generateAssignStmtForValue(exprValue, exprPositions)); exprStmts.forEach(stmt => stmts.push(stmt)); } const returnStmt = new ArkReturnStmt(exprValue); @@ -264,11 +233,7 @@ export class ArkIRTransformer { private expressionStatementToStmts(expressionStatement: ts.ExpressionStatement): Stmt[] { const exprNode = expressionStatement.expression; - const { - value: exprValue, - valueOriginalPositions: exprPositions, - stmts: stmts, - } = this.tsNodeToValueAndStmts(exprNode); + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts(exprNode); if (exprValue instanceof AbstractInvokeExpr) { this.addInvokeStmts(exprValue, exprPositions, stmts); } else if (this.shouldGenerateExtraAssignStmt(exprNode)) { @@ -285,11 +250,13 @@ export class ArkIRTransformer { let hasRepeat: boolean = false; for (const stmt of stmts) { - if ((stmt instanceof ArkAssignStmt) && (stmt.getRightOp() instanceof ArkStaticInvokeExpr)) { + if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof ArkStaticInvokeExpr) { const rightOp = stmt.getRightOp() as ArkStaticInvokeExpr; if (rightOp.getMethodSignature().getMethodSubSignature().getMethodName() === COMPONENT_REPEAT) { - const createMethodSignature = - ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(COMPONENT_REPEAT, COMPONENT_CREATE_FUNCTION); + const createMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName( + COMPONENT_REPEAT, + COMPONENT_CREATE_FUNCTION + ); const createInvokeExpr = new ArkStaticInvokeExpr(createMethodSignature, rightOp.getArgs()); stmt.setRightOp(createInvokeExpr); hasRepeat = true; @@ -308,16 +275,19 @@ export class ArkIRTransformer { if (ts.isParenthesizedExpression(expression)) { return this.shouldGenerateExtraAssignStmt(expression.expression); } - if ((ts.isBinaryExpression(expression) && (expression.operatorToken.kind === ts.SyntaxKind.FirstAssignment || - ArkValueTransformer.isCompoundAssignmentOperator(expression.operatorToken.kind))) || - ts.isEtsComponentExpression(expression) || ts.isVoidExpression(expression) || - ts.isNewExpression(expression) || ts.isCallExpression(expression) || + if ( + (ts.isBinaryExpression(expression) && + (expression.operatorToken.kind === ts.SyntaxKind.FirstAssignment || + ArkValueTransformer.isCompoundAssignmentOperator(expression.operatorToken.kind))) || + ts.isEtsComponentExpression(expression) || + ts.isVoidExpression(expression) || + ts.isNewExpression(expression) || + ts.isCallExpression(expression) || (ts.isPrefixUnaryExpression(expression) && - (expression.operator === ts.SyntaxKind.PlusPlusToken || - expression.operator === ts.SyntaxKind.MinusMinusToken)) || + (expression.operator === ts.SyntaxKind.PlusPlusToken || expression.operator === ts.SyntaxKind.MinusMinusToken)) || (ts.isPostfixUnaryExpression(expression) && - (expression.operator === ts.SyntaxKind.PlusPlusToken || - expression.operator === ts.SyntaxKind.MinusMinusToken))) { + (expression.operator === ts.SyntaxKind.PlusPlusToken || expression.operator === ts.SyntaxKind.MinusMinusToken)) + ) { return false; } @@ -377,8 +347,7 @@ export class ArkIRTransformer { } } else if (ts.isTypeQueryNode(rightOp)) { const localName = rightOp.exprName.getText(this.sourceFile); - const originalLocal = Array.from(this.arkValueTransformer.getLocals()).find(local => - local.getName() === localName); + const originalLocal = Array.from(this.arkValueTransformer.getLocals()).find(local => local.getName() === localName); if (originalLocal === undefined || rightType instanceof UnclearReferenceType) { expr = new AliasTypeExpr(new Local(localName, rightType), true); } else { @@ -441,28 +410,22 @@ export class ArkIRTransformer { public switchStatementToValueAndStmts(switchStatement: ts.SwitchStatement): ValueAndStmts[] { const valueAndStmtsOfSwitchAndCases: ValueAndStmts[] = []; const exprStmts: Stmt[] = []; - let { - value: exprValue, - valueOriginalPositions: exprPositions, - stmts: exprTempStmts, - } = this.tsNodeToValueAndStmts(switchStatement.expression); + let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprTempStmts } = this.tsNodeToValueAndStmts(switchStatement.expression); exprTempStmts.forEach(stmt => exprStmts.push(stmt)); if (IRUtils.moreThanOneAddress(exprValue)) { - ({ value: exprValue, valueOriginalPositions: exprPositions, stmts: exprTempStmts } = - this.generateAssignStmtForValue(exprValue, exprPositions)); + ({ value: exprValue, valueOriginalPositions: exprPositions, stmts: exprTempStmts } = this.generateAssignStmtForValue(exprValue, exprPositions)); exprTempStmts.forEach(stmt => exprStmts.push(stmt)); } - valueAndStmtsOfSwitchAndCases.push( - { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts }); + valueAndStmtsOfSwitchAndCases.push({ + value: exprValue, + valueOriginalPositions: exprPositions, + stmts: exprStmts, + }); for (const clause of switchStatement.caseBlock.clauses) { if (ts.isCaseClause(clause)) { const clauseStmts: Stmt[] = []; - let { - value: clauseValue, - valueOriginalPositions: clausePositions, - stmts: clauseTempStmts, - } = this.tsNodeToValueAndStmts(clause.expression); + let { value: clauseValue, valueOriginalPositions: clausePositions, stmts: clauseTempStmts } = this.tsNodeToValueAndStmts(clause.expression); clauseTempStmts.forEach(stmt => clauseStmts.push(stmt)); if (IRUtils.moreThanOneAddress(clauseValue)) { ({ @@ -472,8 +435,11 @@ export class ArkIRTransformer { } = this.generateAssignStmtForValue(clauseValue, clausePositions)); clauseTempStmts.forEach(stmt => clauseStmts.push(stmt)); } - valueAndStmtsOfSwitchAndCases.push( - { value: clauseValue, valueOriginalPositions: clausePositions, stmts: clauseStmts }); + valueAndStmtsOfSwitchAndCases.push({ + value: clauseValue, + valueOriginalPositions: clausePositions, + stmts: clauseStmts, + }); } } return valueAndStmtsOfSwitchAndCases; @@ -488,10 +454,7 @@ export class ArkIRTransformer { stmts.push(dummyInitializerStmt); if (forStatement.condition) { - const { - value: conditionValue, - stmts: conditionStmts, - } = this.arkValueTransformer.conditionToValueAndStmts(forStatement.condition); + const { value: conditionValue, stmts: conditionStmts } = this.arkValueTransformer.conditionToValueAndStmts(forStatement.condition); conditionStmts.forEach(stmt => stmts.push(stmt)); stmts.push(new ArkIfStmt(conditionValue as ArkConditionExpr)); } else { @@ -508,19 +471,17 @@ export class ArkIRTransformer { private rangeForStatementToStmts(forOfStatement: ts.ForOfStatement | ts.ForInStatement): Stmt[] { const stmts: Stmt[] = []; - let { - value: iterableValue, - valueOriginalPositions: iterablePositions, - stmts: iterableStmts, - } = this.tsNodeToValueAndStmts(forOfStatement.expression); + let { value: iterableValue, valueOriginalPositions: iterablePositions, stmts: iterableStmts } = this.tsNodeToValueAndStmts(forOfStatement.expression); iterableStmts.forEach(stmt => stmts.push(stmt)); if (!(iterableValue instanceof Local)) { - ({ value: iterableValue, valueOriginalPositions: iterablePositions, stmts: iterableStmts } = - this.generateAssignStmtForValue(iterableValue, iterablePositions)); + ({ + value: iterableValue, + valueOriginalPositions: iterablePositions, + stmts: iterableStmts, + } = this.generateAssignStmtForValue(iterableValue, iterablePositions)); iterableStmts.forEach(stmt => stmts.push(stmt)); } - const iteratorMethodSubSignature = new MethodSubSignature(Builtin.ITERATOR_FUNCTION, [], - Builtin.ITERATOR_CLASS_TYPE); + const iteratorMethodSubSignature = new MethodSubSignature(Builtin.ITERATOR_FUNCTION, [], Builtin.ITERATOR_CLASS_TYPE); const iteratorMethodSignature = new MethodSignature(ClassSignature.DEFAULT, iteratorMethodSubSignature); const iteratorInvokeExpr = new ArkInstanceInvokeExpr(iterableValue as Local, iteratorMethodSignature, []); const iteratorInvokeExprPositions = [iterablePositions[0], ...iterablePositions]; @@ -532,8 +493,7 @@ export class ArkIRTransformer { iteratorStmts.forEach(stmt => stmts.push(stmt)); (iterator as Local).setType(Builtin.ITERATOR_CLASS_TYPE); - const nextMethodSubSignature = new MethodSubSignature(Builtin.ITERATOR_NEXT, [], - Builtin.ITERATOR_RESULT_CLASS_TYPE); + const nextMethodSubSignature = new MethodSubSignature(Builtin.ITERATOR_NEXT, [], Builtin.ITERATOR_RESULT_CLASS_TYPE); const nextMethodSignature = new MethodSignature(ClassSignature.DEFAULT, nextMethodSubSignature); const iteratorNextInvokeExpr = new ArkInstanceInvokeExpr(iterator as Local, nextMethodSignature, []); const iteratorNextInvokeExprPositions = [iteratorPositions[0], ...iteratorPositions]; @@ -541,12 +501,10 @@ export class ArkIRTransformer { value: iteratorResult, valueOriginalPositions: iteratorResultPositions, stmts: iteratorResultStmts, - } = this.generateAssignStmtForValue(iteratorNextInvokeExpr, - iteratorNextInvokeExprPositions); + } = this.generateAssignStmtForValue(iteratorNextInvokeExpr, iteratorNextInvokeExprPositions); iteratorResultStmts.forEach(stmt => stmts.push(stmt)); (iteratorResult as Local).setType(Builtin.ITERATOR_RESULT_CLASS_TYPE); - const doneFieldSignature = new FieldSignature(Builtin.ITERATOR_RESULT_DONE, - Builtin.ITERATOR_RESULT_CLASS_SIGNATURE, BooleanType.getInstance(), false); + const doneFieldSignature = new FieldSignature(Builtin.ITERATOR_RESULT_DONE, Builtin.ITERATOR_RESULT_CLASS_SIGNATURE, BooleanType.getInstance(), false); const doneFieldRef = new ArkInstanceFieldRef(iteratorResult as Local, doneFieldSignature); const doneFieldRefPositions = [iteratorResultPositions[0], ...iteratorResultPositions]; const { @@ -562,8 +520,12 @@ export class ArkIRTransformer { ifStmt.setOperandOriginalPositions(conditionExprPositions); stmts.push(ifStmt); - const valueFieldSignature = new FieldSignature(Builtin.ITERATOR_RESULT_VALUE, - Builtin.ITERATOR_RESULT_CLASS_SIGNATURE, UnknownType.getInstance(), false); + const valueFieldSignature = new FieldSignature( + Builtin.ITERATOR_RESULT_VALUE, + Builtin.ITERATOR_RESULT_CLASS_SIGNATURE, + UnknownType.getInstance(), + false + ); const valueFieldRef = new ArkInstanceFieldRef(iteratorResult as Local, valueFieldSignature); const valueFieldRefPositions = [iteratorResultPositions[0], ...iteratorResultPositions]; const { @@ -579,17 +541,17 @@ export class ArkIRTransformer { if (ts.isVariableDeclarationList(initializerNode)) { const isConst = (initializerNode.flags & ts.NodeFlags.Const) !== 0; const { - value: initValue, valueOriginalPositions: initOriPos, stmts: initStmts, - } = this.arkValueTransformer.variableDeclarationToValueAndStmts(initializerNode.declarations[0], isConst, - false); + value: initValue, + valueOriginalPositions: initOriPos, + stmts: initStmts, + } = this.arkValueTransformer.variableDeclarationToValueAndStmts(initializerNode.declarations[0], isConst, false); const assignStmt = new ArkAssignStmt(initValue, castExpr); assignStmt.setOperandOriginalPositions([...initOriPos, ...castExprPositions]); stmts.push(assignStmt); initStmts.forEach(stmt => stmts.push(stmt)); - } else { // initializer maybe an expression - const { - value: initValue, valueOriginalPositions: initOriPos, stmts: initStmts, - } = this.tsNodeToValueAndStmts(initializerNode); + } else { + // initializer maybe an expression + const { value: initValue, valueOriginalPositions: initOriPos, stmts: initStmts } = this.tsNodeToValueAndStmts(initializerNode); const assignStmt = new ArkAssignStmt(initValue, castExpr); assignStmt.setOperandOriginalPositions([...initOriPos, ...castExprPositions]); initStmts.forEach(stmt => stmts.push(stmt)); @@ -603,10 +565,7 @@ export class ArkIRTransformer { const dummyInitializerStmt = new DummyStmt(ArkIRTransformer.DUMMY_LOOP_INITIALIZER_STMT); stmts.push(dummyInitializerStmt); - const { - value: conditionExpr, - stmts: conditionStmts, - } = this.arkValueTransformer.conditionToValueAndStmts(whileStatement.expression); + const { value: conditionExpr, stmts: conditionStmts } = this.arkValueTransformer.conditionToValueAndStmts(whileStatement.expression); conditionStmts.forEach(stmt => stmts.push(stmt)); stmts.push(new ArkIfStmt(conditionExpr as ArkConditionExpr)); return stmts; @@ -614,10 +573,7 @@ export class ArkIRTransformer { private doStatementToStmts(doStatement: ts.DoStatement): Stmt[] { const stmts: Stmt[] = []; - const { - value: conditionExpr, - stmts: conditionStmts, - } = this.arkValueTransformer.conditionToValueAndStmts(doStatement.expression); + const { value: conditionExpr, stmts: conditionStmts } = this.arkValueTransformer.conditionToValueAndStmts(doStatement.expression); conditionStmts.forEach(stmt => stmts.push(stmt)); stmts.push(new ArkIfStmt(conditionExpr as ArkConditionExpr)); return stmts; @@ -644,13 +600,12 @@ export class ArkIRTransformer { const { value: conditionLocal, valueOriginalPositions: conditionLocalPositions, - stmts: assignConditionStmts + stmts: assignConditionStmts, } = this.generateAssignStmtForValue(conditionExpr, conditionExprPositions); assignConditionStmts.forEach(stmt => stmts.push(stmt)); const createInvokeExpr = new ArkStaticInvokeExpr(createMethodSignature, [conditionLocal]); const createInvokeExprPositions = [conditionLocalPositions[0], ...conditionLocalPositions]; - const { stmts: createStmts } = this.generateAssignStmtForValue(createInvokeExpr, - createInvokeExprPositions); + const { stmts: createStmts } = this.generateAssignStmtForValue(createInvokeExpr, createInvokeExprPositions); createStmts.forEach(stmt => stmts.push(stmt)); const branchMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(COMPONENT_IF, COMPONENT_BRANCH_FUNCTION); const branchInvokeExpr = new ArkStaticInvokeExpr(branchMethodSignature, [ValueUtil.getOrCreateNumberConst(0)]); @@ -662,8 +617,7 @@ export class ArkIRTransformer { if (ifStatement.elseStatement) { const branchElseMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(COMPONENT_IF, COMPONENT_BRANCH_FUNCTION); const branchElseInvokeExpr = new ArkStaticInvokeExpr(branchElseMethodSignature, [ValueUtil.getOrCreateNumberConst(1)]); - const branchElseInvokeExprPositions = [FullPosition.buildFromNode(ifStatement.elseStatement, - this.sourceFile), FullPosition.DEFAULT]; + const branchElseInvokeExprPositions = [FullPosition.buildFromNode(ifStatement.elseStatement, this.sourceFile), FullPosition.DEFAULT]; const branchElseInvokeStmt = new ArkInvokeStmt(branchElseInvokeExpr); branchElseInvokeStmt.setOperandOriginalPositions(branchElseInvokeExprPositions); stmts.push(branchElseInvokeStmt); @@ -694,11 +648,7 @@ export class ArkIRTransformer { private throwStatementToStmts(throwStatement: ts.ThrowStatement): Stmt[] { const stmts: Stmt[] = []; - const { - value: throwValue, - valueOriginalPositions: throwValuePositions, - stmts: throwStmts, - } = this.tsNodeToValueAndStmts(throwStatement.expression); + const { value: throwValue, valueOriginalPositions: throwValuePositions, stmts: throwStmts } = this.tsNodeToValueAndStmts(throwStatement.expression); throwStmts.forEach(stmt => stmts.push(stmt)); const throwStmt = new ArkThrowStmt(throwValue); throwStmt.setOperandOriginalPositions(throwValuePositions); @@ -710,9 +660,10 @@ export class ArkIRTransformer { const stmts: Stmt[] = []; if (catchClause.variableDeclaration) { const { - value: catchValue, valueOriginalPositions: catchOriPos, stmts: catchStmts, - } = this.arkValueTransformer.variableDeclarationToValueAndStmts(catchClause.variableDeclaration, false, - false); + value: catchValue, + valueOriginalPositions: catchOriPos, + stmts: catchStmts, + } = this.arkValueTransformer.variableDeclarationToValueAndStmts(catchClause.variableDeclaration, false, false); const caughtExceptionRef = new ArkCaughtExceptionRef(UnknownType.getInstance()); const assignStmt = new ArkAssignStmt(catchValue, caughtExceptionRef); assignStmt.setOperandOriginalPositions(catchOriPos); @@ -731,11 +682,7 @@ export class ArkIRTransformer { private newClassInExportToStmts(expression: ts.NewExpression | ts.ObjectLiteralExpression): Stmt[] { let stmts: Stmt[] = []; - let { - value: rightValue, - valueOriginalPositions: rightPositions, - stmts: rightStmts, - } = this.tsNodeToValueAndStmts(expression); + let { value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts } = this.tsNodeToValueAndStmts(expression); rightStmts.forEach(stmt => stmts.push(stmt)); let leftValue = this.arkValueTransformer.addNewLocal(DEFAULT); let leftPositions = rightPositions; @@ -764,7 +711,6 @@ export class ArkIRTransformer { case ts.SyntaxKind.ExclamationToken: return UnaryOperator.LogicalNot; default: - ; } return null; } @@ -818,7 +764,6 @@ export class ArkIRTransformer { case ts.SyntaxKind.ExclamationEqualsEqualsToken: return RelationalBinaryOperator.StrictInequality; default: - ; } return null; } @@ -828,11 +773,19 @@ export class ArkIRTransformer { const leftOpPosition = valueOriginalPositions[0]; const assignStmt = new ArkAssignStmt(leftOp, value); assignStmt.setOperandOriginalPositions([leftOpPosition, ...valueOriginalPositions]); - return { value: leftOp, valueOriginalPositions: [leftOpPosition], stmts: [assignStmt] }; - } - - public generateIfStmtForValues(leftValue: Value, leftOpOriginalPositions: FullPosition[], rightValue: Value, - rightOpOriginalPositions: FullPosition[]): Stmt[] { + return { + value: leftOp, + valueOriginalPositions: [leftOpPosition], + stmts: [assignStmt], + }; + } + + public generateIfStmtForValues( + leftValue: Value, + leftOpOriginalPositions: FullPosition[], + rightValue: Value, + rightOpOriginalPositions: FullPosition[] + ): Stmt[] { const stmts: Stmt[] = []; if (IRUtils.moreThanOneAddress(leftValue)) { const { @@ -866,4 +819,4 @@ export class ArkIRTransformer { public setBuilderMethodContextFlag(builderMethodContextFlag: boolean): void { this.builderMethodContextFlag = builderMethodContextFlag; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ArkValueTransformer.ts b/ets2panda/linter/arkanalyzer/src/core/common/ArkValueTransformer.ts index 1e22c774d4da3a4961755b32dbf4066430835663..75d86894287526553dc8e0e7a656d10f280cc4da 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/ArkValueTransformer.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/ArkValueTransformer.ts @@ -209,8 +209,7 @@ export class ArkValueTransformer { let { value, valueOriginalPositions, stmts } = this.tsNodeToValueAndStmts(node); stmts.forEach(stmt => allStmts.push(stmt)); if (IRUtils.moreThanOneAddress(value)) { - ({ value, valueOriginalPositions, stmts } = - this.arkIRTransformer.generateAssignStmtForValue(value, valueOriginalPositions)); + ({ value, valueOriginalPositions, stmts } = this.arkIRTransformer.generateAssignStmtForValue(value, valueOriginalPositions)); stmts.forEach(stmt => allStmts.push(stmt)); } return { value, valueOriginalPositions, stmts: allStmts }; @@ -237,8 +236,7 @@ export class ArkValueTransformer { ifStmt.setOperandOriginalPositions(conditionPositions); stmts.push(ifStmt); - stmts.push( - new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT + currConditionalOperatorIndex)); + stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT + currConditionalOperatorIndex)); const { value: whenTrueValue, valueOriginalPositions: whenTruePositions, @@ -251,8 +249,7 @@ export class ArkValueTransformer { assignStmtWhenTrue.setOperandOriginalPositions([...resultLocalPosition, ...whenTruePositions]); stmts.push(assignStmtWhenTrue); - stmts.push( - new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + currConditionalOperatorIndex)); + stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + currConditionalOperatorIndex)); const { value: whenFalseValue, valueOriginalPositions: whenFalsePositions, @@ -262,9 +259,12 @@ export class ArkValueTransformer { const assignStmt = new ArkAssignStmt(resultLocal, whenFalseValue); assignStmt.setOperandOriginalPositions([...resultLocalPosition, ...whenFalsePositions]); stmts.push(assignStmt); - stmts.push( - new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + currConditionalOperatorIndex)); - return { value: resultLocal, valueOriginalPositions: resultLocalPosition, stmts: stmts }; + stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + currConditionalOperatorIndex)); + return { + value: resultLocal, + valueOriginalPositions: resultLocalPosition, + stmts: stmts, + }; } private objectLiteralExpresionToValueAndStmts(objectLiteralExpression: ts.ObjectLiteralExpression): ValueAndStmts { @@ -272,13 +272,11 @@ export class ArkValueTransformer { const declaringArkNamespace = declaringArkClass.getDeclaringArkNamespace(); const anonymousClass = new ArkClass(); if (declaringArkNamespace) { - buildNormalArkClassFromArkNamespace(objectLiteralExpression, declaringArkNamespace, anonymousClass, - this.sourceFile, this.declaringMethod); + buildNormalArkClassFromArkNamespace(objectLiteralExpression, declaringArkNamespace, anonymousClass, this.sourceFile, this.declaringMethod); declaringArkNamespace.addArkClass(anonymousClass); } else { const declaringArkFile = declaringArkClass.getDeclaringArkFile(); - buildNormalArkClassFromArkFile(objectLiteralExpression, declaringArkFile, anonymousClass, this.sourceFile, - this.declaringMethod); + buildNormalArkClassFromArkFile(objectLiteralExpression, declaringArkFile, anonymousClass, this.sourceFile, this.declaringMethod); declaringArkFile.addArkClass(anonymousClass); } @@ -294,24 +292,33 @@ export class ArkValueTransformer { } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [objectLiteralExpressionPosition]); newExprStmts.forEach(stmt => stmts.push(stmt)); - const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName( - CONSTRUCTOR_NAME); + const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME); const constructorMethodSignature = new MethodSignature(anonymousClassSignature, constructorMethodSubSignature); const constructorInvokeExpr = new ArkInstanceInvokeExpr(newExprLocal as Local, constructorMethodSignature, []); const constructorInvokeExprPositions = [objectLiteralExpressionPosition, ...newExprLocalPositions]; const constructorInvokeStmt = new ArkInvokeStmt(constructorInvokeExpr); constructorInvokeStmt.setOperandOriginalPositions(constructorInvokeExprPositions); stmts.push(constructorInvokeStmt); - return { value: newExprLocal, valueOriginalPositions: newExprLocalPositions, stmts: stmts }; + return { + value: newExprLocal, + valueOriginalPositions: newExprLocalPositions, + stmts: stmts, + }; } - private generateSystemComponentStmt(componentName: string, args: Value[], argPositionsAllFlat: FullPosition[], - componentExpression: ts.EtsComponentExpression | ts.CallExpression, - currStmts: Stmt[]): ValueAndStmts { + private generateSystemComponentStmt( + componentName: string, + args: Value[], + argPositionsAllFlat: FullPosition[], + componentExpression: ts.EtsComponentExpression | ts.CallExpression, + currStmts: Stmt[] + ): ValueAndStmts { const stmts: Stmt[] = [...currStmts]; const componentExpressionPosition = FullPosition.buildFromNode(componentExpression, this.sourceFile); const { - value: componentValue, valueOriginalPositions: componentPositions, stmts: componentStmts, + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: componentStmts, } = this.generateComponentCreationStmts(componentName, args, componentExpressionPosition, argPositionsAllFlat); componentStmts.forEach(stmt => stmts.push(stmt)); @@ -321,12 +328,20 @@ export class ArkValueTransformer { } } stmts.push(this.generateComponentPopStmts(componentName, componentExpressionPosition)); - return { value: componentValue, valueOriginalPositions: componentPositions, stmts: stmts }; + return { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: stmts, + }; } - private generateCustomViewStmt(componentName: string, args: Value[], argPositionsAllFlat: FullPosition[], - componentExpression: ts.EtsComponentExpression | ts.CallExpression, - currStmts: Stmt[]): ValueAndStmts { + private generateCustomViewStmt( + componentName: string, + args: Value[], + argPositionsAllFlat: FullPosition[], + componentExpression: ts.EtsComponentExpression | ts.CallExpression, + currStmts: Stmt[] + ): ValueAndStmts { const stmts: Stmt[] = [...currStmts]; const componentExpressionPosition = FullPosition.buildFromNode(componentExpression, this.sourceFile); const classSignature = ArkSignatureBuilder.buildClassSignatureFromClassName(componentName); @@ -338,8 +353,7 @@ export class ArkValueTransformer { stmts: newExprStmts, } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [componentExpressionPosition]); newExprStmts.forEach(stmt => stmts.push(stmt)); - const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName( - CONSTRUCTOR_NAME); + const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME); const constructorMethodSignature = new MethodSignature(classSignature, constructorMethodSubSignature); const instanceInvokeExpr = new ArkInstanceInvokeExpr(newExprLocal as Local, constructorMethodSignature, args); const instanceInvokeExprPositions = [componentExpressionPosition, ...newExprPositions, ...argPositionsAllFlat]; @@ -349,44 +363,52 @@ export class ArkValueTransformer { const createViewArgs = [newExprLocal]; const createViewArgPositionsAll = [newExprPositions]; if (ts.isEtsComponentExpression(componentExpression) && componentExpression.body) { - const anonymous = ts.factory.createArrowFunction([], [], [], undefined, undefined, - componentExpression.body); + const anonymous = ts.factory.createArrowFunction([], [], [], undefined, undefined, componentExpression.body); // @ts-expect-error: add pos info for the created ArrowFunction anonymous.pos = componentExpression.body.pos; // @ts-expect-error: add end info for the created ArrowFunction anonymous.end = componentExpression.body.end; - const { - value: builderMethod, - valueOriginalPositions: builderMethodPositions, - } = this.callableNodeToValueAndStmts(anonymous); + const { value: builderMethod, valueOriginalPositions: builderMethodPositions } = this.callableNodeToValueAndStmts(anonymous); createViewArgs.push(builderMethod); createViewArgPositionsAll.push(builderMethodPositions); } const { - value: componentValue, valueOriginalPositions: componentPositions, stmts: componentStmts, - } = this.generateComponentCreationStmts(COMPONENT_CUSTOMVIEW, createViewArgs, componentExpressionPosition, - createViewArgPositionsAll.flat()); + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: componentStmts, + } = this.generateComponentCreationStmts(COMPONENT_CUSTOMVIEW, createViewArgs, componentExpressionPosition, createViewArgPositionsAll.flat()); componentStmts.forEach(stmt => stmts.push(stmt)); stmts.push(this.generateComponentPopStmts(COMPONENT_CUSTOMVIEW, componentExpressionPosition)); - return { value: componentValue, valueOriginalPositions: componentPositions, stmts: stmts }; + return { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: stmts, + }; } - private generateComponentCreationStmts(componentName: string, createArgs: Value[], - componentExpressionPosition: FullPosition, - createArgsPositionsAllFlat: FullPosition[]): ValueAndStmts { - const createMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName( - componentName, COMPONENT_CREATE_FUNCTION); + private generateComponentCreationStmts( + componentName: string, + createArgs: Value[], + componentExpressionPosition: FullPosition, + createArgsPositionsAllFlat: FullPosition[] + ): ValueAndStmts { + const createMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(componentName, COMPONENT_CREATE_FUNCTION); const createInvokeExpr = new ArkStaticInvokeExpr(createMethodSignature, createArgs); const createInvokeExprPositions = [componentExpressionPosition, ...createArgsPositionsAllFlat]; const { - value: componentValue, valueOriginalPositions: componentPositions, stmts: componentStmts, + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: componentStmts, } = this.arkIRTransformer.generateAssignStmtForValue(createInvokeExpr, createInvokeExprPositions); - return { value: componentValue, valueOriginalPositions: componentPositions, stmts: componentStmts }; + return { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: componentStmts, + }; } private generateComponentPopStmts(componentName: string, componentExpressionPosition: FullPosition): Stmt { - const popMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName( - componentName, COMPONENT_POP_FUNCTION); + const popMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(componentName, COMPONENT_POP_FUNCTION); const popInvokeExpr = new ArkStaticInvokeExpr(popMethodSignature, []); const popInvokeExprPositions = [componentExpressionPosition]; const popInvokeStmt = new ArkInvokeStmt(popInvokeExpr); @@ -397,11 +419,9 @@ export class ArkValueTransformer { private etsComponentExpressionToValueAndStmts(etsComponentExpression: ts.EtsComponentExpression): ValueAndStmts { const stmts: Stmt[] = []; const componentName = (etsComponentExpression.expression as ts.Identifier).text; - const { args: args, argPositions: argPositions } = this.parseArguments(stmts, - etsComponentExpression.arguments); + const { args: args, argPositions: argPositions } = this.parseArguments(stmts, etsComponentExpression.arguments); if (isEtsSystemComponent(componentName)) { - return this.generateSystemComponentStmt(componentName, args, argPositions, etsComponentExpression, - stmts); + return this.generateSystemComponentStmt(componentName, args, argPositions, etsComponentExpression, stmts); } return this.generateCustomViewStmt(componentName, args, argPositions, etsComponentExpression, stmts); } @@ -411,13 +431,11 @@ export class ArkValueTransformer { const declaringArkNamespace = declaringArkClass.getDeclaringArkNamespace(); const newClass = new ArkClass(); if (declaringArkNamespace) { - buildNormalArkClassFromArkNamespace(classExpression, declaringArkNamespace, newClass, this.sourceFile, - this.declaringMethod); + buildNormalArkClassFromArkNamespace(classExpression, declaringArkNamespace, newClass, this.sourceFile, this.declaringMethod); declaringArkNamespace.addArkClass(newClass); } else { const declaringArkFile = declaringArkClass.getDeclaringArkFile(); - buildNormalArkClassFromArkFile(classExpression, declaringArkFile, newClass, this.sourceFile, - this.declaringMethod); + buildNormalArkClassFromArkFile(classExpression, declaringArkFile, newClass, this.sourceFile, this.declaringMethod); declaringArkFile.addArkClass(newClass); } const classValue = this.addNewLocal(newClass.getName(), new ClassType(newClass.getSignature())); @@ -429,17 +447,25 @@ export class ArkValueTransformer { } private templateExpressionToValueAndStmts(templateExpression: ts.TemplateExpression): ValueAndStmts { - const { stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions } = - this.collectTemplateValues(templateExpression); + const { stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions } = this.collectTemplateValues(templateExpression); - const { placeholderStringLocals, placeholderStringLocalPositions, newStmts } = - this.processTemplatePlaceholders(placeholderValues, placeholderPositions, stmts); + const { placeholderStringLocals, placeholderStringLocalPositions, newStmts } = this.processTemplatePlaceholders( + placeholderValues, + placeholderPositions, + stmts + ); return this.combineTemplateParts(stringTextValues, stringTextPositions, placeholderStringLocals, placeholderStringLocalPositions, newStmts); } - private processTemplatePlaceholders(placeholderValues: Value[], placeholderPositions: FullPosition[], currStmts: Stmt[]): { - placeholderStringLocals: Local[], placeholderStringLocalPositions: FullPosition[], newStmts: Stmt[] + private processTemplatePlaceholders( + placeholderValues: Value[], + placeholderPositions: FullPosition[], + currStmts: Stmt[] + ): { + placeholderStringLocals: Local[]; + placeholderStringLocalPositions: FullPosition[]; + newStmts: Stmt[]; } { const placeholderStringLocals: Local[] = []; const placeholderStringLocalPositions: FullPosition[] = []; @@ -451,27 +477,40 @@ export class ArkValueTransformer { let placeholderStmts: Stmt[] = []; if (!(placeholderValue instanceof Local)) { - ({ value: placeholderValue, valueOriginalPositions: placeholderPosition, stmts: placeholderStmts } = - this.arkIRTransformer.generateAssignStmtForValue(placeholderValue, placeholderPosition)); + ({ + value: placeholderValue, + valueOriginalPositions: placeholderPosition, + stmts: placeholderStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(placeholderValue, placeholderPosition)); } placeholderStmts.forEach(stmt => newStmts.push(stmt)); const toStringExpr = new ArkInstanceInvokeExpr(placeholderValue as Local, Builtin.TO_STRING_METHOD_SIGNATURE, []); const toStringExprPosition: FullPosition[] = [placeholderPosition[0], placeholderPosition[0]]; const { - value: placeholderStringLocal, valueOriginalPositions: placeholderStringPositions, stmts: toStringStmts, + value: placeholderStringLocal, + valueOriginalPositions: placeholderStringPositions, + stmts: toStringStmts, } = this.arkIRTransformer.generateAssignStmtForValue(toStringExpr, toStringExprPosition); placeholderStringLocals.push(placeholderStringLocal as Local); placeholderStringLocalPositions.push(placeholderStringPositions[0]); toStringStmts.forEach(stmt => newStmts.push(stmt)); } - return { placeholderStringLocals, placeholderStringLocalPositions, newStmts }; + return { + placeholderStringLocals, + placeholderStringLocalPositions, + newStmts, + }; } - private combineTemplateParts(stringTextValues: Value[], stringTextPositions: FullPosition[], - placeholderStringLocals: Local[], placeholderStringLocalPositions: FullPosition[], - currStmts: Stmt[]): ValueAndStmts { + private combineTemplateParts( + stringTextValues: Value[], + stringTextPositions: FullPosition[], + placeholderStringLocals: Local[], + placeholderStringLocalPositions: FullPosition[], + currStmts: Stmt[] + ): ValueAndStmts { const templateParts: Value[] = []; const templatePartPositions: FullPosition[] = []; @@ -496,60 +535,93 @@ export class ArkValueTransformer { for (let i = 1; i < templateParts.length; i++) { const nextTemplatePartPosition = templatePartPositions[i]; const normalBinopExpr = new ArkNormalBinopExpr(currTemplateResult, templateParts[i], NormalBinaryOperator.Addition); - const normalBinopExprPositions = [FullPosition.merge(currTemplateResultPosition, nextTemplatePartPosition), - currTemplateResultPosition, nextTemplatePartPosition]; + const normalBinopExprPositions = [ + FullPosition.merge(currTemplateResultPosition, nextTemplatePartPosition), + currTemplateResultPosition, + nextTemplatePartPosition, + ]; const { - value: combinationValue, valueOriginalPositions: combinationValuePositions, stmts: combinationStmts, + value: combinationValue, + valueOriginalPositions: combinationValuePositions, + stmts: combinationStmts, } = this.arkIRTransformer.generateAssignStmtForValue(normalBinopExpr, normalBinopExprPositions); combinationStmts.forEach(stmt => finalStmts.push(stmt)); currTemplateResult = combinationValue; currTemplateResultPosition = combinationValuePositions[0]; } - return { value: currTemplateResult, valueOriginalPositions: [currTemplateResultPosition], stmts: finalStmts }; + return { + value: currTemplateResult, + valueOriginalPositions: [currTemplateResultPosition], + stmts: finalStmts, + }; } private taggedTemplateExpressionToValueAndStmts(taggedTemplateExpression: ts.TaggedTemplateExpression): ValueAndStmts { - const { - stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions, - } = this.collectTemplateValues(taggedTemplateExpression.template); + const { stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions } = this.collectTemplateValues( + taggedTemplateExpression.template + ); const stringTextBaseType = StringType.getInstance(); const stringTextArrayLen = stringTextValues.length; const stringTextArrayLenValue = ValueUtil.getOrCreateNumberConst(stringTextArrayLen); const stringTextArrayLenPosition = FullPosition.DEFAULT; const { - value: templateObjectLocal, valueOriginalPositions: templateObjectLocalPositions, + value: templateObjectLocal, + valueOriginalPositions: templateObjectLocalPositions, stmts: templateObjectStmts, - } = this.generateArrayExprAndStmts(stringTextBaseType, stringTextArrayLenValue, stringTextArrayLenPosition, - stringTextArrayLen, stringTextValues, stringTextPositions, stmts, FullPosition.DEFAULT, true); + } = this.generateArrayExprAndStmts( + stringTextBaseType, + stringTextArrayLenValue, + stringTextArrayLenPosition, + stringTextArrayLen, + stringTextValues, + stringTextPositions, + stmts, + FullPosition.DEFAULT, + true + ); const placeholderBaseType = AnyType.getInstance(); const placeholdersArrayLen = placeholderValues.length; const placeholdersArrayLenValue = ValueUtil.getOrCreateNumberConst(placeholdersArrayLen); const placeholdersArrayLenPosition = FullPosition.DEFAULT; const { - value: placeholdersLocal, valueOriginalPositions: placeholdersLocalPositions, + value: placeholdersLocal, + valueOriginalPositions: placeholdersLocalPositions, stmts: placeholdersStmts, - } = this.generateArrayExprAndStmts(placeholderBaseType, placeholdersArrayLenValue, placeholdersArrayLenPosition, - placeholdersArrayLen, placeholderValues, placeholderPositions, templateObjectStmts, FullPosition.DEFAULT, true); + } = this.generateArrayExprAndStmts( + placeholderBaseType, + placeholdersArrayLenValue, + placeholdersArrayLenPosition, + placeholdersArrayLen, + placeholderValues, + placeholderPositions, + templateObjectStmts, + FullPosition.DEFAULT, + true + ); const taggedFuncArgus = { - realGenericTypes: undefined, args: [templateObjectLocal, placeholdersLocal], + realGenericTypes: undefined, + args: [templateObjectLocal, placeholdersLocal], argPositions: [templateObjectLocalPositions[0], placeholdersLocalPositions[0]], }; return this.generateInvokeValueAndStmts(taggedTemplateExpression.tag, taggedFuncArgus, placeholdersStmts, taggedTemplateExpression); } - private collectTemplateValues(templateLiteral: ts.TemplateLiteral): - { - stmts: Stmt[], stringTextValues: Value[], placeholderValues: Value[], stringTextPositions: FullPosition[], - placeholderPositions: FullPosition[] - } { + private collectTemplateValues(templateLiteral: ts.TemplateLiteral): { + stmts: Stmt[]; + stringTextValues: Value[]; + placeholderValues: Value[]; + stringTextPositions: FullPosition[]; + placeholderPositions: FullPosition[]; + } { const stmts: Stmt[] = []; if (ts.isNoSubstitutionTemplateLiteral(templateLiteral)) { const templateLiteralString = templateLiteral.getText(this.sourceFile); return { - stmts: [], stringTextValues: [ValueUtil.createStringConst(templateLiteralString)], + stmts: [], + stringTextValues: [ValueUtil.createStringConst(templateLiteralString)], placeholderValues: [], stringTextPositions: [FullPosition.buildFromNode(templateLiteral, this.sourceFile)], placeholderPositions: [], @@ -561,13 +633,14 @@ export class ArkValueTransformer { const stringTextPositions: FullPosition[] = [FullPosition.buildFromNode(head, this.sourceFile)]; const placeholderPositions: FullPosition[] = []; for (const templateSpan of templateLiteral.templateSpans) { - let { - value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts, - } = this.tsNodeToValueAndStmts(templateSpan.expression); + let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(templateSpan.expression); exprStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(exprValue)) { - ({ value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = - this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions)); + ({ + value: exprValue, + valueOriginalPositions: exprPositions, + stmts: exprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions)); exprStmts.forEach(stmt => stmts.push(stmt)); } placeholderValues.push(exprValue); @@ -575,7 +648,13 @@ export class ArkValueTransformer { stringTextPositions.push(FullPosition.buildFromNode(templateSpan.literal, this.sourceFile)); stringTextValues.push(ValueUtil.createStringConst(templateSpan.literal.rawText || '')); } - return { stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions }; + return { + stmts, + stringTextValues, + placeholderValues, + stringTextPositions, + placeholderPositions, + }; } private identifierToValueAndStmts(identifier: ts.Identifier, variableDefFlag: boolean = false): ValueAndStmts { @@ -590,25 +669,31 @@ export class ArkValueTransformer { identifierValue = this.getOrCreateLocal(identifier.text); } } - return { value: identifierValue, valueOriginalPositions: identifierPositions, stmts: [] }; + return { + value: identifierValue, + valueOriginalPositions: identifierPositions, + stmts: [], + }; } private propertyAccessExpressionToValue(propertyAccessExpression: ts.PropertyAccessExpression): ValueAndStmts { const stmts: Stmt[] = []; - let { - value: baseValue, - valueOriginalPositions: basePositions, - stmts: baseStmts, - } = this.tsNodeToValueAndStmts(propertyAccessExpression.expression); + let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = this.tsNodeToValueAndStmts(propertyAccessExpression.expression); baseStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(baseValue)) { - ({ value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = - this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); + ({ + value: baseValue, + valueOriginalPositions: basePositions, + stmts: baseStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); baseStmts.forEach(stmt => stmts.push(stmt)); } if (!(baseValue instanceof Local)) { - ({ value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = - this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); + ({ + value: baseValue, + valueOriginalPositions: basePositions, + stmts: baseStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); baseStmts.forEach(stmt => stmts.push(stmt)); } @@ -617,32 +702,49 @@ export class ArkValueTransformer { // this if for the case: const obj: Object = Object.create(Object.prototype); if (baseValue instanceof Local && baseValue.getName() === Builtin.OBJECT) { this.locals.delete(baseValue.getName()); - const fieldSignature = new FieldSignature(propertyAccessExpression.name.getText(this.sourceFile), - Builtin.OBJECT_CLASS_SIGNATURE, UnknownType.getInstance(), true); + const fieldSignature = new FieldSignature( + propertyAccessExpression.name.getText(this.sourceFile), + Builtin.OBJECT_CLASS_SIGNATURE, + UnknownType.getInstance(), + true + ); const fieldRef = new ArkStaticFieldRef(fieldSignature); - return { value: fieldRef, valueOriginalPositions: fieldRefPositions, stmts: stmts }; + return { + value: fieldRef, + valueOriginalPositions: fieldRefPositions, + stmts: stmts, + }; } let fieldSignature: FieldSignature; if (baseValue instanceof Local && baseValue.getType() instanceof ClassType) { - fieldSignature = new FieldSignature(propertyAccessExpression.name.getText(this.sourceFile), - (baseValue.getType() as ClassType).getClassSignature(), UnknownType.getInstance()); + fieldSignature = new FieldSignature( + propertyAccessExpression.name.getText(this.sourceFile), + (baseValue.getType() as ClassType).getClassSignature(), + UnknownType.getInstance() + ); } else { fieldSignature = ArkSignatureBuilder.buildFieldSignatureFromFieldName(propertyAccessExpression.name.getText(this.sourceFile)); } const fieldRef = new ArkInstanceFieldRef(baseValue as Local, fieldSignature); - return { value: fieldRef, valueOriginalPositions: fieldRefPositions, stmts: stmts }; + return { + value: fieldRef, + valueOriginalPositions: fieldRefPositions, + stmts: stmts, + }; } private elementAccessExpressionToValueAndStmts(elementAccessExpression: ts.ElementAccessExpression): ValueAndStmts { const stmts: Stmt[] = []; - let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = this.tsNodeToValueAndStmts( - elementAccessExpression.expression); + let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = this.tsNodeToValueAndStmts(elementAccessExpression.expression); baseStmts.forEach(stmt => stmts.push(stmt)); if (!(baseValue instanceof Local)) { - ({ value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = - this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); + ({ + value: baseValue, + valueOriginalPositions: basePositions, + stmts: baseStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); baseStmts.forEach(stmt => stmts.push(stmt)); } let { @@ -652,8 +754,11 @@ export class ArkValueTransformer { } = this.tsNodeToValueAndStmts(elementAccessExpression.argumentExpression); argumentStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(argumentValue)) { - ({ value: argumentValue, valueOriginalPositions: arguPositions, stmts: argumentStmts } = - this.arkIRTransformer.generateAssignStmtForValue(argumentValue, arguPositions)); + ({ + value: argumentValue, + valueOriginalPositions: arguPositions, + stmts: argumentStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(argumentValue, arguPositions)); argumentStmts.forEach(stmt => stmts.push(stmt)); } @@ -666,9 +771,12 @@ export class ArkValueTransformer { elementAccessExpr = new ArkInstanceFieldRef(baseValue as Local, fieldSignature); } // reserve positions for field name - const exprPositions = [FullPosition.buildFromNode(elementAccessExpression, this.sourceFile), ...basePositions, - ...arguPositions]; - return { value: elementAccessExpr, valueOriginalPositions: exprPositions, stmts: stmts }; + const exprPositions = [FullPosition.buildFromNode(elementAccessExpression, this.sourceFile), ...basePositions, ...arguPositions]; + return { + value: elementAccessExpr, + valueOriginalPositions: exprPositions, + stmts: stmts, + }; } private callExpressionToValueAndStmts(callExpression: ts.CallExpression): ValueAndStmts { @@ -677,17 +785,18 @@ export class ArkValueTransformer { return this.generateInvokeValueAndStmts(callExpression.expression, argus, stmts, callExpression); } - private generateInvokeValueAndStmts(functionNameNode: ts.LeftHandSideExpression, argus: { - realGenericTypes: Type[] | undefined, - args: Value[], - argPositions: FullPosition[] - }, currStmts: Stmt[], callExpression: ts.CallExpression | ts.TaggedTemplateExpression): ValueAndStmts { + private generateInvokeValueAndStmts( + functionNameNode: ts.LeftHandSideExpression, + argus: { + realGenericTypes: Type[] | undefined; + args: Value[]; + argPositions: FullPosition[]; + }, + currStmts: Stmt[], + callExpression: ts.CallExpression | ts.TaggedTemplateExpression + ): ValueAndStmts { const stmts: Stmt[] = [...currStmts]; - let { - value: callerValue, - valueOriginalPositions: callerPositions, - stmts: callerStmts, - } = this.tsNodeToValueAndStmts(functionNameNode); + let { value: callerValue, valueOriginalPositions: callerPositions, stmts: callerStmts } = this.tsNodeToValueAndStmts(functionNameNode); callerStmts.forEach(stmt => stmts.push(stmt)); let invokeValue: Value; @@ -724,20 +833,30 @@ export class ArkValueTransformer { invokeValue = new ArkStaticInvokeExpr(methodSignature, args, realGenericTypes); } } else { - ({ value: callerValue, valueOriginalPositions: callerPositions, stmts: callerStmts } = - this.arkIRTransformer.generateAssignStmtForValue(callerValue, callerPositions)); + ({ + value: callerValue, + valueOriginalPositions: callerPositions, + stmts: callerStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(callerValue, callerPositions)); callerStmts.forEach(stmt => stmts.push(stmt)); const methodSignature = ArkSignatureBuilder.buildMethodSignatureFromMethodName((callerValue as Local).getName()); invokeValue = new ArkStaticInvokeExpr(methodSignature, args, realGenericTypes); } invokeValuePositions.push(...argPositions); - return { value: invokeValue, valueOriginalPositions: invokeValuePositions, stmts: stmts }; + return { + value: invokeValue, + valueOriginalPositions: invokeValuePositions, + stmts: stmts, + }; } - private parseArgumentsOfCallExpression(currStmts: Stmt[], callExpression: ts.CallExpression): { - realGenericTypes: Type[] | undefined, - args: Value[], - argPositions: FullPosition[] + private parseArgumentsOfCallExpression( + currStmts: Stmt[], + callExpression: ts.CallExpression + ): { + realGenericTypes: Type[] | undefined; + args: Value[]; + argPositions: FullPosition[]; } { let realGenericTypes: Type[] | undefined; if (callExpression.typeArguments) { @@ -754,15 +873,21 @@ export class ArkValueTransformer { builderMethodIndexes = new Set([1]); } } - const { args: args, argPositions: argPositions } = this.parseArguments(currStmts, - callExpression.arguments, builderMethodIndexes); - return { realGenericTypes: realGenericTypes, args: args, argPositions: argPositions }; + const { args: args, argPositions: argPositions } = this.parseArguments(currStmts, callExpression.arguments, builderMethodIndexes); + return { + realGenericTypes: realGenericTypes, + args: args, + argPositions: argPositions, + }; } - private parseArguments(currStmts: Stmt[], argumentNodes?: ts.NodeArray, - builderMethodIndexes?: Set): { - args: Value[], - argPositions: FullPosition[] + private parseArguments( + currStmts: Stmt[], + argumentNodes?: ts.NodeArray, + builderMethodIndexes?: Set + ): { + args: Value[]; + argPositions: FullPosition[]; } { const args: Value[] = []; const argPositions: FullPosition[] = []; @@ -774,17 +899,16 @@ export class ArkValueTransformer { this.builderMethodContextFlag = true; this.arkIRTransformer.setBuilderMethodContextFlag(true); } - let { - value: argValue, - valueOriginalPositions: argPositionsSingle, - stmts: argStmts, - } = this.tsNodeToValueAndStmts(argument); + let { value: argValue, valueOriginalPositions: argPositionsSingle, stmts: argStmts } = this.tsNodeToValueAndStmts(argument); this.builderMethodContextFlag = prevBuilderMethodContextFlag; this.arkIRTransformer.setBuilderMethodContextFlag(prevBuilderMethodContextFlag); argStmts.forEach(s => currStmts.push(s)); if (IRUtils.moreThanOneAddress(argValue)) { - ({ value: argValue, valueOriginalPositions: argPositionsSingle, stmts: argStmts } = - this.arkIRTransformer.generateAssignStmtForValue(argValue, argPositionsSingle)); + ({ + value: argValue, + valueOriginalPositions: argPositionsSingle, + stmts: argStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(argValue, argPositionsSingle)); argStmts.forEach(s => currStmts.push(s)); } args.push(argValue); @@ -843,23 +967,23 @@ export class ArkValueTransformer { value: newLocal, valueOriginalPositions: newLocalPositions, stmts: newExprStmts, - } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, - [FullPosition.buildFromNode(newExpression, this.sourceFile)]); + } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [FullPosition.buildFromNode(newExpression, this.sourceFile)]); newExprStmts.forEach(stmt => stmts.push(stmt)); - const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName( - CONSTRUCTOR_NAME); + const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME); const constructorMethodSignature = new MethodSignature(classSignature, constructorMethodSubSignature); - const { args: argValues, argPositions: argPositions } = this.parseArguments(stmts, - newExpression.arguments); - const instanceInvokeExpr = new ArkInstanceInvokeExpr(newLocal as Local, constructorMethodSignature, - argValues); + const { args: argValues, argPositions: argPositions } = this.parseArguments(stmts, newExpression.arguments); + const instanceInvokeExpr = new ArkInstanceInvokeExpr(newLocal as Local, constructorMethodSignature, argValues); const instanceInvokeExprPositions = [newLocalPositions[0], ...newLocalPositions, ...argPositions]; const invokeStmt = new ArkInvokeStmt(instanceInvokeExpr); invokeStmt.setOperandOriginalPositions(instanceInvokeExprPositions); stmts.push(invokeStmt); - return { value: newLocal, valueOriginalPositions: newLocalPositions, stmts: stmts }; + return { + value: newLocal, + valueOriginalPositions: newLocalPositions, + stmts: stmts, + }; } private newArrayExpressionToValueAndStmts(newArrayExpression: ts.NewExpression): ValueAndStmts { @@ -871,15 +995,12 @@ export class ArkValueTransformer { } } const stmts: Stmt[] = []; - const { args: argumentValues, argPositions: argPositions } = this.parseArguments(stmts, - newArrayExpression.arguments); + const { args: argumentValues, argPositions: argPositions } = this.parseArguments(stmts, newArrayExpression.arguments); let argumentsLength = newArrayExpression.arguments ? newArrayExpression.arguments.length : 0; let arrayLengthValue: Value; let arrayLength = -1; let arrayLengthPosition = FullPosition.DEFAULT; - if ((argumentsLength === 1) && - ((argumentValues[0].getType() instanceof NumberType) || argumentValues[0].getType() instanceof - UnknownType)) { + if (argumentsLength === 1 && (argumentValues[0].getType() instanceof NumberType || argumentValues[0].getType() instanceof UnknownType)) { arrayLengthValue = argumentValues[0]; arrayLengthPosition = argPositions[0]; } else { @@ -887,15 +1008,24 @@ export class ArkValueTransformer { arrayLength = argumentsLength; } if (baseType instanceof UnknownType) { - if ((argumentsLength > 1) && !(argumentValues[0].getType() instanceof UnknownType)) { + if (argumentsLength > 1 && !(argumentValues[0].getType() instanceof UnknownType)) { baseType = argumentValues[0].getType(); } else { baseType = AnyType.getInstance(); } } const newArrayExprPosition = FullPosition.buildFromNode(newArrayExpression, this.sourceFile); - return this.generateArrayExprAndStmts(baseType, arrayLengthValue, arrayLengthPosition, arrayLength, - argumentValues, argPositions, stmts, newArrayExprPosition, false); + return this.generateArrayExprAndStmts( + baseType, + arrayLengthValue, + arrayLengthPosition, + arrayLength, + argumentValues, + argPositions, + stmts, + newArrayExprPosition, + false + ); } private arrayLiteralExpressionToValueAndStmts(arrayLiteralExpression: ts.ArrayLiteralExpression): ValueAndStmts { @@ -905,15 +1035,14 @@ export class ArkValueTransformer { const elementPositions: FullPosition[] = []; const arrayLength = arrayLiteralExpression.elements.length; for (const element of arrayLiteralExpression.elements) { - let { - value: elementValue, - valueOriginalPositions: elementPosition, - stmts: elementStmts, - } = this.tsNodeToValueAndStmts(element); + let { value: elementValue, valueOriginalPositions: elementPosition, stmts: elementStmts } = this.tsNodeToValueAndStmts(element); elementStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(elementValue)) { - ({ value: elementValue, valueOriginalPositions: elementPosition, stmts: elementStmts } = - this.arkIRTransformer.generateAssignStmtForValue(elementValue, elementPosition)); + ({ + value: elementValue, + valueOriginalPositions: elementPosition, + stmts: elementStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(elementValue, elementPosition)); elementStmts.forEach(stmt => stmts.push(stmt)); } elementValues.push(elementValue); @@ -928,15 +1057,30 @@ export class ArkValueTransformer { baseType = new UnionType(Array.from(elementTypes)); } const newArrayExprPosition = FullPosition.buildFromNode(arrayLiteralExpression, this.sourceFile); - return this.generateArrayExprAndStmts(baseType, ValueUtil.getOrCreateNumberConst(arrayLength), FullPosition.DEFAULT, - arrayLength, elementValues, elementPositions, stmts, newArrayExprPosition, true); - } - - private generateArrayExprAndStmts(baseType: Type, arrayLengthValue: Value, arrayLengthPosition: FullPosition, - arrayLength: number, initializerValues: Value[], - initializerPositions: FullPosition[], - currStmts: Stmt[], - newArrayExprPosition: FullPosition, fromLiteral: boolean): ValueAndStmts { + return this.generateArrayExprAndStmts( + baseType, + ValueUtil.getOrCreateNumberConst(arrayLength), + FullPosition.DEFAULT, + arrayLength, + elementValues, + elementPositions, + stmts, + newArrayExprPosition, + true + ); + } + + private generateArrayExprAndStmts( + baseType: Type, + arrayLengthValue: Value, + arrayLengthPosition: FullPosition, + arrayLength: number, + initializerValues: Value[], + initializerPositions: FullPosition[], + currStmts: Stmt[], + newArrayExprPosition: FullPosition, + fromLiteral: boolean + ): ValueAndStmts { const stmts: Stmt[] = [...currStmts]; const newArrayExpr = new ArkNewArrayExpr(baseType, arrayLengthValue, fromLiteral); const newArrayExprPositions = [newArrayExprPosition, arrayLengthPosition]; @@ -954,21 +1098,23 @@ export class ArkValueTransformer { assignStmt.setOperandOriginalPositions([...arrayRefPositions, initializerPositions[i]]); stmts.push(assignStmt); } - return { value: arrayLocal, valueOriginalPositions: arrayLocalPositions, stmts: stmts }; + return { + value: arrayLocal, + valueOriginalPositions: arrayLocalPositions, + stmts: stmts, + }; } - private prefixUnaryExpressionToValueAndStmts(prefixUnaryExpression: ts.PrefixUnaryExpression): ValueAndStmts { const stmts: Stmt[] = []; - let { - value: operandValue, - valueOriginalPositions: operandPositions, - stmts: operandStmts, - } = this.tsNodeToValueAndStmts(prefixUnaryExpression.operand); + let { value: operandValue, valueOriginalPositions: operandPositions, stmts: operandStmts } = this.tsNodeToValueAndStmts(prefixUnaryExpression.operand); operandStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(operandValue)) { - ({ value: operandValue, valueOriginalPositions: operandPositions, stmts: operandStmts } = - this.arkIRTransformer.generateAssignStmtForValue(operandValue, operandPositions)); + ({ + value: operandValue, + valueOriginalPositions: operandPositions, + stmts: operandStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(operandValue, operandPositions)); operandStmts.forEach(stmt => stmts.push(stmt)); } @@ -981,9 +1127,17 @@ export class ArkValueTransformer { const assignStmt = new ArkAssignStmt(operandValue, binopExpr); assignStmt.setOperandOriginalPositions([...operandPositions, ...exprPositions]); stmts.push(assignStmt); - return { value: operandValue, valueOriginalPositions: operandPositions, stmts: stmts }; + return { + value: operandValue, + valueOriginalPositions: operandPositions, + stmts: stmts, + }; } else if (operatorToken === ts.SyntaxKind.PlusToken) { - return { value: operandValue, valueOriginalPositions: operandPositions, stmts: stmts }; + return { + value: operandValue, + valueOriginalPositions: operandPositions, + stmts: stmts, + }; } else { let unopExpr: Value; const operator = ArkIRTransformer.tokenToUnaryOperator(operatorToken); @@ -994,21 +1148,24 @@ export class ArkValueTransformer { unopExpr = ValueUtil.getUndefinedConst(); exprPositions = [FullPosition.DEFAULT]; } - return { value: unopExpr, valueOriginalPositions: exprPositions, stmts: stmts }; + return { + value: unopExpr, + valueOriginalPositions: exprPositions, + stmts: stmts, + }; } } private postfixUnaryExpressionToValueAndStmts(postfixUnaryExpression: ts.PostfixUnaryExpression): ValueAndStmts { const stmts: Stmt[] = []; - let { - value: operandValue, - valueOriginalPositions: operandPositions, - stmts: exprStmts, - } = this.tsNodeToValueAndStmts(postfixUnaryExpression.operand); + let { value: operandValue, valueOriginalPositions: operandPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(postfixUnaryExpression.operand); exprStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(operandValue)) { - ({ value: operandValue, valueOriginalPositions: operandPositions, stmts: exprStmts } = - this.arkIRTransformer.generateAssignStmtForValue(operandValue, operandPositions)); + ({ + value: operandValue, + valueOriginalPositions: operandPositions, + stmts: exprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(operandValue, operandPositions)); exprStmts.forEach(stmt => stmts.push(stmt)); } @@ -1028,25 +1185,32 @@ export class ArkValueTransformer { exprPositions = [FullPosition.DEFAULT]; } - return { value: value, valueOriginalPositions: exprPositions, stmts: stmts }; + return { + value: value, + valueOriginalPositions: exprPositions, + stmts: stmts, + }; } private awaitExpressionToValueAndStmts(awaitExpression: ts.AwaitExpression): ValueAndStmts { const stmts: Stmt[] = []; - let { - value: promiseValue, - valueOriginalPositions: promisePositions, - stmts: promiseStmts, - } = this.tsNodeToValueAndStmts(awaitExpression.expression); + let { value: promiseValue, valueOriginalPositions: promisePositions, stmts: promiseStmts } = this.tsNodeToValueAndStmts(awaitExpression.expression); promiseStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(promiseValue)) { - ({ value: promiseValue, valueOriginalPositions: promisePositions, stmts: promiseStmts } = - this.arkIRTransformer.generateAssignStmtForValue(promiseValue, promisePositions)); + ({ + value: promiseValue, + valueOriginalPositions: promisePositions, + stmts: promiseStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(promiseValue, promisePositions)); promiseStmts.forEach(stmt => stmts.push(stmt)); } const awaitExpr = new ArkAwaitExpr(promiseValue); const awaitExprPositions = [FullPosition.buildFromNode(awaitExpression, this.sourceFile), ...promisePositions]; - return { value: awaitExpr, valueOriginalPositions: awaitExprPositions, stmts: stmts }; + return { + value: awaitExpr, + valueOriginalPositions: awaitExprPositions, + stmts: stmts, + }; } private yieldExpressionToValueAndStmts(yieldExpression: ts.YieldExpression): ValueAndStmts { @@ -1054,30 +1218,38 @@ export class ArkValueTransformer { let yieldPositions = [FullPosition.DEFAULT]; let stmts: Stmt[] = []; if (yieldExpression.expression) { - ({ value: yieldValue, valueOriginalPositions: yieldPositions, stmts: stmts } = - this.tsNodeToValueAndStmts(yieldExpression.expression)); + ({ value: yieldValue, valueOriginalPositions: yieldPositions, stmts: stmts } = this.tsNodeToValueAndStmts(yieldExpression.expression)); } const yieldExpr = new ArkYieldExpr(yieldValue); const yieldExprPositions = [FullPosition.buildFromNode(yieldExpression, this.sourceFile), ...yieldPositions]; - return { value: yieldExpr, valueOriginalPositions: yieldExprPositions, stmts: stmts }; + return { + value: yieldExpr, + valueOriginalPositions: yieldExprPositions, + stmts: stmts, + }; } private deleteExpressionToValueAndStmts(deleteExpression: ts.DeleteExpression): ValueAndStmts { - const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts( - deleteExpression.expression); + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts(deleteExpression.expression); const deleteExpr = new ArkDeleteExpr(exprValue as AbstractFieldRef); - const deleteExprPositions = [FullPosition.buildFromNode(deleteExpression, this.sourceFile), - ...exprPositions]; - return { value: deleteExpr, valueOriginalPositions: deleteExprPositions, stmts: stmts }; + const deleteExprPositions = [FullPosition.buildFromNode(deleteExpression, this.sourceFile), ...exprPositions]; + return { + value: deleteExpr, + valueOriginalPositions: deleteExprPositions, + stmts: stmts, + }; } private voidExpressionToValueAndStmts(voidExpression: ts.VoidExpression): ValueAndStmts { - const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts( - voidExpression.expression); + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts(voidExpression.expression); const { stmts: exprStmts } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions); exprStmts.forEach(stmt => stmts.push(stmt)); - return { value: ValueUtil.getUndefinedConst(), valueOriginalPositions: [FullPosition.DEFAULT], stmts: stmts }; + return { + value: ValueUtil.getUndefinedConst(), + valueOriginalPositions: [FullPosition.DEFAULT], + stmts: stmts, + }; } private nonNullExpressionToValueAndStmts(nonNullExpression: ts.NonNullExpression): ValueAndStmts { @@ -1089,40 +1261,46 @@ export class ArkValueTransformer { } private typeOfExpressionToValueAndStmts(typeOfExpression: ts.TypeOfExpression): ValueAndStmts { - const { - value: exprValue, - valueOriginalPositions: exprPositions, - stmts: exprStmts, - } = this.tsNodeToValueAndStmts(typeOfExpression.expression); + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(typeOfExpression.expression); const typeOfExpr = new ArkTypeOfExpr(exprValue); const typeOfExprPositions = [FullPosition.buildFromNode(typeOfExpression, this.sourceFile), ...exprPositions]; - return { value: typeOfExpr, valueOriginalPositions: typeOfExprPositions, stmts: exprStmts }; + return { + value: typeOfExpr, + valueOriginalPositions: typeOfExprPositions, + stmts: exprStmts, + }; } private asExpressionToValueAndStmts(asExpression: ts.AsExpression): ValueAndStmts { const stmts: Stmt[] = []; - let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts( - asExpression.expression); + let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(asExpression.expression); exprStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(exprValue)) { - ({ value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = - this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions)); + ({ + value: exprValue, + valueOriginalPositions: exprPositions, + stmts: exprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions)); exprStmts.forEach(stmt => stmts.push(stmt)); } const castExpr = new ArkCastExpr(exprValue, this.resolveTypeNode(asExpression.type)); const castExprPositions = [FullPosition.buildFromNode(asExpression, this.sourceFile), ...exprPositions]; - return { value: castExpr, valueOriginalPositions: castExprPositions, stmts: stmts }; + return { + value: castExpr, + valueOriginalPositions: castExprPositions, + stmts: stmts, + }; } private typeAssertionToValueAndStmts(typeAssertion: ts.TypeAssertion): ValueAndStmts { - const { - value: exprValue, - valueOriginalPositions: exprPositions, - stmts: exprStmts, - } = this.tsNodeToValueAndStmts(typeAssertion.expression); + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(typeAssertion.expression); const castExpr = new ArkCastExpr(exprValue, this.resolveTypeNode(typeAssertion.type)); const castExprPositions = [FullPosition.buildFromNode(typeAssertion, this.sourceFile), ...exprPositions]; - return { value: castExpr, valueOriginalPositions: castExprPositions, stmts: exprStmts }; + return { + value: castExpr, + valueOriginalPositions: castExprPositions, + stmts: exprStmts, + }; } public variableDeclarationListToValueAndStmts(variableDeclarationList: ts.VariableDeclarationList): ValueAndStmts { @@ -1132,21 +1310,28 @@ export class ArkValueTransformer { const { stmts: declaredStmts } = this.variableDeclarationToValueAndStmts(declaration, isConst); declaredStmts.forEach(s => stmts.push(s)); } - return { value: ValueUtil.getUndefinedConst(), valueOriginalPositions: [FullPosition.DEFAULT], stmts: stmts }; + return { + value: ValueUtil.getUndefinedConst(), + valueOriginalPositions: [FullPosition.DEFAULT], + stmts: stmts, + }; } - public variableDeclarationToValueAndStmts(variableDeclaration: ts.VariableDeclaration, - isConst: boolean, needRightOp: boolean = true): ValueAndStmts { + public variableDeclarationToValueAndStmts(variableDeclaration: ts.VariableDeclaration, isConst: boolean, needRightOp: boolean = true): ValueAndStmts { const leftOpNode = variableDeclaration.name; const rightOpNode = variableDeclaration.initializer; - const declarationType = variableDeclaration.type ? this.resolveTypeNode( - variableDeclaration.type) : UnknownType.getInstance(); + const declarationType = variableDeclaration.type ? this.resolveTypeNode(variableDeclaration.type) : UnknownType.getInstance(); return this.assignmentToValueAndStmts(leftOpNode, rightOpNode, true, isConst, declarationType, needRightOp); } - private assignmentToValueAndStmts(leftOpNode: ts.Node, rightOpNode: ts.Node | undefined, variableDefFlag: boolean, - isConst: boolean, declarationType: Type, - needRightOp: boolean = true): ValueAndStmts { + private assignmentToValueAndStmts( + leftOpNode: ts.Node, + rightOpNode: ts.Node | undefined, + variableDefFlag: boolean, + isConst: boolean, + declarationType: Type, + needRightOp: boolean = true + ): ValueAndStmts { let leftValueAndStmts: ValueAndStmts; if (ts.isIdentifier(leftOpNode)) { leftValueAndStmts = this.identifierToValueAndStmts(leftOpNode, variableDefFlag); @@ -1162,22 +1347,31 @@ export class ArkValueTransformer { let stmts: Stmt[] = []; if (needRightOp) { const { - value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts, + value: rightValue, + valueOriginalPositions: rightPositions, + stmts: rightStmts, } = this.assignmentRightOpToValueAndStmts(rightOpNode, leftValue); if (leftValue instanceof Local) { if (variableDefFlag) { leftValue.setConstFlag(isConst); leftValue.setType(declarationType); } - if (leftValue.getType() instanceof UnknownType && !(rightValue.getType() instanceof UnknownType) && - !(rightValue.getType() instanceof UndefinedType)) { + if ( + leftValue.getType() instanceof UnknownType && + !(rightValue.getType() instanceof UnknownType) && + !(rightValue.getType() instanceof UndefinedType) + ) { leftValue.setType(rightValue.getType()); } } const assignStmt = new ArkAssignStmt(leftValue, rightValue); assignStmt.setOperandOriginalPositions([...leftPositions, ...rightPositions]); - if (ts.isArrayBindingPattern(leftOpNode) || ts.isArrayLiteralExpression(leftOpNode) || - ts.isObjectBindingPattern(leftOpNode) || ts.isObjectLiteralExpression(leftOpNode)) { + if ( + ts.isArrayBindingPattern(leftOpNode) || + ts.isArrayLiteralExpression(leftOpNode) || + ts.isObjectBindingPattern(leftOpNode) || + ts.isObjectLiteralExpression(leftOpNode) + ) { rightStmts.forEach(stmt => stmts.push(stmt)); stmts.push(assignStmt); leftStmts.forEach(stmt => stmts.push(stmt)); @@ -1189,7 +1383,11 @@ export class ArkValueTransformer { } else { stmts = leftStmts; } - return { value: leftValue, valueOriginalPositions: leftPositions, stmts: stmts }; + return { + value: leftValue, + valueOriginalPositions: leftPositions, + stmts: stmts, + }; } private assignmentRightOpToValueAndStmts(rightOpNode: ts.Node | undefined, leftValue: Value): ValueAndStmts { @@ -1198,24 +1396,29 @@ export class ArkValueTransformer { let tempRightStmts: Stmt[] = []; const rightStmts: Stmt[] = []; if (rightOpNode) { - ({ value: rightValue, valueOriginalPositions: rightPositions, stmts: tempRightStmts } = - this.tsNodeToValueAndStmts(rightOpNode)); + ({ value: rightValue, valueOriginalPositions: rightPositions, stmts: tempRightStmts } = this.tsNodeToValueAndStmts(rightOpNode)); tempRightStmts.forEach(stmt => rightStmts.push(stmt)); } else { rightValue = ValueUtil.getUndefinedConst(); rightPositions = [FullPosition.DEFAULT]; } if (IRUtils.moreThanOneAddress(leftValue) && IRUtils.moreThanOneAddress(rightValue)) { - ({ value: rightValue, valueOriginalPositions: rightPositions, stmts: tempRightStmts } = - this.arkIRTransformer.generateAssignStmtForValue(rightValue, rightPositions)); + ({ + value: rightValue, + valueOriginalPositions: rightPositions, + stmts: tempRightStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(rightValue, rightPositions)); tempRightStmts.forEach(stmt => rightStmts.push(stmt)); } - return { value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts }; + return { + value: rightValue, + valueOriginalPositions: rightPositions, + stmts: rightStmts, + }; } // In assignment patterns, the left operand will be an array literal expression - private arrayDestructuringToValueAndStmts(arrayDestructuring: ts.ArrayBindingPattern | ts.ArrayLiteralExpression, - isConst: boolean = false): ValueAndStmts { + private arrayDestructuringToValueAndStmts(arrayDestructuring: ts.ArrayBindingPattern | ts.ArrayLiteralExpression, isConst: boolean = false): ValueAndStmts { const stmts: Stmt[] = []; const arrayTempLocal = this.generateTempLocal(); const leftOriginalPosition = FullPosition.buildFromNode(arrayDestructuring, this.sourceFile); @@ -1234,12 +1437,18 @@ export class ArkValueTransformer { stmts.push(assignStmt); index++; } - return { value: arrayTempLocal, valueOriginalPositions: [leftOriginalPosition], stmts: stmts }; + return { + value: arrayTempLocal, + valueOriginalPositions: [leftOriginalPosition], + stmts: stmts, + }; } // In assignment patterns, the left operand will be an object literal expression - private objectDestructuringToValueAndStmts(objectDestructuring: ts.ObjectBindingPattern | ts.ObjectLiteralExpression, - isConst: boolean = false): ValueAndStmts { + private objectDestructuringToValueAndStmts( + objectDestructuring: ts.ObjectBindingPattern | ts.ObjectLiteralExpression, + isConst: boolean = false + ): ValueAndStmts { const stmts: Stmt[] = []; const objectTempLocal = this.generateTempLocal(); const leftOriginalPosition = FullPosition.buildFromNode(objectDestructuring, this.sourceFile); @@ -1249,8 +1458,7 @@ export class ArkValueTransformer { let fieldName = ''; let targetName = ''; if (ts.isBindingElement(element)) { - fieldName = element.propertyName ? element.propertyName.getText(this.sourceFile) : element.name.getText( - this.sourceFile); + fieldName = element.propertyName ? element.propertyName.getText(this.sourceFile) : element.name.getText(this.sourceFile); targetName = element.name.getText(this.sourceFile); } else if (ts.isPropertyAssignment(element)) { fieldName = element.name.getText(this.sourceFile); @@ -1265,15 +1473,18 @@ export class ArkValueTransformer { const fieldSignature = ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); const fieldRef = new ArkInstanceFieldRef(objectTempLocal, fieldSignature); const fieldRefPositions = [leftOriginalPosition, leftOriginalPosition]; - const targetLocal = isObjectBindingPattern ? this.addNewLocal(targetName) : this.getOrCreateLocal( - targetName); + const targetLocal = isObjectBindingPattern ? this.addNewLocal(targetName) : this.getOrCreateLocal(targetName); isObjectBindingPattern && targetLocal.setConstFlag(isConst); const targetLocalPosition = FullPosition.buildFromNode(element, this.sourceFile); const assignStmt = new ArkAssignStmt(targetLocal, fieldRef); assignStmt.setOperandOriginalPositions([targetLocalPosition, ...fieldRefPositions]); stmts.push(assignStmt); } - return { value: objectTempLocal, valueOriginalPositions: [leftOriginalPosition], stmts: stmts }; + return { + value: objectTempLocal, + valueOriginalPositions: [leftOriginalPosition], + stmts: stmts, + }; } private binaryExpressionToValueAndStmts(binaryExpression: ts.BinaryExpression): ValueAndStmts { @@ -1288,16 +1499,11 @@ export class ArkValueTransformer { } const stmts: Stmt[] = []; const binaryExpressionPosition = FullPosition.buildFromNode(binaryExpression, this.sourceFile); - const { - value: opValue1, - valueOriginalPositions: opPositions1, - stmts: opStmts1, - } = this.tsNodeToSingleAddressValueAndStmts(binaryExpression.left); + const { value: opValue1, valueOriginalPositions: opPositions1, stmts: opStmts1 } = this.tsNodeToSingleAddressValueAndStmts(binaryExpression.left); opStmts1.forEach(stmt => stmts.push(stmt)); if (operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword) { - const instanceOfExpr = new ArkInstanceOfExpr(opValue1, - new UnclearReferenceType(binaryExpression.right.getText(this.sourceFile))); + const instanceOfExpr = new ArkInstanceOfExpr(opValue1, new UnclearReferenceType(binaryExpression.right.getText(this.sourceFile))); const instanceOfExprPositions = [binaryExpressionPosition, ...opPositions1]; const { value: instanceofRes, @@ -1305,14 +1511,14 @@ export class ArkValueTransformer { stmts: instanceofStmt, } = this.arkIRTransformer.generateAssignStmtForValue(instanceOfExpr, instanceOfExprPositions); instanceofStmt.forEach(stmt => stmts.push(stmt)); - return { value: instanceofRes, valueOriginalPositions: instanceofPos, stmts: stmts }; + return { + value: instanceofRes, + valueOriginalPositions: instanceofPos, + stmts: stmts, + }; } - const { - value: opValue2, - valueOriginalPositions: opPositions2, - stmts: opStmts2, - } = this.tsNodeToSingleAddressValueAndStmts(binaryExpression.right); + const { value: opValue2, valueOriginalPositions: opPositions2, stmts: opStmts2 } = this.tsNodeToSingleAddressValueAndStmts(binaryExpression.right); opStmts2.forEach(stmt => stmts.push(stmt)); let exprValue: Value; let exprValuePositions = [binaryExpressionPosition]; @@ -1332,22 +1538,18 @@ export class ArkValueTransformer { exprValuePositions.push(binaryExpressionPosition); } } - return { value: exprValue, valueOriginalPositions: exprValuePositions, stmts: stmts }; + return { + value: exprValue, + valueOriginalPositions: exprValuePositions, + stmts: stmts, + }; } private compoundAssignmentToValueAndStmts(binaryExpression: ts.BinaryExpression): ValueAndStmts { const stmts: Stmt[] = []; - let { - value: leftValue, - valueOriginalPositions: leftPositions, - stmts: leftStmts, - } = this.tsNodeToValueAndStmts(binaryExpression.left); + let { value: leftValue, valueOriginalPositions: leftPositions, stmts: leftStmts } = this.tsNodeToValueAndStmts(binaryExpression.left); leftStmts.forEach(stmt => stmts.push(stmt)); - let { - value: rightValue, - valueOriginalPositions: rightPositions, - stmts: rightStmts, - } = this.tsNodeToValueAndStmts(binaryExpression.right); + let { value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts } = this.tsNodeToValueAndStmts(binaryExpression.right); rightStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(leftValue) && IRUtils.moreThanOneAddress(rightValue)) { const { @@ -1367,8 +1569,7 @@ export class ArkValueTransformer { const exprValue = new ArkNormalBinopExpr(leftValue, rightValue, operator); const exprValuePosition = FullPosition.buildFromNode(binaryExpression, this.sourceFile); const assignStmt = new ArkAssignStmt(leftValue, exprValue); - assignStmt.setOperandOriginalPositions( - [...leftPositions, exprValuePosition, ...leftPositions, ...rightPositions]); + assignStmt.setOperandOriginalPositions([...leftPositions, exprValuePosition, ...leftPositions, ...rightPositions]); stmts.push(assignStmt); leftOpValue = leftValue; leftOpPositions = leftPositions; @@ -1376,7 +1577,11 @@ export class ArkValueTransformer { leftOpValue = ValueUtil.getUndefinedConst(); leftOpPositions = [leftPositions[0]]; } - return { value: leftOpValue, valueOriginalPositions: leftOpPositions, stmts: stmts }; + return { + value: leftOpValue, + valueOriginalPositions: leftOpPositions, + stmts: stmts, + }; } private compoundAssignmentTokenToBinaryOperator(token: ts.SyntaxKind): NormalBinaryOperator | null { @@ -1412,21 +1617,16 @@ export class ArkValueTransformer { case ts.SyntaxKind.BarBarEqualsToken: return NormalBinaryOperator.LogicalOr; default: - ; } return null; } public conditionToValueAndStmts(condition: ts.Expression): ValueAndStmts { const stmts: Stmt[] = []; - let { - value: conditionValue, - valueOriginalPositions: conditionPositions, - stmts: conditionStmts, - } = this.tsNodeToValueAndStmts(condition); + let { value: conditionValue, valueOriginalPositions: conditionPositions, stmts: conditionStmts } = this.tsNodeToValueAndStmts(condition); conditionStmts.forEach(stmt => stmts.push(stmt)); let conditionExpr: ArkConditionExpr; - if ((conditionValue instanceof AbstractBinopExpr) && this.isRelationalOperator(conditionValue.getOperator())) { + if (conditionValue instanceof AbstractBinopExpr && this.isRelationalOperator(conditionValue.getOperator())) { const operator = conditionValue.getOperator() as RelationalBinaryOperator; conditionExpr = new ArkConditionExpr(conditionValue.getOp1(), conditionValue.getOp2(), operator); } else { @@ -1438,11 +1638,14 @@ export class ArkValueTransformer { } = this.arkIRTransformer.generateAssignStmtForValue(conditionValue, conditionPositions)); conditionStmts.forEach(stmt => stmts.push(stmt)); } - conditionExpr = new ArkConditionExpr(conditionValue, ValueUtil.getOrCreateNumberConst(0), - RelationalBinaryOperator.InEquality); + conditionExpr = new ArkConditionExpr(conditionValue, ValueUtil.getOrCreateNumberConst(0), RelationalBinaryOperator.InEquality); conditionPositions = [conditionPositions[0], ...conditionPositions, FullPosition.DEFAULT]; } - return { value: conditionExpr, valueOriginalPositions: conditionPositions, stmts: stmts }; + return { + value: conditionExpr, + valueOriginalPositions: conditionPositions, + stmts: stmts, + }; } private literalNodeToValueAndStmts(literalNode: ts.Node): ValueAndStmts | null { @@ -1509,18 +1712,21 @@ export class ArkValueTransformer { } private isRelationalOperator(operator: BinaryOperator): boolean { - return operator === RelationalBinaryOperator.LessThan || + return ( + operator === RelationalBinaryOperator.LessThan || operator === RelationalBinaryOperator.LessThanOrEqual || operator === RelationalBinaryOperator.GreaterThan || operator === RelationalBinaryOperator.GreaterThanOrEqual || operator === RelationalBinaryOperator.Equality || operator === RelationalBinaryOperator.InEquality || operator === RelationalBinaryOperator.StrictEquality || - operator === RelationalBinaryOperator.StrictInequality; + operator === RelationalBinaryOperator.StrictInequality + ); } private isLiteralNode(node: ts.Node): boolean { - if (ts.isStringLiteral(node) || + if ( + ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isBigIntLiteral(node) || ts.isRegularExpressionLiteral(node) || @@ -1528,7 +1734,8 @@ export class ArkValueTransformer { node.kind === ts.SyntaxKind.NullKeyword || node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword || - node.kind === ts.SyntaxKind.UndefinedKeyword) { + node.kind === ts.SyntaxKind.UndefinedKeyword + ) { return true; } return false; @@ -1610,10 +1817,11 @@ export class ArkValueTransformer { if (ts.isQualifiedName(exprNameNode)) { if (exprNameNode.left.getText(this.sourceFile) === THIS_NAME) { const fieldName = exprNameNode.right.getText(this.sourceFile); - const fieldSignature = this.declaringMethod.getDeclaringArkClass().getFieldWithName(fieldName)?.getSignature() ?? + const fieldSignature = + this.declaringMethod.getDeclaringArkClass().getFieldWithName(fieldName)?.getSignature() ?? ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); - const baseLocal = this.locals.get(THIS_NAME) ?? - new Local(THIS_NAME, new ClassType(this.declaringMethod.getDeclaringArkClass().getSignature(), genericTypes)); + const baseLocal = + this.locals.get(THIS_NAME) ?? new Local(THIS_NAME, new ClassType(this.declaringMethod.getDeclaringArkClass().getSignature(), genericTypes)); opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature); } else { const exprName = exprNameNode.getText(this.sourceFile); @@ -1663,7 +1871,6 @@ export class ArkValueTransformer { case ts.SyntaxKind.PrefixUnaryExpression: return new LiteralType(parseFloat(literal.getText(sourceFile))); default: - ; } return new LiteralType(literal.getText(sourceFile)); } @@ -1689,8 +1896,8 @@ export class ArkValueTransformer { const unfoldTemplateTypeStrs: string[] = []; for (const unfoldTemplateType of unfoldTemplateTypes) { unfoldTemplateTypeStrs.push( - unfoldTemplateType instanceof AliasType ? unfoldTemplateType.getOriginalType() - .toString() : unfoldTemplateType.toString()); + unfoldTemplateType instanceof AliasType ? unfoldTemplateType.getOriginalType().toString() : unfoldTemplateType.toString() + ); } const templateSpanString = templateSpan.literal.rawText || ''; @@ -1737,8 +1944,12 @@ export class ArkValueTransformer { } else { if (genericTypes.length > 0) { const oldAlias = aliasTypeAndStmt[0]; - let alias = new AliasType(oldAlias.getName(), TypeInference.replaceTypeWithReal(oldAlias.getOriginalType(), genericTypes), - oldAlias.getSignature(), oldAlias.getGenericTypes()); + let alias = new AliasType( + oldAlias.getName(), + TypeInference.replaceTypeWithReal(oldAlias.getOriginalType(), genericTypes), + oldAlias.getSignature(), + oldAlias.getGenericTypes() + ); alias.setRealGenericTypes(genericTypes); return alias; } @@ -1753,8 +1964,7 @@ export class ArkValueTransformer { if (declaringNamespace) { buildNormalArkClassFromArkNamespace(typeLiteralNode, declaringNamespace, anonymousClass, this.sourceFile); } else { - buildNormalArkClassFromArkFile(typeLiteralNode, declaringClass.getDeclaringArkFile(), anonymousClass, - this.sourceFile); + buildNormalArkClassFromArkFile(typeLiteralNode, declaringClass.getDeclaringArkFile(), anonymousClass, this.sourceFile); } return new ClassType(anonymousClass.getSignature()); } @@ -1786,4 +1996,4 @@ export class ArkValueTransformer { ]; return compoundAssignmentOperators.includes(operator); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/Builtin.ts b/ets2panda/linter/arkanalyzer/src/core/common/Builtin.ts index 87cd5981a204cc06850dc0d0a317935a2b85ba54..5c74ecf4d2d82d15fe7a9166ea515e14d7f18c3b 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/Builtin.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/Builtin.ts @@ -56,8 +56,10 @@ export class Builtin { // constants for string public static TO_STRING = 'toString'; - public static TO_STRING_METHOD_SIGNATURE = new MethodSignature(ClassSignature.DEFAULT, - new MethodSubSignature(this.TO_STRING, [], StringType.getInstance(), false)); + public static TO_STRING_METHOD_SIGNATURE = new MethodSignature( + ClassSignature.DEFAULT, + new MethodSubSignature(this.TO_STRING, [], StringType.getInstance(), false) + ); private static buildBuiltInClasses(): Set { const builtInClasses = new Set(); diff --git a/ets2panda/linter/arkanalyzer/src/core/common/Const.ts b/ets2panda/linter/arkanalyzer/src/core/common/Const.ts index 3edd6f6cc0cb078b3fdf59d4dd133668468b81a9..1fb1a81e79bd89430b9d063059a8d6b279d0de67 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/Const.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/Const.ts @@ -45,4 +45,4 @@ export const TEMP_LOCAL_PREFIX = NAME_PREFIX; export const LEXICAL_ENV_NAME_PREFIX = TEMP_LOCAL_PREFIX + 'closures'; // ArkTS version -export const ARKTS_STATIC_MARK = 'use static'; \ No newline at end of file +export const ARKTS_STATIC_MARK = 'use static'; diff --git a/ets2panda/linter/arkanalyzer/src/core/common/DummyMainCreater.ts b/ets2panda/linter/arkanalyzer/src/core/common/DummyMainCreater.ts index 479cb2f76caad14e21dfa5c520c0cbf3e58ac23b..3818ac805174fb65eddb74175543135802ed9d5b 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/DummyMainCreater.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/DummyMainCreater.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -16,14 +16,7 @@ import { Scene } from '../../Scene'; import { COMPONENT_LIFECYCLE_METHOD_NAME, getCallbackMethodFromStmt, LIFECYCLE_METHOD_NAME } from '../../utils/entryMethodUtils'; import { Constant } from '../base/Constant'; -import { - AbstractInvokeExpr, - ArkConditionExpr, - ArkInstanceInvokeExpr, - ArkNewExpr, - ArkStaticInvokeExpr, - RelationalBinaryOperator, -} from '../base/Expr'; +import { AbstractInvokeExpr, ArkConditionExpr, ArkInstanceInvokeExpr, ArkNewExpr, ArkStaticInvokeExpr, RelationalBinaryOperator } from '../base/Expr'; import { Local } from '../base/Local'; import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnVoidStmt } from '../base/Stmt'; import { ClassType, NumberType, Type } from '../base/Type'; @@ -39,7 +32,6 @@ import { CONSTRUCTOR_NAME } from './TSConst'; import { checkAndUpdateMethod } from '../model/builder/ArkMethodBuilder'; import { ValueUtil } from './ValueUtil'; - /** 收集所有的onCreate,onStart等函数,构造一个虚拟函数,具体为: %statInit() @@ -65,7 +57,6 @@ return */ export class DummyMainCreater { - private entryMethods: ArkMethod[] = []; private classLocalMap: Map = new Map(); private dummyMain: ArkMethod = new ArkMethod(); @@ -81,7 +72,6 @@ export class DummyMainCreater { this.entryMethods.push(...this.getCallbackMethods()); } - public setEntryMethods(methods: ArkMethod[]): void { this.entryMethods = methods; } @@ -89,21 +79,23 @@ export class DummyMainCreater { public createDummyMain(): void { const dummyMainFile = new ArkFile(Language.UNKNOWN); dummyMainFile.setScene(this.scene); - const dummyMainFileSignature = new FileSignature(this.scene.getProjectName(), '@dummyFile') - dummyMainFile.setFileSignature(dummyMainFileSignature) + const dummyMainFileSignature = new FileSignature(this.scene.getProjectName(), '@dummyFile'); + dummyMainFile.setFileSignature(dummyMainFileSignature); this.scene.setFile(dummyMainFile); const dummyMainClass = new ArkClass(); dummyMainClass.setDeclaringArkFile(dummyMainFile); - const dummyMainClassSignature = new ClassSignature('@dummyClass', - dummyMainClass.getDeclaringArkFile().getFileSignature(), dummyMainClass.getDeclaringArkNamespace()?.getSignature() || null); + const dummyMainClassSignature = new ClassSignature( + '@dummyClass', + dummyMainClass.getDeclaringArkFile().getFileSignature(), + dummyMainClass.getDeclaringArkNamespace()?.getSignature() || null + ); dummyMainClass.setSignature(dummyMainClassSignature); dummyMainFile.addArkClass(dummyMainClass); this.dummyMain = new ArkMethod(); this.dummyMain.setDeclaringArkClass(dummyMainClass); const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName('@dummyMain'); - const methodSignature = new MethodSignature(this.dummyMain.getDeclaringArkClass().getSignature(), - methodSubSignature); + const methodSignature = new MethodSignature(this.dummyMain.getDeclaringArkClass().getSignature(), methodSubSignature); this.dummyMain.setImplementationSignature(methodSignature); this.dummyMain.setLineCol(0); checkAndUpdateMethod(this.dummyMain, dummyMainClass); @@ -134,8 +126,8 @@ export class DummyMainCreater { } const localSet = new Set(Array.from(this.classLocalMap.values()).filter((value): value is Local => value !== null)); const dummyBody = new ArkBody(localSet, this.createDummyMainCfg()); - this.dummyMain.setBody(dummyBody) - this.addCfg2Stmt() + this.dummyMain.setBody(dummyBody); + this.addCfg2Stmt(); this.scene.addToMethodsMap(this.dummyMain); } @@ -191,6 +183,7 @@ export class DummyMainCreater { paramLocals.push(paramLocal); if (paramType instanceof ClassType) { const assStmt = new ArkAssignStmt(paramLocal, new ArkNewExpr(paramType)); + paramLocal.setDeclaringStmt(assStmt); invokeBlock.addStmt(assStmt); } paramIdx++; @@ -264,7 +257,7 @@ export class DummyMainCreater { return dummyCfg; } - private addCfg2Stmt() { + private addCfg2Stmt(): void { const cfg = this.dummyMain.getCfg(); if (!cfg) { return; @@ -283,7 +276,8 @@ export class DummyMainCreater { private getEntryMethodsFromComponents(): ArkMethod[] { const COMPONENT_BASE_CLASSES = ['CustomComponent', 'ViewPU']; let methods: ArkMethod[] = []; - this.scene.getClasses() + this.scene + .getClasses() .filter(cls => { if (COMPONENT_BASE_CLASSES.includes(cls.getSuperClassName())) { return true; @@ -316,26 +310,30 @@ export class DummyMainCreater { public getMethodsFromAllAbilities(): ArkMethod[] { let methods: ArkMethod[] = []; - this.scene.getClasses() + this.scene + .getClasses() .filter(cls => this.classInheritsAbility(cls)) .forEach(cls => { methods.push(...cls.getMethods().filter(mtd => LIFECYCLE_METHOD_NAME.includes(mtd.getName()))); }); return methods; } - + public getCallbackMethods(): ArkMethod[] { const callbackMethods: ArkMethod[] = []; this.scene.getMethods().forEach(method => { if (!method.getCfg()) { return; } - method.getCfg()!.getStmts().forEach(stmt => { - const cbMethod = getCallbackMethodFromStmt(stmt, this.scene); - if (cbMethod && !callbackMethods.includes(cbMethod)) { - callbackMethods.push(cbMethod); - } - }); + method + .getCfg()! + .getStmts() + .forEach(stmt => { + const cbMethod = getCallbackMethodFromStmt(stmt, this.scene); + if (cbMethod && !callbackMethods.includes(cbMethod)) { + callbackMethods.push(cbMethod); + } + }); }); return callbackMethods; } diff --git a/ets2panda/linter/arkanalyzer/src/core/common/EtsConst.ts b/ets2panda/linter/arkanalyzer/src/core/common/EtsConst.ts index 3d4c1a5161df9819222d57aa9e32ad344057c757..f01f9396e9a7847171d183eee2b6232e64d1e43f 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/EtsConst.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/EtsConst.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -923,11 +923,7 @@ export const ETS_COMPILER_OPTIONS = { export const COMPONENT_FOR_EACH: string = 'ForEach'; export const COMPONENT_LAZY_FOR_EACH: string = 'LazyForEach'; -export const BUILDIN_SYSTEM_COMPONENT: Set = new Set([ - ...ETS_COMPILER_OPTIONS.ets.components, - COMPONENT_FOR_EACH, - COMPONENT_LAZY_FOR_EACH, -]); +export const BUILDIN_SYSTEM_COMPONENT: Set = new Set([...ETS_COMPILER_OPTIONS.ets.components, COMPONENT_FOR_EACH, COMPONENT_LAZY_FOR_EACH]); export const BUILDIN_ATOMIC_COMPONENT: Set = new Set([ 'AbilityComponent', @@ -1011,13 +1007,7 @@ export const COMPONENT_IF_BRANCH: string = 'IfBranch'; export const COMPONENT_BRANCH_FUNCTION: string = 'branch'; export const COMPONENT_BUILD_FUNCTION: string = 'build'; -export const SPECIAL_CONTAINER_COMPONENT: Set = new Set([ - COMPONENT_IF, - COMPONENT_IF_BRANCH, - COMPONENT_CUSTOMVIEW, - COMPONENT_REPEAT, -]); - +export const SPECIAL_CONTAINER_COMPONENT: Set = new Set([COMPONENT_IF, COMPONENT_IF_BRANCH, COMPONENT_CUSTOMVIEW, COMPONENT_REPEAT]); export const COMPONENT_COMMON: string = 'Common'; export const COMPONENT_INSTANCE: string = 'Instance'; @@ -1027,4 +1017,4 @@ export const CALL_BACK: string = 'Callback'; export const ON_OFF: Set = new Set(['on', 'off']); export const OH_PACKAGE_JSON5 = 'oh-package.json5'; -export const BUILD_PROFILE_JSON5 = 'build-profile.json5'; \ No newline at end of file +export const BUILD_PROFILE_JSON5 = 'build-profile.json5'; diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ExprUseReplacer.ts b/ets2panda/linter/arkanalyzer/src/core/common/ExprUseReplacer.ts index 3603b3bc51a7e472ada8fc2f17eb682377eff164..9bc96442dfbd372c39a128ee5b60babcc887a126 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/ExprUseReplacer.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/ExprUseReplacer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -40,7 +40,7 @@ export class ExprUseReplacer { private newUse: Value; constructor(oldUse: Value, newUse: Value) { - this.oldUse = oldUse + this.oldUse = oldUse; this.newUse = newUse; } @@ -86,7 +86,7 @@ export class ExprUseReplacer { } if (expr instanceof ArkInstanceInvokeExpr && expr.getBase() === this.oldUse) { - expr.setBase(this.newUse); + expr.setBase( this.newUse); } else if (expr instanceof ArkPtrInvokeExpr && expr.getFuncPtrLocal() === this.oldUse && this.newUse instanceof Local) { expr.setFunPtrLocal(this.newUse); } @@ -139,4 +139,4 @@ export class ExprUseReplacer { expr.setOp(this.newUse); } } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/IRInference.ts b/ets2panda/linter/arkanalyzer/src/core/common/IRInference.ts index 44f222faa0e316112c3751c52dcc1b1c59c254ad..08083474900627f2a07599c37994fc757e87c692 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/IRInference.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/IRInference.ts @@ -43,7 +43,7 @@ import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; import { Scene } from '../../Scene'; import { ArkClass } from '../model/ArkClass'; import { findArkExport, ModelUtils } from './ModelUtils'; -import { ArkField } from '../model/ArkField'; +import { ArkField, FieldCategory } from '../model/ArkField'; import { CALL_BACK } from './EtsConst'; import { AliasClassSignature, @@ -63,7 +63,8 @@ import { ArkArrayRef, ArkInstanceFieldRef, ArkParameterRef, - ArkStaticFieldRef + ArkStaticFieldRef, + GlobalRef } from '../base/Ref'; import { Value } from '../base/Value'; import { Constant } from '../base/Constant'; @@ -83,7 +84,6 @@ import { ArkBaseModel } from '../model/ArkBaseModel'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'IRInference'); export class IRInference { - private static inferExportInfos(file: ArkFile): void { file.getExportInfos().forEach(exportInfo => { if (exportInfo.getArkExport() === undefined) { @@ -94,6 +94,15 @@ export class IRInference { } } }); + file.getNamespaces().forEach(namespace => { + namespace.getExportInfos().forEach(exportInfo => { + if (exportInfo.getArkExport() === undefined) { + let arkExport = findArkExport(exportInfo); + exportInfo.setArkExport(arkExport); + arkExport !== null ? exportInfo.setExportClauseType(arkExport.getExportType()) : true; + } + }); + }); } private static inferImportInfos(file: ArkFile): void { @@ -129,6 +138,7 @@ export class IRInference { public static inferStaticInvokeExpr(expr: ArkStaticInvokeExpr, arkMethod: ArkMethod): AbstractInvokeExpr { const arkClass = arkMethod.getDeclaringArkClass(); const methodName = expr.getMethodSignature().getMethodSubSignature().getMethodName(); + expr.getArgs().forEach(arg => TypeInference.inferValueType(arg, arkMethod)); if (methodName === IMPORT) { const arg = expr.getArg(0); let type; @@ -139,9 +149,7 @@ export class IRInference { expr.getMethodSignature().getMethodSubSignature().setReturnType(type); } return expr; - } - expr.getArgs().forEach(arg => TypeInference.inferValueType(arg, arkMethod)); - if (methodName === SUPER_NAME) { + } else if (methodName === SUPER_NAME) { const superClass = arkClass.getSuperClass(); if (superClass !== null) { const newMethodSignature = new MethodSignature(superClass.getSignature(), expr.getMethodSignature().getMethodSubSignature()); @@ -151,7 +159,7 @@ export class IRInference { } const className = expr.getMethodSignature().getDeclaringClassSignature().getClassName(); if (className && className !== UNKNOWN_CLASS_NAME) { - const baseType = TypeInference.inferUnclearRefName(className, arkClass); + const baseType = TypeInference.inferBaseType(className, arkClass); if (baseType) { let result = this.inferInvokeExpr(expr, baseType, methodName, arkClass.getDeclaringArkFile().getScene()); if (result) { @@ -166,7 +174,8 @@ export class IRInference { private static inferStaticInvokeExprByMethodName(methodName: string, arkMethod: ArkMethod, expr: AbstractInvokeExpr): AbstractInvokeExpr { const arkClass = arkMethod.getDeclaringArkClass(); - const arkExport = ModelUtils.getStaticMethodWithName(methodName, arkClass) ?? + const arkExport = + ModelUtils.getStaticMethodWithName(methodName, arkClass) ?? arkMethod.getFunctionLocal(methodName) ?? ModelUtils.findDeclaredLocal(new Local(methodName), arkMethod) ?? ModelUtils.getArkExportInImportInfoWithName(methodName, arkClass.getDeclaringArkFile()) ?? @@ -178,7 +187,7 @@ export class IRInference { } else if (arkExport instanceof ArkClass) { method = arkExport.getMethodWithName(CONSTRUCTOR_NAME); } else if (arkExport instanceof Local) { - const type = arkExport.getType(); + const type = TypeInference.replaceAliasType(arkExport.getType()); if (type instanceof ClassType) { const cls = arkClass.getDeclaringArkFile().getScene().getClass(type.getClassSignature()); method = cls?.getMethodWithName(CONSTRUCTOR_NAME) ?? cls?.getMethodWithName(CALL_SIGNATURE_NAME); @@ -218,13 +227,12 @@ export class IRInference { } } const scene = arkClass.getDeclaringArkFile().getScene(); - if ((methodName === 'forEach') && (baseType instanceof ArrayType)) { + if (methodName === 'forEach' && baseType instanceof ArrayType) { this.processForEach(expr.getArg(0), baseType, scene); return expr; } expr.getArgs().forEach(arg => TypeInference.inferValueType(arg, arkMethod)); - let result = this.inferInvokeExpr(expr, baseType, methodName, scene) ?? - this.processExtendFunc(expr, arkMethod, methodName); + let result = this.inferInvokeExpr(expr, baseType, methodName, scene) ?? this.processExtendFunc(expr, arkMethod, methodName); if (result) { this.inferArgs(result, arkMethod); return result; @@ -275,11 +283,24 @@ export class IRInference { private static inferBase(instance: ArkInstanceFieldRef | ArkInstanceInvokeExpr, arkMethod: ArkMethod): void { const base = instance.getBase(); if (base.getName() === THIS_NAME) { - let newBase = this.inferThisLocal(arkMethod); - if (newBase) { - instance.setBase(newBase); + const declaringArkClass = arkMethod.getDeclaringArkClass(); + if (declaringArkClass.isAnonymousClass()) { + let newBase = this.inferThisLocal(arkMethod); + if (newBase) { + instance.setBase(newBase); + } + } else if (base.getType() instanceof UnknownType) { + base.setType(new ClassType(declaringArkClass.getSignature(), declaringArkClass.getRealTypes())); } } else { + const value = arkMethod.getBody()?.getUsedGlobals()?.get(base.getName()); + if (value instanceof GlobalRef && !value.getRef()) { + const arkExport = ModelUtils.findGlobalRef(base.getName(), arkMethod); + if (arkExport instanceof Local) { + arkExport.getUsedStmts().push(...base.getUsedStmts()); + value.setRef(arkExport); + } + } this.inferLocal(instance.getBase(), arkMethod); } } @@ -341,15 +362,17 @@ export class IRInference { } } - if (paramType instanceof ClassType && scene.getProjectSdkMap().has(paramType.getClassSignature() - .getDeclaringFileSignature().getProjectName())) { + if (paramType instanceof ClassType && scene.getProjectSdkMap().has(paramType.getClassSignature().getDeclaringFileSignature().getProjectName())) { this.inferArgTypeWithSdk(paramType, scene, argType); } else if (paramType instanceof GenericType || paramType instanceof AnyType) { realTypes.push(argType); } else if (paramType instanceof FunctionType && argType instanceof FunctionType) { - const method = scene.getMethod(argType.getMethodSignature()); - if (method) { - TypeInference.inferTypeInMethod(method); + if (paramType.getMethodSignature().getParamLength() > 0 && paramType.getMethodSignature().getType() instanceof GenericType) { + const paramMethod = scene.getMethod(expr.getMethodSignature()); + const argMethod = scene.getMethod(argType.getMethodSignature()); + if (paramMethod && paramMethod.getGenericTypes() && argMethod) { + TypeInference.inferTypeInMethod(argMethod); + } } const realTypes = expr.getRealGenericTypes(); TypeInference.inferFunctionType(argType, paramType.getMethodSignature().getMethodSubSignature(), realTypes); @@ -380,14 +403,12 @@ export class IRInference { } else if (argType instanceof ClassType && argType.getClassSignature().getClassName().startsWith(ANONYMOUS_CLASS_PREFIX)) { this.inferAnonymousClass(scene.getClass(argType.getClassSignature()), sdkType.getClassSignature()); } else if (argType instanceof FunctionType) { - const param = scene.getClass(sdkType.getClassSignature()) - ?.getMethodWithName(CALL_SIGNATURE_NAME)?.getSignature().getMethodSubSignature(); + const param = scene.getClass(sdkType.getClassSignature())?.getMethodWithName(CALL_SIGNATURE_NAME)?.getSignature().getMethodSubSignature(); const realTypes = sdkType.getRealGenericTypes(); TypeInference.inferFunctionType(argType, param, realTypes); } } - private static inferInvokeExpr(expr: AbstractInvokeExpr, baseType: Type, methodName: string, scene: Scene): AbstractInvokeExpr | null { if (baseType instanceof AliasType) { return this.inferInvokeExpr(expr, baseType.getOriginalType(), methodName, scene); @@ -412,8 +433,7 @@ export class IRInference { let signature = foundMethod.matchMethodSignature(expr.getArgs()); TypeInference.inferSignatureReturnType(signature, foundMethod); expr.setMethodSignature(signature); - return expr instanceof ArkInstanceInvokeExpr ? - new ArkStaticInvokeExpr(signature, expr.getArgs(), expr.getRealGenericTypes()) : expr; + return expr instanceof ArkInstanceInvokeExpr ? new ArkStaticInvokeExpr(signature, expr.getArgs(), expr.getRealGenericTypes()) : expr; } } } else if (baseType instanceof FunctionType) { @@ -427,8 +447,7 @@ export class IRInference { private static inferInvokeExprWithArray(methodName: string, expr: AbstractInvokeExpr, baseType: ArrayType, scene: Scene): AbstractInvokeExpr | null { if (methodName === Builtin.ITERATOR_FUNCTION) { const returnType = expr.getMethodSignature().getMethodSubSignature().getReturnType(); - if (returnType instanceof ClassType && returnType.getClassSignature().getDeclaringFileSignature() - .getProjectName() === Builtin.DUMMY_PROJECT_NAME) { + if (returnType instanceof ClassType && returnType.getClassSignature().getDeclaringFileSignature().getProjectName() === Builtin.DUMMY_PROJECT_NAME) { expr.setRealGenericTypes([baseType.getBaseType()]); return expr; } @@ -458,8 +477,12 @@ export class IRInference { return null; } - private static inferInvokeExprWithDeclaredClass(expr: AbstractInvokeExpr, baseType: ClassType, methodName: string, - scene: Scene): AbstractInvokeExpr | null { + private static inferInvokeExprWithDeclaredClass( + expr: AbstractInvokeExpr, + baseType: ClassType, + methodName: string, + scene: Scene + ): AbstractInvokeExpr | null { if (Builtin.isBuiltinClass(baseType.getClassSignature().getClassName())) { expr.setMethodSignature(new MethodSignature(baseType.getClassSignature(), expr.getMethodSignature().getMethodSubSignature())); } @@ -492,16 +515,20 @@ export class IRInference { } } if (methodSignature) { - const ptr = expr instanceof ArkInstanceInvokeExpr ? - new ArkInstanceFieldRef(expr.getBase(), method.getSignature()) : new ArkStaticFieldRef(method.getSignature()); + const ptr = + expr instanceof ArkInstanceInvokeExpr + ? new ArkInstanceFieldRef(expr.getBase(), method.getSignature()) + : new ArkStaticFieldRef(method.getSignature()); expr = new ArkPtrInvokeExpr(methodSignature, ptr, expr.getArgs(), expr.getRealGenericTypes()); } return expr; - } else if (methodName === CONSTRUCTOR_NAME) { //sdk隐式构造 + } else if (methodName === CONSTRUCTOR_NAME) { + //sdk隐式构造 const subSignature = new MethodSubSignature(methodName, [], new ClassType(baseType.getClassSignature())); expr.setMethodSignature(new MethodSignature(baseType.getClassSignature(), subSignature)); return expr; - } else if (methodName === Builtin.ITERATOR_NEXT) { //sdk隐式构造 + } else if (methodName === Builtin.ITERATOR_NEXT) { + //sdk隐式构造 const returnType = expr.getMethodSignature().getMethodSubSignature().getReturnType(); if (returnType instanceof ClassType && returnType.getClassSignature().getDeclaringFileSignature().getProjectName() === Builtin.DUMMY_PROJECT_NAME) { returnType.setRealGenericTypes(baseType.getRealGenericTypes()); @@ -531,8 +558,7 @@ export class IRInference { } let newSubSignature; if (classSignature || newSubSignature) { - return new MethodSignature(classSignature ?? declared.getDeclaringClassSignature(), - newSubSignature ?? declared.getMethodSubSignature()); + return new MethodSignature(classSignature ?? declared.getDeclaringClassSignature(), newSubSignature ?? declared.getMethodSubSignature()); } return declared; } @@ -545,7 +571,7 @@ export class IRInference { if (argMethod != null && argMethod.getBody()) { const body = argMethod.getBody() as ArkBody; const firstStmt = body.getCfg().getStartingStmt(); - if ((firstStmt instanceof ArkAssignStmt) && (firstStmt.getRightOp() instanceof ArkParameterRef)) { + if (firstStmt instanceof ArkAssignStmt && firstStmt.getRightOp() instanceof ArkParameterRef) { const parameterRef = firstStmt.getRightOp() as ArkParameterRef; parameterRef.setType(baseType.getBaseType()); const argMethodParams = argMethod.getSignature().getMethodSubSignature().getParameters(); @@ -593,8 +619,8 @@ export class IRInference { const fieldName = ref.getFieldName().replace(/[\"|\']/g, ''); const propertyAndType = TypeInference.inferFieldType(baseType, fieldName, arkClass); let propertyType = propertyAndType?.[1]; - if (!propertyType) { - const newType = TypeInference.inferUnclearRefName(fieldName, arkClass); + if (!propertyType || propertyType instanceof UnknownType) { + const newType = TypeInference.inferBaseType(fieldName, arkClass); if (newType) { propertyType = newType; } @@ -608,11 +634,12 @@ export class IRInference { let signature: BaseSignature; if (baseType instanceof ClassType) { const property = propertyAndType?.[0]; - if (property instanceof ArkField) { + if (property instanceof ArkField && property.getCategory() !== FieldCategory.ENUM_MEMBER) { return property.getSignature(); } - staticFlag = baseType.getClassSignature().getClassName() === DEFAULT_ARK_CLASS_NAME || - (property instanceof ArkMethod && property.isStatic()); + staticFlag = + baseType.getClassSignature().getClassName() === DEFAULT_ARK_CLASS_NAME || + ((property instanceof ArkField || property instanceof ArkMethod) && property.isStatic()); signature = property instanceof ArkMethod ? property.getSignature().getDeclaringClassSignature() : baseType.getClassSignature(); } else if (baseType instanceof AnnotationNamespaceType) { staticFlag = true; @@ -623,7 +650,6 @@ export class IRInference { return new FieldSignature(fieldName, signature, propertyType ?? ref.getType(), staticFlag); } - public static inferAnonymousClass(anon: ArkClass | null, declaredSignature: ClassSignature, set: Set = new Set()): void { if (!anon) { return; @@ -648,8 +674,9 @@ export class IRInference { if (type instanceof FunctionType) { this.assignAnonMethod(scene.getMethod(type.getMethodSignature()), property); } - anonField.setSignature(new FieldSignature(anonField.getName(), - property.getDeclaringArkClass().getSignature(), new FunctionType(property.getSignature()))); + anonField.setSignature( + new FieldSignature(anonField.getName(), property.getDeclaringArkClass().getSignature(), new FunctionType(property.getSignature())) + ); } } for (const anonMethod of anon.getMethods()) { @@ -657,7 +684,6 @@ export class IRInference { } } - private static assignAnonMethod(anonMethod: ArkMethod | null, declaredMethod: ArkMethod | null): void { if (declaredMethod && anonMethod) { anonMethod.setImplementationSignature(declaredMethod.matchMethodSignature(anonMethod.getSubSignature().getParameters())); @@ -677,8 +703,7 @@ export class IRInference { const rightType = lastStmt.getRightOp().getType(); if (type instanceof ClassType) { deepInfer(rightType, type.getClassSignature()); - } else if (type instanceof ArrayType && type.getBaseType() instanceof ClassType && - rightType instanceof ArrayType) { + } else if (type instanceof ArrayType && type.getBaseType() instanceof ClassType && rightType instanceof ArrayType) { const baseType = rightType.getBaseType(); const classSignature = (type.getBaseType() as ClassType).getClassSignature(); if (baseType instanceof UnionType) { @@ -753,7 +778,7 @@ export class IRInference { return; } if (opValue instanceof Local) { - const newOpValueType = TypeInference.inferUnclearRefName(opValue.getName(), arkMethod.getDeclaringArkClass()); + const newOpValueType = TypeInference.inferBaseType(opValue.getName(), arkMethod.getDeclaringArkClass()); const scene = arkMethod.getDeclaringArkFile().getScene(); if (newOpValueType instanceof ClassType) { const newOpValue = ModelUtils.findArkModelBySignature(newOpValueType.getClassSignature(), scene); @@ -796,7 +821,9 @@ export class IRInference { return ref; } } else if (paramType instanceof LexicalEnvType) { - paramType.getClosures().filter(c => TypeInference.isUnclearType(c.getType())) + paramType + .getClosures() + .filter(c => TypeInference.isUnclearType(c.getType())) .forEach(e => this.inferLocal(e, arkMethod)); return ref; } @@ -806,4 +833,4 @@ export class IRInference { } return ref; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/IRUtils.ts b/ets2panda/linter/arkanalyzer/src/core/common/IRUtils.ts index 9af148f93bddf2f631f418b3347915ffd9a99f0a..c6b5ea378ea243bbf73f9dc2ebde3bb9f45e4a32 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/IRUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/IRUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -52,10 +52,7 @@ export class IRUtils { } } - public static setComments(metadata: Stmt | ArkBaseModel, - node: ts.Node, - sourceFile: ts.SourceFile, - options: SceneOptions): void { + public static setComments(metadata: Stmt | ArkBaseModel, node: ts.Node, sourceFile: ts.SourceFile, options: SceneOptions): void { const leadingCommentsMetadata = this.getCommentsMetadata(node, sourceFile, options, true); if (leadingCommentsMetadata.getComments().length > 0) { metadata.setMetadata(ArkMetadataKind.LEADING_COMMENTS, leadingCommentsMetadata); @@ -67,17 +64,17 @@ export class IRUtils { } } - public static getCommentsMetadata(node: ts.Node, sourceFile: ts.SourceFile, options: SceneOptions, - isLeading: boolean): CommentsMetadata { + public static getCommentsMetadata(node: ts.Node, sourceFile: ts.SourceFile, options: SceneOptions, isLeading: boolean): CommentsMetadata { const comments: CommentItem[] = []; if ((isLeading && !options.enableLeadingComments) || (!isLeading && !options.enableTrailingComments)) { return new CommentsMetadata(comments); } - const commentRanges = (isLeading ? ts.getLeadingCommentRanges(sourceFile.text, node.pos) - : ts.getTrailingCommentRanges(sourceFile.text, node.end)) || []; // node.pos is the start position of - // leading comment, while node.end is the - // end position of the statement + // node.pos is the start position of + const commentRanges = + (isLeading ? ts.getLeadingCommentRanges(sourceFile.text, node.pos) : ts.getTrailingCommentRanges(sourceFile.text, node.end)) || []; + // leading comment, while node.end is the + // end position of the statement const getPosition = (pos: number, end: number): FullPosition => { const start = ts.getLineAndCharacterOfPosition(sourceFile, pos); const endPos = ts.getLineAndCharacterOfPosition(sourceFile, end); @@ -125,23 +122,18 @@ export class IRUtils { if (oldValue instanceof AbstractRef && newValue instanceof AbstractRef) { if (newValue instanceof ArkStaticFieldRef) { - operandOriginalPositions.splice(oldValueIdx + baseValueOffset, - oldValueUseSize - newValueUseSize); + operandOriginalPositions.splice(oldValueIdx + baseValueOffset, oldValueUseSize - newValueUseSize); } else if (oldValue instanceof ArkStaticFieldRef) { - operandOriginalPositions.splice(oldValueIdx + baseValueOffset, 0, - ...IRUtils.generateDefaultPositions( - newValueUseSize - oldValueUseSize)); + operandOriginalPositions.splice(oldValueIdx + baseValueOffset, 0, ...IRUtils.generateDefaultPositions(newValueUseSize - oldValueUseSize)); } if (oldValue instanceof ArkInstanceFieldRef && newValue instanceof ArkArrayRef) { - if (operandOriginalPositionSize === defUseSize) { // may not reserve positions for field name - operandOriginalPositions.splice(oldValueIdx + fieldValueOffset, 0, - ...IRUtils.generateDefaultPositions( - newValueUseSize - oldValueUseSize)); + if (operandOriginalPositionSize === defUseSize) { + // may not reserve positions for field name + operandOriginalPositions.splice(oldValueIdx + fieldValueOffset, 0, ...IRUtils.generateDefaultPositions(newValueUseSize - oldValueUseSize)); } } else if (oldValue instanceof ArkArrayRef && newValue instanceof ArkInstanceFieldRef) { - operandOriginalPositions.splice(oldValueIdx + fieldValueOffset, - oldValueUseSize - newValueUseSize); + operandOriginalPositions.splice(oldValueIdx + fieldValueOffset, oldValueUseSize - newValueUseSize); } } else if (oldValue instanceof AbstractInvokeExpr && newValue instanceof AbstractInvokeExpr) { if (oldValueUseSize === newValueUseSize + 1) { diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ModelUtils.ts b/ets2panda/linter/arkanalyzer/src/core/common/ModelUtils.ts index 9e3f335317625ed65256675a616fad809002d845..7b90129608f4f99a927f46f22ad6f4491e4f6572 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/ModelUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/ModelUtils.ts @@ -27,7 +27,7 @@ import { LocalSignature, MethodSignature, NamespaceSignature, - Signature + Signature, } from '../model/ArkSignature'; import { ArkExport, ExportInfo, ExportType, FromInfo } from '../model/ArkExport'; import { ArkField } from '../model/ArkField'; @@ -51,6 +51,7 @@ import { EMPTY_STRING } from './ValueUtil'; import { ArkBaseModel } from '../model/ArkBaseModel'; import { ArkAssignStmt } from '../base/Stmt'; import { ClosureFieldRef } from '../base/Ref'; +import { SdkUtils } from './SdkUtils'; export class ModelUtils { public static implicitArkUIBuilderMethods: Set = new Set(); @@ -95,8 +96,9 @@ export class ModelUtils { const names = className.split('.'); let nameSpace = this.getNamespaceWithNameFromClass(names[0], startFrom); for (let i = 1; i < names.length - 1; i++) { - if (nameSpace) + if (nameSpace) { nameSpace = nameSpace.getNamespaceWithName(names[i]); + } } if (nameSpace) { return nameSpace.getClassWithName(names[names.length - 1]); @@ -214,7 +216,6 @@ export class ModelUtils { } public static getStaticMethodWithName(methodName: string, thisClass: ArkClass): ArkMethod | null { - const thisNamespace = thisClass.getDeclaringArkNamespace(); if (thisNamespace) { const defaultClass = thisNamespace.getClassWithName(DEFAULT_ARK_CLASS_NAME); @@ -274,7 +275,7 @@ export class ModelUtils { public static getAllClassesInFile(arkFile: ArkFile): ArkClass[] { const allClasses = arkFile.getClasses(); - this.getAllNamespacesInFile(arkFile).forEach((namespace) => { + this.getAllNamespacesInFile(arkFile).forEach(namespace => { allClasses.push(...namespace.getClasses()); }); return allClasses; @@ -282,7 +283,7 @@ export class ModelUtils { public static getAllMethodsInFile(arkFile: ArkFile): ArkMethod[] { const allMethods: ArkMethod[] = []; - this.getAllClassesInFile(arkFile).forEach((cls) => { + this.getAllClassesInFile(arkFile).forEach(cls => { allMethods.push(...cls.getMethods()); }); return allMethods; @@ -291,12 +292,7 @@ export class ModelUtils { public static isArkUIBuilderMethod(arkMethod: ArkMethod): boolean { let isArkUIBuilderMethod = arkMethod.hasBuilderDecorator() || this.implicitArkUIBuilderMethods.has(arkMethod); - if ( - !isArkUIBuilderMethod && - arkMethod.getName() === 'build' && - arkMethod.getDeclaringArkClass().hasComponentDecorator() && - !arkMethod.isStatic() - ) { + if (!isArkUIBuilderMethod && arkMethod.getName() === 'build' && arkMethod.getDeclaringArkClass().hasComponentDecorator() && !arkMethod.isStatic()) { const fileName = arkMethod.getDeclaringArkClass().getDeclaringArkFile().getName(); if (fileName.endsWith('.ets')) { isArkUIBuilderMethod = true; @@ -347,18 +343,22 @@ export class ModelUtils { } public static findPropertyInNamespace(name: string, namespace: ArkNamespace): ArkExport | undefined { - return namespace.getDefaultClass()?.getMethodWithName(name) - ?? findArkExport(namespace.getExportInfoBy(name)) - ?? namespace.getClassWithName(name) - ?? namespace.getNamespaceWithName(name) - ?? namespace.getDefaultClass()?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name) - ?? namespace.getDefaultClass()?.getDefaultArkMethod()?.getBody()?.getLocals()?.get(name); + return ( + namespace.getDefaultClass()?.getMethodWithName(name) ?? + findArkExport(namespace.getExportInfoBy(name)) ?? + namespace.getClassWithName(name) ?? + namespace.getNamespaceWithName(name) ?? + namespace.getDefaultClass()?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name) ?? + namespace.getDefaultClass()?.getDefaultArkMethod()?.getBody()?.getLocals()?.get(name) + ); } public static findPropertyInClass(name: string, arkClass: ArkClass): ArkExport | ArkField | null { - let property: ArkExport | ArkField | null = arkClass.getMethodWithName(name) - ?? arkClass.getStaticMethodWithName(name) ?? arkClass.getFieldWithName(name) - ?? arkClass.getStaticFieldWithName(name); + let property: ArkExport | ArkField | null = + arkClass.getMethodWithName(name) ?? + arkClass.getStaticMethodWithName(name) ?? + arkClass.getFieldWithName(name) ?? + arkClass.getStaticFieldWithName(name); if (property) { return property; } @@ -388,8 +388,11 @@ export class ModelUtils { } if (times > 0) { const declaredLocal = arkMethod.getBody()?.getLocals().get(name); - if (declaredLocal && declaredLocal.getDeclaringStmt() instanceof ArkAssignStmt && - !((declaredLocal.getDeclaringStmt() as ArkAssignStmt).getRightOp() instanceof ClosureFieldRef)) { + if ( + declaredLocal && + declaredLocal.getDeclaringStmt() instanceof ArkAssignStmt && + !((declaredLocal.getDeclaringStmt() as ArkAssignStmt).getRightOp() instanceof ClosureFieldRef) + ) { return declaredLocal; } } @@ -403,7 +406,9 @@ export class ModelUtils { const outerStart = className.indexOf(NAME_DELIMITER); const outerEnd = className.lastIndexOf('.'); if (outerStart > -1 && outerEnd > -1) { - invokeMethod = arkMethod.getDeclaringArkFile().getClassWithName(className.substring(outerStart + 1, outerEnd)) + invokeMethod = arkMethod + .getDeclaringArkFile() + .getClassWithName(className.substring(outerStart + 1, outerEnd)) ?.getMethodWithName(className.substring(outerEnd + 1)); } else { const cls = arkMethod.getDeclaringArkClass(); @@ -417,13 +422,16 @@ export class ModelUtils { } public static findArkModel(baseName: string, arkClass: ArkClass): ArkExport | ArkField | null { - let arkModel: ArkExport | ArkField | null = arkClass.getMethodWithName(baseName) ?? - arkClass.getStaticMethodWithName(baseName) ?? arkClass.getFieldWithName(baseName) ?? + let arkModel: ArkExport | ArkField | null = + arkClass.getMethodWithName(baseName) ?? + arkClass.getStaticMethodWithName(baseName) ?? + arkClass.getFieldWithName(baseName) ?? arkClass.getStaticFieldWithName(baseName); if (arkModel) { return arkModel; } - arkModel = ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getLocals()?.get(baseName) ?? + arkModel = + ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getLocals()?.get(baseName) ?? ModelUtils.getClassWithName(baseName, arkClass) ?? ModelUtils.getNamespaceWithName(baseName, arkClass) ?? ModelUtils.getDefaultClass(arkClass)?.getMethodWithName(baseName) ?? @@ -435,6 +443,14 @@ export class ModelUtils { return arkModel; } + public static findGlobalRef(refName: string, method: ArkMethod): ArkExport | null { + return ( + this.findDeclaredLocal(new Local(refName), method, 1) ?? + this.getArkExportInImportInfoWithName(refName, method.getDeclaringArkFile()) ?? + method.getDeclaringArkFile().getScene().getSdkGlobal(refName) + ); + } + public static findArkModelByRefName(refName: string, arkClass: ArkClass): ArkExport | ArkField | null { const singleNames = refName.split('.'); let model = null; @@ -458,7 +474,6 @@ export class ModelUtils { if (!model) { return null; } - } return model; } @@ -505,10 +520,8 @@ export class ModelUtils { } } - const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ModelUtils'); let moduleMap: Map | undefined; -export const sdkImportMap: Map = new Map(); /** * find arkFile by from info @@ -522,12 +535,13 @@ export function getArkFile(im: FromInfo): ArkFile | null | undefined { if (!from) { return null; } - if (/^([^@]*\/)([^\/]*)$/.test(from)) { //relative path - const parentPath = /^\.{1,2}\//.test(from) ? path.dirname(im.getDeclaringArkFile().getFilePath()) - : im.getDeclaringArkFile().getProjectDir(); + if (/^([^@]*\/)([^\/]*)$/.test(from)) { + //relative path + const parentPath = /^\.{1,2}\//.test(from) ? path.dirname(im.getDeclaringArkFile().getFilePath()) : im.getDeclaringArkFile().getProjectDir(); const originPath = path.resolve(parentPath, from); return getArkFileFromScene(im, originPath); - } else if (/^@[a-z|\-]+?\//.test(from)) { //module path + } else if (/^@[a-z|\-]+?\//.test(from)) { + //module path const arkFile = getArkFileFromOtherModule(im); if (arkFile) { return arkFile; @@ -535,7 +549,7 @@ export function getArkFile(im: FromInfo): ArkFile | null | undefined { } //sdk path - const file = sdkImportMap.get(from); + const file = SdkUtils.getImportSdkFile(from); if (file) { return file; } @@ -546,6 +560,7 @@ export function getArkFile(im: FromInfo): ArkFile | null | undefined { return arkFile; } } + return null; } /** @@ -570,8 +585,7 @@ export function findExportInfo(fromInfo: FromInfo): ExportInfo | null { } let exportInfo = findExportInfoInfile(fromInfo, file) || null; if (exportInfo === null) { - logger.warn('export info not found, ' + fromInfo.getFrom() + ' in file: ' - + fromInfo.getDeclaringArkFile().getFileSignature().toString()); + logger.warn('export info not found, ' + fromInfo.getFrom() + ' in file: ' + fromInfo.getDeclaringArkFile().getFileSignature().toString()); return null; } const arkExport = findArkExport(exportInfo); @@ -592,10 +606,11 @@ export function findArkExport(exportInfo: ExportInfo | undefined): ArkExport | n } if (!exportInfo.getFrom()) { const name = exportInfo.getOriginName(); + const defaultClass = exportInfo.getDeclaringArkNamespace()?.getDefaultClass() ?? exportInfo.getDeclaringArkFile().getDefaultClass(); if (exportInfo.getExportClauseType() === ExportType.LOCAL) { - arkExport = exportInfo.getDeclaringArkFile().getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals().get(name) || null; + arkExport = defaultClass.getDefaultArkMethod()?.getBody()?.getExportLocalByName(name); } else if (exportInfo.getExportClauseType() === ExportType.TYPE) { - arkExport = exportInfo.getDeclaringArkFile().getDefaultClass().getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name) || null; + arkExport = defaultClass.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name); } else { arkExport = findArkExportInFile(name, exportInfo.getDeclaringArkFile()); } @@ -605,7 +620,9 @@ export function findArkExport(exportInfo: ExportInfo | undefined): ArkExport | n arkExport = result.getArkExport() || null; } } - if (!arkExport) { + if (arkExport) { + exportInfo.setArkExport(arkExport); + } else { logger.warn(`${exportInfo.getExportClauseName()} get arkExport fail from ${exportInfo.getFrom()} at ${exportInfo.getDeclaringArkFile().getFileSignature().toString()}`); } @@ -613,11 +630,12 @@ export function findArkExport(exportInfo: ExportInfo | undefined): ArkExport | n } export function findArkExportInFile(name: string, declaringArkFile: ArkFile): ArkExport | null { - let arkExport: ArkExport | undefined | null = declaringArkFile.getNamespaceWithName(name) - ?? declaringArkFile.getDefaultClass().getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name) - ?? declaringArkFile.getClassWithName(name) - ?? declaringArkFile.getDefaultClass().getMethodWithName(name) - ?? declaringArkFile.getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals().get(name); + let arkExport: ArkExport | undefined | null = + declaringArkFile.getNamespaceWithName(name) ?? + declaringArkFile.getDefaultClass().getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name) ?? + declaringArkFile.getClassWithName(name) ?? + declaringArkFile.getDefaultClass().getMethodWithName(name) ?? + declaringArkFile.getDefaultClass().getDefaultArkMethod()?.getBody()?.getExportLocalByName(name); if (!arkExport) { const importInfo = declaringArkFile.getImportInfoBy(name); @@ -639,7 +657,7 @@ function processSdkPath(sdk: Sdk, formPath: string): string { return `${formPath}`; } -function getArkFileFromScene(im: FromInfo, originPath: string) { +function getArkFileFromScene(im: FromInfo, originPath: string): ArkFile | null { if (FileUtils.isDirectory(originPath)) { originPath = path.join(originPath, FileUtils.getIndexFileName(originPath)); } @@ -670,8 +688,7 @@ function getArkFileFormMap(projectName: string, filePath: string, scene: Scene): return null; } - -function findExportInfoInfile(fromInfo: FromInfo, file: ArkFile) { +function findExportInfoInfile(fromInfo: FromInfo, file: ArkFile): ExportInfo | undefined { const exportName = fromInfo.isDefault() ? DEFAULT : fromInfo.getOriginName(); let exportInfo = file.getExportInfoBy(exportName); if (exportInfo) { @@ -690,8 +707,7 @@ function findExportInfoInfile(fromInfo: FromInfo, file: ArkFile) { exportInfo = buildDefaultExportInfo(fromInfo, file); file.addExportInfo(exportInfo, ALL); } else if (/\.d\.e?ts$/.test(file.getName())) { - let declare = exportName === DEFAULT ? undefined - : findArkExportInFile(fromInfo.getOriginName(), file) || undefined; + let declare = exportName === DEFAULT ? undefined : findArkExportInFile(fromInfo.getOriginName(), file) || undefined; exportInfo = buildDefaultExportInfo(fromInfo, file, declare); } @@ -705,10 +721,9 @@ export function initModulePathMap(ohPkgContentMap: Map): void { + private static sdkImportMap: Map = new Map(); + + public static buildSdkImportMap(file: ArkFile): void { const fileName = path.basename(file.getName()); if (fileName.startsWith('@')) { - sdkImportMap.set(fileName.replace(/\.d\.e?ts$/, ''), file); + this.sdkImportMap.set(fileName.replace(/\.d\.e?ts$/, ''), file); } + } + + public static getImportSdkFile(from: string): ArkFile | undefined { + return this.sdkImportMap.get(from); + } - const isGlobalPath = file.getScene().getOptions().sdkGlobalFolders - ?.find(x => file.getFilePath().includes(path.sep + x + path.sep)); + public static buildGlobalMap(file: ArkFile, globalMap: Map): void { + const isGlobalPath = file + .getScene() + .getOptions() + .sdkGlobalFolders?.find(x => file.getFilePath().includes(path.sep + x + path.sep)); if (!isGlobalPath) { return; } - IRInference.inferFile(file); ModelUtils.getAllClassesInFile(file).forEach(cls => { if (!cls.isAnonymousClass() && !cls.isDefaultArkClass()) { SdkUtils.loadClass(globalMap, cls); @@ -54,13 +63,22 @@ export class SdkUtils { } }); const defaultArkMethod = file.getDefaultClass().getDefaultArkMethod(); - defaultArkMethod?.getBody()?.getLocals().forEach(local => { - const name = local.getName(); - if (name !== THIS_NAME && !name.startsWith(TEMP_LOCAL_PREFIX)) { - this.loadGlobalLocal(local, defaultArkMethod, globalMap); - } - }); - defaultArkMethod?.getBody()?.getAliasTypeMap()?.forEach(a => globalMap.set(a[0].getName(), a[0])); + if (defaultArkMethod) { + TypeInference.inferTypeInMethod(defaultArkMethod); + } + defaultArkMethod + ?.getBody() + ?.getLocals() + .forEach(local => { + const name = local.getName(); + if (name !== THIS_NAME && !name.startsWith(TEMP_LOCAL_PREFIX)) { + this.loadGlobalLocal(local, defaultArkMethod, globalMap); + } + }); + defaultArkMethod + ?.getBody() + ?.getAliasTypeMap() + ?.forEach(a => globalMap.set(a[0].getName(), a[0])); ModelUtils.getAllNamespacesInFile(file).forEach(ns => globalMap.set(ns.getName(), ns)); } @@ -87,11 +105,13 @@ export class SdkUtils { const instance = globalMap.get(name + 'Interface'); const attr = globalMap.get(name + COMPONENT_ATTRIBUTE); if (attr instanceof ArkClass && instance instanceof ArkClass) { - instance.getMethods().filter(m => !attr.getMethodWithName(m.getName())).forEach(m => attr.addMethod(m)); + instance + .getMethods() + .filter(m => !attr.getMethodWithName(m.getName())) + .forEach(m => attr.addMethod(m)); globalMap.set(name, attr); return; } - } const old = globalMap.get(name); if (!old) { @@ -99,7 +119,10 @@ export class SdkUtils { } else if (old instanceof ArkClass && local.getType() instanceof ClassType) { const localConstructor = scene.getClass((local.getType() as ClassType).getClassSignature()); if (localConstructor) { - localConstructor.getMethods().filter(m => !old.getMethodWithName(m.getName())).forEach(m => old.addMethod(m)); + localConstructor + .getMethods() + .filter(m => !old.getMethodWithName(m.getName())) + .forEach(m => old.addMethod(m)); } } } @@ -119,9 +142,11 @@ export class SdkUtils { public static computeGlobalThis(leftOp: AbstractFieldRef, arkMethod: ArkMethod): void { const globalThis = arkMethod.getDeclaringArkFile().getScene().getSdkGlobal(GLOBAL_THIS_NAME); if (globalThis instanceof ArkNamespace) { - const exportInfo = new ExportInfo.Builder().exportClauseName(leftOp.getFieldName()) - .arkExport(new Local(leftOp.getFieldName(), leftOp.getType())).build(); + const exportInfo = new ExportInfo.Builder() + .exportClauseName(leftOp.getFieldName()) + .arkExport(new Local(leftOp.getFieldName(), leftOp.getType())) + .build(); globalThis.addExportInfo(exportInfo); } } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/StmtDefReplacer.ts b/ets2panda/linter/arkanalyzer/src/core/common/StmtDefReplacer.ts index e746072a67175a04679773b97e0e2fdfa07307f0..134cebf5fa48bd9d773693e52bf7894c9d116fbb 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/StmtDefReplacer.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/StmtDefReplacer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -42,5 +42,4 @@ export class StmtDefReplacer { stmt.setLeftOp(this.newDef); } } - -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/StmtUseReplacer.ts b/ets2panda/linter/arkanalyzer/src/core/common/StmtUseReplacer.ts index 051192098e605653bd8fdc8145eb51fc091b9832..82e743935c43dcc8e5a5179f5cff85d5dc708e01 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/StmtUseReplacer.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/StmtUseReplacer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -29,7 +29,7 @@ export class StmtUseReplacer { private newUse: Value; constructor(oldUse: Value, newUse: Value) { - this.oldUse = oldUse + this.oldUse = oldUse; this.newUse = newUse; } @@ -106,6 +106,4 @@ export class StmtUseReplacer { stmt.setOp(this.newUse); } } - - -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/TSConst.ts b/ets2panda/linter/arkanalyzer/src/core/common/TSConst.ts index 269c4107dade3992111e5fe41c7923f6e7ac551b..929711063de8c852b0ab5bd754a8f89b509cc51a 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/TSConst.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/TSConst.ts @@ -16,7 +16,7 @@ export const CONSTRUCTOR_NAME = 'constructor'; export const SUPER_NAME = 'super'; export const THIS_NAME = 'this'; -export const GLOBAL_THIS_NAME: string = 'globalThis' +export const GLOBAL_THIS_NAME: string = 'globalThis'; export const DEFAULT = 'default'; @@ -39,4 +39,3 @@ export const VOID_KEYWORD = 'void'; export const NEVER_KEYWORD = 'never'; export const BIGINT_KEYWORD = 'bigint'; export const TSCONFIG_JSON = 'tsconfig.json'; - diff --git a/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts b/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts index 44a3d0136f4dd0ccf2f3219a25a9c08747ca157e..e754272cbfd07f2cd1290ef386b91ac55e12fa2a 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts @@ -16,14 +16,7 @@ import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; import { AbstractExpr, ArkInstanceInvokeExpr, ArkPtrInvokeExpr, ArkStaticInvokeExpr } from '../base/Expr'; import { Local } from '../base/Local'; -import { - AbstractFieldRef, - AbstractRef, - ArkArrayRef, - ArkInstanceFieldRef, - ArkParameterRef, - ArkStaticFieldRef, -} from '../base/Ref'; +import { AbstractFieldRef, AbstractRef, ArkArrayRef, ArkInstanceFieldRef, ArkParameterRef, ArkStaticFieldRef } from '../base/Ref'; import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkReturnStmt, Stmt } from '../base/Stmt'; import { AliasType, @@ -33,6 +26,7 @@ import { BigIntType, BooleanType, ClassType, + EnumValueType, FunctionType, GenericType, IntersectionType, @@ -50,7 +44,7 @@ import { } from '../base/Type'; import { ArkMethod } from '../model/ArkMethod'; import { ArkExport } from '../model/ArkExport'; -import { ArkClass } from '../model/ArkClass'; +import { ArkClass, ClassCategory } from '../model/ArkClass'; import { ArkField } from '../model/ArkField'; import { Value } from '../base/Value'; import { Constant } from '../base/Constant'; @@ -86,14 +80,11 @@ import { ModifierType } from '../model/ArkBaseModel'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'TypeInference'); - export class TypeInference { - public static inferTypeInArkField(arkField: ArkField): void { const arkClass = arkField.getDeclaringArkClass(); const stmts = arkField.getInitializer(); - const method = arkClass.getMethodWithName(INSTANCE_INIT_METHOD_NAME) ?? - arkClass.getMethodWithName(CONSTRUCTOR_NAME); + const method = arkClass.getMethodWithName(INSTANCE_INIT_METHOD_NAME) ?? arkClass.getMethodWithName(CONSTRUCTOR_NAME); for (const stmt of stmts) { if (method) { this.resolveStmt(stmt, method); @@ -142,8 +133,7 @@ export class TypeInference { visited.add(leftOpType); } let type; - if (leftOpType instanceof ClassType && - leftOpType.getClassSignature().getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME) { + if (leftOpType instanceof ClassType && leftOpType.getClassSignature().getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME) { type = TypeInference.inferUnclearRefName(leftOpType.getClassSignature().getClassName(), declaringArkClass); } else if (leftOpType instanceof UnionType || leftOpType instanceof IntersectionType || leftOpType instanceof TupleType) { let types = leftOpType.getTypes(); @@ -184,9 +174,11 @@ export class TypeInference { signatures.push(impl); } signatures.forEach(s => { - s.getMethodSubSignature().getParameters().forEach(p => { - this.inferParameterType(p, arkMethod); - }); + s.getMethodSubSignature() + .getParameters() + .forEach(p => { + this.inferParameterType(p, arkMethod); + }); }); const body = arkMethod.getBody(); if (!body) { @@ -239,8 +231,10 @@ export class TypeInference { private static resolveExprsInStmt(stmt: Stmt, arkMethod: ArkMethod): void { for (const expr of stmt.getExprs()) { const newExpr = expr.inferType(arkMethod); - if (stmt.containsInvokeExpr() && ((expr instanceof ArkInstanceInvokeExpr && newExpr instanceof ArkStaticInvokeExpr) || - newExpr instanceof ArkPtrInvokeExpr)) { + if ( + stmt.containsInvokeExpr() && + ((expr instanceof ArkInstanceInvokeExpr && newExpr instanceof ArkStaticInvokeExpr) || newExpr instanceof ArkPtrInvokeExpr) + ) { stmt.replaceUse(expr, newExpr); } } @@ -269,8 +263,13 @@ export class TypeInference { } const stmtDef = stmt.getDef(); if (stmtDef && stmtDef instanceof AbstractRef) { - if (arkMethod.getName() === INSTANCE_INIT_METHOD_NAME && stmtDef instanceof ArkInstanceFieldRef && - stmtDef.getBase().getName() === THIS_NAME && arkMethod.getDeclaringArkClass().isAnonymousClass()) { + if ( + arkMethod.getName() === INSTANCE_INIT_METHOD_NAME && + stmtDef instanceof ArkInstanceFieldRef && + stmtDef.getBase().getName() === THIS_NAME && + arkMethod.getDeclaringArkClass().isAnonymousClass() && + stmtDef.getFieldName().indexOf('.') === -1 + ) { return; } const fieldRef = stmtDef.inferType(arkMethod); @@ -388,12 +387,15 @@ export class TypeInference { public static isUnclearType(type: Type | null | undefined): boolean { // TODO: For UnionType, IntersectionType and TupleType, it should recurse check every item of them. - if (!type || type instanceof UnknownType || type instanceof UnclearReferenceType - || type instanceof NullType || type instanceof UndefinedType) { + if (!type || type instanceof UnknownType || type instanceof UnclearReferenceType || type instanceof NullType || type instanceof UndefinedType) { return true; - } else if (type instanceof ClassType && (type.getClassSignature().getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME || - (type.getClassSignature().getDeclaringFileSignature().getFileName() === Builtin.DUMMY_FILE_NAME && - type.getRealGenericTypes()?.find(t => t instanceof GenericType)))) { + } else if ( + type instanceof ClassType && + (type.getClassSignature().getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME || + (type.getClassSignature().getClassName() === PROMISE && !type.getRealGenericTypes()) || + (type.getClassSignature().getDeclaringFileSignature().getFileName() === Builtin.DUMMY_FILE_NAME && + type.getRealGenericTypes()?.find(t => t instanceof GenericType))) + ) { return true; } else if (type instanceof UnionType || type instanceof IntersectionType || type instanceof TupleType) { return !!type.getTypes().find(t => this.hasUnclearReferenceType(t)); @@ -539,7 +541,9 @@ export class TypeInference { for (let returnValue of arkMethod.getReturnValues()) { const type = returnValue.getType(); if (type instanceof UnionType) { - type.flatType().filter(t => !TypeInference.isUnclearType(t)).forEach(t => typeMap.set(t.toString(), t)); + type.flatType() + .filter(t => !TypeInference.isUnclearType(t)) + .forEach(t => typeMap.set(t.toString(), t)); } else if (!TypeInference.isUnclearType(type)) { typeMap.set(type.toString(), type); } @@ -558,7 +562,7 @@ export class TypeInference { return null; } - public static inferGenericType(types: GenericType[] | undefined, arkClass: ArkClass) { + public static inferGenericType(types: GenericType[] | undefined, arkClass: ArkClass): void { types?.forEach(type => { const defaultType = type.getDefaultType(); if (defaultType instanceof UnclearReferenceType) { @@ -617,7 +621,7 @@ export class TypeInference { return EMPTY_STRING; }); if (i === 0) { - type = this.inferBaseType(name, arkClass); + type = singleNames.length > 1 ? this.inferBaseType(name, arkClass) : this.inferTypeByName(name, arkClass); } else if (type) { type = this.inferFieldType(type, name, arkClass)?.[1]; } @@ -626,7 +630,7 @@ export class TypeInference { } if (genericName) { const realTypes = genericName.split(',').map(generic => { - const realType = this.inferBaseType(generic, arkClass); + const realType = this.inferUnclearRefName(generic, arkClass); return realType ?? new UnclearReferenceType(generic); }); if (type instanceof ClassType) { @@ -657,8 +661,10 @@ export class TypeInference { } let propertyAndType: [any, Type] | null = null; if (baseType instanceof ClassType) { - if (fieldName === Builtin.ITERATOR_RESULT_VALUE && baseType.getClassSignature() - .getDeclaringFileSignature().getProjectName() === Builtin.DUMMY_PROJECT_NAME) { + if ( + fieldName === Builtin.ITERATOR_RESULT_VALUE && + baseType.getClassSignature().getDeclaringFileSignature().getProjectName() === Builtin.DUMMY_PROJECT_NAME + ) { const types = baseType.getRealGenericTypes(); if (types && types.length > 0) { return [null, types[0]]; @@ -689,7 +695,16 @@ export class TypeInference { const property = ModelUtils.findPropertyInClass(fieldName, arkClass); let propertyType: Type | null = null; if (property instanceof ArkField) { - propertyType = property.getType(); + if (arkClass.getCategory() === ClassCategory.ENUM) { + let constant; + const lastStmt = property.getInitializer().at(-1); + if (lastStmt instanceof ArkAssignStmt && lastStmt.getRightOp() instanceof Constant) { + constant = lastStmt.getRightOp() as Constant; + } + propertyType = new EnumValueType(property.getSignature(), constant); + } else { + propertyType = property.getType(); + } } else if (property) { propertyType = this.parseArkExport2Type(property); } @@ -714,22 +729,39 @@ export class TypeInference { if (SUPER_NAME === baseName) { return this.parseArkExport2Type(arkClass.getSuperClass()); } - const field = ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod() - ?.getBody()?.getLocals()?.get(baseName); + const field = ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getLocals()?.get(baseName); if (field && !this.isUnclearType(field.getType())) { return field.getType(); } - let arkExport: ArkExport | null = ModelUtils.getClassWithName(baseName, arkClass) - ?? ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(baseName) - ?? ModelUtils.getNamespaceWithName(baseName, arkClass) - ?? ModelUtils.getDefaultClass(arkClass)?.getMethodWithName(baseName) - ?? ModelUtils.getArkExportInImportInfoWithName(baseName, arkClass.getDeclaringArkFile()); + let arkExport: ArkExport | null = + ModelUtils.getClassWithName(baseName, arkClass) ?? + ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(baseName) ?? + ModelUtils.getNamespaceWithName(baseName, arkClass) ?? + ModelUtils.getDefaultClass(arkClass)?.getMethodWithName(baseName) ?? + ModelUtils.getArkExportInImportInfoWithName(baseName, arkClass.getDeclaringArkFile()); if (!arkExport && !arkClass.getDeclaringArkFile().getImportInfoBy(baseName)) { arkExport = arkClass.getDeclaringArkFile().getScene().getSdkGlobal(baseName); } return this.parseArkExport2Type(arkExport); } + public static inferTypeByName(typeName: string, arkClass: ArkClass): Type | null { + let arkExport: ArkExport | null = + ModelUtils.getClassWithName(typeName, arkClass) ?? + ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(typeName) ?? + ModelUtils.getArkExportInImportInfoWithName(typeName, arkClass.getDeclaringArkFile()); + if (arkExport instanceof ArkClass || arkExport instanceof AliasType) { + return this.parseArkExport2Type(arkExport); + } + if (!arkClass.getDeclaringArkFile().getImportInfoBy(typeName)) { + arkExport = arkClass.getDeclaringArkFile().getScene().getSdkGlobal(typeName); + } + if (arkExport instanceof ArkClass || arkExport instanceof AliasType) { + return this.parseArkExport2Type(arkExport); + } + return null; + } + public static inferRealGenericTypes(realTypes: Type[] | undefined, arkClass: ArkClass): void { if (!realTypes) { return; @@ -745,7 +777,6 @@ export class TypeInference { } } - public static inferDynamicImportType(from: string, arkClass: ArkClass): Type | null { const importInfo = new ImportInfo(); importInfo.setNameBeforeAs(ALL); @@ -755,7 +786,6 @@ export class TypeInference { return TypeInference.parseArkExport2Type(importInfo.getLazyExportInfo()?.getArkExport()); } - public static replaceTypeWithReal(type: Type, realTypes?: Type[], visited: Set = new Set()): Type { if (visited.has(type)) { return type; @@ -814,7 +844,6 @@ export class TypeInference { return aliasType; } - public static inferFunctionType(argType: FunctionType, paramSubSignature: MethodSubSignature | undefined, realTypes: Type[] | undefined): void { const returnType = argType.getMethodSignature().getMethodSubSignature().getReturnType(); const declareType = paramSubSignature?.getReturnType(); @@ -825,7 +854,10 @@ export class TypeInference { if (!params) { return; } - argType.getMethodSignature().getMethodSubSignature().getParameters() + argType + .getMethodSignature() + .getMethodSubSignature() + .getParameters() .filter(p => !p.getName().startsWith(LEXICAL_ENV_NAME_PREFIX)) .forEach((p, i) => { let type = params?.[i]?.getType(); @@ -850,5 +882,4 @@ export class TypeInference { IRInference.inferRightWithSdkType(returnType, stmt.getOp().getType(), arkMethod.getDeclaringArkClass()); } } - } diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ValueUtil.ts b/ets2panda/linter/arkanalyzer/src/core/common/ValueUtil.ts index 9247f8f4db59601d5b13a665c9854c3507a16f79..1731b701b04d71d60c4e12b93931b2c9ec0547aa 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/ValueUtil.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/ValueUtil.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,15 +13,7 @@ * limitations under the License. */ -import { - BigIntConstant, - BooleanConstant, - Constant, - NullConstant, - NumberConstant, - StringConstant, - UndefinedConstant, -} from '../base/Constant'; +import { BigIntConstant, BooleanConstant, Constant, NullConstant, NumberConstant, StringConstant, UndefinedConstant } from '../base/Constant'; export const EMPTY_STRING = ''; @@ -68,4 +60,4 @@ export class ValueUtil { public static getBooleanConstant(value: boolean): Constant { return BooleanConstant.getInstance(value); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/VisibleValue.ts b/ets2panda/linter/arkanalyzer/src/core/common/VisibleValue.ts index 658042681072f2aa699a09d558367cdd8ba5721c..762f02592e50211b74c82e9b72a6f9af3230735f 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/VisibleValue.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/VisibleValue.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -58,7 +58,6 @@ export class VisibleValue { } logger.info('---- into scope:{', name, '}'); - // get values in this scope let values: Value[] = []; if (model instanceof ArkFile || model instanceof ArkNamespace) { @@ -99,7 +98,6 @@ export class VisibleValue { this.deleteScope(targetDepth); } - /** clear up previous scope */ private deleteScope(targetDepth: number): void { const prevDepth = this.currScope.depth; @@ -118,7 +116,7 @@ export class VisibleValue { } this.scopeChain.splice(this.scopeChain.length - popScopeCnt, popScopeCnt)[0]; // popScopeCnt >= 1 - this.currScope = this.scopeChain[this.scopeChain.length - 1] + this.currScope = this.scopeChain[this.scopeChain.length - 1]; const totalValuesCnt = this.currVisibleValues.length; this.currVisibleValues.splice(totalValuesCnt - popScopeValuesCnt, popScopeValuesCnt); } @@ -143,13 +141,13 @@ export class VisibleValue { } else { targetDepth = prevDepth; } - } else if ((model instanceof ArkFile) && (prevModel instanceof ArkFile)) { + } else if (model instanceof ArkFile && prevModel instanceof ArkFile) { targetDepth = prevDepth; - } else if ((model instanceof ArkNamespace) && (prevModel instanceof ArkNamespace)) { + } else if (model instanceof ArkNamespace && prevModel instanceof ArkNamespace) { targetDepth = prevDepth; - } else if ((model instanceof ArkClass) && (prevModel instanceof ArkClass)) { + } else if (model instanceof ArkClass && prevModel instanceof ArkClass) { targetDepth = prevDepth; - } else if ((model instanceof ArkMethod) && (prevModel instanceof ArkMethod)) { + } else if (model instanceof ArkMethod && prevModel instanceof ArkMethod) { targetDepth = prevDepth; } return targetDepth; @@ -160,7 +158,6 @@ export class VisibleValue { return values; } - private getVisibleValuesIntoClass(cls: ArkClass): Value[] { const values: Value[] = []; const fields = cls.getFields(); @@ -193,7 +190,6 @@ export class VisibleValue { } } - type ArkModel = ArkFile | ArkNamespace | ArkClass | ArkMethod | BasicBlock; export class Scope { @@ -205,4 +201,4 @@ export class Scope { this.depth = depth; this.arkModel = arkModel; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowProblem.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowProblem.ts index b18d1efe48d0b4d495e1638ed42bae00dd360e8b..f877a1be0eb5a041a60931f74aa391db77c3474e 100644 --- a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowProblem.ts +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowProblem.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -17,10 +17,9 @@ import { Stmt } from '../base/Stmt'; import { ArkMethod } from '../model/ArkMethod'; export abstract class DataflowProblem { - /** * Transfer the outFact of srcStmt to the inFact of tgtStmt - * + * * Return true if keeping progagation (i.e., tgtStmt will be added to the WorkList for further analysis) */ /* @@ -33,23 +32,23 @@ export abstract class DataflowProblem { abstract transferReturnEdge(srcStmt: Stmt, tgtStmt: Stmt, result: DataflowResult): boolean; */ - abstract getNormalFlowFunction(srcStmt:Stmt, tgtStmt:Stmt) : FlowFunction; + abstract getNormalFlowFunction(srcStmt: Stmt, tgtStmt: Stmt): FlowFunction; - abstract getCallFlowFunction(srcStmt:Stmt, method:ArkMethod) : FlowFunction; + abstract getCallFlowFunction(srcStmt: Stmt, method: ArkMethod): FlowFunction; - abstract getExitToReturnFlowFunction(srcStmt:Stmt, tgtStmt:Stmt, callStmt:Stmt) : FlowFunction; + abstract getExitToReturnFlowFunction(srcStmt: Stmt, tgtStmt: Stmt, callStmt: Stmt): FlowFunction; - abstract getCallToReturnFlowFunction(srcStmt:Stmt, tgtStmt:Stmt) : FlowFunction; + abstract getCallToReturnFlowFunction(srcStmt: Stmt, tgtStmt: Stmt): FlowFunction; - abstract createZeroValue() : D; + abstract createZeroValue(): D; - abstract getEntryPoint() : Stmt; + abstract getEntryPoint(): Stmt; - abstract getEntryMethod() : ArkMethod; + abstract getEntryMethod(): ArkMethod; abstract factEqual(d1: D, d2: D): boolean; } -export interface FlowFunction { - getDataFacts(d:D) : Set; -} \ No newline at end of file +export interface FlowFunction { + getDataFacts(d: D): Set; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowResult.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowResult.ts index 6a26568ddf181f9e5466cde2640e4d36833ac444..d01d56d46aa907ce971a28496066daf0d6f02204 100644 --- a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowResult.ts +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowResult.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -22,4 +22,4 @@ export class DataflowResult { //should we specifically keep global facts or just embedding them into the two maps above globalFacts: Set = new Set(); -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowSolver.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowSolver.ts index ef55d3354cde33ccdb2417f5c4ca47d79d8933e9..523dd9a41b17104bc1b850c060e8a50fd796ba03 100644 --- a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowSolver.ts +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowSolver.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -37,7 +37,6 @@ it have several improvments: type CallToReturnCacheEdge = PathEdge; export abstract class DataflowSolver { - protected problem: DataflowProblem; protected workList: Array>; protected pathEdgeSet: Set>; @@ -63,7 +62,7 @@ export abstract class DataflowSolver { this.stmtNexts = new Map(); } - public solve() { + public solve(): void { this.init(); this.doSolve(); } @@ -81,21 +80,21 @@ export abstract class DataflowSolver { return Array.from(this.stmtNexts.get(stmt) || []); } - protected init() { + protected init(): void { let edgePoint: PathEdgePoint = new PathEdgePoint(this.problem.getEntryPoint(), this.zeroFact); let edge: PathEdge = new PathEdge(edgePoint, edgePoint); this.workList.push(edge); this.pathEdgeSet.add(edge); // build CHA - let cg = new CallGraph(this.scene) - this.CHA = new ClassHierarchyAnalysis(this.scene, cg) + let cg = new CallGraph(this.scene); + this.CHA = new ClassHierarchyAnalysis(this.scene, cg); this.buildStmtMapInClass(); this.setCfg4AllStmt(); return; } - protected buildStmtMapInClass() { + protected buildStmtMapInClass(): void { const methods = this.scene.getMethods(); methods.push(this.problem.getEntryMethod()); for (const method of methods) { @@ -126,7 +125,7 @@ export abstract class DataflowSolver { } } - protected setCfg4AllStmt() { + protected setCfg4AllStmt(): void { for (const cls of this.scene.getClasses()) { for (const mtd of cls.getMethods(true)) { addCfg2Stmt(mtd); @@ -136,7 +135,9 @@ export abstract class DataflowSolver { protected getAllCalleeMethods(callNode: ArkInvokeStmt): Set { const callSites = this.CHA.resolveCall( - this.CHA.getCallGraph().getCallGraphNodeByMethod(this.problem.getEntryMethod().getSignature()).getID(), callNode); + this.CHA.getCallGraph().getCallGraphNodeByMethod(this.problem.getEntryMethod().getSignature()).getID(), + callNode + ); const methods: Set = new Set(); for (const callSite of callSites) { const method = this.scene.getMethod(this.CHA.getCallGraph().getMethodByFuncID(callSite.calleeFuncID)!); @@ -157,18 +158,22 @@ export abstract class DataflowSolver { return [...cfg.getBlocks()][0].getStmts()[paraNum]; } - protected pathEdgeSetHasEdge(edge: PathEdge) { + protected pathEdgeSetHasEdge(edge: PathEdge): boolean { for (const path of this.pathEdgeSet) { this.problem.factEqual(path.edgeEnd.fact, edge.edgeEnd.fact); - if (path.edgeEnd.node === edge.edgeEnd.node && this.problem.factEqual(path.edgeEnd.fact, edge.edgeEnd.fact) && - path.edgeStart.node === edge.edgeStart.node && this.problem.factEqual(path.edgeStart.fact, edge.edgeStart.fact)) { + if ( + path.edgeEnd.node === edge.edgeEnd.node && + this.problem.factEqual(path.edgeEnd.fact, edge.edgeEnd.fact) && + path.edgeStart.node === edge.edgeStart.node && + this.problem.factEqual(path.edgeStart.fact, edge.edgeStart.fact) + ) { return true; } } return false; } - protected propagate(edge: PathEdge) { + protected propagate(edge: PathEdge): void { if (!this.pathEdgeSetHasEdge(edge)) { let index = this.workList.length; for (let i = 0; i < this.workList.length; i++) { @@ -182,7 +187,7 @@ export abstract class DataflowSolver { } } - protected processExitNode(edge: PathEdge) { + protected processExitNode(edge: PathEdge): void { let startEdgePoint: PathEdgePoint = edge.edgeStart; let exitEdgePoint: PathEdgePoint = edge.edgeEnd; const summary = this.endSummary.get(startEdgePoint); @@ -205,8 +210,7 @@ export abstract class DataflowSolver { } } - private handleFacts(returnFlowFunc: FlowFunction, returnSite: Stmt, - exitEdgePoint: PathEdgePoint, callEdgePoint: PathEdgePoint): void { + private handleFacts(returnFlowFunc: FlowFunction, returnSite: Stmt, exitEdgePoint: PathEdgePoint, callEdgePoint: PathEdgePoint): void { for (let fact of returnFlowFunc.getDataFacts(exitEdgePoint.fact)) { let returnSitePoint: PathEdgePoint = new PathEdgePoint(returnSite, fact); let cacheEdge: CallToReturnCacheEdge = new PathEdge(callEdgePoint, returnSitePoint); @@ -230,7 +234,7 @@ export abstract class DataflowSolver { } } - protected processNormalNode(edge: PathEdge) { + protected processNormalNode(edge: PathEdge): void { let start: PathEdgePoint = edge.edgeStart; let end: PathEdgePoint = edge.edgeEnd; let stmts: Stmt[] = [...this.getChildren(end.node)].reverse(); @@ -239,14 +243,14 @@ export abstract class DataflowSolver { let set: Set = flowFunction.getDataFacts(end.fact); for (let fact of set) { let edgePoint: PathEdgePoint = new PathEdgePoint(stmt, fact); - const edge = new PathEdge(start, edgePoint) + const edge = new PathEdge(start, edgePoint); this.propagate(edge); this.laterEdges.add(edge); } } } - protected processCallNode(edge: PathEdge) { + protected processCallNode(edge: PathEdge): void { let start: PathEdgePoint = edge.edgeStart; let callEdgePoint: PathEdgePoint = edge.edgeEnd; const invokeStmt = callEdgePoint.node as ArkInvokeStmt; @@ -312,7 +316,7 @@ export abstract class DataflowSolver { } } - protected doSolve() { + protected doSolve(): void { while (this.workList.length !== 0) { let pathEdge: PathEdge = this.workList.shift()!; if (this.laterEdges.has(pathEdge)) { diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/Edge.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/Edge.ts index c758713bcb9868df4ef0e07ade156b75befca0ba..8f37f08ab0751ef36ea007e74f977c259f5b979a 100644 --- a/ets2panda/linter/arkanalyzer/src/core/dataflow/Edge.ts +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/Edge.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -16,21 +16,21 @@ import { Stmt } from '../base/Stmt'; export class PathEdgePoint { - public node:Stmt; - public fact:D; + public node: Stmt; + public fact: D; - constructor(node:Stmt, fact:D){ + constructor(node: Stmt, fact: D) { this.node = node; this.fact = fact; } } export class PathEdge { - public edgeStart:PathEdgePoint; - public edgeEnd:PathEdgePoint; + public edgeStart: PathEdgePoint; + public edgeEnd: PathEdgePoint; - constructor(start:PathEdgePoint, end:PathEdgePoint) { - this.edgeStart=start; - this.edgeEnd=end; + constructor(start: PathEdgePoint, end: PathEdgePoint) { + this.edgeStart = start; + this.edgeEnd = end; } } diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/Fact.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/Fact.ts index 0e8eea6ca0f3fdc1f68ca05765d9f5a04ffd7777..accc0b13e0bcb0259c63042a7e60f6505d6c6674 100644 --- a/ets2panda/linter/arkanalyzer/src/core/dataflow/Fact.ts +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/Fact.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -18,5 +18,5 @@ import { Stmt } from '../base/Stmt'; export class Fact { values: Set = new Set(); - valueMap: Map = new Map(); // 用最近的def代表value的值 -} \ No newline at end of file + valueMap: Map = new Map(); // 用最近的def代表value的值 +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/GenericDataFlow.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/GenericDataFlow.ts index 1c921878667f1c45d482d875a5ac4a08f0a39860..a6b4e50d733e67e0a845ab61ea3cfeaf8c5490c8 100644 --- a/ets2panda/linter/arkanalyzer/src/core/dataflow/GenericDataFlow.ts +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/GenericDataFlow.ts @@ -15,12 +15,12 @@ /** * Generic Data Flow Analysis Framework - * + * * This module provides a generic framework for implementing data flow analyses, * such as Reaching Definitions, Live Variables, and Available Expressions. * The framework is designed to be flexible and extensible, allowing users to * define custom flow graphs, transfer functions, and meet operations. - * + * * Design Notes: * - The framework is designed to be generic and reusable, allowing users to * implement custom data flow analyses by defining appropriate transfer functions @@ -28,7 +28,7 @@ * - The solver uses a worklist algorithm to efficiently compute the MFP solution. * - The analysis can be configured as either forward or backward, depending on * the problem requirements. - * + * */ /** @@ -168,11 +168,11 @@ export class MFPDataFlowSolver { while (workList.length > 0) { newEntries.clear(); - workList.forEach((n) => { + workList.forEach(n => { let inSet: V | undefined; const predecessors = problem.flowGraph.pred(n); if (predecessors && predecessors.length > 0) { - const predecessorOuts = predecessors.map((pred) => _out.get(pred)); + const predecessorOuts = predecessors.map(pred => _out.get(pred)); inSet = predecessorOuts.reduce((acc, cur) => problem.meet(acc!, cur!), problem.empty); } else { inSet = problem.empty; @@ -184,7 +184,7 @@ export class MFPDataFlowSolver { if (!old || old.count() === 0 || !old.equals(newSet)) { _out.set(n, newSet); - problem.flowGraph.succ(n).forEach((succ) => newEntries.add(succ)); + problem.flowGraph.succ(n).forEach(succ => newEntries.add(succ)); } }); @@ -210,7 +210,7 @@ export class MFPDataFlowSolver { while (workList.length > 0) { newEntries.clear(); - workList.forEach((n) => { + workList.forEach(n => { let outSet: T = problem.flowGraph.succ(n).reduce((acc, curr) => { return problem.meet(acc, _in.get(curr)!); }, problem.empty); @@ -220,7 +220,7 @@ export class MFPDataFlowSolver { let newSet: T = problem.transferFunction.apply(n, outSet); if (!old || !old.equals(newSet)) { _in.set(n, newSet); - problem.flowGraph.pred(n).forEach((pred) => newEntries.add(pred)); + problem.flowGraph.pred(n).forEach(pred => newEntries.add(pred)); } }); @@ -229,4 +229,4 @@ export class MFPDataFlowSolver { return new Solution(_in, _out, problem); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/ReachingDef.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/ReachingDef.ts index da681fd84544adee73d8b1833420dbee6b16dc69..b9b491e6972b08f45a2f051686b6ecd61cf424cd 100644 --- a/ets2panda/linter/arkanalyzer/src/core/dataflow/ReachingDef.ts +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/ReachingDef.ts @@ -15,25 +15,25 @@ /** * Reaching Definitions Data Flow Analysis - * + * * This module implements the Reaching Definitions data flow analysis algorithm. * Reaching Definitions is a forward data flow analysis that determines, for each * program point, the set of variable definitions (assignments) that may reach * that point without being overwritten. - * + * * Key Components: * 1. **Transfer Function**: * - Computes the out set for each node based on its in set. * - Uses gen and kill sets to model the effects of assignments: * - **gen**: The set of definitions generated by the current node. * - **kill**: The set of definitions killed (overwritten) by the current node. - * + * * 2. **Meet Operation**: * - Combines data flow values from multiple paths (e.g., union for reaching definitions). * - Ensures that the analysis is conservative (safe) by over-approximating the result. - * + * * The analysis is forward, meaning it propagates information from predecessors to successors. - * + * */ import { ArkAssignStmt, Stmt } from '../base/Stmt'; @@ -66,8 +66,8 @@ export class ReachingDefProblem implements DataFlowProblem [i, new coCtor(BV_SIZE)])); - this.initOut = new Map(this.flowGraph.nodesInPostOrder.map((i) => [i, new coCtor(BV_SIZE)])); + this.initIn = new Map(this.flowGraph.nodesInPostOrder.map(i => [i, new coCtor(BV_SIZE)])); + this.initOut = new Map(this.flowGraph.nodesInPostOrder.map(i => [i, new coCtor(BV_SIZE)])); this.forward = forward; } } @@ -107,7 +107,7 @@ class ReachingDefFlowGraph extends BaseImplicitGraph implements FlowGrap this.succMap = new Map(); this.predMap = new Map(); - cfg.getBlocks().forEach((bb) => { + cfg.getBlocks().forEach(bb => { let stmts = bb.getStmts(); if (stmts.length === 0) { return; @@ -128,7 +128,13 @@ class ReachingDefFlowGraph extends BaseImplicitGraph implements FlowGrap throw new Error('cfg has no terminal'); } - bb.getSuccessors().forEach((succBB) => { + let successors = bb.getSuccessors(); + // try...catch语句,catch所在的block在CFG表示里是没有前驱block的,需要在这里额外查找并将exceptionalSuccessorBlocks作为try块的后继块之一 + const exceptionalSuccessorBlocks = bb.getExceptionalSuccessorBlocks(); + if (exceptionalSuccessorBlocks !== undefined) { + successors.push(...exceptionalSuccessorBlocks); + } + successors.forEach(succBB => { let head = succBB.getHead(); if (!head) { return; @@ -202,4 +208,4 @@ export class ReachingDefTransferFunction implements TransferFunction { classMap: Map; globalVariableMap: Map; outcomes: Outcome[] = []; - constructor(stmt: Stmt, method: ArkMethod){ + constructor(stmt: Stmt, method: ArkMethod) { super(); this.entryPoint = stmt; this.entryMethod = method; @@ -68,21 +68,21 @@ export class UndefinedVariableChecker extends DataflowProblem { return false; } - getNormalFlowFunction(srcStmt:Stmt, tgtStmt:Stmt): FlowFunction { + getNormalFlowFunction(srcStmt: Stmt, tgtStmt: Stmt): FlowFunction { let checkerInstance: UndefinedVariableChecker = this; - return new class implements FlowFunction { + return new (class implements FlowFunction { getDataFacts(dataFact: Value): Set { let ret: Set = new Set(); if (checkerInstance.getEntryPoint() === srcStmt && checkerInstance.getZeroValue() === dataFact) { ret.add(checkerInstance.getZeroValue()); return ret; } - if (srcStmt instanceof ArkAssignStmt ) { + if (srcStmt instanceof ArkAssignStmt) { checkerInstance.insideNormalFlowFunction(ret, srcStmt, dataFact); } return ret; } - } + })(); } insideNormalFlowFunction(ret: Set, srcStmt: ArkAssignStmt, dataFact: Value): void { @@ -91,7 +91,7 @@ export class UndefinedVariableChecker extends DataflowProblem { ret.add(dataFact); } } - let ass: ArkAssignStmt = (srcStmt as ArkAssignStmt); + let ass: ArkAssignStmt = srcStmt as ArkAssignStmt; let assigned: Value = ass.getLeftOp(); let rightOp: Value = ass.getRightOp(); if (this.getZeroValue() === dataFact) { @@ -102,7 +102,7 @@ export class UndefinedVariableChecker extends DataflowProblem { ret.add(assigned); } else if (rightOp instanceof ArkInstanceFieldRef) { const base = rightOp.getBase(); - if (base === dataFact || !base.getDeclaringStmt() && base.getName() === dataFact.toString()) { + if (base === dataFact || (!base.getDeclaringStmt() && base.getName() === dataFact.toString())) { this.outcomes.push(new Outcome(rightOp, ass)); logger.info('undefined base'); logger.info(srcStmt.toString()); @@ -114,27 +114,38 @@ export class UndefinedVariableChecker extends DataflowProblem { } } - getCallFlowFunction(srcStmt:Stmt, method:ArkMethod): FlowFunction { + getCallFlowFunction(srcStmt: Stmt, method: ArkMethod): FlowFunction { let checkerInstance: UndefinedVariableChecker = this; - return new class implements FlowFunction { + return new (class implements FlowFunction { getDataFacts(dataFact: Value): Set { const ret: Set = new Set(); if (checkerInstance.getZeroValue() === dataFact) { checkerInstance.insideCallFlowFunction(ret, method); } else { const callExpr = srcStmt.getExprs()[0]; - if (callExpr instanceof ArkInstanceInvokeExpr && dataFact instanceof ArkInstanceFieldRef && callExpr.getBase().getName() === dataFact.getBase().getName()) { + if ( + callExpr instanceof ArkInstanceInvokeExpr && + dataFact instanceof ArkInstanceFieldRef && + callExpr.getBase().getName() === dataFact.getBase().getName() + ) { // todo:base转this - const thisRef = new ArkInstanceFieldRef(new Local('this', new ClassType(method.getDeclaringArkClass().getSignature())), dataFact.getFieldSignature()); + const thisRef = new ArkInstanceFieldRef( + new Local('this', new ClassType(method.getDeclaringArkClass().getSignature())), + dataFact.getFieldSignature() + ); ret.add(thisRef); - } else if (callExpr instanceof ArkStaticInvokeExpr && dataFact instanceof ArkStaticFieldRef && callExpr.getMethodSignature().getDeclaringClassSignature() === dataFact.getFieldSignature().getDeclaringSignature()) { + } else if ( + callExpr instanceof ArkStaticInvokeExpr && + dataFact instanceof ArkStaticFieldRef && + callExpr.getMethodSignature().getDeclaringClassSignature() === dataFact.getFieldSignature().getDeclaringSignature() + ) { ret.add(dataFact); } } checkerInstance.addParameters(srcStmt, dataFact, method, ret); return ret; } - } + })(); } insideCallFlowFunction(ret: Set, method: ArkMethod): void { @@ -175,7 +186,7 @@ export class UndefinedVariableChecker extends DataflowProblem { const callStmt = srcStmt as ArkInvokeStmt; const args = callStmt.getInvokeExpr().getArgs(); for (let i = 0; i < args.length; i++) { - if (args[i] === dataFact || this.isUndefined(args[i]) && this.getZeroValue() === dataFact) { + if (args[i] === dataFact || (this.isUndefined(args[i]) && this.getZeroValue() === dataFact)) { const realParameter = [...method.getCfg()!.getBlocks()][0].getStmts()[i].getDef(); if (realParameter) { ret.add(realParameter); @@ -190,9 +201,9 @@ export class UndefinedVariableChecker extends DataflowProblem { } } - getExitToReturnFlowFunction(srcStmt:Stmt, tgtStmt:Stmt, callStmt:Stmt): FlowFunction { + getExitToReturnFlowFunction(srcStmt: Stmt, tgtStmt: Stmt, callStmt: Stmt): FlowFunction { let checkerInstance: UndefinedVariableChecker = this; - return new class implements FlowFunction { + return new (class implements FlowFunction { getDataFacts(dataFact: Value): Set { let ret: Set = new Set(); if (dataFact === checkerInstance.getZeroValue()) { @@ -200,15 +211,14 @@ export class UndefinedVariableChecker extends DataflowProblem { } return ret; } - - } + })(); } - getCallToReturnFlowFunction(srcStmt:Stmt, tgtStmt:Stmt): FlowFunction { + getCallToReturnFlowFunction(srcStmt: Stmt, tgtStmt: Stmt): FlowFunction { let checkerInstance: UndefinedVariableChecker = this; - return new class implements FlowFunction { + return new (class implements FlowFunction { getDataFacts(dataFact: Value): Set { - const ret:Set = new Set(); + const ret: Set = new Set(); if (checkerInstance.getZeroValue() === dataFact) { ret.add(checkerInstance.getZeroValue()); } @@ -218,8 +228,7 @@ export class UndefinedVariableChecker extends DataflowProblem { } return ret; } - - } + })(); } createZeroValue(): Value { @@ -247,12 +256,11 @@ export class UndefinedVariableChecker extends DataflowProblem { } export class UndefinedVariableSolver extends DataflowSolver { - constructor(problem: UndefinedVariableChecker, scene: Scene){ + constructor(problem: UndefinedVariableChecker, scene: Scene) { super(problem, scene); } } - class Outcome { value: Value; stmt: Stmt; @@ -260,4 +268,4 @@ class Outcome { this.value = v; this.stmt = s; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/Util.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/Util.ts index 8bb2346eb6ec428cedd549d094147390fdb75325..34ca4323dfd4d7ee46796de6fdc1a8fdb21c760d 100644 --- a/ets2panda/linter/arkanalyzer/src/core/dataflow/Util.ts +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/Util.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,24 +13,21 @@ * limitations under the License. */ -import { ArkInvokeStmt } from "../base/Stmt"; -import { FunctionType } from "../base/Type"; -import { ArkMethod } from "../model/ArkMethod"; -import { Local } from "../base/Local"; -import { AbstractRef, ArkStaticFieldRef, ArkInstanceFieldRef } from "../base/Ref"; +import { ArkInvokeStmt } from '../base/Stmt'; +import { FunctionType } from '../base/Type'; +import { ArkMethod } from '../model/ArkMethod'; +import { Local } from '../base/Local'; +import { AbstractRef, ArkStaticFieldRef, ArkInstanceFieldRef } from '../base/Ref'; - -export const INTERNAL_PARAMETER_SOURCE: string[] = [ - '@ohos.app.ability.Want.d.ts: Want' -] +export const INTERNAL_PARAMETER_SOURCE: string[] = ['@ohos.app.ability.Want.d.ts: Want']; export const INTERNAL_SINK_METHOD: string[] = [ 'console.<@%unk/%unk: .log()>', 'console.<@%unk/%unk: .error()>', 'console.<@%unk/%unk: .info()>', 'console.<@%unk/%unk: .warn()>', - 'console.<@%unk/%unk: .assert()>' -] + 'console.<@%unk/%unk: .assert()>', +]; export function getRecallMethodInParam(stmt: ArkInvokeStmt): ArkMethod | null { for (const param of stmt.getInvokeExpr().getArgs()) { @@ -45,7 +42,6 @@ export function getRecallMethodInParam(stmt: ArkInvokeStmt): ArkMethod | null { return null; } - export function LocalEqual(local1: Local, local2: Local): boolean { if (local1.getName() === 'this' && local2.getName() === 'this') { return true; @@ -63,4 +59,4 @@ export function RefEqual(ref1: AbstractRef, ref2: AbstractRef): boolean { return LocalEqual(ref1.getBase(), ref2.getBase()) && ref1.getFieldSignature().toString() === ref2.getFieldSignature().toString(); } return false; -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/BaseExplicitGraph.ts b/ets2panda/linter/arkanalyzer/src/core/graph/BaseExplicitGraph.ts index 5823fec53649b39feaa8e5ac29128e6c75b4cca5..fc55eb7e989930622539e9feb4db434354a10db5 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/BaseExplicitGraph.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/BaseExplicitGraph.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -15,7 +15,7 @@ import { Kind, NodeID, GraphTraits } from './GraphTraits'; -export {Kind, NodeID}; +export { Kind, NodeID }; export abstract class BaseEdge { private src: BaseNode; private dst: BaseNode; diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/BaseImplicitGraph.ts b/ets2panda/linter/arkanalyzer/src/core/graph/BaseImplicitGraph.ts index 671b642c4c20ee1d5e2651e6ee4c30836aed47f6..8eb3556425baf36bee2bfb76cc2e209fe5db1316 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/BaseImplicitGraph.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/BaseImplicitGraph.ts @@ -88,7 +88,6 @@ export abstract class BaseImplicitGraph implements GraphTraits { } return this.nodeToIdMap.get(s)!; - } /** @@ -137,4 +136,4 @@ export abstract class BaseImplicitGraph implements GraphTraits { * @returns The name of the graph. */ public abstract getGraphName(): string; -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/BasicBlock.ts b/ets2panda/linter/arkanalyzer/src/core/graph/BasicBlock.ts index dd9ee3b6d83d1ec85c9789177acb1cff5699483d..f8487e4e1221dd312bd115ee0e33ba464ec80412 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/BasicBlock.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/BasicBlock.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -202,7 +202,7 @@ export class BasicBlock { } // Temp just for SSA - public addStmtToFirst(stmt: Stmt) { + public addStmtToFirst(stmt: Stmt): void { this.addHead(stmt); } @@ -240,28 +240,30 @@ export class BasicBlock { public validate(): ArkError { let branchStmts: Stmt[] = []; for (const stmt of this.stmts) { - if ( - stmt instanceof ArkIfStmt || - stmt instanceof ArkReturnStmt || - stmt instanceof ArkReturnVoidStmt - ) { + if (stmt instanceof ArkIfStmt || stmt instanceof ArkReturnStmt || stmt instanceof ArkReturnVoidStmt) { branchStmts.push(stmt); } } if (branchStmts.length > 1) { - let errMsg = `More than one branch or return stmts in the block: ${branchStmts.map((value) => value.toString()).join('\n')}`; + let errMsg = `More than one branch or return stmts in the block: ${branchStmts.map(value => value.toString()).join('\n')}`; logger.error(errMsg); - return {errCode: ArkErrorCode.BB_MORE_THAN_ONE_BRANCH_RET_STMT, errMsg: errMsg }; + return { + errCode: ArkErrorCode.BB_MORE_THAN_ONE_BRANCH_RET_STMT, + errMsg: errMsg, + }; } if (branchStmts.length === 1 && branchStmts[0] !== this.stmts[this.stmts.length - 1]) { let errMsg = `${branchStmts[0].toString()} not at the end of block.`; logger.error(errMsg); - return {errCode: ArkErrorCode.BB_BRANCH_RET_STMT_NOT_AT_END, errMsg: errMsg}; + return { + errCode: ArkErrorCode.BB_BRANCH_RET_STMT_NOT_AT_END, + errMsg: errMsg, + }; } - return {errCode: ArkErrorCode.OK}; + return { errCode: ArkErrorCode.OK }; } private insertPos(index: number, toInsert: Stmt | Stmt[]): number { diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts b/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts index 34707934632f22ea4ca122f6ee4f985deee97d0c..4ef2fadcaf347b848862c8e586dc20911828d8fb 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -139,7 +139,7 @@ export class Cfg { return this.declaringMethod; } - public setDeclaringMethod(method: ArkMethod) { + public setDeclaringMethod(method: ArkMethod): void { this.declaringMethod = method; } @@ -258,26 +258,28 @@ export class Cfg { if (!startBB) { let errMsg = `Not found starting block}`; logger.error(errMsg); - return { errCode: ArkErrorCode.CFG_NOT_FOUND_START_BLOCK, errMsg: errMsg }; + return { + errCode: ArkErrorCode.CFG_NOT_FOUND_START_BLOCK, + errMsg: errMsg, + }; } let unreachable = this.getUnreachableBlocks(); if (unreachable.size !== 0) { let errMsg = `Unreachable blocks: ${Array.from(unreachable) - .map((value) => value.toString()) + .map(value => value.toString()) .join('\n')}`; logger.error(errMsg); - return { errCode: ArkErrorCode.CFG_HAS_UNREACHABLE_BLOCK, errMsg: errMsg }; + return { + errCode: ArkErrorCode.CFG_HAS_UNREACHABLE_BLOCK, + errMsg: errMsg, + }; } return { errCode: ArkErrorCode.OK }; } - private dfsPostOrder( - node: BasicBlock, - visitor: Set = new Set(), - postOrder: Set = new Set() - ): Set { + private dfsPostOrder(node: BasicBlock, visitor: Set = new Set(), postOrder: Set = new Set()): Set { visitor.add(node); for (const succ of node.getSuccessors()) { if (visitor.has(succ)) { diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/DependsGraph.ts b/ets2panda/linter/arkanalyzer/src/core/graph/DependsGraph.ts index e4cab5ac971fe80f431437c5ef2ff1a9a1fa0cd1..dc3f40e69d0aa9c011acab21e5790ddb738bfb02 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/DependsGraph.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/DependsGraph.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -97,11 +97,7 @@ export class DependsGraph, - dst: DependsNode, - attr: EdgeAttr - ): DependsEdge { + public addEdge(src: DependsNode, dst: DependsNode, attr: EdgeAttr): DependsEdge { let edge = new DependsEdge(src, dst, attr); let key = edge.getKey(); if (this.edgesMap.has(key)) { diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/DominanceFinder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/DominanceFinder.ts index a3cd26a2362d56aed091b7d969108467f4c54135..08afcef3be19921d3b6f6883a312a16bf37479d7 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/DominanceFinder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/DominanceFinder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -18,7 +18,7 @@ import { Cfg } from './Cfg'; export class DominanceFinder { private blocks: BasicBlock[] = []; - private blockToIdx = new Map; + private blockToIdx = new Map(); private idoms: number[] = []; private domFrontiers: number[][] = []; @@ -51,7 +51,7 @@ export class DominanceFinder { } for (const pred of preds) { let predIdx = this.blockToIdx.get(pred) as number; - this.idoms[predIdx] !== -1 ? newIdom = this.intersect(newIdom, predIdx) : null; + this.idoms[predIdx] !== -1 ? (newIdom = this.intersect(newIdom, predIdx)) : null; } if (this.idoms[blockIdx] !== newIdom) { this.idoms[blockIdx] = newIdom; @@ -83,7 +83,7 @@ export class DominanceFinder { public getDominanceFrontiers(block: BasicBlock): Set { if (!this.blockToIdx.has(block)) { - throw new Error("The given block: " + block + " is not in Cfg!") + throw new Error('The given block: ' + block + ' is not in Cfg!'); } let idx = this.blockToIdx.get(block) as number; let dfs = new Set(); @@ -106,7 +106,6 @@ export class DominanceFinder { return this.idoms; } - private getFirstDefinedBlockPredIdx(preds: BasicBlock[]): number { for (const block of preds) { let idx = this.blockToIdx.get(block) as number; @@ -127,4 +126,4 @@ export class DominanceFinder { } return a; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/DominanceTree.ts b/ets2panda/linter/arkanalyzer/src/core/graph/DominanceTree.ts index b0cf79915cc4211ae3c560fe10a14d900966d25a..5b595c8418b9fea5fb41b7825b1446438c3eab7e 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/DominanceTree.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/DominanceTree.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/GraphTraits.ts b/ets2panda/linter/arkanalyzer/src/core/graph/GraphTraits.ts index cf2b89a3dbad8c378a088354caea330d8e1096d7..b9a8a1f71fb2d2f61961d9107088a1e0a7078efe 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/GraphTraits.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/GraphTraits.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -20,4 +20,4 @@ export interface GraphTraits { nodesItor(): IterableIterator; getGraphName(): string; getNode(id: NodeID): Node | undefined; -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/Scc.ts b/ets2panda/linter/arkanalyzer/src/core/graph/Scc.ts index 337065934785ca58e2630eca8cbae7259d23a8c1..aeb568012db582c7a1cd860edb59b2f22820a163 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/Scc.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/Scc.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -153,7 +153,7 @@ export class SCCDetection> { this.setVisited(v); let node = this.getNode(v); - node.getOutgoingEdges().forEach((e) => { + node.getOutgoingEdges().forEach(e => { let w: NodeID = e.getDstID(); if (!this.isVisited(w)) { this.visit(w); @@ -275,4 +275,4 @@ export class SCCDetection> { public getRepNodes(): NodeSet { return this.repNodes; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/ViewTree.ts b/ets2panda/linter/arkanalyzer/src/core/graph/ViewTree.ts index 5324873ac4be028d716b97ab001084dfa9755aa2..b37c77074882c8cac5e34cc7a4b91c9acf846f58 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/ViewTree.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/ViewTree.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -46,8 +46,8 @@ export interface ViewTreeNode { /** * Custom component value transfer * - key: ArkField, child custom component class stateValue field. - * - value: ArkField | ArkMethod, parent component transfer value. - * key is BuilderParam, the value is Builder ArkMethod. + * - value: ArkField | ArkMethod, parent component transfer value. + * key is BuilderParam, the value is Builder ArkMethod. * Others, the value is parent class stateValue field. */ stateValuesTransfer?: Map; @@ -59,10 +59,10 @@ export interface ViewTreeNode { builder?: MethodSignature; /** - * walk node and node's children + * walk node and node's children * @param selector Node selector function, return true skipping the follow-up nodes. - * @returns - * - true: There are nodes that meet the selector. + * @returns + * - true: There are nodes that meet the selector. * - false: does not exist. */ walk(selector: (item: ViewTreeNode) => boolean): boolean; @@ -86,49 +86,49 @@ export interface ViewTreeNode { * // Component Class get ViewTree * let arkClas: ArkClass = ...; * let viewtree = arkClas.getViewTree(); - * + * * // get viewtree root node * let root: ViewTreeNode = viewtree.getRoot(); - * + * * // get viewtree stateValues Map * let stateValues: Map> = viewtree.getStateValues(); - * + * * // walk all nodes * root.walk((node) => { * // check node is builder * if (node.isBuilder()) { * xx - * } - * + * } + * * // check node is sub CustomComponent * if (node.isCustomComponent()) { * xx * } - * + * * if (xxx) { * // Skip the remaining nodes and end the traversal * return true; * } - * + * * return false; * }) - * + * * @category core/graph */ export interface ViewTree { /** - * @deprecated Use {@link getStateValues} instead. + * @deprecated Use {@link getStateValues} instead. */ isClassField(name: string): boolean; /** - * @deprecated Use {@link getStateValues} instead. + * @deprecated Use {@link getStateValues} instead. */ getClassFieldType(name: string): Decorator | Type | undefined; /** * Map of the component controlled by the state variable - * @returns + * @returns */ getStateValues(): Map>; diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/CfgBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/CfgBuilder.ts index 61742e133cb6046e59dd5390ddeb182168e10d69..5cd44402ec52488fb5bef3750f8b7af54b0c2f3e 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/builder/CfgBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/CfgBuilder.ts @@ -35,16 +35,16 @@ import { ModifierType } from '../../model/ArkBaseModel'; class StatementBuilder { type: string; - //节点对应源代码 + //节点对应源代码 code: string; next: StatementBuilder | null; lasts: Set; walked: boolean; index: number; - // TODO:以下两个属性需要获取 - line: number;//行号//ast节点存了一个start值为这段代码的起始地址,可以从start开始往回查原文有几个换行符确定行号 - column: number; // 列 - astNode: ts.Node | null;//ast节点对象 + // TODO:以下两个属性需要获取 + line: number; //行号//ast节点存了一个start值为这段代码的起始地址,可以从start开始往回查原文有几个换行符确定行号 + column: number; // 列 + astNode: ts.Node | null; //ast节点对象 scopeID: number; addressCode3: string[] = []; block: BlockBuilder | null; @@ -268,7 +268,6 @@ export class CfgBuilder { lastStatement.next = s; s.lasts.add(lastStatement); } - } ASTNodeBreakStatement(c: ts.Node, lastStatement: StatementBuilder): void { @@ -359,7 +358,8 @@ export class CfgBuilder { loopExit.lasts.add(loopstm); loopstm.code = 'for ('; if (ts.isForStatement(c)) { - loopstm.code += c.initializer?.getText(this.sourceFile) + '; ' + c.condition?.getText(this.sourceFile) + '; ' + c.incrementor?.getText(this.sourceFile); + loopstm.code += + c.initializer?.getText(this.sourceFile) + '; ' + c.condition?.getText(this.sourceFile) + '; ' + c.incrementor?.getText(this.sourceFile); } else if (ts.isForOfStatement(c)) { loopstm.code += c.initializer?.getText(this.sourceFile) + ' of ' + c.expression.getText(this.sourceFile); } else { @@ -497,7 +497,6 @@ export class CfgBuilder { } else { trystm.catchError = 'Error'; } - } let final = new StatementBuilder('statement', 'finally', c, scopeID); let finalExit = new StatementBuilder('finallyExit', '', c, scopeID); @@ -505,7 +504,7 @@ export class CfgBuilder { if (c.finallyBlock && c.finallyBlock.statements.length > 0) { this.walkAST(final, finalExit, [...c.finallyBlock.statements]); } else { - let dummyFinally = new StatementBuilder('statement', 'dummyFinally', c, (new Scope(this.scopes.length)).id); + let dummyFinally = new StatementBuilder('statement', 'dummyFinally', c, new Scope(this.scopes.length).id); final.next = dummyFinally; dummyFinally.lasts.add(final); dummyFinally.next = finalExit; @@ -648,13 +647,16 @@ export class CfgBuilder { addStmt2BlockStmtQueueInSpecialCase(stmt: StatementBuilder, stmtQueue: StatementBuilder[]): StatementBuilder | null { if (stmt.next) { - if ((stmt.type === 'continueStatement' || stmt.next.type === 'loopStatement') && stmt.next.block || stmt.next.type.includes('exit')) { + if (((stmt.type === 'continueStatement' || stmt.next.type === 'loopStatement') && stmt.next.block) || stmt.next.type.includes('exit')) { return null; } stmt.next.passTmies++; if (stmt.next.passTmies === stmt.next.lasts.size || stmt.next.type === 'loopStatement' || stmt.next.isDoWhile) { - if (stmt.next.scopeID !== stmt.scopeID && !(stmt.next instanceof ConditionStatementBuilder && stmt.next.doStatement) && - !(ts.isCaseClause(stmt.astNode!) || ts.isDefaultClause(stmt.astNode!))) { + if ( + stmt.next.scopeID !== stmt.scopeID && + !(stmt.next instanceof ConditionStatementBuilder && stmt.next.doStatement) && + !(ts.isCaseClause(stmt.astNode!) || ts.isDefaultClause(stmt.astNode!)) + ) { stmtQueue.push(stmt.next); return null; } @@ -725,8 +727,7 @@ export class CfgBuilder { } } - buildConditionNextBlocks(originStatement: ConditionStatementBuilder, block: BlockBuilder, - isLastStatement: boolean): void { + buildConditionNextBlocks(originStatement: ConditionStatementBuilder, block: BlockBuilder, isLastStatement: boolean): void { let nextT = originStatement.nextT?.block; if (nextT && (isLastStatement || nextT !== block) && !originStatement.nextT?.type.includes(' exit')) { block.nexts.push(nextT); @@ -739,8 +740,7 @@ export class CfgBuilder { } } - buildSwitchNextBlocks(originStatement: SwitchStatementBuilder, block: BlockBuilder, - isLastStatement: boolean): void { + buildSwitchNextBlocks(originStatement: SwitchStatementBuilder, block: BlockBuilder, isLastStatement: boolean): void { if (originStatement.nexts.length === 0) { const nextBlock = originStatement.afterSwitch!.block; if (nextBlock && (isLastStatement || nextBlock !== block)) { @@ -768,7 +768,7 @@ export class CfgBuilder { buildBlocksNextLast(): void { for (let block of this.blocks) { for (let originStatement of block.stmts) { - let isLastStatement = (block.stmts.indexOf(originStatement) === block.stmts.length - 1); + let isLastStatement = block.stmts.indexOf(originStatement) === block.stmts.length - 1; if (originStatement instanceof ConditionStatementBuilder) { this.buildConditionNextBlocks(originStatement, block, isLastStatement); } else if (originStatement instanceof SwitchStatementBuilder) { @@ -853,10 +853,7 @@ export class CfgBuilder { addStmtBuilderPosition(): void { for (const stmt of this.statementArray) { if (stmt.astNode) { - const { line, character } = ts.getLineAndCharacterOfPosition( - this.sourceFile, - stmt.astNode.getStart(this.sourceFile), - ); + const { line, character } = ts.getLineAndCharacterOfPosition(this.sourceFile, stmt.astNode.getStart(this.sourceFile)); stmt.line = line + 1; stmt.column = character + 1; } @@ -864,7 +861,6 @@ export class CfgBuilder { } CfgBuilder2Array(stmt: StatementBuilder): void { - if (stmt.walked) { return; } @@ -964,10 +960,15 @@ export class CfgBuilder { let stmts: ts.Node[] = []; if (ts.isSourceFile(this.astRoot)) { stmts = [...this.astRoot.statements]; - } else if (ts.isFunctionDeclaration(this.astRoot) || ts.isMethodDeclaration(this.astRoot) || - ts.isConstructorDeclaration(this.astRoot) || ts.isGetAccessorDeclaration(this.astRoot) || - ts.isSetAccessorDeclaration(this.astRoot) || ts.isFunctionExpression(this.astRoot) || - ts.isClassStaticBlockDeclaration(this.astRoot)) { + } else if ( + ts.isFunctionDeclaration(this.astRoot) || + ts.isMethodDeclaration(this.astRoot) || + ts.isConstructorDeclaration(this.astRoot) || + ts.isGetAccessorDeclaration(this.astRoot) || + ts.isSetAccessorDeclaration(this.astRoot) || + ts.isFunctionExpression(this.astRoot) || + ts.isClassStaticBlockDeclaration(this.astRoot) + ) { if (this.astRoot.body) { stmts = [...this.astRoot.body.statements]; } else { @@ -977,8 +978,12 @@ export class CfgBuilder { if (ts.isBlock(this.astRoot.body)) { stmts = [...this.astRoot.body.statements]; } - } else if (ts.isMethodSignature(this.astRoot) || ts.isConstructSignatureDeclaration(this.astRoot) || - ts.isCallSignatureDeclaration(this.astRoot) || ts.isFunctionTypeNode(this.astRoot)) { + } else if ( + ts.isMethodSignature(this.astRoot) || + ts.isConstructSignatureDeclaration(this.astRoot) || + ts.isCallSignatureDeclaration(this.astRoot) || + ts.isFunctionTypeNode(this.astRoot) + ) { this.emptyBody = true; } else if (ts.isModuleDeclaration(this.astRoot) && ts.isModuleBlock(this.astRoot.body!)) { stmts = [...this.astRoot.body.statements]; @@ -996,7 +1001,7 @@ export class CfgBuilder { this.CfgBuilder2Array(this.entry); this.addStmtBuilderPosition(); this.buildBlocks(); - this.blocks = this.blocks.filter((b) => b.stmts.length !== 0); + this.blocks = this.blocks.filter(b => b.stmts.length !== 0); this.buildBlocksNextLast(); this.addReturnStmt(); } @@ -1018,11 +1023,11 @@ export class CfgBuilder { } public buildCfg(): { - cfg: Cfg, - locals: Set, - globals: Map | null, - aliasTypeMap: Map, - traps: Trap[], + cfg: Cfg; + locals: Set; + globals: Map | null; + aliasTypeMap: Map; + traps: Trap[]; } { if (ts.isArrowFunction(this.astRoot) && !ts.isBlock(this.astRoot.body)) { return this.buildCfgForSimpleArrowFunction(); @@ -1032,11 +1037,11 @@ export class CfgBuilder { } public buildCfgForSimpleArrowFunction(): { - cfg: Cfg, - locals: Set, - globals: Map | null, - aliasTypeMap: Map, - traps: Trap[], + cfg: Cfg; + locals: Set; + globals: Map | null; + aliasTypeMap: Map; + traps: Trap[]; } { const stmts: Stmt[] = []; const arkIRTransformer = new ArkIRTransformer(this.sourceFile, this.declaringMethod); @@ -1081,22 +1086,29 @@ export class CfgBuilder { } public buildNormalCfg(): { - cfg: Cfg, - locals: Set, - globals: Map | null, - aliasTypeMap: Map, - traps: Trap[], + cfg: Cfg; + locals: Set; + globals: Map | null; + aliasTypeMap: Map; + traps: Trap[]; } { const { blockBuilderToCfgBlock, basicBlockSet, arkIRTransformer } = this.initializeBuild(); - const { - blocksContainLoopCondition, blockBuildersBeforeTry, blockBuildersContainSwitch, - valueAndStmtsOfSwitchAndCasesAll, - } = this.processBlocks(blockBuilderToCfgBlock, basicBlockSet, arkIRTransformer); + const { blocksContainLoopCondition, blockBuildersBeforeTry, blockBuildersContainSwitch, valueAndStmtsOfSwitchAndCasesAll } = this.processBlocks( + blockBuilderToCfgBlock, + basicBlockSet, + arkIRTransformer + ); const currBlockId = this.blocks.length; this.linkBasicBlocks(blockBuilderToCfgBlock); - this.adjustBlocks(blockBuilderToCfgBlock, blocksContainLoopCondition, basicBlockSet, blockBuildersContainSwitch, - valueAndStmtsOfSwitchAndCasesAll, arkIRTransformer); + this.adjustBlocks( + blockBuilderToCfgBlock, + blocksContainLoopCondition, + basicBlockSet, + blockBuildersContainSwitch, + valueAndStmtsOfSwitchAndCasesAll, + arkIRTransformer + ); const trapBuilder = new TrapBuilder(); const traps = trapBuilder.buildTraps(blockBuilderToCfgBlock, blockBuildersBeforeTry, arkIRTransformer, basicBlockSet); @@ -1112,9 +1124,9 @@ export class CfgBuilder { } private initializeBuild(): { - blockBuilderToCfgBlock: Map, - basicBlockSet: Set, - arkIRTransformer: ArkIRTransformer, + blockBuilderToCfgBlock: Map; + basicBlockSet: Set; + arkIRTransformer: ArkIRTransformer; } { const blockBuilderToCfgBlock = new Map(); const basicBlockSet = new Set(); @@ -1125,12 +1137,12 @@ export class CfgBuilder { private processBlocks( blockBuilderToCfgBlock: Map, basicBlockSet: Set, - arkIRTransformer: ArkIRTransformer, + arkIRTransformer: ArkIRTransformer ): { - blocksContainLoopCondition: Set, - blockBuildersBeforeTry: Set, - blockBuildersContainSwitch: BlockBuilder[], - valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][], + blocksContainLoopCondition: Set; + blockBuildersBeforeTry: Set; + blockBuildersContainSwitch: BlockBuilder[]; + valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][]; } { const blocksContainLoopCondition = new Set(); const blockBuildersBeforeTry = new Set(); @@ -1150,8 +1162,7 @@ export class CfgBuilder { blocksContainLoopCondition.add(this.blocks[i]); } else if (statementBuilder instanceof SwitchStatementBuilder) { blockBuildersContainSwitch.push(this.blocks[i]); - const valueAndStmtsOfSwitchAndCases = arkIRTransformer.switchStatementToValueAndStmts( - statementBuilder.astNode as ts.SwitchStatement); + const valueAndStmtsOfSwitchAndCases = arkIRTransformer.switchStatementToValueAndStmts(statementBuilder.astNode as ts.SwitchStatement); valueAndStmtsOfSwitchAndCasesAll.push(valueAndStmtsOfSwitchAndCases); continue; } @@ -1170,7 +1181,9 @@ export class CfgBuilder { blockBuilderToCfgBlock.set(this.blocks[i], blockInCfg); } return { - blocksContainLoopCondition, blockBuildersBeforeTry, blockBuildersContainSwitch, + blocksContainLoopCondition, + blockBuildersBeforeTry, + blockBuildersContainSwitch, valueAndStmtsOfSwitchAndCasesAll, }; } @@ -1201,21 +1214,17 @@ export class CfgBuilder { basicBlockSet: Set, blockBuildersContainSwitch: BlockBuilder[], valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][], - arkIRTransformer: ArkIRTransformer, + arkIRTransformer: ArkIRTransformer ): void { const loopBuilder = new LoopBuilder(); loopBuilder.rebuildBlocksInLoop(blockBuilderToCfgBlock, blocksContainLoopCondition, basicBlockSet, this.blocks); const switchBuilder = new SwitchBuilder(); - switchBuilder.buildSwitch(blockBuilderToCfgBlock, blockBuildersContainSwitch, - valueAndStmtsOfSwitchAndCasesAll, arkIRTransformer, basicBlockSet); + switchBuilder.buildSwitch(blockBuilderToCfgBlock, blockBuildersContainSwitch, valueAndStmtsOfSwitchAndCasesAll, arkIRTransformer, basicBlockSet); const conditionalBuilder = new ConditionBuilder(); conditionalBuilder.rebuildBlocksContainConditionalOperator(basicBlockSet, ModelUtils.isArkUIBuilderMethod(this.declaringMethod)); } - private createCfg( - blockBuilderToCfgBlock: Map, - basicBlockSet: Set, prevBlockId: number, - ): Cfg { + private createCfg(blockBuilderToCfgBlock: Map, basicBlockSet: Set, prevBlockId: number): Cfg { let currBlockId = prevBlockId; for (const blockBuilder of this.blocks) { if (blockBuilder.id === -1) { @@ -1257,4 +1266,4 @@ export class CfgBuilder { } } } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/ConditionBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/ConditionBuilder.ts index 8faaad123c2551516e964b698599e32b40e274c6..2cb3c912011f5f3fb682b8702db617876616fd0f 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/builder/ConditionBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/ConditionBuilder.ts @@ -36,8 +36,7 @@ export class ConditionBuilder { let conditionalOperatorEndPos = -1; for (let i = stmtsCnt - 1; i >= 0; i--) { const stmt = stmtsInCurrBasicBlock[i]; - if (stmt instanceof DummyStmt && stmt.toString() - ?.startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT)) { + if (stmt instanceof DummyStmt && stmt.toString()?.startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT)) { conditionalOperatorEndPos = i; break; } @@ -46,17 +45,16 @@ export class ConditionBuilder { continue; } - let { - generatedTopBlock: generatedTopBlock, - generatedBottomBlocks: generatedBottomBlocks, - } = this.generateBlocksContainConditionalOperatorGroup( - stmtsInCurrBasicBlock.slice(0, conditionalOperatorEndPos + 1), basicBlockSet); + let { generatedTopBlock: generatedTopBlock, generatedBottomBlocks: generatedBottomBlocks } = this.generateBlocksContainConditionalOperatorGroup( + stmtsInCurrBasicBlock.slice(0, conditionalOperatorEndPos + 1), + basicBlockSet + ); - if (conditionalOperatorEndPos !== stmtsCnt - 1) { // need create a new basic block for rest statements - const { - generatedTopBlock: extraBlock, - } = this.generateBlockWithoutConditionalOperator( - stmtsInCurrBasicBlock.slice(conditionalOperatorEndPos + 1)); + if (conditionalOperatorEndPos !== stmtsCnt - 1) { + // need create a new basic block for rest statements + const { generatedTopBlock: extraBlock } = this.generateBlockWithoutConditionalOperator( + stmtsInCurrBasicBlock.slice(conditionalOperatorEndPos + 1) + ); generatedBottomBlocks.forEach(generatedBottomBlock => { generatedBottomBlock.addSuccessorBlock(extraBlock); extraBlock.addPredecessorBlock(generatedBottomBlock); @@ -69,9 +67,11 @@ export class ConditionBuilder { } } - private relinkPrevAndSuccOfBlockContainConditionalOperator(currBasicBlock: BasicBlock, - generatedTopBlock: BasicBlock, - generatedBottomBlocks: BasicBlock[]): void { + private relinkPrevAndSuccOfBlockContainConditionalOperator( + currBasicBlock: BasicBlock, + generatedTopBlock: BasicBlock, + generatedBottomBlocks: BasicBlock[] + ): void { const predecessorsOfCurrBasicBlock = Array.from(currBasicBlock.getPredecessors()); predecessorsOfCurrBasicBlock.forEach(predecessor => { predecessor.removeSuccessorBlock(currBasicBlock); @@ -90,9 +90,12 @@ export class ConditionBuilder { }); } - private generateBlocksContainConditionalOperatorGroup(sourceStmts: Stmt[], basicBlockSet: Set): { - generatedTopBlock: BasicBlock, - generatedBottomBlocks: BasicBlock[], + private generateBlocksContainConditionalOperatorGroup( + sourceStmts: Stmt[], + basicBlockSet: Set + ): { + generatedTopBlock: BasicBlock; + generatedBottomBlocks: BasicBlock[]; } { const { firstEndPos: firstEndPos } = this.findFirstConditionalOperator(sourceStmts); if (firstEndPos === -1) { @@ -107,12 +110,10 @@ export class ConditionBuilder { let generatedBottomBlocks = firstGeneratedBottomBlocks; firstGeneratedAllBlocks.forEach(block => basicBlockSet.add(block)); const stmtsCnt = sourceStmts.length; - if (firstEndPos !== stmtsCnt - 1) { // need handle other conditional operators - const { - generatedTopBlock: restGeneratedTopBlock, - generatedBottomBlocks: restGeneratedBottomBlocks, - } = this.generateBlocksContainConditionalOperatorGroup( - sourceStmts.slice(firstEndPos + 1, stmtsCnt), basicBlockSet); + if (firstEndPos !== stmtsCnt - 1) { + // need handle other conditional operators + const { generatedTopBlock: restGeneratedTopBlock, generatedBottomBlocks: restGeneratedBottomBlocks } = + this.generateBlocksContainConditionalOperatorGroup(sourceStmts.slice(firstEndPos + 1, stmtsCnt), basicBlockSet); firstGeneratedBottomBlocks.forEach(firstGeneratedBottomBlock => { firstGeneratedBottomBlock.addSuccessorBlock(restGeneratedTopBlock); restGeneratedTopBlock.addPredecessorBlock(firstGeneratedBottomBlock); @@ -125,22 +126,17 @@ export class ConditionBuilder { } private generateBlocksContainSingleConditionalOperator(sourceStmts: Stmt[]): { - generatedTopBlock: BasicBlock, - generatedBottomBlocks: BasicBlock[], - generatedAllBlocks: BasicBlock[], + generatedTopBlock: BasicBlock; + generatedBottomBlocks: BasicBlock[]; + generatedAllBlocks: BasicBlock[]; } { - const { - firstIfTruePos: ifTruePos, - firstIfFalsePos: ifFalsePos, - firstEndPos: endPos, - } = this.findFirstConditionalOperator(sourceStmts); + const { firstIfTruePos: ifTruePos, firstIfFalsePos: ifFalsePos, firstEndPos: endPos } = this.findFirstConditionalOperator(sourceStmts); if (endPos === -1) { return this.generateBlockWithoutConditionalOperator(sourceStmts); } - const { - generatedTopBlock: generatedTopBlock, - generatedAllBlocks: generatedAllBlocks, - } = this.generateBlockWithoutConditionalOperator(sourceStmts.slice(0, ifTruePos)); + const { generatedTopBlock: generatedTopBlock, generatedAllBlocks: generatedAllBlocks } = this.generateBlockWithoutConditionalOperator( + sourceStmts.slice(0, ifTruePos) + ); let generatedBottomBlocks: BasicBlock[] = []; const { generatedTopBlock: generatedTopBlockOfTrueBranch, @@ -162,10 +158,9 @@ export class ConditionBuilder { generatedTopBlock.addSuccessorBlock(generatedTopBlockOfFalseBranch); generatedTopBlockOfFalseBranch.addPredecessorBlock(generatedTopBlock); const stmtsCnt = sourceStmts.length; - if (endPos !== stmtsCnt - 1) { // need create a new basic block for rest statements - const { - generatedTopBlock: extraBlock, - } = this.generateBlockWithoutConditionalOperator(sourceStmts.slice(endPos + 1)); + if (endPos !== stmtsCnt - 1) { + // need create a new basic block for rest statements + const { generatedTopBlock: extraBlock } = this.generateBlockWithoutConditionalOperator(sourceStmts.slice(endPos + 1)); generatedBottomBlocks.forEach(generatedBottomBlock => { generatedBottomBlock.addSuccessorBlock(extraBlock); extraBlock.addPredecessorBlock(generatedBottomBlock); @@ -177,9 +172,9 @@ export class ConditionBuilder { } private generateBlockWithoutConditionalOperator(sourceStmts: Stmt[]): { - generatedTopBlock: BasicBlock, - generatedBottomBlocks: BasicBlock[], - generatedAllBlocks: BasicBlock[], + generatedTopBlock: BasicBlock; + generatedBottomBlocks: BasicBlock[]; + generatedAllBlocks: BasicBlock[]; } { const generatedBlock = new BasicBlock(); sourceStmts.forEach(stmt => generatedBlock.addStmt(stmt)); @@ -194,8 +189,7 @@ export class ConditionBuilder { for (const basicBlock of basicBlockSet) { const stmts = Array.from(basicBlock.getStmts()); for (const stmt of stmts) { - if (stmt instanceof DummyStmt && stmt.toString() - ?.startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR)) { + if (stmt instanceof DummyStmt && stmt.toString()?.startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR)) { basicBlock.remove(stmt); } } @@ -203,7 +197,9 @@ export class ConditionBuilder { } private findFirstConditionalOperator(stmts: Stmt[]): { - firstIfTruePos: number, firstIfFalsePos: number, firstEndPos: number, + firstIfTruePos: number; + firstIfFalsePos: number; + firstEndPos: number; } { let firstIfTruePos = -1; let firstIfFalsePos = -1; @@ -212,17 +208,12 @@ export class ConditionBuilder { for (let i = 0; i < stmts.length; i++) { const stmt = stmts[i]; if (stmt instanceof DummyStmt) { - if (stmt.toString() - .startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT) && firstIfTruePos === - -1) { + if (stmt.toString().startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT) && firstIfTruePos === -1) { firstIfTruePos = i; - firstConditionalOperatorNo = - stmt.toString().replace(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT, ''); - } else if (stmt.toString() === ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + - firstConditionalOperatorNo) { + firstConditionalOperatorNo = stmt.toString().replace(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT, ''); + } else if (stmt.toString() === ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + firstConditionalOperatorNo) { firstIfFalsePos = i; - } else if (stmt.toString() === ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + - firstConditionalOperatorNo) { + } else if (stmt.toString() === ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + firstConditionalOperatorNo) { firstEndPos = i; } } @@ -230,8 +221,7 @@ export class ConditionBuilder { return { firstIfTruePos, firstIfFalsePos, firstEndPos }; } - private removeUnnecessaryBlocksInConditionalOperator(bottomBlock: BasicBlock, - allBlocks: Set): BasicBlock[] { + private removeUnnecessaryBlocksInConditionalOperator(bottomBlock: BasicBlock, allBlocks: Set): BasicBlock[] { const firstStmtInBottom = bottomBlock.getStmts()[0]; if (!(firstStmtInBottom instanceof ArkAssignStmt)) { return [bottomBlock]; @@ -246,29 +236,27 @@ export class ConditionBuilder { const newPredecessors: BasicBlock[] = []; for (const predecessor of oldPredecessors) { predecessor.removeSuccessorBlock(bottomBlock); - newPredecessors.push( - ...this.replaceTempRecursively(predecessor, targetValue as Local, tempResultValue as Local, - allBlocks)); + newPredecessors.push(...this.replaceTempRecursively(predecessor, targetValue as Local, tempResultValue as Local, allBlocks)); } bottomBlock.remove(firstStmtInBottom); - if (bottomBlock.getStmts().length === 0) { // must be a new block without successors + if (bottomBlock.getStmts().length === 0) { + // must be a new block without successors allBlocks.delete(bottomBlock); return newPredecessors; } - oldPredecessors.forEach((oldPredecessor) => { + oldPredecessors.forEach(oldPredecessor => { bottomBlock.removePredecessorBlock(oldPredecessor); }); - newPredecessors.forEach((newPredecessor) => { + newPredecessors.forEach(newPredecessor => { bottomBlock.addPredecessorBlock(newPredecessor); newPredecessor.addSuccessorBlock(bottomBlock); }); return [bottomBlock]; } - private replaceTempRecursively(currBottomBlock: BasicBlock, targetLocal: Local, - tempResultLocal: Local, allBlocks: Set): BasicBlock[] { + private replaceTempRecursively(currBottomBlock: BasicBlock, targetLocal: Local, tempResultLocal: Local, allBlocks: Set): BasicBlock[] { const stmts = currBottomBlock.getStmts(); const stmtsCnt = stmts.length; let tempResultReassignStmt: Stmt | null = null; @@ -290,8 +278,7 @@ export class ConditionBuilder { const prevTempResultLocal = (tempResultReassignStmt as ArkAssignStmt).getRightOp() as Local; for (const predecessor of oldPredecessors) { predecessor.removeSuccessorBlock(currBottomBlock); - newPredecessors.push( - ...this.replaceTempRecursively(predecessor, targetLocal, prevTempResultLocal, allBlocks)); + newPredecessors.push(...this.replaceTempRecursively(predecessor, targetLocal, prevTempResultLocal, allBlocks)); } currBottomBlock.remove(tempResultReassignStmt); @@ -301,7 +288,7 @@ export class ConditionBuilder { allBlocks.delete(currBottomBlock); } else { currBottomBlock.getPredecessors().splice(0, oldPredecessors.length, ...newPredecessors); - newPredecessors.forEach((newPredecessor) => { + newPredecessors.forEach(newPredecessor => { newPredecessor.addSuccessorBlock(currBottomBlock); }); newBottomBlocks = [currBottomBlock]; @@ -311,4 +298,4 @@ export class ConditionBuilder { } return newBottomBlocks; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/LoopBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/LoopBuilder.ts index df6d7cbad78bd7e1f6673afb3d16d38e39d53b2a..f082fe773aabcb56931dc677b0390b2093d9ba3b 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/builder/LoopBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/LoopBuilder.ts @@ -24,9 +24,12 @@ import { BlockBuilder } from './CfgBuilder'; * Builder for loop in CFG */ export class LoopBuilder { - public rebuildBlocksInLoop(blockBuilderToCfgBlock: Map, - blocksContainLoopCondition: Set, - basicBlockSet: Set, blockBuilders: BlockBuilder[]): void { + public rebuildBlocksInLoop( + blockBuilderToCfgBlock: Map, + blocksContainLoopCondition: Set, + basicBlockSet: Set, + blockBuilders: BlockBuilder[] + ): void { for (const blockBuilder of blocksContainLoopCondition) { if (!blockBuilderToCfgBlock.get(blockBuilder)) { continue; @@ -38,8 +41,7 @@ export class LoopBuilder { const stmtsCnt = stmts.length; const { ifStmtIdx, iteratorNextStmtIdx, dummyInitializerStmtIdx } = this.findIteratorIdx(stmts); if (iteratorNextStmtIdx !== -1 || dummyInitializerStmtIdx !== -1) { - const lastStmtIdxBeforeCondition = iteratorNextStmtIdx !== - -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx; + const lastStmtIdxBeforeCondition = iteratorNextStmtIdx !== -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx; const stmtsInsertBeforeCondition = stmts.slice(0, lastStmtIdxBeforeCondition); // If the loop body is empty, the loop conditional block should contain its own @@ -51,12 +53,17 @@ export class LoopBuilder { block.addPredecessorBlock(block); } - let prevBlockBuilderContainsLoop = this.doesPrevBlockBuilderContainLoop(blockBuilder, blockId, - blocksContainLoopCondition); + let prevBlockBuilderContainsLoop = this.doesPrevBlockBuilderContainLoop(blockBuilder, blockId, blocksContainLoopCondition); if (prevBlockBuilderContainsLoop) { // should create an extra block when previous block contains loop condition - this.insertBeforeConditionBlockBuilder(blockBuilderToCfgBlock, blockBuilder, - stmtsInsertBeforeCondition, false, basicBlockSet, blockBuilders); + this.insertBeforeConditionBlockBuilder( + blockBuilderToCfgBlock, + blockBuilder, + stmtsInsertBeforeCondition, + false, + basicBlockSet, + blockBuilders + ); } else { const blockBuilderBeforeCondition = blockBuilder.lasts[0]; const blockBeforeCondition = blockBuilderToCfgBlock.get(blockBuilderBeforeCondition) as BasicBlock; @@ -64,8 +71,17 @@ export class LoopBuilder { } if (dummyInitializerStmtIdx !== -1 && ifStmtIdx !== stmtsCnt - 1) { // put incrementor statements into block which reenters condition - this.adjustIncrementorStmts(stmts, ifStmtIdx, blockBuilder, blockId, blockBuilderToCfgBlock, - blocksContainLoopCondition, basicBlockSet, emptyLoopBody, blockBuilders); + this.adjustIncrementorStmts( + stmts, + ifStmtIdx, + blockBuilder, + blockId, + blockBuilderToCfgBlock, + blocksContainLoopCondition, + basicBlockSet, + emptyLoopBody, + blockBuilders + ); } else if (iteratorNextStmtIdx !== -1) { // put statements which get value of iterator into block after condition const blockBuilderAfterCondition = blockBuilder.nexts[0]; @@ -74,16 +90,14 @@ export class LoopBuilder { blockAfterCondition?.getStmts().splice(0, 0, ...stmtsAfterCondition); } // remove statements which should not in condition - const firstStmtIdxInCondition = iteratorNextStmtIdx !== - -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx + 1; + const firstStmtIdxInCondition = iteratorNextStmtIdx !== -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx + 1; stmts.splice(0, firstStmtIdxInCondition); stmts.splice(ifStmtIdx - firstStmtIdxInCondition + 1); } } } - private doesPrevBlockBuilderContainLoop(currBlockBuilder: BlockBuilder, currBlockId: number, - blocksContainLoopCondition: Set): boolean { + private doesPrevBlockBuilderContainLoop(currBlockBuilder: BlockBuilder, currBlockId: number, blocksContainLoopCondition: Set): boolean { let prevBlockBuilderContainsLoop = false; for (const prevBlockBuilder of currBlockBuilder.lasts) { if (prevBlockBuilder.id < currBlockId && blocksContainLoopCondition.has(prevBlockBuilder)) { @@ -100,49 +114,68 @@ export class LoopBuilder { stmtsInsertBeforeCondition: Stmt[], collectReenter: Boolean, basicBlockSet: Set, - blockBuilders: BlockBuilder[], + blockBuilders: BlockBuilder[] ): void { if (stmtsInsertBeforeCondition.length === 0) { return; } const blockId = conditionBlockBuilder.id; const block = this.getBlockFromMap(blockBuilderToCfgBlock, conditionBlockBuilder); - const { - blockBuildersBeforeCondition, blocksBeforeCondition, blockBuildersReenterCondition, blocksReenterCondition, - } = this.collectBlocksBeforeAndReenter(blockBuilderToCfgBlock, conditionBlockBuilder, blockId); + const { blockBuildersBeforeCondition, blocksBeforeCondition, blockBuildersReenterCondition, blocksReenterCondition } = + this.collectBlocksBeforeAndReenter(blockBuilderToCfgBlock, conditionBlockBuilder, blockId); - const { - collectedBlockBuilders, collectedBlocks, - } = this.getCollectedBlocks(collectReenter, blockBuildersBeforeCondition, blocksBeforeCondition, - blockBuildersReenterCondition, blocksReenterCondition); + const { collectedBlockBuilders, collectedBlocks } = this.getCollectedBlocks( + collectReenter, + blockBuildersBeforeCondition, + blocksBeforeCondition, + blockBuildersReenterCondition, + blocksReenterCondition + ); const { blockBuilderInsertBeforeCondition, blockInsertBeforeCondition } = this.createAndLinkBlocks( - collectedBlockBuilders, collectedBlocks, conditionBlockBuilder, stmtsInsertBeforeCondition, block); + collectedBlockBuilders, + collectedBlocks, + conditionBlockBuilder, + stmtsInsertBeforeCondition, + block + ); - this.updatePredecessors(collectedBlockBuilders, blockBuilderToCfgBlock, conditionBlockBuilder, - blockBuilderInsertBeforeCondition, blockInsertBeforeCondition); + this.updatePredecessors( + collectedBlockBuilders, + blockBuilderToCfgBlock, + conditionBlockBuilder, + blockBuilderInsertBeforeCondition, + blockInsertBeforeCondition + ); const { newPrevBlockBuildersBeforeCondition, newPrevBlocksBeforeCondition } = this.getNewPrevBlocks( - collectReenter, blockBuildersBeforeCondition, blocksBeforeCondition, blockBuilderInsertBeforeCondition, - blockInsertBeforeCondition, blockBuildersReenterCondition, blocksReenterCondition); + collectReenter, + blockBuildersBeforeCondition, + blocksBeforeCondition, + blockBuilderInsertBeforeCondition, + blockInsertBeforeCondition, + blockBuildersReenterCondition, + blocksReenterCondition + ); this.updateConditionBlockBuilder(conditionBlockBuilder, newPrevBlockBuildersBeforeCondition, block, newPrevBlocksBeforeCondition); this.finalizeInsertion(blockBuilderInsertBeforeCondition, blockInsertBeforeCondition, basicBlockSet, blockBuilderToCfgBlock, blockBuilders); } - private getBlockFromMap(blockBuilderToCfgBlock: Map, - conditionBlockBuilder: BlockBuilder): BasicBlock { + private getBlockFromMap(blockBuilderToCfgBlock: Map, conditionBlockBuilder: BlockBuilder): BasicBlock { return blockBuilderToCfgBlock.get(conditionBlockBuilder) as BasicBlock; } private collectBlocksBeforeAndReenter( blockBuilderToCfgBlock: Map, conditionBlockBuilder: BlockBuilder, - blockId: number, + blockId: number ): { - blockBuildersBeforeCondition: BlockBuilder[], blocksBeforeCondition: BasicBlock[], - blockBuildersReenterCondition: BlockBuilder[], blocksReenterCondition: BasicBlock[] + blockBuildersBeforeCondition: BlockBuilder[]; + blocksBeforeCondition: BasicBlock[]; + blockBuildersReenterCondition: BlockBuilder[]; + blocksReenterCondition: BasicBlock[]; } { const blockBuildersBeforeCondition: BlockBuilder[] = []; const blocksBeforeCondition: BasicBlock[] = []; @@ -159,7 +192,10 @@ export class LoopBuilder { } } return { - blockBuildersBeforeCondition, blocksBeforeCondition, blockBuildersReenterCondition, blocksReenterCondition, + blockBuildersBeforeCondition, + blocksBeforeCondition, + blockBuildersReenterCondition, + blocksReenterCondition, }; } @@ -168,8 +204,8 @@ export class LoopBuilder { blockBuildersBeforeCondition: BlockBuilder[], blocksBeforeCondition: BasicBlock[], blockBuildersReenterCondition: BlockBuilder[], - blocksReenterCondition: BasicBlock[], - ): { collectedBlockBuilders: BlockBuilder[], collectedBlocks: BasicBlock[] } { + blocksReenterCondition: BasicBlock[] + ): { collectedBlockBuilders: BlockBuilder[]; collectedBlocks: BasicBlock[] } { let collectedBlockBuilders: BlockBuilder[] = []; let collectedBlocks: BasicBlock[] = []; if (collectReenter) { @@ -187,8 +223,11 @@ export class LoopBuilder { collectedBlocks: BasicBlock[], conditionBlockBuilder: BlockBuilder, stmtsInsertBeforeCondition: Stmt[], - block: BasicBlock, - ): { blockBuilderInsertBeforeCondition: BlockBuilder, blockInsertBeforeCondition: BasicBlock } { + block: BasicBlock + ): { + blockBuilderInsertBeforeCondition: BlockBuilder; + blockInsertBeforeCondition: BasicBlock; + } { const blockBuilderInsertBeforeCondition = new BlockBuilder(-1, []); blockBuilderInsertBeforeCondition.lasts.push(...collectedBlockBuilders); blockBuilderInsertBeforeCondition.nexts.push(conditionBlockBuilder); @@ -204,7 +243,7 @@ export class LoopBuilder { blockBuilderToCfgBlock: Map, conditionBlockBuilder: BlockBuilder, blockBuilderInsertBeforeCondition: BlockBuilder, - blockInsertBeforeCondition: BasicBlock, + blockInsertBeforeCondition: BasicBlock ): void { for (const prevBlockBuilder of collectedBlockBuilders) { const prevBlock = blockBuilderToCfgBlock.get(prevBlockBuilder) as BasicBlock; @@ -225,8 +264,11 @@ export class LoopBuilder { blockBuilderInsertBeforeCondition: BlockBuilder, blockInsertBeforeCondition: BasicBlock, blockBuildersReenterCondition: BlockBuilder[], - blocksReenterCondition: BasicBlock[], - ): { newPrevBlockBuildersBeforeCondition: BlockBuilder[], newPrevBlocksBeforeCondition: BasicBlock[] } { + blocksReenterCondition: BasicBlock[] + ): { + newPrevBlockBuildersBeforeCondition: BlockBuilder[]; + newPrevBlocksBeforeCondition: BasicBlock[]; + } { let newPrevBlockBuildersBeforeCondition: BlockBuilder[] = []; let newPrevBlocksBeforeCondition: BasicBlock[] = []; if (collectReenter) { @@ -236,14 +278,17 @@ export class LoopBuilder { newPrevBlockBuildersBeforeCondition = [blockBuilderInsertBeforeCondition, ...blockBuildersReenterCondition]; newPrevBlocksBeforeCondition = [blockInsertBeforeCondition, ...blocksReenterCondition]; } - return { newPrevBlockBuildersBeforeCondition, newPrevBlocksBeforeCondition }; + return { + newPrevBlockBuildersBeforeCondition, + newPrevBlocksBeforeCondition, + }; } private updateConditionBlockBuilder( conditionBlockBuilder: BlockBuilder, newPrevBlockBuildersBeforeCondition: BlockBuilder[], block: BasicBlock, - newPrevBlocksBeforeCondition: BasicBlock[], + newPrevBlocksBeforeCondition: BasicBlock[] ): void { conditionBlockBuilder.lasts = newPrevBlockBuildersBeforeCondition; const predecessorsCnt = block.getPredecessors().length; @@ -255,7 +300,7 @@ export class LoopBuilder { blockInsertBeforeCondition: BasicBlock, basicBlockSet: Set, blockBuilderToCfgBlock: Map, - blockBuilders: BlockBuilder[], + blockBuilders: BlockBuilder[] ): void { blockBuilders.push(blockBuilderInsertBeforeCondition); basicBlockSet.add(blockInsertBeforeCondition); @@ -263,7 +308,9 @@ export class LoopBuilder { } private findIteratorIdx(stmts: Stmt[]): { - ifStmtIdx: number, iteratorNextStmtIdx: number, dummyInitializerStmtIdx: number + ifStmtIdx: number; + iteratorNextStmtIdx: number; + dummyInitializerStmtIdx: number; } { let ifStmtIdx = -1; let iteratorNextStmtIdx = -1; @@ -273,8 +320,7 @@ export class LoopBuilder { const stmt = stmts[i]; if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof AbstractInvokeExpr) { const invokeExpr = stmt.getRightOp() as AbstractInvokeExpr; - if (invokeExpr.getMethodSignature().getMethodSubSignature() - .getMethodName() === Builtin.ITERATOR_NEXT) { + if (invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName() === Builtin.ITERATOR_NEXT) { iteratorNextStmtIdx = i; continue; } @@ -295,10 +341,17 @@ export class LoopBuilder { }; } - private adjustIncrementorStmts(stmts: Stmt[], ifStmtIdx: number, currBlockBuilder: BlockBuilder, - currBlockId: number, blockBuilderToCfgBlock: Map, - blocksContainLoopCondition: Set, basicBlockSet: Set, - emptyLoopBody: boolean, blockBuilders: BlockBuilder[]): void { + private adjustIncrementorStmts( + stmts: Stmt[], + ifStmtIdx: number, + currBlockBuilder: BlockBuilder, + currBlockId: number, + blockBuilderToCfgBlock: Map, + blocksContainLoopCondition: Set, + basicBlockSet: Set, + emptyLoopBody: boolean, + blockBuilders: BlockBuilder[] + ): void { const stmtsReenterCondition = stmts.slice(ifStmtIdx + 1); if (emptyLoopBody) { const incrementorBlockBuilder = new BlockBuilder(-1, []); @@ -327,16 +380,13 @@ export class LoopBuilder { } } - if (blockBuildersReenterCondition.length > 1 || blocksContainLoopCondition.has( - blockBuildersReenterCondition[0])) { + if (blockBuildersReenterCondition.length > 1 || blocksContainLoopCondition.has(blockBuildersReenterCondition[0])) { // put incrementor statements into an extra block - this.insertBeforeConditionBlockBuilder(blockBuilderToCfgBlock, currBlockBuilder, - stmtsReenterCondition, true, basicBlockSet, blockBuilders); + this.insertBeforeConditionBlockBuilder(blockBuilderToCfgBlock, currBlockBuilder, stmtsReenterCondition, true, basicBlockSet, blockBuilders); } else { // put incrementor statements into prev reenter block - const blockReenterCondition = blockBuilderToCfgBlock.get( - blockBuildersReenterCondition[0]) as BasicBlock; + const blockReenterCondition = blockBuilderToCfgBlock.get(blockBuildersReenterCondition[0]) as BasicBlock; stmtsReenterCondition.forEach(stmt => blockReenterCondition?.getStmts().push(stmt)); } } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/SwitchBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/SwitchBuilder.ts index 60a231c2c2fd3b26066f5e53a107ce2b47400435..3fa74eacf9467ab50c7900424be90e8274b8c3a2 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/builder/SwitchBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/SwitchBuilder.ts @@ -25,16 +25,18 @@ const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'SwitchBuilder'); * Builder for switch statement in CFG */ export class SwitchBuilder { - public buildSwitch(blockBuilderToCfgBlock: Map, - blockBuildersContainSwitch: BlockBuilder[], - valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][], arkIRTransformer: ArkIRTransformer, - basicBlockSet: Set): void { + public buildSwitch( + blockBuilderToCfgBlock: Map, + blockBuildersContainSwitch: BlockBuilder[], + valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][], + arkIRTransformer: ArkIRTransformer, + basicBlockSet: Set + ): void { for (let i = 0; i < blockBuildersContainSwitch.length; i++) { const blockBuilderContainSwitch = blockBuildersContainSwitch[i]; if (!blockBuilderToCfgBlock.has(blockBuilderContainSwitch)) { - logger.error( - `can't find basicBlock corresponding to the blockBuilder.`); + logger.error(`can't find basicBlock corresponding to the blockBuilder.`); continue; } @@ -50,7 +52,8 @@ export class SwitchBuilder { const cases = switchStmtBuilder.cases; let nonEmptyCaseCnt = 0; for (const currCase of cases) { - if (currCase.stmt.block) { // there are stmts after this case + if (currCase.stmt.block) { + // there are stmts after this case nonEmptyCaseCnt++; } } @@ -59,16 +62,24 @@ export class SwitchBuilder { } const caseCnt = cases.length; - const caseIfBlocks = this.generateIfBlocksForCases(valueAndStmtsOfSwitchAndCasesAll[i], caseCnt, - blockContainSwitch, basicBlockSet, arkIRTransformer); - this.linkIfBlockAndCaseBlock(blockContainSwitch, caseIfBlocks, switchStmtBuilder, - blockBuilderToCfgBlock); + const caseIfBlocks = this.generateIfBlocksForCases( + valueAndStmtsOfSwitchAndCasesAll[i], + caseCnt, + blockContainSwitch, + basicBlockSet, + arkIRTransformer + ); + this.linkIfBlockAndCaseBlock(blockContainSwitch, caseIfBlocks, switchStmtBuilder, blockBuilderToCfgBlock); } } - private generateIfBlocksForCases(valueAndStmtsOfSwitchAndCases: ValueAndStmts[], caseCnt: number, - blockContainSwitch: BasicBlock, basicBlockSet: Set, - arkIRTransformer: ArkIRTransformer): BasicBlock[] { + private generateIfBlocksForCases( + valueAndStmtsOfSwitchAndCases: ValueAndStmts[], + caseCnt: number, + blockContainSwitch: BasicBlock, + basicBlockSet: Set, + arkIRTransformer: ArkIRTransformer + ): BasicBlock[] { const valueAndStmtsOfSwitch = valueAndStmtsOfSwitchAndCases[0]; const valueOfSwitch = valueAndStmtsOfSwitch.value; const caseIfBlocks: BasicBlock[] = []; @@ -89,9 +100,12 @@ export class SwitchBuilder { caseStmts.forEach((stmt: Stmt) => { caseIfBlock.addStmt(stmt); }); - const caseIfStmts = arkIRTransformer.generateIfStmtForValues(valueOfSwitch, - valueAndStmtsOfSwitch.valueOriginalPositions, caseValue, - caseValueAndStmts.valueOriginalPositions); + const caseIfStmts = arkIRTransformer.generateIfStmtForValues( + valueOfSwitch, + valueAndStmtsOfSwitch.valueOriginalPositions, + caseValue, + caseValueAndStmts.valueOriginalPositions + ); caseIfStmts.forEach((stmt: Stmt) => { caseIfBlock.addStmt(stmt); }); @@ -99,9 +113,12 @@ export class SwitchBuilder { return caseIfBlocks; } - private linkIfBlockAndCaseBlock(blockContainSwitch: BasicBlock, caseIfBlocks: BasicBlock[], - switchStmtBuilder: SwitchStatementBuilder, - blockBuilderToCfgBlock: Map): boolean { + private linkIfBlockAndCaseBlock( + blockContainSwitch: BasicBlock, + caseIfBlocks: BasicBlock[], + switchStmtBuilder: SwitchStatementBuilder, + blockBuilderToCfgBlock: Map + ): boolean { const successorsOfBlockContainSwitch = Array.from(blockContainSwitch.getSuccessors()); const expectedSuccessorsOfCaseIfBlock: BasicBlock[] = []; const defaultStmtBuilder = switchStmtBuilder.default; @@ -121,13 +138,14 @@ export class SwitchBuilder { const currCase = switchStmtBuilder.cases[i]; if (currCase.stmt.block) { expectedSuccessorsOfCaseIfBlock.push(...successorsOfBlockContainSwitch.splice(-1, 1)); - } else { // if there are no stmts after this case, reuse the successor of the next case + } else { + // if there are no stmts after this case, reuse the successor of the next case expectedSuccessorsOfCaseIfBlock.push(...expectedSuccessorsOfCaseIfBlock.slice(-1)); } } expectedSuccessorsOfCaseIfBlock.reverse(); - blockContainSwitch.getSuccessors().forEach((successor) => { + blockContainSwitch.getSuccessors().forEach(successor => { successor.getPredecessors().splice(0, 1); }); blockContainSwitch.getSuccessors().splice(0); @@ -135,7 +153,8 @@ export class SwitchBuilder { const caseIfBlock = caseIfBlocks[j]; caseIfBlock.addSuccessorBlock(expectedSuccessorsOfCaseIfBlock[j]); expectedSuccessorsOfCaseIfBlock[j].addPredecessorBlock(caseIfBlock); - if (j === caseCnt - 1) { // the false branch of last case should be default or block after switch statement + if (j === caseCnt - 1) { + // the false branch of last case should be default or block after switch statement caseIfBlock.addSuccessorBlock(expectedSuccessorsOfCaseIfBlock[j + 1]); expectedSuccessorsOfCaseIfBlock[j + 1].addPredecessorBlock(caseIfBlock); } else { @@ -145,4 +164,4 @@ export class SwitchBuilder { } return true; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/TrapBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/TrapBuilder.ts index fdb4689601bca42236b270ca9d08c1621a03e2b2..160df9fdc0420bd843f79edbbe7f43552c9e3699 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/builder/TrapBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/TrapBuilder.ts @@ -19,15 +19,7 @@ import { Trap } from '../../base/Trap'; import { ArkCaughtExceptionRef } from '../../base/Ref'; import { UnknownType } from '../../base/Type'; import { FullPosition } from '../../base/Position'; -import { - ArkAssignStmt, - ArkIfStmt, - ArkInvokeStmt, - ArkReturnStmt, - ArkReturnVoidStmt, - ArkThrowStmt, - Stmt, -} from '../../base/Stmt'; +import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, ArkThrowStmt, Stmt } from '../../base/Stmt'; import { BlockBuilder, TryStatementBuilder } from './CfgBuilder'; import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; @@ -37,8 +29,12 @@ const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'TrapBuilder'); * Builder for traps from try...catch */ export class TrapBuilder { - public buildTraps(blockBuilderToCfgBlock: Map, blockBuildersBeforeTry: Set, - arkIRTransformer: ArkIRTransformer, basicBlockSet: Set): Trap[] { + public buildTraps( + blockBuilderToCfgBlock: Map, + blockBuildersBeforeTry: Set, + arkIRTransformer: ArkIRTransformer, + basicBlockSet: Set + ): Trap[] { const traps: Trap[] = []; for (const blockBuilderBeforeTry of blockBuildersBeforeTry) { if (blockBuilderBeforeTry.nexts.length === 0) { @@ -53,14 +49,16 @@ export class TrapBuilder { logger.error(`can't find finally block or dummy finally block.`); continue; } - const { bfsBlocks: tryBfsBlocks, tailBlocks: tryTailBlocks } = this.getAllBlocksBFS(blockBuilderToCfgBlock, - blockBuilderContainTry, finallyBlockBuilder); + const { bfsBlocks: tryBfsBlocks, tailBlocks: tryTailBlocks } = this.getAllBlocksBFS( + blockBuilderToCfgBlock, + blockBuilderContainTry, + finallyBlockBuilder + ); let catchBfsBlocks: BasicBlock[] = []; let catchTailBlocks: BasicBlock[] = []; const catchBlockBuilder = tryStmtBuilder.catchStatement?.block; if (catchBlockBuilder) { - ({ bfsBlocks: catchBfsBlocks, tailBlocks: catchTailBlocks } = this.getAllBlocksBFS( - blockBuilderToCfgBlock, catchBlockBuilder)); + ({ bfsBlocks: catchBfsBlocks, tailBlocks: catchTailBlocks } = this.getAllBlocksBFS(blockBuilderToCfgBlock, catchBlockBuilder)); } const finallyStmts = finallyBlockBuilder.stmts; const blockBuilderAfterFinally = tryStmtBuilder.afterFinal?.block; @@ -68,27 +66,49 @@ export class TrapBuilder { logger.error(`can't find block after try...catch.`); continue; } - if (finallyStmts.length === 1 && finallyStmts[0].code === 'dummyFinally') { // no finally block - const trapsIfNoFinally = this.buildTrapsIfNoFinally(tryBfsBlocks, tryTailBlocks, catchBfsBlocks, + if (finallyStmts.length === 1 && finallyStmts[0].code === 'dummyFinally') { + // no finally block + const trapsIfNoFinally = this.buildTrapsIfNoFinally( + tryBfsBlocks, + tryTailBlocks, + catchBfsBlocks, catchTailBlocks, - finallyBlockBuilder, blockBuilderAfterFinally, basicBlockSet, blockBuilderToCfgBlock); + finallyBlockBuilder, + blockBuilderAfterFinally, + basicBlockSet, + blockBuilderToCfgBlock + ); if (trapsIfNoFinally) { traps.push(...trapsIfNoFinally); } } else { - const trapsIfFinallyExist = this.buildTrapsIfFinallyExist(tryBfsBlocks, tryTailBlocks, catchBfsBlocks, - catchTailBlocks, finallyBlockBuilder, blockBuilderAfterFinally, basicBlockSet, arkIRTransformer, - blockBuilderToCfgBlock); + const trapsIfFinallyExist = this.buildTrapsIfFinallyExist( + tryBfsBlocks, + tryTailBlocks, + catchBfsBlocks, + catchTailBlocks, + finallyBlockBuilder, + blockBuilderAfterFinally, + basicBlockSet, + arkIRTransformer, + blockBuilderToCfgBlock + ); traps.push(...trapsIfFinallyExist); } } return traps; } - private buildTrapsIfNoFinally(tryBfsBlocks: BasicBlock[], tryTailBlocks: BasicBlock[], catchBfsBlocks: BasicBlock[], - catchTailBlocks: BasicBlock[], finallyBlockBuilder: BlockBuilder, - blockBuilderAfterFinally: BlockBuilder, basicBlockSet: Set, - blockBuilderToCfgBlock: Map): Trap[] | null { + private buildTrapsIfNoFinally( + tryBfsBlocks: BasicBlock[], + tryTailBlocks: BasicBlock[], + catchBfsBlocks: BasicBlock[], + catchTailBlocks: BasicBlock[], + finallyBlockBuilder: BlockBuilder, + blockBuilderAfterFinally: BlockBuilder, + basicBlockSet: Set, + blockBuilderToCfgBlock: Map + ): Trap[] | null { if (catchBfsBlocks.length === 0) { logger.error(`catch block expected.`); return null; @@ -130,16 +150,23 @@ export class TrapBuilder { return [new Trap(tryBfsBlocks, catchBfsBlocks)]; } - private buildTrapsIfFinallyExist(tryBfsBlocks: BasicBlock[], tryTailBlocks: BasicBlock[], - catchBfsBlocks: BasicBlock[], catchTailBlocks: BasicBlock[], - finallyBlockBuilder: BlockBuilder, blockBuilderAfterFinally: BlockBuilder, - basicBlockSet: Set, arkIRTransformer: ArkIRTransformer, - blockBuilderToCfgBlock: Map): Trap[] { + private buildTrapsIfFinallyExist( + tryBfsBlocks: BasicBlock[], + tryTailBlocks: BasicBlock[], + catchBfsBlocks: BasicBlock[], + catchTailBlocks: BasicBlock[], + finallyBlockBuilder: BlockBuilder, + blockBuilderAfterFinally: BlockBuilder, + basicBlockSet: Set, + arkIRTransformer: ArkIRTransformer, + blockBuilderToCfgBlock: Map + ): Trap[] { const { bfsBlocks: finallyBfsBlocks, tailBlocks: finallyTailBlocks } = this.getAllBlocksBFS( blockBuilderToCfgBlock, - finallyBlockBuilder, blockBuilderAfterFinally); - const copyFinallyBfsBlocks = this.copyFinallyBlocks(finallyBfsBlocks, finallyTailBlocks, basicBlockSet, - arkIRTransformer, blockBuilderToCfgBlock); + finallyBlockBuilder, + blockBuilderAfterFinally + ); + const copyFinallyBfsBlocks = this.copyFinallyBlocks(finallyBfsBlocks, finallyTailBlocks, basicBlockSet, arkIRTransformer, blockBuilderToCfgBlock); const traps: Trap[] = []; if (catchBfsBlocks.length !== 0) { for (const catchTailBlock of catchTailBlocks) { @@ -166,8 +193,11 @@ export class TrapBuilder { return traps; } - private getAllBlocksBFS(blockBuilderToCfgBlock: Map, startBlockBuilder: BlockBuilder, - endBlockBuilder?: BlockBuilder): { bfsBlocks: BasicBlock[], tailBlocks: BasicBlock[] } { + private getAllBlocksBFS( + blockBuilderToCfgBlock: Map, + startBlockBuilder: BlockBuilder, + endBlockBuilder?: BlockBuilder + ): { bfsBlocks: BasicBlock[]; tailBlocks: BasicBlock[] } { const bfsBlocks: BasicBlock[] = []; const tailBlocks: BasicBlock[] = []; const queue: BlockBuilder[] = []; @@ -187,7 +217,7 @@ export class TrapBuilder { bfsBlocks.push(currBlock); const childList = currBlockBuilder.nexts; - if (childList.length === 0 || (childList.length !== 0 && (childList[0] === endBlockBuilder))) { + if (childList.length === 0 || (childList.length !== 0 && childList[0] === endBlockBuilder)) { if (childList[0] === endBlockBuilder) { tailBlocks.push(currBlock); continue; @@ -202,21 +232,21 @@ export class TrapBuilder { return { bfsBlocks, tailBlocks }; } - private copyFinallyBlocks(finallyBfsBlocks: BasicBlock[], finallyTailBlocks: BasicBlock[], - basicBlockSet: Set, arkIRTransformer: ArkIRTransformer, - blockBuilderToCfgBlock: Map): BasicBlock[] { + private copyFinallyBlocks( + finallyBfsBlocks: BasicBlock[], + finallyTailBlocks: BasicBlock[], + basicBlockSet: Set, + arkIRTransformer: ArkIRTransformer, + blockBuilderToCfgBlock: Map + ): BasicBlock[] { const copyFinallyBfsBlocks = this.copyBlocks(finallyBfsBlocks); const caughtExceptionRef = new ArkCaughtExceptionRef(UnknownType.getInstance()); - const { - value: exceptionValue, - stmts: exceptionAssignStmts, - } = arkIRTransformer.generateAssignStmtForValue(caughtExceptionRef, [FullPosition.DEFAULT]); + const { value: exceptionValue, stmts: exceptionAssignStmts } = arkIRTransformer.generateAssignStmtForValue(caughtExceptionRef, [FullPosition.DEFAULT]); copyFinallyBfsBlocks[0].addHead(exceptionAssignStmts); const finallyPredecessorsCnt = copyFinallyBfsBlocks[0].getPredecessors().length; copyFinallyBfsBlocks[0].getPredecessors().splice(0, finallyPredecessorsCnt); const throwStmt = new ArkThrowStmt(exceptionValue); - let copyFinallyTailBlocks = copyFinallyBfsBlocks.splice( - copyFinallyBfsBlocks.length - finallyTailBlocks.length, finallyTailBlocks.length); + let copyFinallyTailBlocks = copyFinallyBfsBlocks.splice(copyFinallyBfsBlocks.length - finallyTailBlocks.length, finallyTailBlocks.length); copyFinallyTailBlocks.forEach((copyFinallyTailBlock: BasicBlock) => { const successorsCnt = copyFinallyTailBlock.getSuccessors().length; copyFinallyTailBlock.getSuccessors().splice(0, successorsCnt); @@ -278,4 +308,4 @@ export class TrapBuilder { } return null; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/ViewTreeBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/ViewTreeBuilder.ts index a0c37d94bb687090a39ab07ec45df694bce2bc42..bf8482f4c9ce1f780577f0e20ba4f495067668ad 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/builder/ViewTreeBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/ViewTreeBuilder.ts @@ -81,7 +81,7 @@ function parseObjectLiteral(objectLiteralCls: ArkClass | null, scene: Scene): Ob if (objectLiteralCls?.getCategory() !== ClassCategory.OBJECT) { return map; } - objectLiteralCls?.getFields().forEach((field) => { + objectLiteralCls?.getFields().forEach(field => { let stmts = field.getInitializer(); if (stmts.length === 0) { return; @@ -169,11 +169,7 @@ class StateValuesUtils { return uses; } - private parseMethodUsesStateValues( - methodSignature: MethodSignature, - uses: Set, - visitor: Set = new Set() - ): void { + private parseMethodUsesStateValues(methodSignature: MethodSignature, uses: Set, visitor: Set = new Set()): void { if (visitor.has(methodSignature)) { return; } @@ -332,14 +328,12 @@ class ViewTreeNodeImpl implements ViewTreeNode { this.children.push(child as ViewTreeNodeImpl); } } else { - logger.error( - `ViewTree->changeBuilderParam2BuilderNode ${builder.getSignature().toString()} @Builder viewtree fail.` - ); + logger.error(`ViewTree->changeBuilderParam2BuilderNode ${builder.getSignature().toString()} @Builder viewtree fail.`); } } public hasBuilderParam(): boolean { - return this.walk((item) => { + return this.walk(item => { return (item as ViewTreeNodeImpl).isBuilderParam(); }); } @@ -406,11 +400,7 @@ class ViewTreeNodeImpl implements ViewTreeNode { } } - private getBindValues( - local: Local, - relationValues: (Constant | ArkInstanceFieldRef | MethodSignature)[], - visitor: Set = new Set() - ): void { + private getBindValues(local: Local, relationValues: (Constant | ArkInstanceFieldRef | MethodSignature)[], visitor: Set = new Set()): void { if (visitor.has(local)) { return; } @@ -435,10 +425,8 @@ class ViewTreeNodeImpl implements ViewTreeNode { } public parseStateValues(tree: ViewTreeImpl, stmt: Stmt): void { - let stateValues: Set = StateValuesUtils.getInstance( - tree.getDeclaringArkClass() - ).parseStmtUsesStateValues(stmt); - stateValues.forEach((field) => { + let stateValues: Set = StateValuesUtils.getInstance(tree.getDeclaringArkClass()).parseStmtUsesStateValues(stmt); + stateValues.forEach(field => { this.stateValues.add(field); tree.addStateValue(field, this); }, this); @@ -456,7 +444,7 @@ class TreeNodeStack { /** * @internal */ - public push(node: ViewTreeNodeImpl) { + public push(node: ViewTreeNodeImpl): void { let parent = this.getParent(); node.parent = parent; this.stack.push(node); @@ -470,7 +458,7 @@ class TreeNodeStack { /** * @internal */ - public pop() { + public pop(): void { this.stack.pop(); } @@ -614,7 +602,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { /** * @internal */ - public addStateValue(field: ArkField, node: ViewTreeNode) { + public addStateValue(field: ArkField, node: ViewTreeNode): void { if (!this.stateValues.has(field)) { this.stateValues.set(field, new Set()); } @@ -682,7 +670,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { this.getDeclaringArkClass() .getDeclaringArkNamespace() ?.getAllMethodsUnderThisNamespace() - .forEach((value) => { + .forEach(value => { if (value.getName() === name) { method = value; } @@ -694,8 +682,8 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { this.getDeclaringArkClass() .getDeclaringArkFile() .getAllNamespacesUnderThisFile() - .forEach((namespace) => { - namespace.getAllMethodsUnderThisNamespace().forEach((value) => { + .forEach(namespace => { + namespace.getAllMethodsUnderThisNamespace().forEach(value => { if (value.getName() === name) { method = value; } @@ -761,20 +749,14 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { /** * @internal */ - private addCustomComponentNode( - cls: ArkClass, - arg: Value | undefined, - builder: ArkMethod | undefined - ): ViewTreeNodeImpl { + private addCustomComponentNode(cls: ArkClass, arg: Value | undefined, builder: ArkMethod | undefined): ViewTreeNodeImpl { let node = ViewTreeNodeImpl.createCustomComponent(); node.signature = cls.getSignature(); node.classSignature = node.signature; node.stateValuesTransfer = this.parseObjectLiteralExpr(cls, arg, builder); if (arg instanceof Local && arg.getType()) { - let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseObjectUsedStateValues( - arg.getType() - ); - stateValues.forEach((field) => { + let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseObjectUsedStateValues(arg.getType()); + stateValues.forEach(field => { node.stateValues.add(field); this.addStateValue(field, node); }); @@ -797,7 +779,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { private cloneBuilderParamNode(node: ViewTreeNodeImpl, root: ViewTreeNodeImpl): ViewTreeNodeImpl { root = root.clone(node); if (node.stateValuesTransfer) { - root.walk((item) => { + root.walk(item => { let child = item as ViewTreeNodeImpl; if (!child.isBuilderParam() || !child.builderParam) { return false; @@ -838,7 +820,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { private findMethodInvokeBuilderMethod(method: ArkMethod): ArkMethod | undefined { let stmts = method.getCfg()?.getStmts(); if (!stmts) { - return; + return undefined; } for (const stmt of stmts) { let expr: AbstractInvokeExpr | undefined; @@ -861,6 +843,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { return method; } } + return undefined; } private parseFieldInObjectLiteral(field: ArkField, cls: ArkClass, transferMap: Map): void { @@ -899,22 +882,18 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { } } - private parseObjectLiteralExpr( - cls: ArkClass, - object: Value | undefined, - builder: ArkMethod | undefined - ): Map | undefined { + private parseObjectLiteralExpr(cls: ArkClass, object: Value | undefined, builder: ArkMethod | undefined): Map | undefined { let transferMap: Map = new Map(); if (object instanceof Local && object.getType() instanceof ClassType) { let anonymousSig = (object.getType() as ClassType).getClassSignature(); let anonymous = this.findClass(anonymousSig); - anonymous?.getFields().forEach((field) => { + anonymous?.getFields().forEach(field => { this.parseFieldInObjectLiteral(field, cls, transferMap); }); } // If the builder exists, there will be a unique BuilderParam if (builder) { - cls.getFields().forEach((value) => { + cls.getFields().forEach(value => { if (value.hasBuilderParamDecorator()) { transferMap.set(value, builder); } @@ -922,19 +901,15 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { } if (transferMap.size === 0) { - return; + return undefined; } return transferMap; } - private viewComponentCreationParser( - name: string, - stmt: Stmt, - expr: AbstractInvokeExpr - ): ViewTreeNodeImpl | undefined { + private viewComponentCreationParser(name: string, stmt: Stmt, expr: AbstractInvokeExpr): ViewTreeNodeImpl | undefined { let temp = expr.getArg(0) as Local; let arg: Value | undefined; - temp.getUsedStmts().forEach((value) => { + temp.getUsedStmts().forEach(value => { if (value instanceof ArkInvokeStmt) { let invokerExpr = value.getInvokeExpr(); let methodName = invokerExpr.getMethodSignature().getMethodSubSignature().getMethodName(); @@ -970,9 +945,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { if (cls && cls.hasComponentDecorator()) { return this.addCustomComponentNode(cls, arg, builderMethod); } else { - logger.error( - `ViewTree->viewComponentCreationParser not found class ${clsSignature.toString()}. ${stmt.toString()}` - ); + logger.error(`ViewTree->viewComponentCreationParser not found class ${clsSignature.toString()}. ${stmt.toString()}`); } } return undefined; @@ -1009,10 +982,8 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { let values = expr.getArg(0) as Local; let declaringStmt = values?.getDeclaringStmt(); if (declaringStmt) { - let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseStmtUsesStateValues( - declaringStmt - ); - stateValues.forEach((field) => { + let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseStmtUsesStateValues(declaringStmt); + stateValues.forEach(field => { node.stateValues.add(field); this.addStateValue(field, node); }); @@ -1031,10 +1002,8 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { let arg = expr.getArg(0) as Local; let declaringStmt = arg?.getDeclaringStmt(); if (declaringStmt) { - let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseStmtUsesStateValues( - declaringStmt - ); - stateValues.forEach((field) => { + let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseStmtUsesStateValues(declaringStmt); + stateValues.forEach(field => { node.stateValues.add(field); this.addStateValue(field, node); }); @@ -1048,10 +1017,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { return this.addSystemComponentNode(COMPONENT_IF_BRANCH); } - private COMPONENT_CREATE_PARSERS: Map< - string, - (name: string, stmt: Stmt, expr: AbstractInvokeExpr) => ViewTreeNodeImpl | undefined - > = new Map([ + private COMPONENT_CREATE_PARSERS: Map ViewTreeNodeImpl | undefined> = new Map([ ['ForEach.create', this.forEachCreationParser.bind(this)], ['LazyForEach.create', this.forEachCreationParser.bind(this)], ['Repeat.create', this.repeatCreationParser.bind(this)], @@ -1060,12 +1026,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { ['WaterFlow.create', this.waterFlowCreationParser.bind(this)], ]); - private componentCreateParse( - componentName: string, - methodName: string, - stmt: Stmt, - expr: ArkStaticInvokeExpr - ): ViewTreeNodeImpl | undefined { + private componentCreateParse(componentName: string, methodName: string, stmt: Stmt, expr: ArkStaticInvokeExpr): ViewTreeNodeImpl | undefined { let parserFn = this.COMPONENT_CREATE_PARSERS.get(`${componentName}.${methodName}`); if (parserFn) { let node = parserFn(componentName, stmt, expr); @@ -1078,11 +1039,7 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { return node; } - private parseStaticInvokeExpr( - local2Node: Map, - stmt: Stmt, - expr: ArkStaticInvokeExpr - ): ViewTreeNodeImpl | undefined { + private parseStaticInvokeExpr(local2Node: Map, stmt: Stmt, expr: ArkStaticInvokeExpr): ViewTreeNodeImpl | undefined { let methodSignature = expr.getMethodSignature(); let method = this.findMethod(methodSignature); if (method?.hasBuilderDecorator()) { @@ -1118,18 +1075,11 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { * @param local2Node * @param expr */ - private parseInstanceInvokeExpr( - local2Node: Map, - stmt: Stmt, - expr: ArkInstanceInvokeExpr - ): ViewTreeNodeImpl | undefined { + private parseInstanceInvokeExpr(local2Node: Map, stmt: Stmt, expr: ArkInstanceInvokeExpr): ViewTreeNodeImpl | undefined { let temp = expr.getBase(); if (local2Node.has(temp)) { let component = local2Node.get(temp); - if ( - component?.name === COMPONENT_REPEAT && - expr.getMethodSignature().getMethodSubSignature().getMethodName() === 'each' - ) { + if (component?.name === COMPONENT_REPEAT && expr.getMethodSignature().getMethodSubSignature().getMethodName() === 'each') { let arg = expr.getArg(0); let type = arg.getType(); if (type instanceof FunctionType) { @@ -1166,18 +1116,11 @@ export class ViewTreeImpl extends TreeNodeStack implements ViewTree { return undefined; } - private parsePtrInvokeExpr( - local2Node: Map, - stmt: Stmt, - expr: ArkPtrInvokeExpr - ): ViewTreeNodeImpl | undefined { + private parsePtrInvokeExpr(local2Node: Map, stmt: Stmt, expr: ArkPtrInvokeExpr): ViewTreeNodeImpl | undefined { let temp = expr.getFuncPtrLocal(); if (temp instanceof Local && local2Node.has(temp)) { let component = local2Node.get(temp); - if ( - component?.name === COMPONENT_REPEAT && - expr.getMethodSignature().getMethodSubSignature().getMethodName() === 'each' - ) { + if (component?.name === COMPONENT_REPEAT && expr.getMethodSignature().getMethodSubSignature().getMethodName() === 'each') { let arg = expr.getArg(0); let type = arg.getType(); if (type instanceof FunctionType) { diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkBaseModel.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkBaseModel.ts index 9d363cdcb459b4c36d04a14a4dfe46da0ceff010..483acec423d0297182fcae9192ad3a5029f69d9f 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkBaseModel.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkBaseModel.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -220,7 +220,7 @@ export abstract class ArkBaseModel { } public removeDecorator(kind: string): void { - this.decorators?.forEach((value) => { + this.decorators?.forEach(value => { if (value.getKind() === kind) { this.decorators?.delete(value); } @@ -235,7 +235,7 @@ export abstract class ArkBaseModel { if (!this.decorators) { return []; } - return Array.from(this.decorators).filter((item) => { + return Array.from(this.decorators).filter(item => { return COMPONENT_MEMBER_DECORATORS.has(item.getKind()); }) as Decorator[]; } @@ -255,7 +255,7 @@ export abstract class ArkBaseModel { public hasDecorator(kind: string | Set): boolean { let decorators = this.getDecorators(); return ( - decorators.filter((value) => { + decorators.filter(value => { if (kind instanceof Set) { return kind.has(value.getKind()); } @@ -276,7 +276,10 @@ export abstract class ArkBaseModel { return { errCode: ArkErrorCode.OK }; } logger.error(`class fields: ${errs.join(',')} is undefined.`); - return { errCode: ArkErrorCode.CLASS_INSTANCE_FIELD_UNDEFINDED, errMsg: `${errs.join(',')} is undefined.` }; + return { + errCode: ArkErrorCode.CLASS_INSTANCE_FIELD_UNDEFINDED, + errMsg: `${errs.join(',')} is undefined.`, + }; } public abstract validate(): ArkError; diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkBody.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkBody.ts index 100e84ff016572756ab91937d7b24091805a59c7..610a3a425f614dde5c4153e484f4cb5656802d7f 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkBody.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkBody.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -19,6 +19,7 @@ import { AliasType } from '../base/Type'; import { Trap } from '../base/Trap'; import { Value } from '../base/Value'; import { ArkAliasTypeDefineStmt } from '../base/Stmt'; +import { LocalSignature } from './ArkSignature'; export class ArkBody { private locals: Map; @@ -27,8 +28,7 @@ export class ArkBody { private aliasTypeMap?: Map; private traps?: Trap[]; - constructor(locals: Set, cfg: Cfg, aliasTypeMap?: Map, - traps?: Trap[]) { + constructor(locals: Set, cfg: Cfg, aliasTypeMap?: Map, traps?: Trap[]) { this.cfg = cfg; this.aliasTypeMap = aliasTypeMap; this.locals = new Map(); @@ -82,4 +82,13 @@ export class ArkBody { public getTraps(): Trap[] | undefined { return this.traps; } -} \ No newline at end of file + + public getExportLocalByName(name: string): Local | null { + const local = this.locals?.get(name); + if (local) { + local.setSignature(new LocalSignature(name, this.cfg.getDeclaringMethod().getSignature())); + return local; + } + return null; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkClass.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkClass.ts index 71584a6492c8292351e5d811a3d4498b14c75f8f..6b013ddbd55e8d55aac0d658007e9b709048d31d 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkClass.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkClass.ts @@ -89,7 +89,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { * Returns the **string**name of this class. * @returns The name of this class. */ - public getName() { + public getName(): string { return this.classSignature.getClassName(); } @@ -97,11 +97,11 @@ export class ArkClass extends ArkBaseModel implements ArkExport { * Returns the codes of class as a **string.** * @returns the codes of class. */ - public getCode() { + public getCode(): string | undefined { return this.code; } - public setCode(code: string) { + public setCode(code: string): void { this.code = code; } @@ -109,11 +109,11 @@ export class ArkClass extends ArkBaseModel implements ArkExport { * Returns the line position of this class. * @returns The line position of this class. */ - public getLine() { + public getLine(): number { return getLineNo(this.lineCol); } - public setLine(line: number) { + public setLine(line: number): void { this.lineCol = setLine(this.lineCol, line); } @@ -121,11 +121,11 @@ export class ArkClass extends ArkBaseModel implements ArkExport { * Returns the column position of this class. * @returns The column position of this class. */ - public getColumn() { + public getColumn(): number { return getColNo(this.lineCol); } - public setColumn(column: number) { + public setColumn(column: number): void { this.lineCol = setCol(this.lineCol, column); } @@ -147,11 +147,11 @@ export class ArkClass extends ArkBaseModel implements ArkExport { const arkFile = arkClass.getDeclaringArkFile(); ``` */ - public getDeclaringArkFile() { + public getDeclaringArkFile(): ArkFile { return this.declaringArkFile; } - public setDeclaringArkFile(declaringArkFile: ArkFile) { + public setDeclaringArkFile(declaringArkFile: ArkFile): void { this.declaringArkFile = declaringArkFile; } @@ -163,7 +163,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { return this.declaringArkNamespace; } - public setDeclaringArkNamespace(declaringArkNamespace: ArkNamespace | undefined) { + public setDeclaringArkNamespace(declaringArkNamespace: ArkNamespace | undefined): void { this.declaringArkNamespace = declaringArkNamespace; } @@ -180,11 +180,11 @@ export class ArkClass extends ArkBaseModel implements ArkExport { * The {@link ClassSignature} can uniquely identify a class, according to which we can find the class from the scene. * @returns The class signature. */ - public getSignature() { + public getSignature(): ClassSignature { return this.classSignature; } - public setSignature(classSig: ClassSignature) { + public setSignature(classSig: ClassSignature): void { this.classSignature = classSig; } @@ -218,8 +218,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { if (type) { type = TypeInference.replaceAliasType(type); } - if (type instanceof ClassType && - (superClass = this.declaringArkFile.getScene().getClass(type.getClassSignature()))) { + if (type instanceof ClassType && (superClass = this.declaringArkFile.getScene().getClass(type.getClassSignature()))) { superClass.addExtendedClass(this); const realGenericTypes = type.getRealGenericTypes(); if (realGenericTypes) { @@ -246,7 +245,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { return this.extendedClasses; } - public addExtendedClass(extendedClass: ArkClass) { + public addExtendedClass(extendedClass: ArkClass): void { this.extendedClasses.set(extendedClass.getName(), extendedClass); } @@ -257,7 +256,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { return Array.from(this.heritageClasses.keys()).slice(1); } - public hasImplementedInterface(interfaceName: string) { + public hasImplementedInterface(interfaceName: string): boolean { return this.heritageClasses.has(interfaceName) && this.getSuperClassName() !== interfaceName; } @@ -302,7 +301,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { return allFields; } - public addField(field: ArkField) { + public addField(field: ArkField): void { if (field.isStatic()) { this.staticFields.set(field.getName(), field); } else { @@ -310,8 +309,8 @@ export class ArkClass extends ArkBaseModel implements ArkExport { } } - public addFields(fields: ArkField[]) { - fields.forEach((field) => { + public addFields(fields: ArkField[]): void { + fields.forEach(field => { this.addField(field); }); } @@ -324,7 +323,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { return this.genericsTypes ? Array.from(this.genericsTypes) : undefined; } - public addGenericType(gType: GenericType) { + public addGenericType(gType: GenericType): void { if (!this.genericsTypes) { this.genericsTypes = []; } @@ -348,8 +347,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { ``` */ public getMethods(generated?: boolean): ArkMethod[] { - const allMethods = Array.from(this.methods.values()) - .filter(f => !generated && !f.isGenerated() || generated); + const allMethods = Array.from(this.methods.values()).filter(f => (!generated && !f.isGenerated()) || generated); allMethods.push(...this.staticMethods.values()); return [...new Set(allMethods)]; } @@ -404,7 +402,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { } } - public setDefaultArkMethod(defaultMethod: ArkMethod) { + public setDefaultArkMethod(defaultMethod: ArkMethod): void { this.defaultMethod = defaultMethod; this.addMethod(defaultMethod); } @@ -413,7 +411,7 @@ export class ArkClass extends ArkBaseModel implements ArkExport { return this.defaultMethod; } - public setViewTree(viewTree: ViewTree) { + public setViewTree(viewTree: ViewTree): void { this.viewTree = viewTree; } @@ -483,11 +481,11 @@ export class ArkClass extends ArkBaseModel implements ArkExport { return globalMap.get(this.declaringArkFile.getFileSignature())!; } - public getAnonymousMethodNumber() { + public getAnonymousMethodNumber(): number { return this.anonymousMethodNumber++; } - public getIndexSignatureNumber() { + public getIndexSignatureNumber(): number { return this.indexSignatureNumber++; } @@ -532,4 +530,4 @@ export class ArkClass extends ArkBaseModel implements ArkExport { public validate(): ArkError { return this.validateFields(['declaringArkFile', 'category', 'classSignature']); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkExport.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkExport.ts index 3830d699365f9d8757798e17dcab5ef0dd5e7331..8d02d8867fe6b123ed275a7df06a522c71e5f582 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkExport.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkExport.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -20,6 +20,7 @@ import { DEFAULT } from '../common/TSConst'; import { ArkBaseModel, ModifierType } from './ArkBaseModel'; import { ArkError } from '../common/ArkError'; import { ArkMetadataKind, CommentsMetadata } from './ArkMetadata'; +import { ArkNamespace } from './ArkNamespace'; export type ExportSignature = NamespaceSignature | ClassSignature | MethodSignature | LocalSignature; @@ -29,7 +30,7 @@ export enum ExportType { METHOD = 2, LOCAL = 3, TYPE = 4, - UNKNOWN = 9 + UNKNOWN = 9, } export interface ArkExport extends ArkSignature { @@ -39,7 +40,6 @@ export interface ArkExport extends ArkSignature { getName(): string; getExportType(): ExportType; - } export interface FromInfo { @@ -67,7 +67,7 @@ export class ExportInfo extends ArkBaseModel implements FromInfo { private originTsPosition?: LineColPosition; private tsSourceCode?: string; private declaringArkFile!: ArkFile; - + private declaringArkNamespace?: ArkNamespace; private constructor() { super(); } @@ -103,7 +103,7 @@ export class ExportInfo extends ArkBaseModel implements FromInfo { return this.nameBeforeAs; } - public setArkExport(value: ArkExport | null) { + public setArkExport(value: ArkExport | null): void { this.arkExport = value; } @@ -133,6 +133,10 @@ export class ExportInfo extends ArkBaseModel implements FromInfo { return this.declaringArkFile; } + public getDeclaringArkNamespace(): ArkNamespace | undefined { + return this.declaringArkNamespace; + } + public static Builder = class ArkExportBuilder { exportInfo: ExportInfo = new ExportInfo(); @@ -171,6 +175,11 @@ export class ExportInfo extends ArkBaseModel implements FromInfo { return this; } + public declaringArkNamespace(value: ArkNamespace): ArkExportBuilder { + this.exportInfo.declaringArkNamespace = value; + return this; + } + public arkExport(value: ArkExport): ArkExportBuilder { this.exportInfo.arkExport = value; return this; diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkField.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkField.ts index e85ce04d1a467abf4dd0361fd1ed49e9eec7bc37..2fcfc43cedeea01220c84a1cba378882d59db1ff 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkField.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkField.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -22,7 +22,6 @@ import { ArkBaseModel, ModifierType } from './ArkBaseModel'; import { ArkError } from '../common/ArkError'; import { Language } from './ArkFile'; - export enum FieldCategory { PROPERTY_DECLARATION = 0, PROPERTY_ASSIGNMENT = 1, @@ -39,7 +38,7 @@ export enum FieldCategory { * @category core/model */ export class ArkField extends ArkBaseModel { - private code: string = ""; + private code: string = ''; private category!: FieldCategory; private declaringClass!: ArkClass; @@ -62,11 +61,11 @@ export class ArkField extends ArkBaseModel { return this.getDeclaringArkClass().getLanguage(); } - public getDeclaringArkClass() { + public getDeclaringArkClass(): ArkClass { return this.declaringClass; } - public setDeclaringArkClass(declaringClass: ArkClass) { + public setDeclaringArkClass(declaringClass: ArkClass): void { this.declaringClass = declaringClass; } @@ -74,11 +73,11 @@ export class ArkField extends ArkBaseModel { * Returns the codes of field as a **string.** * @returns the codes of field. */ - public getCode() { + public getCode(): string { return this.code; } - public setCode(code: string) { + public setCode(code: string): void { this.code = code; } @@ -90,11 +89,11 @@ export class ArkField extends ArkBaseModel { this.category = category; } - public getName() { + public getName(): string { return this.fieldSignature.getFieldName(); } - public getType():Type { + public getType(): Type { return this.fieldSignature.getType(); } @@ -102,7 +101,7 @@ export class ArkField extends ArkBaseModel { return this.fieldSignature; } - public setSignature(fieldSig: FieldSignature) { + public setSignature(fieldSig: FieldSignature): void { this.fieldSignature = fieldSig; } @@ -114,27 +113,27 @@ export class ArkField extends ArkBaseModel { return this.initializer; } - public setInitializer(initializer: Stmt[]) { + public setInitializer(initializer: Stmt[]): void { this.initializer = initializer; } - public setQuestionToken(questionToken: boolean) { + public setQuestionToken(questionToken: boolean): void { this.questionToken = questionToken; } - public setExclamationToken(exclamationToken: boolean) { + public setExclamationToken(exclamationToken: boolean): void { this.exclamationToken = exclamationToken; } - public getQuestionToken() { + public getQuestionToken(): boolean { return this.questionToken; } - public getExclamationToken() { + public getExclamationToken(): boolean { return this.exclamationToken; } - public setOriginPosition(position: LineColPosition) { + public setOriginPosition(position: LineColPosition): void { this.originPosition = position; } @@ -152,12 +151,14 @@ export class ArkField extends ArkBaseModel { // For class field, it is default public if there is not any access modify public isPublic(): boolean { - if (!this.containsModifier(ModifierType.PUBLIC) && + if ( + !this.containsModifier(ModifierType.PUBLIC) && !this.containsModifier(ModifierType.PRIVATE) && !this.containsModifier(ModifierType.PROTECTED) && - this.getDeclaringArkClass().getCategory() === ClassCategory.CLASS) { + this.getDeclaringArkClass().getCategory() === ClassCategory.CLASS + ) { return true; } return this.containsModifier(ModifierType.PUBLIC); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkFile.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkFile.ts index 897af2e03f85df2b8a854d1c76790fe7eca1f229..bc2f6352f1a8ccb8375375bccf70457e015b4208 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkFile.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkFile.ts @@ -19,16 +19,32 @@ import { ImportInfo } from './ArkImport'; import { ArkClass } from './ArkClass'; import { ArkNamespace } from './ArkNamespace'; import { AliasClassSignature, ClassSignature, FileSignature, NamespaceSignature } from './ArkSignature'; -import { ALL } from "../common/TSConst"; - -export const notStmtOrExprKind = ['ModuleDeclaration', 'ClassDeclaration', 'InterfaceDeclaration', 'EnumDeclaration', 'ExportDeclaration', - 'ExportAssignment', 'MethodDeclaration', 'Constructor', 'FunctionDeclaration', 'GetAccessor', 'SetAccessor', 'ArrowFunction', - 'FunctionExpression', 'MethodSignature', 'ConstructSignature', 'CallSignature']; +import { ALL } from '../common/TSConst'; + +export const notStmtOrExprKind = [ + 'ModuleDeclaration', + 'ClassDeclaration', + 'InterfaceDeclaration', + 'EnumDeclaration', + 'ExportDeclaration', + 'ExportAssignment', + 'MethodDeclaration', + 'Constructor', + 'FunctionDeclaration', + 'GetAccessor', + 'SetAccessor', + 'ArrowFunction', + 'FunctionExpression', + 'MethodSignature', + 'ConstructSignature', + 'CallSignature', +]; export enum Language { TYPESCRIPT = 0, ARKTS1_1 = 1, ARKTS1_2 = 2, + JAVASCRIPT = 3, UNKNOWN = -1, } @@ -78,33 +94,33 @@ export class ArkFile { * Returns the **string** name of the file, which also acts as the file's relative path. * @returns The file's name (also means its relative path). */ - public getName() { + public getName(): string { return this.fileSignature.getFileName(); } - public setScene(scene: Scene) { + public setScene(scene: Scene): void { this.scene = scene; } /** - * Returns the scene (i.e., {@link Scene}) built for the project. The {@link Scene} is the core class of ArkAnalyzer, - * through which users can access all the information of the analyzed code (project), + * Returns the scene (i.e., {@link Scene}) built for the project. The {@link Scene} is the core class of ArkAnalyzer, + * through which users can access all the information of the analyzed code (project), * including file list, class list, method list, property list, etc. * @returns The scene of the file. */ - public getScene() { + public getScene(): Scene { return this.scene; } - public getModuleScene() { + public getModuleScene(): ModuleScene | undefined { return this.moduleScene; } - public setModuleScene(moduleScene: ModuleScene) { + public setModuleScene(moduleScene: ModuleScene): void { this.moduleScene = moduleScene; } - public setProjectDir(projectDir: string) { + public setProjectDir(projectDir: string): void { this.projectDir = projectDir; } @@ -126,11 +142,11 @@ export class ArkFile { return this.absoluteFilePath; } - public setFilePath(absoluteFilePath: string) { + public setFilePath(absoluteFilePath: string): void { this.absoluteFilePath = absoluteFilePath; } - public setCode(code: string) { + public setCode(code: string): void { this.code = code; } @@ -138,19 +154,19 @@ export class ArkFile { * Returns the codes of file as a **string.** * @returns the codes of file. */ - public getCode() { + public getCode(): string { return this.code; } - public addArkClass(arkClass: ArkClass) { + public addArkClass(arkClass: ArkClass): void { this.classes.set(arkClass.getName(), arkClass); } - public getDefaultClass() { + public getDefaultClass(): ArkClass { return this.defaultClass; } - public setDefaultClass(defaultClass: ArkClass) { + public setDefaultClass(defaultClass: ArkClass): void { this.defaultClass = defaultClass; } @@ -173,8 +189,7 @@ export class ArkFile { * @returns A class. If there is no class, the return will be a **null**. */ public getClass(classSignature: ClassSignature): ArkClass | null { - const className = classSignature instanceof AliasClassSignature ? classSignature.getOriginName() - : classSignature.getClassName(); + const className = classSignature instanceof AliasClassSignature ? classSignature.getOriginName() : classSignature.getClassName(); return this.getClassWithName(className); } @@ -186,12 +201,12 @@ export class ArkFile { return Array.from(this.classes.values()); } - public addNamespace(namespace: ArkNamespace) { + public addNamespace(namespace: ArkNamespace): void { this.namespaces.set(namespace.getName(), namespace); } - + /** - * Returns an **array** of import information. + * Returns an **array** of import information. * The import information includes: clause's name, type, modifiers, location where it is imported from, etc. * @returns An **array** of import information. */ @@ -203,7 +218,7 @@ export class ArkFile { return this.importInfoMap.get(name); } - public addImportInfo(importInfo: ImportInfo) { + public addImportInfo(importInfo: ImportInfo): void { this.importInfoMap.set(importInfo.getImportClauseName(), importInfo); } @@ -229,7 +244,7 @@ export class ArkFile { if (key !== ALL || value.getFrom()) { exportInfos.push(value); } - }) + }); return exportInfos; } @@ -286,7 +301,7 @@ export class ArkFile { return currExportInfo; } - public addExportInfo(exportInfo: ExportInfo, key?: string) { + public addExportInfo(exportInfo: ExportInfo, key?: string): void { this.exportInfoMap.set(key ?? exportInfo.getExportClauseName(), exportInfo); } @@ -298,19 +313,19 @@ export class ArkFile { this.exportInfoMap.delete(exportInfo.getExportClauseName()); } - public getProjectName() { + public getProjectName(): string { return this.fileSignature.getProjectName(); } - public getModuleName() { + public getModuleName(): string | undefined { return this.moduleScene?.getModuleName(); } - public setOhPackageJson5Path(ohPackageJson5Path: string[]) { + public setOhPackageJson5Path(ohPackageJson5Path: string[]): void { this.ohPackageJson5Path = ohPackageJson5Path; } - public getOhPackageJson5Path() { + public getOhPackageJson5Path(): string[] { return this.ohPackageJson5Path; } @@ -318,7 +333,7 @@ export class ArkFile { * Returns the file signature of this file. A file signature consists of project's name and file's name. * @returns The file signature of this file. */ - public getFileSignature() { + public getFileSignature(): FileSignature { return this.fileSignature; } @@ -329,13 +344,13 @@ export class ArkFile { public getAllNamespacesUnderThisFile(): ArkNamespace[] { let namespaces: ArkNamespace[] = []; namespaces.push(...this.namespaces.values()); - this.namespaces.forEach((ns) => { + this.namespaces.forEach(ns => { namespaces.push(...ns.getAllNamespacesUnderThisNamespace()); }); return namespaces; } - public getAnonymousClassNumber() { + public getAnonymousClassNumber(): number { return this.anonymousClassNumber++; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkImport.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkImport.ts index 80c95ddff1f305a10748dcadf25e562a79d70fef..8ff3ff50acd2f3c10cdee22d87c4f6994626bac8 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkImport.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkImport.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -16,7 +16,7 @@ import { ArkFile, Language } from './ArkFile'; import { LineColPosition } from '../base/Position'; import { ExportInfo, FromInfo } from './ArkExport'; -import { findExportInfo } from "../common/ModelUtils"; +import { findExportInfo } from '../common/ModelUtils'; import { ArkBaseModel } from './ArkBaseModel'; import { ArkError } from '../common/ArkError'; @@ -45,8 +45,14 @@ export class ImportInfo extends ArkBaseModel implements FromInfo { return this.getDeclaringArkFile().getLanguage(); } - public build(importClauseName: string, importType: string, importFrom: string, originTsPosition: LineColPosition, - modifiers: number, nameBeforeAs?: string) { + public build( + importClauseName: string, + importType: string, + importFrom: string, + originTsPosition: LineColPosition, + modifiers: number, + nameBeforeAs?: string + ): void { this.setImportClauseName(importClauseName); this.setImportType(importType); this.setImportFrom(importFrom); @@ -60,8 +66,8 @@ export class ImportInfo extends ArkBaseModel implements FromInfo { } /** - * Returns the export information, i.e., the actual reference generated at the time of call. - * The export information includes: clause's name, clause's type, modifiers, location + * Returns the export information, i.e., the actual reference generated at the time of call. + * The export information includes: clause's name, clause's type, modifiers, location * where it is exported from, etc. If the export information could not be found, **null** will be returned. * @returns The export information. If there is no export information, the return will be a **null**. */ @@ -104,7 +110,7 @@ export class ImportInfo extends ArkBaseModel implements FromInfo { return this.nameBeforeAs; } - public setNameBeforeAs(nameBeforeAs: string | undefined) { + public setNameBeforeAs(nameBeforeAs: string | undefined): void { this.nameBeforeAs = nameBeforeAs; } diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkMetadata.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkMetadata.ts index 76e7cd36e67778ed9c0f4fa6c32d11e9b7d5dfbf..80cbec966fc13586aeeedd49c2c55e0e45f54b23 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkMetadata.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkMetadata.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -20,8 +20,7 @@ export enum ArkMetadataKind { TRAILING_COMMENTS, } -export interface ArkMetadataType { -} +export interface ArkMetadataType {} /** * ArkMetadata @@ -30,7 +29,7 @@ export interface ArkMetadataType { * let stmt: Stmt = xxx; * let comments = stmt.getMetadata(ArkMetadataKind.LEADING_COMMENTS) || []; * comments.forEach((comment) => { - * logger.info(comment); + * logger.info(comment); * }); */ export class ArkMetadata { @@ -49,8 +48,8 @@ export class ArkMetadata { } export type CommentItem = { - content: string, - position: FullPosition + content: string; + position: FullPosition; }; export class CommentsMetadata implements ArkMetadataType { @@ -63,4 +62,4 @@ export class CommentsMetadata implements ArkMetadataType { public getComments(): CommentItem[] { return this.comments; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts index 0f3f704fc8d95b0486f287db66d23314b3d55a4f..f3476d3567b9c43686118ab0ebe8d4f1d266d61e 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts @@ -15,13 +15,13 @@ import { ArkParameterRef, ArkThisRef } from '../base/Ref'; import { ArkAssignStmt, ArkReturnStmt, Stmt } from '../base/Stmt'; -import { ClassType, FunctionType, GenericType, LiteralType, NumberType, Type, UnionType } from '../base/Type'; +import { ClassType, EnumValueType, FunctionType, GenericType, LiteralType, Type, UnionType } from '../base/Type'; import { Value } from '../base/Value'; import { Cfg } from '../graph/Cfg'; import { ViewTree } from '../graph/ViewTree'; import { ArkBody } from './ArkBody'; import { ArkClass, ClassCategory } from './ArkClass'; -import { MethodSignature } from './ArkSignature'; +import { MethodSignature, MethodSubSignature } from './ArkSignature'; import { BodyBuilder } from './builder/BodyBuilder'; import { ArkExport, ExportType } from './ArkExport'; import { ANONYMOUS_METHOD_PREFIX, DEFAULT_ARK_METHOD_NAME } from '../common/Const'; @@ -32,11 +32,22 @@ import { CALL_BACK } from '../common/EtsConst'; import { Scene } from '../../Scene'; import { Constant } from '../base/Constant'; import { Local } from '../base/Local'; -import { Language } from './ArkFile'; +import { ArkFile, Language } from './ArkFile'; import { CONSTRUCTOR_NAME } from '../common/TSConst'; - -export const arkMethodNodeKind = ['MethodDeclaration', 'Constructor', 'FunctionDeclaration', 'GetAccessor', - 'SetAccessor', 'ArrowFunction', 'FunctionExpression', 'MethodSignature', 'ConstructSignature', 'CallSignature']; +import { MethodParameter } from './builder/ArkMethodBuilder'; + +export const arkMethodNodeKind = [ + 'MethodDeclaration', + 'Constructor', + 'FunctionDeclaration', + 'GetAccessor', + 'SetAccessor', + 'ArrowFunction', + 'FunctionExpression', + 'MethodSignature', + 'ConstructSignature', + 'CallSignature', +]; /** * @category core/model @@ -79,7 +90,7 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return ExportType.METHOD; } - public getName() { + public getName(): string { return this.getSignature().getMethodSubSignature().getMethodName(); } @@ -87,11 +98,11 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { * Returns the codes of method as a **string.** * @returns the codes of method. */ - public getCode() { + public getCode(): string | undefined { return this.code; } - public setCode(code: string) { + public setCode(code: string): void { this.code = code; } @@ -231,15 +242,15 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { * Returns the declaring class of the method. * @returns The declaring class of the method. */ - public getDeclaringArkClass() { + public getDeclaringArkClass(): ArkClass { return this.declaringArkClass; } - public setDeclaringArkClass(declaringArkClass: ArkClass) { + public setDeclaringArkClass(declaringArkClass: ArkClass): void { this.declaringArkClass = declaringArkClass; } - public getDeclaringArkFile() { + public getDeclaringArkFile(): ArkFile { return this.declaringArkClass.getDeclaringArkFile(); } @@ -251,11 +262,11 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return this.getName().startsWith(ANONYMOUS_METHOD_PREFIX); } - public getParameters() { + public getParameters(): MethodParameter[] { return this.getSignature().getMethodSubSignature().getParameters(); } - public getReturnType() { + public getReturnType(): Type { return this.getSignature().getType(); } @@ -353,7 +364,7 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { this.methodSignature = signature; } - public getSubSignature() { + public getSubSignature(): MethodSubSignature { return this.getSignature().getMethodSubSignature(); } @@ -398,7 +409,7 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return this.body; } - public setBody(body: ArkBody) { + public setBody(body: ArkBody): void { this.body = body; } @@ -501,19 +512,23 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { public getReturnValues(): Value[] { // 获取方法体中return值实例 let resultValues: Value[] = []; - this.getCfg()?.getStmts().forEach(stmt => { - if (stmt instanceof ArkReturnStmt) { - resultValues.push(stmt.getOp()); - } - }); + this.getCfg() + ?.getStmts() + .forEach(stmt => { + if (stmt instanceof ArkReturnStmt) { + resultValues.push(stmt.getOp()); + } + }); return resultValues; } public getReturnStmt(): Stmt[] { - return this.getCfg()!.getStmts().filter(stmt => stmt instanceof ArkReturnStmt); + return this.getCfg()! + .getStmts() + .filter(stmt => stmt instanceof ArkReturnStmt); } - public setViewTree(viewTree: ViewTree) { + public setViewTree(viewTree: ViewTree): void { this.viewTree = viewTree; } @@ -525,7 +540,7 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return this.viewTree !== undefined; } - public setBodyBuilder(bodyBuilder: BodyBuilder) { + public setBodyBuilder(bodyBuilder: BodyBuilder): void { this.bodyBuilder = bodyBuilder; if (this.getDeclaringArkFile().getScene().buildClassDone()) { this.buildBody(); @@ -536,7 +551,7 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { this.bodyBuilder = undefined; } - public buildBody() { + public buildBody(): void { if (this.bodyBuilder) { const arkBody: ArkBody | null = this.bodyBuilder.build(); if (arkBody) { @@ -553,7 +568,7 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return this.isGeneratedFlag; } - public setIsGeneratedFlag(isGeneratedFlag: boolean) { + public setIsGeneratedFlag(isGeneratedFlag: boolean): void { this.isGeneratedFlag = isGeneratedFlag; } @@ -561,7 +576,7 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return this.asteriskToken; } - public setAsteriskToken(asteriskToken: boolean) { + public setAsteriskToken(asteriskToken: boolean): void { this.asteriskToken = asteriskToken; } @@ -574,25 +589,25 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { if (declareSignatures === null && signature === null) { return { errCode: ArkErrorCode.METHOD_SIGNATURE_UNDEFINED, - errMsg: 'methodDeclareSignatures and methodSignature are both undefined.' + errMsg: 'methodDeclareSignatures and methodSignature are both undefined.', }; } if ((declareSignatures === null) !== (declareLineCols === null)) { return { errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, - errMsg: 'methodDeclareSignatures and methodDeclareLineCols are not matched.' + errMsg: 'methodDeclareSignatures and methodDeclareLineCols are not matched.', }; } if (declareSignatures !== null && declareLineCols !== null && declareSignatures.length !== declareLineCols.length) { return { errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, - errMsg: 'methodDeclareSignatures and methodDeclareLineCols are not matched.' + errMsg: 'methodDeclareSignatures and methodDeclareLineCols are not matched.', }; } if ((signature === null) !== (lineCol === null)) { return { errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, - errMsg: 'methodSignature and lineCol are not matched.' + errMsg: 'methodSignature and lineCol are not matched.', }; } return this.validateFields(['declaringArkClass']); @@ -609,19 +624,23 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return args.length >= min && args.length <= max; }); const scene = this.getDeclaringArkFile().getScene(); - return signatures?.find(p => { - const parameters = p.getMethodSubSignature().getParameters(); - for (let i = 0; i < parameters.length; i++) { - if (!args[i]) { - return parameters[i].isOptional(); - } - const isMatched = this.matchParam(parameters[i].getType(), args[i], scene); - if (!isMatched) { - return false; + return ( + signatures?.find(p => { + const parameters = p.getMethodSubSignature().getParameters(); + for (let i = 0; i < parameters.length; i++) { + if (!args[i]) { + return parameters[i].isOptional(); + } + const isMatched = this.matchParam(parameters[i].getType(), args[i], scene); + if (!isMatched) { + return false; + } } - } - return true; - }) ?? signatures?.[0] ?? this.getSignature(); + return true; + }) ?? + signatures?.[0] ?? + this.getSignature() + ); } private matchParam(paramType: Type, arg: Value, scene: Scene): boolean { @@ -643,15 +662,24 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return matched; } else if (argType instanceof FunctionType && paramType instanceof FunctionType) { return argType.getMethodSignature().getParamLength() === paramType.getMethodSignature().getParamLength(); - } else if (argType instanceof FunctionType && paramType instanceof ClassType && - paramType.getClassSignature().getClassName().includes(CALL_BACK)) { - return true; + } else if (paramType instanceof ClassType && paramType.getClassSignature().getClassName().includes(CALL_BACK)) { + return argType instanceof FunctionType; } else if (paramType instanceof LiteralType && arg instanceof Constant) { - return arg.getValue().replace(/[\"|\']/g, '') === paramType.getLiteralName() - .toString().replace(/[\"|\']/g, ''); - } else if (paramType instanceof NumberType && argType instanceof ClassType && ClassCategory.ENUM === - scene.getClass(argType.getClassSignature())?.getCategory()) { - return true; + return ( + arg.getValue().replace(/[\"|\']/g, '') === + paramType + .getLiteralName() + .toString() + .replace(/[\"|\']/g, '') + ); + } else if (paramType instanceof ClassType && argType instanceof EnumValueType) { + return paramType.getClassSignature() === argType.getFieldSignature().getDeclaringSignature(); + } else if (paramType instanceof EnumValueType) { + if (argType instanceof EnumValueType) { + return paramType.getFieldSignature() === argType.getFieldSignature(); + } else if (argType.constructor === paramType.getConstant()?.getType().constructor && arg instanceof Constant) { + return paramType.getConstant()?.getValue() === arg.getValue(); + } } return argType.constructor === paramType.constructor; } @@ -679,16 +707,18 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { // For class method, if there is no public/private/protected access modifier, it is actually public public isPublic(): boolean { - if (!this.containsModifier(ModifierType.PUBLIC) && + if ( + !this.containsModifier(ModifierType.PUBLIC) && !this.containsModifier(ModifierType.PRIVATE) && !this.containsModifier(ModifierType.PROTECTED) && !this.getDeclaringArkClass().isDefaultArkClass() && !this.isGenerated() && !this.isAnonymousMethod() && this.getName() !== CONSTRUCTOR_NAME && - this.getDeclaringArkClass().getCategory() === ClassCategory.CLASS) { + this.getDeclaringArkClass().getCategory() === ClassCategory.CLASS + ) { return true; } return this.containsModifier(ModifierType.PUBLIC); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkNamespace.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkNamespace.ts index b6fb1659c6d5e5f473ed3ca2b2325c0509dcae38..e8558124106face9013b69d5ad1037e774f20b53 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkNamespace.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkNamespace.ts @@ -58,7 +58,7 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { return this.getDeclaringArkFile().getLanguage(); } - public addNamespace(namespace: ArkNamespace) { + public addNamespace(namespace: ArkNamespace): void { this.namespaces.set(namespace.getName(), namespace); } @@ -79,23 +79,23 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { this.namespaceSignature = namespaceSignature; } - public getSignature() { + public getSignature(): NamespaceSignature { return this.namespaceSignature; } - public getNamespaceSignature() { + public getNamespaceSignature(): NamespaceSignature { return this.namespaceSignature; } - public getName() { + public getName(): string { return this.namespaceSignature.getNamespaceName(); } - public getCode() { + public getCode(): string { return this.sourceCodes[0]; } - public setCode(sourceCode: string) { + public setCode(sourceCode: string): void { this.sourceCodes[0] = sourceCode; } @@ -118,19 +118,19 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { this.sourceCodes.push(sourceCode); } - public getLine() { + public getLine(): number { return getLineNo(this.lineCols[0]); } - public setLine(line: number) { + public setLine(line: number): void { this.lineCols[0] = setLine(this.lineCols[0], line); } - public getColumn() { + public getColumn(): number { return getColNo(this.lineCols[0]); } - public setColumn(column: number) { + public setColumn(column: number): void { this.lineCols[0] = setCol(this.lineCols[0], column); } @@ -149,33 +149,32 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { }); } - public getDeclaringInstance() { + public getDeclaringInstance(): ArkNamespace | ArkFile { return this.declaringInstance; } - public setDeclaringInstance(declaringInstance: ArkFile | ArkNamespace) { + public setDeclaringInstance(declaringInstance: ArkFile | ArkNamespace): void { this.declaringInstance = declaringInstance; } - public getDeclaringArkFile() { + public getDeclaringArkFile(): ArkFile { return this.declaringArkFile; } - public setDeclaringArkFile(declaringArkFile: ArkFile) { + public setDeclaringArkFile(declaringArkFile: ArkFile): void { this.declaringArkFile = declaringArkFile; } - public getDeclaringArkNamespace() { + public getDeclaringArkNamespace(): ArkNamespace | null { return this.declaringArkNamespace; } - public setDeclaringArkNamespace(declaringArkNamespace: ArkNamespace) { + public setDeclaringArkNamespace(declaringArkNamespace: ArkNamespace): void { this.declaringArkNamespace = declaringArkNamespace; } public getClass(classSignature: ClassSignature): ArkClass | null { - const className = classSignature instanceof AliasClassSignature ? classSignature.getOriginName() - : classSignature.getClassName(); + const className = classSignature instanceof AliasClassSignature ? classSignature.getOriginName() : classSignature.getClassName(); return this.getClassWithName(className); } @@ -187,7 +186,7 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { return Array.from(this.classes.values()); } - public addArkClass(arkClass: ArkClass) { + public addArkClass(arkClass: ArkClass): void { this.classes.set(arkClass.getName(), arkClass); } @@ -205,24 +204,24 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { return this.exportInfos.get(name); } - public addExportInfo(exportInfo: ExportInfo) { + public addExportInfo(exportInfo: ExportInfo): void { this.exportInfos.set(exportInfo.getExportClauseName(), exportInfo); } - public getDefaultClass() { + public getDefaultClass(): ArkClass { return this.defaultClass; } - public setDefaultClass(defaultClass: ArkClass) { + public setDefaultClass(defaultClass: ArkClass): void { this.defaultClass = defaultClass; } public getAllMethodsUnderThisNamespace(): ArkMethod[] { let methods: ArkMethod[] = []; - this.classes.forEach((cls) => { + this.classes.forEach(cls => { methods.push(...cls.getMethods()); }); - this.namespaces.forEach((ns) => { + this.namespaces.forEach(ns => { methods.push(...ns.getAllMethodsUnderThisNamespace()); }); return methods; @@ -231,7 +230,7 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { public getAllClassesUnderThisNamespace(): ArkClass[] { let classes: ArkClass[] = []; classes.push(...this.classes.values()); - this.namespaces.forEach((ns) => { + this.namespaces.forEach(ns => { classes.push(...ns.getAllClassesUnderThisNamespace()); }); return classes; @@ -240,13 +239,13 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { public getAllNamespacesUnderThisNamespace(): ArkNamespace[] { let namespaces: ArkNamespace[] = []; namespaces.push(...this.namespaces.values()); - this.namespaces.forEach((ns) => { + this.namespaces.forEach(ns => { namespaces.push(...ns.getAllNamespacesUnderThisNamespace()); }); return namespaces; } - public getAnonymousClassNumber() { + public getAnonymousClassNumber(): number { return this.anonymousClassNumber++; } @@ -270,4 +269,3 @@ export class ArkNamespace extends ArkBaseModel implements ArkExport { return this.validateFields(['declaringArkFile', 'declaringInstance', 'namespaceSignature', 'defaultClass']); } } - diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkSignature.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkSignature.ts index a7d875221aa999fb9ac50d1a76661bfe2e5d29b3..16fa6a76b8a27a4c3c88229da70fba5b4bffe483 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkSignature.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkSignature.ts @@ -24,18 +24,11 @@ import { UNKNOWN_CLASS_NAME, UNKNOWN_FILE_NAME, UNKNOWN_NAMESPACE_NAME, - UNKNOWN_PROJECT_NAME + UNKNOWN_PROJECT_NAME, } from '../common/Const'; import { CryptoUtils } from '../../utils/crypto_utils'; -export type Signature = - FileSignature - | NamespaceSignature - | ClassSignature - | MethodSignature - | FieldSignature - | LocalSignature - | AliasTypeSignature; +export type Signature = FileSignature | NamespaceSignature | ClassSignature | MethodSignature | FieldSignature | LocalSignature | AliasTypeSignature; export interface ArkSignature { getSignature(): Signature; @@ -57,11 +50,11 @@ export class FileSignature { this.hashcode = CryptoUtils.hashcode(this.toString()); } - public getProjectName() { + public getProjectName(): string { return this.projectName; } - public getFileName() { + public getFileName(): string { return this.fileName; } @@ -79,25 +72,23 @@ export class NamespaceSignature { private declaringFileSignature: FileSignature; private declaringNamespaceSignature: NamespaceSignature | null; - public static readonly DEFAULT: NamespaceSignature = new NamespaceSignature(UNKNOWN_NAMESPACE_NAME, - FileSignature.DEFAULT, null); + public static readonly DEFAULT: NamespaceSignature = new NamespaceSignature(UNKNOWN_NAMESPACE_NAME, FileSignature.DEFAULT, null); - constructor(namespaceName: string, declaringFileSignature: FileSignature, - declaringNamespaceSignature: NamespaceSignature | null = null) { + constructor(namespaceName: string, declaringFileSignature: FileSignature, declaringNamespaceSignature: NamespaceSignature | null = null) { this.namespaceName = namespaceName; this.declaringFileSignature = declaringFileSignature; this.declaringNamespaceSignature = declaringNamespaceSignature; } - public getNamespaceName() { + public getNamespaceName(): string { return this.namespaceName; } - public getDeclaringFileSignature() { + public getDeclaringFileSignature(): FileSignature { return this.declaringFileSignature; } - public getDeclaringNamespaceSignature() { + public getDeclaringNamespaceSignature(): NamespaceSignature | null { return this.declaringNamespaceSignature; } @@ -123,11 +114,9 @@ export class ClassSignature { private declaringNamespaceSignature: NamespaceSignature | null; private className: string; - public static readonly DEFAULT: ClassSignature = new ClassSignature(UNKNOWN_CLASS_NAME, FileSignature.DEFAULT, - null); + public static readonly DEFAULT: ClassSignature = new ClassSignature(UNKNOWN_CLASS_NAME, FileSignature.DEFAULT, null); - constructor(className: string, declaringFileSignature: FileSignature, - declaringNamespaceSignature: NamespaceSignature | null = null) { + constructor(className: string, declaringFileSignature: FileSignature, declaringNamespaceSignature: NamespaceSignature | null = null) { this.className = className; this.declaringFileSignature = declaringFileSignature; this.declaringNamespaceSignature = declaringNamespaceSignature; @@ -137,7 +126,7 @@ export class ClassSignature { * Returns the declaring file signature. * @returns The declaring file signature. */ - public getDeclaringFileSignature() { + public getDeclaringFileSignature(): FileSignature { return this.declaringFileSignature; } @@ -145,7 +134,7 @@ export class ClassSignature { * Get the declaring namespace's signature. * @returns the declaring namespace's signature. */ - public getDeclaringNamespaceSignature() { + public getDeclaringNamespaceSignature(): NamespaceSignature | null { return this.declaringNamespaceSignature; } @@ -153,7 +142,7 @@ export class ClassSignature { * Get the **string** name of class from the the class signature. The default value is `""`. * @returns The name of this class. */ - public getClassName() { + public getClassName(): string { return this.className; } @@ -172,7 +161,7 @@ export class ClassSignature { return this.className; } - public setClassName(className: string) { + public setClassName(className: string): void { this.className = className; } @@ -238,16 +227,15 @@ export class FieldSignature { this.staticFlag = staticFlag; } - public getDeclaringSignature() { + public getDeclaringSignature(): BaseSignature { return this.declaringSignature; } - public getBaseName() { - return this.declaringSignature instanceof ClassSignature ? this.declaringSignature.getClassName() - : this.declaringSignature.getNamespaceName(); + public getBaseName(): string { + return this.declaringSignature instanceof ClassSignature ? this.declaringSignature.getClassName() : this.declaringSignature.getNamespaceName(); } - public getFieldName() { + public getFieldName(): string { return this.fieldName; } @@ -291,17 +279,17 @@ export class MethodSubSignature { this.staticFlag = staticFlag; } - public getMethodName() { + public getMethodName(): string { return this.methodName; } - public getParameters() { + public getParameters(): MethodParameter[] { return this.parameters; } public getParameterTypes(): Type[] { const parameterTypes: Type[] = []; - this.parameters.forEach((parameter) => { + this.parameters.forEach(parameter => { parameterTypes.push(parameter.getType()); }); return parameterTypes; @@ -320,9 +308,9 @@ export class MethodSubSignature { } public toString(ptrName?: string): string { - let paraStr = ""; - this.getParameterTypes().forEach((parameterType) => { - paraStr += parameterType.toString() + ", "; + let paraStr = ''; + this.getParameterTypes().forEach(parameterType => { + paraStr += parameterType.toString() + ', '; }); paraStr = paraStr.replace(/, $/, ''); let tmpSig = `${ptrName ?? this.getMethodName()}(${paraStr})`; @@ -348,8 +336,10 @@ export class MethodSignature { /** * Return the declaring class signature. * A {@link ClassSignature} includes: - * - File Signature: including the **string** names of the project and file, respectively. The default value of project's name is "%unk" and the default value of file's name is "%unk". - * - Namespace Signature | **null**: it may be a namespace signature or **null**. A namespace signature can indicate its **string** name of namespace and its file signature. + * - File Signature: including the **string** names of the project and file, respectively. + * The default value of project's name is "%unk" and the default value of file's name is "%unk". + * - Namespace Signature | **null**: it may be a namespace signature or **null**. + * A namespace signature can indicate its **string** name of namespace and its file signature. * - Class Name: the **string** name of this class. * @returns The declaring class signature. * @example @@ -361,7 +351,7 @@ export class MethodSignature { ``` * */ - public getDeclaringClassSignature() { + public getDeclaringClassSignature(): ClassSignature { return this.declaringClassSignature; } @@ -371,7 +361,7 @@ export class MethodSignature { * identify the name of the method, its parameters and the return value type. * @returns The sub-signature of this method signature. */ - public getMethodSubSignature() { + public getMethodSubSignature(): MethodSubSignature { return this.methodSubSignature; } @@ -388,12 +378,11 @@ export class MethodSignature { } public isMatch(signature: MethodSignature): boolean { - return ((this.toString() === signature.toString()) && (this.getType().toString() === signature.getType().toString())); + return this.toString() === signature.toString() && this.getType().toString() === signature.getType().toString(); } public getParamLength(): number { - return this.methodSubSignature.getParameters() - .filter(p => !p.getName().startsWith(LEXICAL_ENV_NAME_PREFIX)).length; + return this.methodSubSignature.getParameters().filter(p => !p.getName().startsWith(LEXICAL_ENV_NAME_PREFIX)).length; } } @@ -443,45 +432,48 @@ export class AliasTypeSignature { //TODO, reconstruct export function fieldSignatureCompare(leftSig: FieldSignature, rightSig: FieldSignature): boolean { - if (leftSig.getDeclaringSignature().toString() === rightSig.getDeclaringSignature().toString() && - (leftSig.getFieldName() === rightSig.getFieldName())) { + if (leftSig.getDeclaringSignature().toString() === rightSig.getDeclaringSignature().toString() && leftSig.getFieldName() === rightSig.getFieldName()) { return true; } return false; } export function methodSignatureCompare(leftSig: MethodSignature, rightSig: MethodSignature): boolean { - if (classSignatureCompare(leftSig.getDeclaringClassSignature(), rightSig.getDeclaringClassSignature()) && - methodSubSignatureCompare(leftSig.getMethodSubSignature(), rightSig.getMethodSubSignature())) { + if ( + classSignatureCompare(leftSig.getDeclaringClassSignature(), rightSig.getDeclaringClassSignature()) && + methodSubSignatureCompare(leftSig.getMethodSubSignature(), rightSig.getMethodSubSignature()) + ) { return true; } return false; } export function methodSubSignatureCompare(leftSig: MethodSubSignature, rightSig: MethodSubSignature): boolean { - if ((leftSig.getMethodName() === rightSig.getMethodName()) && arrayCompare(leftSig.getParameterTypes(), - rightSig.getParameterTypes()) && leftSig.getReturnType() === rightSig.getReturnType()) { + if ( + leftSig.getMethodName() === rightSig.getMethodName() && + arrayCompare(leftSig.getParameterTypes(), rightSig.getParameterTypes()) && + leftSig.getReturnType() === rightSig.getReturnType() + ) { return true; } return false; } export function classSignatureCompare(leftSig: ClassSignature, rightSig: ClassSignature): boolean { - if ((fileSignatureCompare(leftSig.getDeclaringFileSignature(), rightSig.getDeclaringFileSignature())) && - (leftSig.getClassName() === rightSig.getClassName())) { + if (fileSignatureCompare(leftSig.getDeclaringFileSignature(), rightSig.getDeclaringFileSignature()) && leftSig.getClassName() === rightSig.getClassName()) { return true; } return false; } export function fileSignatureCompare(leftSig: FileSignature, rightSig: FileSignature): boolean { - if ((leftSig.getFileName() === rightSig.getFileName()) && (leftSig.getProjectName() === rightSig.getProjectName())) { + if (leftSig.getFileName() === rightSig.getFileName() && leftSig.getProjectName() === rightSig.getProjectName()) { return true; } return false; } -function arrayCompare(leftArray: any[], rightArray: any[]) { +function arrayCompare(leftArray: any[], rightArray: any[]): boolean { if (leftArray.length !== rightArray.length) { return false; } @@ -495,4 +487,4 @@ function arrayCompare(leftArray: any[], rightArray: any[]) { export function genSignature4ImportClause(arkFileName: string, importClauseName: string): string { return `<${arkFileName}>.<${importClauseName}>`; -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkClassBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkClassBuilder.ts index 62b1f124c0f3d026cdda6336a0076638835beebd..7c3f16938470b32b10ed1636e6a0354baa1baa73 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkClassBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkClassBuilder.ts @@ -45,37 +45,40 @@ import { ArkStaticInvokeExpr } from '../../base/Expr'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkClassBuilder'); export type ClassLikeNode = - ts.ClassDeclaration | - ts.InterfaceDeclaration | - ts.EnumDeclaration | - ts.ClassExpression | - ts.TypeLiteralNode | - ts.StructDeclaration | - ts.ObjectLiteralExpression; + | ts.ClassDeclaration + | ts.InterfaceDeclaration + | ts.EnumDeclaration + | ts.ClassExpression + | ts.TypeLiteralNode + | ts.StructDeclaration + | ts.ObjectLiteralExpression; type ClassLikeNodeWithMethod = - ts.ClassDeclaration | - ts.InterfaceDeclaration | - ts.EnumDeclaration | - ts.ClassExpression | - ts.TypeLiteralNode | - ts.StructDeclaration; - -export function buildDefaultArkClassFromArkFile(arkFile: ArkFile, defaultClass: ArkClass, astRoot: ts.SourceFile) { + | ts.ClassDeclaration + | ts.InterfaceDeclaration + | ts.EnumDeclaration + | ts.ClassExpression + | ts.TypeLiteralNode + | ts.StructDeclaration; + +export function buildDefaultArkClassFromArkFile(arkFile: ArkFile, defaultClass: ArkClass, astRoot: ts.SourceFile): void { defaultClass.setDeclaringArkFile(arkFile); defaultClass.setCategory(ClassCategory.CLASS); buildDefaultArkClass(defaultClass, astRoot); } -export function buildDefaultArkClassFromArkNamespace(arkNamespace: ArkNamespace, defaultClass: ArkClass, - nsNode: ts.ModuleDeclaration, sourceFile: ts.SourceFile) { +export function buildDefaultArkClassFromArkNamespace( + arkNamespace: ArkNamespace, + defaultClass: ArkClass, + nsNode: ts.ModuleDeclaration, + sourceFile: ts.SourceFile +): void { defaultClass.setDeclaringArkNamespace(arkNamespace); defaultClass.setDeclaringArkFile(arkNamespace.getDeclaringArkFile()); buildDefaultArkClass(defaultClass, sourceFile, nsNode); } -export function buildNormalArkClassFromArkMethod(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile, - declaringMethod?: ArkMethod) { +export function buildNormalArkClassFromArkMethod(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { const namespace = cls.getDeclaringArkNamespace(); if (namespace) { buildNormalArkClassFromArkNamespace(clsNode, namespace, cls, sourceFile, declaringMethod); @@ -84,14 +87,16 @@ export function buildNormalArkClassFromArkMethod(clsNode: ClassLikeNode, cls: Ar } } -export function buildNormalArkClassFromArkFile(clsNode: ClassLikeNode, arkFile: ArkFile, cls: ArkClass, - sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +export function buildNormalArkClassFromArkFile( + clsNode: ClassLikeNode, + arkFile: ArkFile, + cls: ArkClass, + sourceFile: ts.SourceFile, + declaringMethod?: ArkMethod +): void { cls.setDeclaringArkFile(arkFile); cls.setCode(clsNode.getText(sourceFile)); - const { line, character } = ts.getLineAndCharacterOfPosition( - sourceFile, - clsNode.getStart(sourceFile), - ); + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, clsNode.getStart(sourceFile)); cls.setLine(line + 1); cls.setColumn(character + 1); @@ -99,15 +104,17 @@ export function buildNormalArkClassFromArkFile(clsNode: ClassLikeNode, arkFile: arkFile.addArkClass(cls); } -export function buildNormalArkClassFromArkNamespace(clsNode: ClassLikeNode, arkNamespace: ArkNamespace, cls: ArkClass, - sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +export function buildNormalArkClassFromArkNamespace( + clsNode: ClassLikeNode, + arkNamespace: ArkNamespace, + cls: ArkClass, + sourceFile: ts.SourceFile, + declaringMethod?: ArkMethod +): void { cls.setDeclaringArkNamespace(arkNamespace); cls.setDeclaringArkFile(arkNamespace.getDeclaringArkFile()); cls.setCode(clsNode.getText(sourceFile)); - const { line, character } = ts.getLineAndCharacterOfPosition( - sourceFile, - clsNode.getStart(sourceFile), - ); + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, clsNode.getStart(sourceFile)); cls.setLine(line + 1); cls.setColumn(character + 1); @@ -115,21 +122,24 @@ export function buildNormalArkClassFromArkNamespace(clsNode: ClassLikeNode, arkN arkNamespace.addArkClass(cls); } -function buildDefaultArkClass(cls: ArkClass, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration) { - const defaultArkClassSignature = new ClassSignature(DEFAULT_ARK_CLASS_NAME, - cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); +function buildDefaultArkClass(cls: ArkClass, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration): void { + const defaultArkClassSignature = new ClassSignature( + DEFAULT_ARK_CLASS_NAME, + cls.getDeclaringArkFile().getFileSignature(), + cls.getDeclaringArkNamespace()?.getSignature() || null + ); cls.setSignature(defaultArkClassSignature); genDefaultArkMethod(cls, sourceFile, node); } -function genDefaultArkMethod(cls: ArkClass, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration) { +function genDefaultArkMethod(cls: ArkClass, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration): void { let defaultMethod = new ArkMethod(); buildDefaultArkMethodFromArkClass(cls, defaultMethod, sourceFile, node); cls.setDefaultArkMethod(defaultMethod); } -export function buildNormalArkClass(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +export function buildNormalArkClass(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { switch (clsNode.kind) { case ts.SyntaxKind.StructDeclaration: buildStruct2ArkClass(clsNode, cls, sourceFile, declaringMethod); @@ -153,19 +163,17 @@ export function buildNormalArkClass(clsNode: ClassLikeNode, cls: ArkClass, sourc buildObjectLiteralExpression2ArkClass(clsNode, cls, sourceFile, declaringMethod); break; default: - ; } IRUtils.setComments(cls, clsNode, sourceFile, cls.getDeclaringArkFile().getScene().getOptions()); } -function init4InstanceInitMethod(cls: ArkClass) { +function init4InstanceInitMethod(cls: ArkClass): void { const instanceInit = new ArkMethod(); instanceInit.setDeclaringArkClass(cls); instanceInit.setIsGeneratedFlag(true); const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(INSTANCE_INIT_METHOD_NAME); methodSubSignature.setReturnType(VoidType.getInstance()); - const methodSignature = new MethodSignature(instanceInit.getDeclaringArkClass().getSignature(), - methodSubSignature); + const methodSignature = new MethodSignature(instanceInit.getDeclaringArkClass().getSignature(), methodSubSignature); instanceInit.setImplementationSignature(methodSignature); instanceInit.setLineCol(0); @@ -174,14 +182,13 @@ function init4InstanceInitMethod(cls: ArkClass) { cls.setInstanceInitMethod(instanceInit); } -function init4StaticInitMethod(cls: ArkClass) { +function init4StaticInitMethod(cls: ArkClass): void { const staticInit = new ArkMethod(); staticInit.setDeclaringArkClass(cls); staticInit.setIsGeneratedFlag(true); const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(STATIC_INIT_METHOD_NAME); methodSubSignature.setReturnType(VoidType.getInstance()); - const methodSignature = new MethodSignature(staticInit.getDeclaringArkClass().getSignature(), - methodSubSignature); + const methodSignature = new MethodSignature(staticInit.getDeclaringArkClass().getSignature(), methodSubSignature); staticInit.setImplementationSignature(methodSignature); staticInit.setLineCol(0); @@ -190,14 +197,13 @@ function init4StaticInitMethod(cls: ArkClass) { cls.setStaticInitMethod(staticInit); } -function buildStruct2ArkClass(clsNode: ts.StructDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +function buildStruct2ArkClass(clsNode: ts.StructDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); - const classSignature = new ClassSignature(className, - cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); cls.setSignature(classSignature); if (clsNode.typeParameters) { - buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach((typeParameter) => { + buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { cls.addGenericType(typeParameter); }); } @@ -213,14 +219,13 @@ function buildStruct2ArkClass(clsNode: ts.StructDeclaration, cls: ArkClass, sour buildArkClassMembers(clsNode, cls, sourceFile); } -function buildClass2ArkClass(clsNode: ts.ClassDeclaration | ts.ClassExpression, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +function buildClass2ArkClass(clsNode: ts.ClassDeclaration | ts.ClassExpression, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); - const classSignature = new ClassSignature(className, - cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); cls.setSignature(classSignature); if (clsNode.typeParameters) { - buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach((typeParameter) => { + buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { cls.addGenericType(typeParameter); }); } @@ -250,14 +255,13 @@ function initHeritage(heritageClauses: Map, cls: ArkClass): void } } -function buildInterface2ArkClass(clsNode: ts.InterfaceDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +function buildInterface2ArkClass(clsNode: ts.InterfaceDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); - const classSignature = new ClassSignature(className, - cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); cls.setSignature(classSignature); if (clsNode.typeParameters) { - buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach((typeParameter) => { + buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { cls.addGenericType(typeParameter); }); } @@ -272,10 +276,9 @@ function buildInterface2ArkClass(clsNode: ts.InterfaceDeclaration, cls: ArkClass buildArkClassMembers(clsNode, cls, sourceFile); } -function buildEnum2ArkClass(clsNode: ts.EnumDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +function buildEnum2ArkClass(clsNode: ts.EnumDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); - const classSignature = new ClassSignature(className, - cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); cls.setSignature(classSignature); cls.setModifiers(buildModifiers(clsNode)); @@ -287,28 +290,28 @@ function buildEnum2ArkClass(clsNode: ts.EnumDeclaration, cls: ArkClass, sourceFi buildArkClassMembers(clsNode, cls, sourceFile); } -function buildTypeLiteralNode2ArkClass(clsNode: ts.TypeLiteralNode, cls: ArkClass, - sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +function buildTypeLiteralNode2ArkClass(clsNode: ts.TypeLiteralNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { const className = genClassName('', cls, declaringMethod); - const classSignature = new ClassSignature(className, - cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); cls.setSignature(classSignature); - cls.setCategory(ClassCategory.TYPE_LITERAL); if (ts.isTypeAliasDeclaration(clsNode.parent) && clsNode.parent.typeParameters) { - buildTypeParameters(clsNode.parent.typeParameters, sourceFile, cls).forEach((typeParameter) => { + buildTypeParameters(clsNode.parent.typeParameters, sourceFile, cls).forEach(typeParameter => { cls.addGenericType(typeParameter); }); } buildArkClassMembers(clsNode, cls, sourceFile); } -function buildObjectLiteralExpression2ArkClass(clsNode: ts.ObjectLiteralExpression, cls: ArkClass, - sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +function buildObjectLiteralExpression2ArkClass( + clsNode: ts.ObjectLiteralExpression, + cls: ArkClass, + sourceFile: ts.SourceFile, + declaringMethod?: ArkMethod +): void { const className = genClassName('', cls, declaringMethod); - const classSignature = new ClassSignature(className, - cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); cls.setSignature(classSignature); cls.setCategory(ClassCategory.OBJECT); @@ -318,7 +321,7 @@ function buildObjectLiteralExpression2ArkClass(clsNode: ts.ObjectLiteralExpressi init4InstanceInitMethod(cls); const instanceIRTransformer = new ArkIRTransformer(sourceFile, cls.getInstanceInitMethod()); const instanceFieldInitializerStmts: Stmt[] = []; - clsNode.properties.forEach((property) => { + clsNode.properties.forEach(property => { if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isSpreadAssignment(property)) { const arkField = buildProperty2ArkField(property, sourceFile, cls); if (ts.isPropertyAssignment(property)) { @@ -332,7 +335,7 @@ function buildObjectLiteralExpression2ArkClass(clsNode: ts.ObjectLiteralExpressi } }); buildInitMethod(cls.getInstanceInitMethod(), instanceFieldInitializerStmts, instanceIRTransformer.getThisLocal()); - arkMethods.forEach((mtd) => { + arkMethods.forEach(mtd => { checkAndUpdateMethod(mtd, cls); cls.addMethod(mtd); }); @@ -348,7 +351,7 @@ function genClassName(declaringName: string, cls: ArkClass, declaringMethod?: Ar return declaringName + suffix; } -function buildArkClassMembers(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile) { +function buildArkClassMembers(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile): void { if (ts.isObjectLiteralExpression(clsNode)) { return; } @@ -366,7 +369,7 @@ function buildArkClassMembers(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: const staticInitStmts: Stmt[] = []; const instanceInitStmts: Stmt[] = []; let staticBlockId = 0; - clsNode.members.forEach((member) => { + clsNode.members.forEach(member => { if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) { const arkField = buildProperty2ArkField(member, sourceFile, cls); if (ts.isClassDeclaration(clsNode) || ts.isClassExpression(clsNode) || ts.isStructDeclaration(clsNode)) { @@ -374,8 +377,9 @@ function buildArkClassMembers(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: getInitStmts(staticIRTransformer, arkField, member.initializer); arkField.getInitializer().forEach(stmt => staticInitStmts.push(stmt)); } else { - if (!instanceIRTransformer) + if (!instanceIRTransformer) { console.log(clsNode.getText(sourceFile)); + } getInitStmts(instanceIRTransformer, arkField, member.initializer); arkField.getInitializer().forEach(stmt => instanceInitStmts.push(stmt)); } @@ -406,7 +410,7 @@ function buildArkClassMembers(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: } function buildMethodsForClass(clsNode: ClassLikeNodeWithMethod, cls: ArkClass, sourceFile: ts.SourceFile): void { - clsNode.members.forEach((member) => { + clsNode.members.forEach(member => { if ( ts.isMethodDeclaration(member) || ts.isConstructorDeclaration(member) || @@ -431,7 +435,7 @@ function buildParameterProperty2ArkField(params: ts.NodeArray { + params.forEach(parameter => { if (parameter.modifiers === undefined || !ts.isIdentifier(parameter.name)) { return; } @@ -445,7 +449,7 @@ function buildParameterProperty2ArkField(params: ts.NodeArray { + clsNode.members.forEach(member => { if (ts.isClassStaticBlockDeclaration(member)) { const staticBlockMethod = new ArkMethod(); staticBlockMethod.setDeclaringArkClass(cls); @@ -471,10 +474,7 @@ function buildStaticBlocksForClass(clsNode: ClassLikeNodeWithMethod, cls: ArkCla const methodSignature = new MethodSignature(cls.getSignature(), methodSubSignature); staticBlockMethodSignatures.push(methodSignature); staticBlockMethod.setImplementationSignature(methodSignature); - const { line, character } = ts.getLineAndCharacterOfPosition( - sourceFile, - member.getStart(sourceFile), - ); + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, member.getStart(sourceFile)); staticBlockMethod.setLine(line + 1); staticBlockMethod.setColumn(character + 1); @@ -487,18 +487,13 @@ function buildStaticBlocksForClass(clsNode: ClassLikeNodeWithMethod, cls: ArkCla return staticBlockMethodSignatures; } -function getInitStmts(transformer: ArkIRTransformer, field: ArkField, initNode?: ts.Node) { +function getInitStmts(transformer: ArkIRTransformer, field: ArkField, initNode?: ts.Node): void { if (initNode) { const stmts: Stmt[] = []; - let { - value: initValue, - valueOriginalPositions: initPositions, - stmts: initStmts, - } = transformer.tsNodeToValueAndStmts(initNode); + let { value: initValue, valueOriginalPositions: initPositions, stmts: initStmts } = transformer.tsNodeToValueAndStmts(initNode); initStmts.forEach(stmt => stmts.push(stmt)); if (IRUtils.moreThanOneAddress(initValue)) { - ({ value: initValue, valueOriginalPositions: initPositions, stmts: initStmts } = - transformer.generateAssignStmtForValue(initValue, initPositions)); + ({ value: initValue, valueOriginalPositions: initPositions, stmts: initStmts } = transformer.generateAssignStmtForValue(initValue, initPositions)); initStmts.forEach(stmt => stmts.push(stmt)); } diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkExportBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkExportBuilder.ts index 9bfee8c4c8de240e8a4d22f20979a28174847b1a..c66aa142a4cac9f052943f4685d1709fbe3fde04 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkExportBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkExportBuilder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -23,6 +23,7 @@ import { ArkBaseModel, ModifierType } from '../ArkBaseModel'; import { IRUtils } from '../../common/IRUtils'; import { ArkClass } from '../ArkClass'; import { buildNormalArkClassFromArkFile } from './ArkClassBuilder'; +import { ArkNamespace } from '../ArkNamespace'; export { buildExportInfo, buildExportAssignment, buildExportDeclaration }; @@ -43,8 +44,7 @@ function buildExportInfo(arkInstance: ArkExport, arkFile: ArkFile, line: LineCol .build(); } - -export function buildDefaultExportInfo(im: FromInfo, file: ArkFile, arkExport?: ArkExport) { +export function buildDefaultExportInfo(im: FromInfo, file: ArkFile, arkExport?: ArkExport): ExportInfo { return new ExportInfo.Builder() .exportClauseType(arkExport?.getExportType() ?? ExportType.CLASS) .exportClauseName(im.getOriginName()) @@ -64,7 +64,7 @@ function buildExportDeclaration(node: ts.ExportDeclaration, sourceFile: ts.Sourc let exportInfos: ExportInfo[] = []; // just like: export {xxx as x} from './yy' if (node.exportClause && ts.isNamedExports(node.exportClause) && node.exportClause.elements) { - node.exportClause.elements.forEach((element) => { + node.exportClause.elements.forEach(element => { let builder = new ExportInfo.Builder() .exportClauseType(ExportType.UNKNOWN) .exportClauseName(element.name.text) @@ -93,9 +93,11 @@ function buildExportDeclaration(node: ts.ExportDeclaration, sourceFile: ts.Sourc .setLeadingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), true)) .setTrailingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), false)) .originTsPosition(originTsPosition); - if (node.exportClause && ts.isNamespaceExport(node.exportClause) && ts.isIdentifier(node.exportClause.name)) { // just like: export * as xx from './yy' + if (node.exportClause && ts.isNamespaceExport(node.exportClause) && ts.isIdentifier(node.exportClause.name)) { + // just like: export * as xx from './yy' exportInfos.push(builder1.exportClauseName(node.exportClause.name.text).build()); - } else if (!node.exportClause && node.moduleSpecifier) { // just like: export * from './yy' + } else if (!node.exportClause && node.moduleSpecifier) { + // just like: export * from './yy' exportInfos.push(builder1.exportClauseName(ALL).build()); } return exportInfos; @@ -122,17 +124,19 @@ function buildExportAssignment(node: ts.ExportAssignment, sourceFile: ts.SourceF .declaringArkFile(arkFile) .exportClauseName(DEFAULT) .setLeadingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), true)) - .setTrailingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), false)) + .setTrailingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), false)); if (ts.isNewExpression(node.expression) && ts.isClassExpression(node.expression.expression)) { let cls: ArkClass = new ArkClass(); buildNormalArkClassFromArkFile(node.expression.expression, arkFile, cls, sourceFile); } - if (ts.isIdentifier(node.expression)) { // just like: export default xx + if (ts.isIdentifier(node.expression)) { + // just like: export default xx exportInfo.nameBeforeAs(node.expression.text); - } else if (ts.isAsExpression(node.expression)) { // just like: export default xx as YY - exportInfo.nameBeforeAs(node.expression.expression.getText(sourceFile)) + } else if (ts.isAsExpression(node.expression)) { + // just like: export default xx as YY + exportInfo.nameBeforeAs(node.expression.expression.getText(sourceFile)); } exportInfos.push(exportInfo.build()); @@ -145,22 +149,24 @@ function buildExportAssignment(node: ts.ExportAssignment, sourceFile: ts.SourceF * @param sourceFile * @param arkFile */ -export function buildExportVariableStatement(node: ts.VariableStatement, sourceFile: ts.SourceFile, arkFile: ArkFile): ExportInfo[] { +export function buildExportVariableStatement(node: ts.VariableStatement, sourceFile: ts.SourceFile, arkFile: ArkFile, namespace?: ArkNamespace): ExportInfo[] { let exportInfos: ExportInfo[] = []; const originTsPosition = LineColPosition.buildFromNode(node, sourceFile); const modifiers = node.modifiers ? buildModifiers(node) : 0; const tsSourceCode = node.getText(sourceFile); node.declarationList.declarations.forEach(dec => { - const exportInfo = new ExportInfo.Builder() + const exportInfoBuilder = new ExportInfo.Builder() .exportClauseName(dec.name.getText(sourceFile)) .exportClauseType(ExportType.LOCAL) .modifiers(modifiers) .tsSourceCode(tsSourceCode) .originTsPosition(originTsPosition) - .declaringArkFile(arkFile) - .build(); - exportInfos.push(exportInfo); - }) + .declaringArkFile(arkFile); + if (namespace) { + exportInfoBuilder.declaringArkNamespace(namespace); + } + exportInfos.push(exportInfoBuilder.build()); + }); return exportInfos; } diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFieldBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFieldBuilder.ts index f6db292b178bd1abeb8556ceb302a724a511e209..ede55e7c9373fe86d87b73f0907a24c8e4cc9157 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFieldBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFieldBuilder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -29,9 +29,11 @@ const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkFieldBuilder'); export type PropertyLike = ts.PropertyDeclaration | ts.PropertyAssignment; -export function buildProperty2ArkField(member: ts.PropertyDeclaration | ts.PropertyAssignment | ts.ShorthandPropertyAssignment - | ts.SpreadAssignment | ts.PropertySignature | ts.EnumMember, sourceFile: ts.SourceFile, cls: ArkClass): ArkField { - +export function buildProperty2ArkField( + member: ts.PropertyDeclaration | ts.PropertyAssignment | ts.ShorthandPropertyAssignment | ts.SpreadAssignment | ts.PropertySignature | ts.EnumMember, + sourceFile: ts.SourceFile, + cls: ArkClass +): ArkField { let field = new ArkField(); field.setCategory(mapSyntaxKindToFieldOriginType(member.kind) as FieldCategory); field.setCode(member.getText(sourceFile)); @@ -45,7 +47,7 @@ export function buildProperty2ArkField(member: ts.PropertyDeclaration | ts.Prope } else if (ts.isPropertyAccessExpression(member.name.expression)) { fieldName = handlePropertyAccessExpression(member.name.expression); } else { - logger.warn("Other property expression type found!"); + logger.warn('Other property expression type found!'); } } else if (member.name && (ts.isIdentifier(member.name) || ts.isLiteralExpression(member.name))) { fieldName = member.name.text; @@ -54,11 +56,11 @@ export function buildProperty2ArkField(member: ts.PropertyDeclaration | ts.Prope fieldName = propertyName.substring(1); field.addModifier(ModifierType.PRIVATE); } else { - logger.warn("Other type of property name found!"); + logger.warn('Other type of property name found!'); } let fieldType: Type = UnknownType.getInstance(); - if ((ts.isPropertyDeclaration(member) || ts.isPropertySignature(member))) { + if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) { if (member.modifiers) { field.addModifier(buildModifiers(member)); } @@ -85,7 +87,7 @@ export function buildProperty2ArkField(member: ts.PropertyDeclaration | ts.Prope return field; } -export function buildIndexSignature2ArkField(member: ts.IndexSignatureDeclaration, sourceFile: ts.SourceFile, cls: ArkClass) { +export function buildIndexSignature2ArkField(member: ts.IndexSignatureDeclaration, sourceFile: ts.SourceFile, cls: ArkClass): void { const field = new ArkField(); field.setCode(member.getText(sourceFile)); field.setCategory(mapSyntaxKindToFieldOriginType(member.kind) as FieldCategory); @@ -106,7 +108,7 @@ export function buildIndexSignature2ArkField(member: ts.IndexSignatureDeclaratio cls.addField(field); } -export function buildGetAccessor2ArkField(member: ts.GetAccessorDeclaration, mthd: ArkMethod, sourceFile: ts.SourceFile) { +export function buildGetAccessor2ArkField(member: ts.GetAccessorDeclaration, mthd: ArkMethod, sourceFile: ts.SourceFile): void { let cls = mthd.getDeclaringArkClass(); let field = new ArkField(); field.setDeclaringArkClass(cls); @@ -118,8 +120,7 @@ export function buildGetAccessor2ArkField(member: ts.GetAccessorDeclaration, mth let fieldName = member.getText(sourceFile); if (ts.isIdentifier(member.name) || ts.isLiteralExpression(member.name)) { fieldName = member.name.text; - } - else if (ts.isComputedPropertyName(member.name)) { + } else if (ts.isComputedPropertyName(member.name)) { if (ts.isIdentifier(member.name.expression)) { let propertyName = member.name.expression.text; fieldName = propertyName; @@ -128,11 +129,10 @@ export function buildGetAccessor2ArkField(member: ts.GetAccessorDeclaration, mth } else if (ts.isLiteralExpression(member.name.expression)) { fieldName = member.name.expression.text; } else { - logger.warn("Other type of computed property name found!"); + logger.warn('Other type of computed property name found!'); } - } - else { - logger.warn("Please contact developers to support new type of GetAccessor name!"); + } else { + logger.warn('Please contact developers to support new type of GetAccessor name!'); } const fieldType = mthd.getReturnType(); @@ -169,7 +169,6 @@ function mapSyntaxKindToFieldOriginType(syntaxKind: ts.SyntaxKind): FieldCategor fieldOriginType = FieldCategory.GET_ACCESSOR; break; default: - ; } return fieldOriginType; -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFileBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFileBuilder.ts index 52935cbb5b0222cd56d2300b8b3198a48dadcdfe..1e201453b195b0a2bc6bc66d515215471dc277dc 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFileBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFileBuilder.ts @@ -40,9 +40,24 @@ import { ARKTS_STATIC_MARK } from '../../common/Const'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkFileBuilder'); -export const notStmtOrExprKind = ['ModuleDeclaration', 'ClassDeclaration', 'InterfaceDeclaration', 'EnumDeclaration', 'ExportDeclaration', - 'ExportAssignment', 'MethodDeclaration', 'Constructor', 'FunctionDeclaration', 'GetAccessor', 'SetAccessor', 'ArrowFunction', - 'FunctionExpression', 'MethodSignature', 'ConstructSignature', 'CallSignature']; +export const notStmtOrExprKind = [ + 'ModuleDeclaration', + 'ClassDeclaration', + 'InterfaceDeclaration', + 'EnumDeclaration', + 'ExportDeclaration', + 'ExportAssignment', + 'MethodDeclaration', + 'Constructor', + 'FunctionDeclaration', + 'GetAccessor', + 'SetAccessor', + 'ArrowFunction', + 'FunctionExpression', + 'MethodSignature', + 'ConstructSignature', + 'CallSignature', +]; /** * Entry of building ArkFile instance @@ -50,8 +65,7 @@ export const notStmtOrExprKind = ['ModuleDeclaration', 'ClassDeclaration', 'Inte * @param arkFile * @returns */ -export function buildArkFileFromFile(absoluteFilePath: string, projectDir: string, arkFile: ArkFile, - projectName: string) { +export function buildArkFileFromFile(absoluteFilePath: string, projectDir: string, arkFile: ArkFile, projectName: string): void { arkFile.setFilePath(absoluteFilePath); arkFile.setProjectDir(projectDir); @@ -59,14 +73,7 @@ export function buildArkFileFromFile(absoluteFilePath: string, projectDir: strin arkFile.setFileSignature(fileSignature); arkFile.setCode(fs.readFileSync(arkFile.getFilePath(), 'utf8')); - const sourceFile = ts.createSourceFile( - arkFile.getName(), - arkFile.getCode(), - ts.ScriptTarget.Latest, - true, - undefined, - ETS_COMPILER_OPTIONS, - ); + const sourceFile = ts.createSourceFile(arkFile.getName(), arkFile.getCode(), ts.ScriptTarget.Latest, true, undefined, ETS_COMPILER_OPTIONS); genDefaultArkClass(arkFile, sourceFile); buildArkFile(arkFile, sourceFile); } @@ -78,13 +85,11 @@ export function buildArkFileFromFile(absoluteFilePath: string, projectDir: strin * @param astRoot * @returns */ -function buildArkFile(arkFile: ArkFile, astRoot: ts.SourceFile) { +function buildArkFile(arkFile: ArkFile, astRoot: ts.SourceFile): void { const statements = astRoot.statements; const namespaces: ArkNamespace[] = []; - statements.forEach((child) => { - if ( - ts.isModuleDeclaration(child) - ) { + statements.forEach(child => { + if (ts.isModuleDeclaration(child)) { let ns: ArkNamespace = new ArkNamespace(); ns.setDeclaringArkFile(arkFile); @@ -93,12 +98,7 @@ function buildArkFile(arkFile: ArkFile, astRoot: ts.SourceFile) { if (ns.isExported()) { arkFile.addExportInfo(buildExportInfo(ns, arkFile, LineColPosition.buildFromNode(child, astRoot))); } - } else if ( - ts.isClassDeclaration(child) || - ts.isInterfaceDeclaration(child) || - ts.isEnumDeclaration(child) || - ts.isStructDeclaration(child) - ) { + } else if (ts.isClassDeclaration(child) || ts.isInterfaceDeclaration(child) || ts.isEnumDeclaration(child) || ts.isStructDeclaration(child)) { let cls: ArkClass = new ArkClass(); buildNormalArkClassFromArkFile(child, arkFile, cls, astRoot); @@ -126,15 +126,11 @@ function buildArkFile(arkFile: ArkFile, astRoot: ts.SourceFile) { if (mthd.isExported()) { arkFile.addExportInfo(buildExportInfo(mthd, arkFile, LineColPosition.buildFromNode(child, astRoot))); } - } else if ( - ts.isImportEqualsDeclaration(child) || - ts.isImportDeclaration(child) - ) { + } else if (ts.isImportEqualsDeclaration(child) || ts.isImportDeclaration(child)) { let importInfos = buildImportInfo(child, astRoot, arkFile); - importInfos?.forEach((element) => { + importInfos?.forEach(element => { element.setDeclaringArkFile(arkFile); arkFile.addImportInfo(element); - }); } else if (ts.isExportDeclaration(child)) { buildExportDeclaration(child, astRoot, arkFile).forEach(item => arkFile.addExportInfo(item)); @@ -161,13 +157,10 @@ function buildArkFile(arkFile: ArkFile, astRoot: ts.SourceFile) { }); } -function genDefaultArkClass(arkFile: ArkFile, astRoot: ts.SourceFile) { +function genDefaultArkClass(arkFile: ArkFile, astRoot: ts.SourceFile): void { let defaultClass = new ArkClass(); buildDefaultArkClassFromArkFile(arkFile, defaultClass, astRoot); arkFile.setDefaultClass(defaultClass); arkFile.addArkClass(defaultClass); } - - - diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkImportBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkImportBuilder.ts index e73d267268d88609e6025cb502a6a1c6b6b9f2fb..432f64acd19435dde5f28cd92d02bee9ba521dca 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkImportBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkImportBuilder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -20,7 +20,6 @@ import { buildModifiers } from './builderUtils'; import { IRUtils } from '../../common/IRUtils'; import { ArkFile } from '../ArkFile'; - export function buildImportInfo(node: ts.ImportEqualsDeclaration | ts.ImportDeclaration, sourceFile: ts.SourceFile, arkFile: ArkFile): ImportInfo[] { if (ts.isImportDeclaration(node)) { return buildImportDeclarationNode(node, sourceFile, arkFile); @@ -59,9 +58,10 @@ function buildImportDeclarationNode(node: ts.ImportDeclaration, sourceFile: ts.S //just like: import fs from 'fs' if (node.importClause && node.importClause.name && ts.isIdentifier(node.importClause.name)) { let importClauseName = node.importClause.name.text; + const pos = LineColPosition.buildFromNode(node.importClause.name, sourceFile); let importType = 'Identifier'; let importInfo = new ImportInfo(); - importInfo.build(importClauseName, importType, importFrom, originTsPosition, modifiers); + importInfo.build(importClauseName, importType, importFrom, pos, modifiers); importInfo.setTsSourceCode(tsSourceCode); IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); importInfos.push(importInfo); @@ -71,18 +71,19 @@ function buildImportDeclarationNode(node: ts.ImportDeclaration, sourceFile: ts.S if (node.importClause && node.importClause.namedBindings && ts.isNamedImports(node.importClause.namedBindings)) { let importType = 'NamedImports'; if (node.importClause.namedBindings.elements) { - node.importClause.namedBindings.elements.forEach((element) => { + node.importClause.namedBindings.elements.forEach(element => { if (element.name && ts.isIdentifier(element.name)) { let importClauseName = element.name.text; + const pos = LineColPosition.buildFromNode(element, sourceFile); if (element.propertyName && ts.isIdentifier(element.propertyName)) { let importInfo = new ImportInfo(); - importInfo.build(importClauseName, importType, importFrom, originTsPosition, modifiers, element.propertyName.text); + importInfo.build(importClauseName, importType, importFrom, pos, modifiers, element.propertyName.text); importInfo.setTsSourceCode(tsSourceCode); IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); importInfos.push(importInfo); } else { let importInfo = new ImportInfo(); - importInfo.build(importClauseName, importType, importFrom, originTsPosition, modifiers); + importInfo.build(importClauseName, importType, importFrom, pos, modifiers); importInfo.setTsSourceCode(tsSourceCode); IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); importInfos.push(importInfo); @@ -99,7 +100,8 @@ function buildImportDeclarationNode(node: ts.ImportDeclaration, sourceFile: ts.S let importClauseName = node.importClause.namedBindings.name.text; let importInfo = new ImportInfo(); let nameBeforeAs = '*'; - importInfo.build(importClauseName, importType, importFrom, originTsPosition, modifiers, nameBeforeAs); + const pos = LineColPosition.buildFromNode(node.importClause.namedBindings.name, sourceFile); + importInfo.build(importClauseName, importType, importFrom, pos, modifiers, nameBeforeAs); importInfo.setTsSourceCode(tsSourceCode); IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); importInfos.push(importInfo); @@ -119,8 +121,12 @@ function buildImportEqualsDeclarationNode(node: ts.ImportEqualsDeclaration, sour if (node.modifiers) { modifiers = buildModifiers(node); } - if (node.moduleReference && ts.isExternalModuleReference(node.moduleReference) && - node.moduleReference.expression && ts.isStringLiteral(node.moduleReference.expression)) { + if ( + node.moduleReference && + ts.isExternalModuleReference(node.moduleReference) && + node.moduleReference.expression && + ts.isStringLiteral(node.moduleReference.expression) + ) { let importFrom = node.moduleReference.expression.text; let importClauseName = node.name.text; let importInfo = new ImportInfo(); diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts index d124679e6b26af057714c2234fa37419c3d411e5..29221c377c4737302b92774d61b2e79941b2246d 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts @@ -39,14 +39,7 @@ import { BasicBlock } from '../../graph/BasicBlock'; import { Local } from '../../base/Local'; import { Value } from '../../base/Value'; import { CONSTRUCTOR_NAME, SUPER_NAME, THIS_NAME } from '../../common/TSConst'; -import { - ANONYMOUS_METHOD_PREFIX, - CALL_SIGNATURE_NAME, - DEFAULT_ARK_CLASS_NAME, - DEFAULT_ARK_METHOD_NAME, - NAME_DELIMITER, - NAME_PREFIX, -} from '../../common/Const'; +import { ANONYMOUS_METHOD_PREFIX, CALL_SIGNATURE_NAME, DEFAULT_ARK_CLASS_NAME, DEFAULT_ARK_METHOD_NAME, NAME_DELIMITER, NAME_PREFIX } from '../../common/Const'; import { ArkSignatureBuilder } from './ArkSignatureBuilder'; import { IRUtils } from '../../common/IRUtils'; import { ArkErrorCode } from '../../common/ArkError'; @@ -54,19 +47,18 @@ import { ArkErrorCode } from '../../common/ArkError'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkMethodBuilder'); export type MethodLikeNode = - ts.FunctionDeclaration | - ts.MethodDeclaration | - ts.ConstructorDeclaration | - ts.ArrowFunction | - ts.AccessorDeclaration | - ts.FunctionExpression | - ts.MethodSignature | - ts.ConstructSignatureDeclaration | - ts.CallSignatureDeclaration | - ts.FunctionTypeNode; - -export function buildDefaultArkMethodFromArkClass(declaringClass: ArkClass, mtd: ArkMethod, - sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration) { + | ts.FunctionDeclaration + | ts.MethodDeclaration + | ts.ConstructorDeclaration + | ts.ArrowFunction + | ts.AccessorDeclaration + | ts.FunctionExpression + | ts.MethodSignature + | ts.ConstructSignatureDeclaration + | ts.CallSignatureDeclaration + | ts.FunctionTypeNode; + +export function buildDefaultArkMethodFromArkClass(declaringClass: ArkClass, mtd: ArkMethod, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration): void { mtd.setDeclaringArkClass(declaringClass); const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(DEFAULT_ARK_METHOD_NAME, true); @@ -80,7 +72,13 @@ export function buildDefaultArkMethodFromArkClass(declaringClass: ArkClass, mtd: mtd.setBodyBuilder(bodyBuilder); } -export function buildArkMethodFromArkClass(methodNode: MethodLikeNode, declaringClass: ArkClass, mtd: ArkMethod, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod) { +export function buildArkMethodFromArkClass( + methodNode: MethodLikeNode, + declaringClass: ArkClass, + mtd: ArkMethod, + sourceFile: ts.SourceFile, + declaringMethod?: ArkMethod +): void { mtd.setDeclaringArkClass(declaringClass); declaringMethod !== undefined && mtd.setOuterMethod(declaringMethod); @@ -100,7 +98,7 @@ export function buildArkMethodFromArkClass(methodNode: MethodLikeNode, declaring // build methodDeclareSignatures and methodSignature as well as corresponding positions const methodName = buildMethodName(methodNode, declaringClass, sourceFile, declaringMethod); const methodParameters: MethodParameter[] = []; - buildParameters(methodNode.parameters, mtd, sourceFile).forEach((parameter) => { + buildParameters(methodNode.parameters, mtd, sourceFile).forEach(parameter => { buildGenericType(parameter.getType(), mtd); methodParameters.push(parameter); }); @@ -176,7 +174,7 @@ function buildMethodName(node: MethodLikeNode, declaringClass: ArkClass, sourceF return name; } -function buildAnonymousMethodName(node: MethodLikeNode, declaringClass: ArkClass) { +function buildAnonymousMethodName(node: MethodLikeNode, declaringClass: ArkClass): string { return `${ANONYMOUS_METHOD_PREFIX}${declaringClass.getAnonymousMethodNumber()}`; } @@ -192,30 +190,29 @@ export class ObjectBindingPatternParameter { private name: string = ''; private optional: boolean = false; - constructor() { - } + constructor() {} - public getName() { + public getName(): string { return this.name; } - public setName(name: string) { + public setName(name: string): void { this.name = name; } - public getPropertyName() { + public getPropertyName(): string { return this.propertyName; } - public setPropertyName(propertyName: string) { + public setPropertyName(propertyName: string): void { this.propertyName = propertyName; } - public isOptional() { + public isOptional(): boolean { return this.optional; } - public setOptional(optional: boolean) { + public setOptional(optional: boolean): void { this.optional = optional; } } @@ -225,30 +222,29 @@ export class ArrayBindingPatternParameter { private name: string = ''; private optional: boolean = false; - constructor() { - } + constructor() {} - public getName() { + public getName(): string { return this.name; } - public setName(name: string) { + public setName(name: string): void { this.name = name; } - public getPropertyName() { + public getPropertyName(): string { return this.propertyName; } - public setPropertyName(propertyName: string) { + public setPropertyName(propertyName: string): void { this.propertyName = propertyName; } - public isOptional() { + public isOptional(): boolean { return this.optional; } - public setOptional(optional: boolean) { + public setOptional(optional: boolean): void { this.optional = optional; } } @@ -261,62 +257,61 @@ export class MethodParameter implements Value { private objElements: ObjectBindingPatternParameter[] = []; private arrayElements: ArrayBindingPatternParameter[] = []; - constructor() { - } + constructor() {} - public getName() { + public getName(): string { return this.name; } - public setName(name: string) { + public setName(name: string): void { this.name = name; } - public getType() { + public getType(): Type { return this.type; } - public setType(type: Type) { + public setType(type: Type): void { this.type = type; } - public isOptional() { + public isOptional(): boolean { return this.optional; } - public setOptional(optional: boolean) { + public setOptional(optional: boolean): void { this.optional = optional; } - public hasDotDotDotToken() { + public hasDotDotDotToken(): boolean { return this.dotDotDotToken; } - public setDotDotDotToken(dotDotDotToken: boolean) { + public setDotDotDotToken(dotDotDotToken: boolean): void { this.dotDotDotToken = dotDotDotToken; } - public addObjElement(element: ObjectBindingPatternParameter) { + public addObjElement(element: ObjectBindingPatternParameter): void { this.objElements.push(element); } - public getObjElements() { + public getObjElements(): ObjectBindingPatternParameter[] { return this.objElements; } - public setObjElements(objElements: ObjectBindingPatternParameter[]) { + public setObjElements(objElements: ObjectBindingPatternParameter[]): void { this.objElements = objElements; } - public addArrayElement(element: ArrayBindingPatternParameter) { + public addArrayElement(element: ArrayBindingPatternParameter): void { this.arrayElements.push(element); } - public getArrayElements() { + public getArrayElements(): ArrayBindingPatternParameter[] { return this.arrayElements; } - public setArrayElements(arrayElements: ArrayBindingPatternParameter[]) { + public setArrayElements(arrayElements: ArrayBindingPatternParameter[]): void { this.arrayElements = arrayElements; } @@ -327,10 +322,12 @@ export class MethodParameter implements Value { function needDefaultConstructorInClass(arkClass: ArkClass): boolean { const originClassType = arkClass.getCategory(); - return arkClass.getMethodWithName(CONSTRUCTOR_NAME) === null && + return ( + arkClass.getMethodWithName(CONSTRUCTOR_NAME) === null && (originClassType === ClassCategory.CLASS || originClassType === ClassCategory.OBJECT) && arkClass.getName() !== DEFAULT_ARK_CLASS_NAME && - !arkClass.isDeclare(); + !arkClass.isDeclare() + ); } function recursivelyCheckAndBuildSuperConstructor(arkClass: ArkClass): void { @@ -455,18 +452,21 @@ export function addInitInConstructor(constructor: ArkMethod): void { break; } const initInvokeStmt = new ArkInvokeStmt( - new ArkInstanceInvokeExpr(thisLocal, constructor.getDeclaringArkClass().getInstanceInitMethod().getSignature(), [])); + new ArkInstanceInvokeExpr(thisLocal, constructor.getDeclaringArkClass().getInstanceInitMethod().getSignature(), []) + ); firstBlockStmts.splice(index, 0, initInvokeStmt); } export function isMethodImplementation(node: MethodLikeNode): boolean { - if (ts.isFunctionDeclaration(node) || + if ( + ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isConstructorDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node) || ts.isFunctionExpression(node) || - ts.isArrowFunction(node)) { + ts.isArrowFunction(node) + ) { if (node.body !== undefined) { return true; } @@ -498,7 +498,7 @@ export function checkAndUpdateMethod(method: ArkMethod, cls: ArkClass): void { if (presentDeclareSignatures !== null && presentImplSignature === null) { if (newDeclareSignature === null || presentMethod.getDeclareSignatureIndex(newDeclareSignature[0]) >= 0) { method.setDeclareSignatures(presentDeclareSignatures); - method.setDeclareLineCols((presentDeclareLineCols as number[])); + method.setDeclareLineCols(presentDeclareLineCols as number[]); } else { method.setDeclareSignatures(presentDeclareSignatures.concat(newDeclareSignature)); method.setDeclareLineCols((presentDeclareLineCols as number[]).concat(newDeclareLineCols as number[])); @@ -513,4 +513,3 @@ export function checkAndUpdateMethod(method: ArkMethod, cls: ArkClass): void { return; } } - diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkNamespaceBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkNamespaceBuilder.ts index a4d4b6428dab1a1cc539ef5f4e2b01f76173e3d1..930a0bba21cd77dab5d45b67ebc9b3a897842fef 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkNamespaceBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkNamespaceBuilder.ts @@ -21,7 +21,7 @@ import ts from 'ohos-typescript'; import { ArkNamespace } from '../ArkNamespace'; import { buildDecorators, buildModifiers } from './builderUtils'; import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; -import { buildExportAssignment, buildExportDeclaration, buildExportInfo } from './ArkExportBuilder'; +import { buildExportAssignment, buildExportDeclaration, buildExportInfo, buildExportVariableStatement, isExported } from './ArkExportBuilder'; import { ArkClass } from '../ArkClass'; import { ArkMethod } from '../ArkMethod'; import { NamespaceSignature } from '../ArkSignature'; @@ -29,7 +29,7 @@ import { IRUtils } from '../../common/IRUtils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkNamespaceBuilder'); -export function buildArkNamespace(node: ts.ModuleDeclaration, declaringInstance: ArkFile | ArkNamespace, ns: ArkNamespace, sourceFile: ts.SourceFile) { +export function buildArkNamespace(node: ts.ModuleDeclaration, declaringInstance: ArkFile | ArkNamespace, ns: ArkNamespace, sourceFile: ts.SourceFile): void { // modifiers if (node.modifiers) { ns.setModifiers(buildModifiers(node)); @@ -44,18 +44,18 @@ export function buildArkNamespace(node: ts.ModuleDeclaration, declaringInstance: } ns.setDeclaringInstance(declaringInstance); const namespaceName = node.name.text; - const namespaceSignature = new NamespaceSignature(namespaceName, ns.getDeclaringArkFile().getFileSignature(), - ns.getDeclaringArkNamespace()?.getSignature() || null); + const namespaceSignature = new NamespaceSignature( + namespaceName, + ns.getDeclaringArkFile().getFileSignature(), + ns.getDeclaringArkNamespace()?.getSignature() || null + ); ns.setSignature(namespaceSignature); // TODO: whether needed? ns.setCode(node.getText(sourceFile)); // set line and column - const { line, character } = ts.getLineAndCharacterOfPosition( - sourceFile, - node.getStart(sourceFile), - ); + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)); ns.setLine(line + 1); ns.setColumn(character + 1); @@ -66,7 +66,7 @@ export function buildArkNamespace(node: ts.ModuleDeclaration, declaringInstance: if (ts.isModuleBlock(node.body)) { buildNamespaceMembers(node.body, ns, sourceFile); } - // NamespaceDeclaration extends ModuleDeclaration + // NamespaceDeclaration extends ModuleDeclaration //TODO: Check else if (ts.isModuleDeclaration(node.body)) { logger.warn('This ModuleBody is an NamespaceDeclaration.'); @@ -85,33 +85,25 @@ export function buildArkNamespace(node: ts.ModuleDeclaration, declaringInstance: } // TODO: check and update -function buildNamespaceMembers(node: ts.ModuleBlock, namespace: ArkNamespace, sourceFile: ts.SourceFile) { +function buildNamespaceMembers(node: ts.ModuleBlock, namespace: ArkNamespace, sourceFile: ts.SourceFile): void { const statements = node.statements; const nestedNamespaces: ArkNamespace[] = []; - statements.forEach((child) => { - if ( - ts.isModuleDeclaration(child) - ) { + statements.forEach(child => { + if (ts.isModuleDeclaration(child)) { let childNs: ArkNamespace = new ArkNamespace(); childNs.setDeclaringArkNamespace(namespace); childNs.setDeclaringArkFile(namespace.getDeclaringArkFile()); buildArkNamespace(child, namespace, childNs, sourceFile); nestedNamespaces.push(childNs); - } else if ( - ts.isClassDeclaration(child) || - ts.isInterfaceDeclaration(child) || - ts.isEnumDeclaration(child) || - ts.isStructDeclaration(child) - ) { + } else if (ts.isClassDeclaration(child) || ts.isInterfaceDeclaration(child) || ts.isEnumDeclaration(child) || ts.isStructDeclaration(child)) { let cls: ArkClass = new ArkClass(); buildNormalArkClassFromArkNamespace(child, namespace, cls, sourceFile); namespace.addArkClass(cls); if (cls.isExported()) { - namespace.addExportInfo(buildExportInfo(cls, namespace.getDeclaringArkFile(), - LineColPosition.buildFromNode(child, sourceFile))); + namespace.addExportInfo(buildExportInfo(cls, namespace.getDeclaringArkFile(), LineColPosition.buildFromNode(child, sourceFile))); } } // TODO: Check @@ -122,8 +114,7 @@ function buildNamespaceMembers(node: ts.ModuleBlock, namespace: ArkNamespace, so buildArkMethodFromArkClass(child, namespace.getDefaultClass(), mthd, sourceFile); if (mthd.isExported()) { - namespace.addExportInfo(buildExportInfo(mthd, namespace.getDeclaringArkFile(), - LineColPosition.buildFromNode(child, sourceFile))); + namespace.addExportInfo(buildExportInfo(mthd, namespace.getDeclaringArkFile(), LineColPosition.buildFromNode(child, sourceFile))); } } else if (ts.isFunctionDeclaration(child)) { let mthd: ArkMethod = new ArkMethod(); @@ -131,15 +122,14 @@ function buildNamespaceMembers(node: ts.ModuleBlock, namespace: ArkNamespace, so buildArkMethodFromArkClass(child, namespace.getDefaultClass(), mthd, sourceFile); if (mthd.isExported()) { - namespace.addExportInfo(buildExportInfo(mthd, namespace.getDeclaringArkFile(), - LineColPosition.buildFromNode(child, sourceFile))); + namespace.addExportInfo(buildExportInfo(mthd, namespace.getDeclaringArkFile(), LineColPosition.buildFromNode(child, sourceFile))); } } else if (ts.isExportDeclaration(child)) { - buildExportDeclaration(child, sourceFile, namespace.getDeclaringArkFile()) - .forEach(item => namespace.addExportInfo(item)); + buildExportDeclaration(child, sourceFile, namespace.getDeclaringArkFile()).forEach(item => namespace.addExportInfo(item)); } else if (ts.isExportAssignment(child)) { - buildExportAssignment(child, sourceFile, namespace.getDeclaringArkFile()) - .forEach(item => namespace.addExportInfo(item)); + buildExportAssignment(child, sourceFile, namespace.getDeclaringArkFile()).forEach(item => namespace.addExportInfo(item)); + } else if (ts.isVariableStatement(child) && isExported(child.modifiers)) { + buildExportVariableStatement(child, sourceFile, namespace.getDeclaringArkFile(), namespace).forEach(item => namespace.addExportInfo(item)); } else { logger.info('Child joined default method of arkFile: ', ts.SyntaxKind[child.kind]); // join default method @@ -156,7 +146,7 @@ function buildNamespaceMembers(node: ts.ModuleBlock, namespace: ArkNamespace, so }); } -function genDefaultArkClass(ns: ArkNamespace, node: ts.ModuleDeclaration, sourceFile: ts.SourceFile) { +function genDefaultArkClass(ns: ArkNamespace, node: ts.ModuleDeclaration, sourceFile: ts.SourceFile): void { let defaultClass = new ArkClass(); buildDefaultArkClassFromArkNamespace(ns, defaultClass, node, sourceFile); @@ -164,7 +154,6 @@ function genDefaultArkClass(ns: ArkNamespace, node: ts.ModuleDeclaration, source ns.addArkClass(defaultClass); } - export function mergeNameSpaces(arkNamespaces: ArkNamespace[]): ArkNamespace[] { const namespaceMap = new Map(); for (let i = 0; i < arkNamespaces.length; i++) { diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkSignatureBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkSignatureBuilder.ts index 1c0ecdaefd346feeb750c9b30aef898909b0daad..4804a8136c2257a9e7f379e0f23baf6479e6706b 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkSignatureBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkSignatureBuilder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -17,8 +17,7 @@ import { ClassSignature, FieldSignature, FileSignature, MethodSignature, MethodS import { UnknownType } from '../../base/Type'; export class ArkSignatureBuilder { - public static buildMethodSignatureFromClassNameAndMethodName(className: string, methodName: string, - staticFlag: boolean = false): MethodSignature { + public static buildMethodSignatureFromClassNameAndMethodName(className: string, methodName: string, staticFlag: boolean = false): MethodSignature { const classSignature = this.buildClassSignatureFromClassName(className); const methodSubSignature = this.buildMethodSubSignatureFromMethodName(methodName, staticFlag); return new MethodSignature(classSignature, methodSubSignature); @@ -29,8 +28,7 @@ export class ArkSignatureBuilder { return new MethodSignature(ClassSignature.DEFAULT, methodSubSignature); } - public static buildMethodSubSignatureFromMethodName(methodName: string, - staticFlag: boolean = false): MethodSubSignature { + public static buildMethodSubSignatureFromMethodName(methodName: string, staticFlag: boolean = false): MethodSubSignature { return new MethodSubSignature(methodName, [], UnknownType.getInstance(), staticFlag); } @@ -41,4 +39,4 @@ export class ArkSignatureBuilder { public static buildFieldSignatureFromFieldName(fieldName: string, staticFlag: boolean = false): FieldSignature { return new FieldSignature(fieldName, ClassSignature.DEFAULT, UnknownType.getInstance(), staticFlag); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/BodyBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/BodyBuilder.ts index 67f2d15b4a3286194a3077904688a6e0c9c88505..77b28a411fc80b6884620cdf50e2d5e564b93a81 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/BodyBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/BodyBuilder.ts @@ -23,16 +23,7 @@ import { MethodParameter } from './ArkMethodBuilder'; import { LEXICAL_ENV_NAME_PREFIX, NAME_DELIMITER, NAME_PREFIX } from '../../common/Const'; import { ArkParameterRef, ArkStaticFieldRef, ClosureFieldRef, GlobalRef } from '../../base/Ref'; import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkInvokeStmt, ArkReturnStmt } from '../../base/Stmt'; -import { - AliasType, - ArrayType, - ClosureType, - FunctionType, - LexicalEnvType, - Type, - UnclearReferenceType, - UnionType, -} from '../../base/Type'; +import { AliasType, ArrayType, ClosureType, FunctionType, LexicalEnvType, Type, UnclearReferenceType, UnionType } from '../../base/Type'; import { AbstractInvokeExpr, ArkPtrInvokeExpr } from '../../base/Expr'; type NestedMethodChain = { @@ -121,7 +112,7 @@ export class BodyBuilder { * 4. Recursively do this for all nested method level by level. */ private buildLexicalEnv(childrenChain: NestedMethodChain, baseLocals: Map, index: number): number { - let usedClosures = this.findClosuresUsedInNested(childrenChain, baseLocals, new Map); + let usedClosures = this.findClosuresUsedInNested(childrenChain, baseLocals, new Map()); const nestedMethod = childrenChain.parent; const nestedSignature = nestedMethod.getImplementationSignature(); if (nestedSignature !== null && usedClosures !== null && usedClosures.length > 0) { @@ -259,11 +250,14 @@ export class BodyBuilder { private generateNestedMethodChains(outerMethod: ArkMethod): NestedMethodChain { let candidateMethods: ArkMethod[] = []; - outerMethod.getDeclaringArkClass().getMethods().forEach(method => { - if (method.getName().startsWith(NAME_PREFIX) && method.getName().endsWith(`${NAME_DELIMITER}${outerMethod.getName()}`)) { - candidateMethods.push(method); - } - }); + outerMethod + .getDeclaringArkClass() + .getMethods() + .forEach(method => { + if (method.getName().startsWith(NAME_PREFIX) && method.getName().endsWith(`${NAME_DELIMITER}${outerMethod.getName()}`)) { + candidateMethods.push(method); + } + }); const childrenChains = this.getNestedChildrenChains(outerMethod, candidateMethods); if (childrenChains.length > 0) { return { parent: outerMethod, children: childrenChains }; @@ -278,9 +272,9 @@ export class BodyBuilder { if (outerMethodSignature !== undefined && methodSignatureCompare(parentMethod.getSignature(), outerMethodSignature)) { const childrenChains = this.getNestedChildrenChains(method, candidateMethods); if (childrenChains.length > 0) { - nestedMethodChain.push({parent: method, children: childrenChains}); + nestedMethodChain.push({ parent: method, children: childrenChains }); } else { - nestedMethodChain.push({parent: method, children: null}); + nestedMethodChain.push({ parent: method, children: null }); } } } @@ -344,7 +338,7 @@ export class BodyBuilder { } } - private updateNestedMethodUsedInOuter(nestedChain: NestedMethodChain) : void { + private updateNestedMethodUsedInOuter(nestedChain: NestedMethodChain): void { const nestedMethod = nestedChain.parent; const outerMethod = nestedMethod.getOuterMethod(); if (outerMethod === undefined) { @@ -353,8 +347,10 @@ export class BodyBuilder { const outerLocals = outerMethod.getBody()?.getLocals(); if (outerLocals !== undefined) { for (let local of outerLocals.values()) { - if (local.getType() instanceof LexicalEnvType && - methodSignatureCompare((local.getType() as LexicalEnvType).getNestedMethod(), nestedMethod.getSignature())) { + if ( + local.getType() instanceof LexicalEnvType && + methodSignatureCompare((local.getType() as LexicalEnvType).getNestedMethod(), nestedMethod.getSignature()) + ) { this.updateOuterMethodWithClosures(outerMethod, nestedMethod, local); break; } @@ -369,8 +365,9 @@ export class BodyBuilder { const fieldSignature = new FieldSignature( nestedMethodName, nestedMethod.getDeclaringArkClass().getSignature(), - new FunctionType(nestedMethod.getSignature())); - callGlobal.setRef(new ArkStaticFieldRef((fieldSignature))); + new FunctionType(nestedMethod.getSignature()) + ); + callGlobal.setRef(new ArkStaticFieldRef(fieldSignature)); } const childrenChains = nestedChain.children; @@ -452,8 +449,9 @@ export class BodyBuilder { const fieldSignature = new FieldSignature( methodSignature.getMethodSubSignature().getMethodName(), methodSignature.getDeclaringClassSignature(), - new ClosureType(lexicalEnv, methodSignature)); - globalRef.setRef(new ArkStaticFieldRef((fieldSignature))); + new ClosureType(lexicalEnv, methodSignature) + ); + globalRef.setRef(new ArkStaticFieldRef(fieldSignature)); this.updateAbstractInvokeExprWithClosures(globalRef, outerMethod.getSignature(), nestedMethod.getSignature(), closuresLocal); } @@ -481,8 +479,12 @@ export class BodyBuilder { // 更新所有stmt中调用内层函数处的AbstractInvokeExpr中的函数签名和实参args,加入闭包参数 // 更新所有stmt中定义的函数指针的usedStmt中的函数签名和实参args,加入闭包参数 - private updateAbstractInvokeExprWithClosures(value: Local | GlobalRef, outerMethodSignature: MethodSignature, - nestedMethodSignature: MethodSignature, closuresLocal: Local): void { + private updateAbstractInvokeExprWithClosures( + value: Local | GlobalRef, + outerMethodSignature: MethodSignature, + nestedMethodSignature: MethodSignature, + closuresLocal: Local + ): void { for (const usedStmt of value.getUsedStmts()) { if (usedStmt instanceof ArkInvokeStmt) { this.updateSignatureAndArgsInArkInvokeExpr(usedStmt, nestedMethodSignature, closuresLocal); @@ -515,12 +517,7 @@ export class BodyBuilder { closuresParam.setName(closuresLocal.getName()); closuresParam.setType(closuresLocal.getType()); params.unshift(closuresParam); - let newSubSignature = new MethodSubSignature( - oldSubSignature.getMethodName(), - params, - oldSubSignature.getReturnType(), - oldSubSignature.isStatic() - ); + let newSubSignature = new MethodSubSignature(oldSubSignature.getMethodName(), params, oldSubSignature.getReturnType(), oldSubSignature.isStatic()); return new MethodSignature(oldSignature.getDeclaringClassSignature(), newSubSignature); } @@ -577,7 +574,7 @@ export class BodyBuilder { stmts.splice(index, 0, assignStmt); closuresLocal.setDeclaringStmt(assignStmt); - oldParamRefs?.forEach((paramRef) => { + oldParamRefs?.forEach(paramRef => { index++; paramRef.setIndex(index); }); @@ -598,4 +595,4 @@ export class BodyBuilder { closuresLocal.addUsedStmt(assignStmt); } } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/builderUtils.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/builderUtils.ts index 73c93776b2797ae7966c11333ea2406e682eb092..7e5c218116d6583bbdbc6250544992cce55f5b01 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/builderUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/builderUtils.ts @@ -33,12 +33,7 @@ import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; import { ArkClass } from '../ArkClass'; import { ArkMethod } from '../ArkMethod'; import { Decorator } from '../../base/Decorator'; -import { - ArrayBindingPatternParameter, - buildArkMethodFromArkClass, - MethodParameter, - ObjectBindingPatternParameter, -} from './ArkMethodBuilder'; +import { ArrayBindingPatternParameter, buildArkMethodFromArkClass, MethodParameter, ObjectBindingPatternParameter } from './ArkMethodBuilder'; import { buildNormalArkClassFromArkMethod } from './ArkClassBuilder'; import { Builtin } from '../../common/Builtin'; import { modifierKind2Enum } from '../ArkBaseModel'; @@ -47,12 +42,14 @@ import { KeyofTypeExpr, TypeQueryExpr } from '../../base/TypeExpr'; import { ANY_KEYWORD, BIGINT_KEYWORD, - BOOLEAN_KEYWORD, NEVER_KEYWORD, + BOOLEAN_KEYWORD, + NEVER_KEYWORD, NULL_KEYWORD, NUMBER_KEYWORD, STRING_KEYWORD, THIS_NAME, - UNDEFINED_KEYWORD, VOID_KEYWORD, + UNDEFINED_KEYWORD, + VOID_KEYWORD, } from '../../common/TSConst'; import { ArkSignatureBuilder } from './ArkSignatureBuilder'; import { ArkInstanceFieldRef } from '../../base/Ref'; @@ -89,7 +86,7 @@ export function handlePropertyAccessExpression(node: ts.PropertyAccessExpression export function buildDecorators(node: ts.Node, sourceFile: ts.SourceFile): Set { let decorators: Set = new Set(); - ts.getAllDecorators(node).forEach((decoratorNode) => { + ts.getAllDecorators(node).forEach(decoratorNode => { let decorator = parseDecorator(decoratorNode); if (decorator) { decorator.setContent(decoratorNode.expression.getText(sourceFile)); @@ -128,7 +125,7 @@ export function buildModifiers(node: ts.Node): number { let modifiers: number = 0; if (ts.canHaveModifiers(node)) { - ts.getModifiers(node)?.forEach((modifier) => { + ts.getModifiers(node)?.forEach(modifier => { modifiers |= modifierKind2Enum(modifier.kind); }); } @@ -138,8 +135,8 @@ export function buildModifiers(node: ts.Node): number { export function buildHeritageClauses(heritageClauses?: ts.NodeArray): Map { let heritageClausesMap: Map = new Map(); - heritageClauses?.forEach((heritageClause) => { - heritageClause.types.forEach((type) => { + heritageClauses?.forEach(heritageClause => { + heritageClause.types.forEach(type => { let heritageClauseName: string = ''; if (type.typeArguments) { heritageClauseName = type.getText(); @@ -156,8 +153,11 @@ export function buildHeritageClauses(heritageClauses?: ts.NodeArray, - sourceFile: ts.SourceFile, arkInstance: ArkMethod | ArkClass): GenericType[] { +export function buildTypeParameters( + typeParameters: ts.NodeArray, + sourceFile: ts.SourceFile, + arkInstance: ArkMethod | ArkClass +): GenericType[] { const genericTypes: GenericType[] = []; let index = 0; if (arkInstance instanceof ArkMethod) { @@ -166,7 +166,7 @@ export function buildTypeParameters(typeParameters: ts.NodeArray { + typeParameters.forEach(typeParameter => { const genericType = tsNode2Type(typeParameter, sourceFile, arkInstance); if (genericType instanceof GenericType) { genericType.setIndex(index++); @@ -187,7 +187,7 @@ export function buildTypeParameters(typeParameters: ts.NodeArray { + paramNameNode.elements.forEach(element => { let paraElement = new ObjectBindingPatternParameter(); if (element.propertyName) { if (ts.isIdentifier(element.propertyName)) { @@ -246,7 +246,7 @@ function buildBindingElementOfBindingPatternParam(element: ts.BindingElement, pa function buildArrayBindingPatternParam(methodParameter: MethodParameter, paramNameNode: ts.ArrayBindingPattern): void { methodParameter.setName('ArrayBindingPattern'); let elements: ArrayBindingPatternParameter[] = []; - paramNameNode.elements.forEach((element) => { + paramNameNode.elements.forEach(element => { let paraElement = new ArrayBindingPatternParameter(); if (ts.isBindingElement(element)) { buildBindingElementOfBindingPatternParam(element, paraElement); @@ -260,7 +260,7 @@ function buildArrayBindingPatternParam(methodParameter: MethodParameter, paramNa export function buildParameters(params: ts.NodeArray, arkInstance: ArkMethod | ArkField, sourceFile: ts.SourceFile): MethodParameter[] { let parameters: MethodParameter[] = []; - params.forEach((parameter) => { + params.forEach(parameter => { let methodParameter = new MethodParameter(); // name @@ -317,7 +317,10 @@ export function buildGenericType(type: Type, arkInstance: ArkMethod | ArkField | gType = arkInstance.getGenericTypes()?.find(f => f.getName() === typeName); } if (!gType) { - gType = arkInstance.getDeclaringArkClass().getGenericsTypes()?.find(f => f.getName() === typeName); + gType = arkInstance + .getDeclaringArkClass() + .getGenericsTypes() + ?.find(f => f.getName() === typeName); } } if (gType) { @@ -359,7 +362,7 @@ export function buildGenericType(type: Type, arkInstance: ArkMethod | ArkField | return type; } -export function buildReturnType(node: TypeNode, sourceFile: ts.SourceFile, method: ArkMethod) { +export function buildReturnType(node: TypeNode, sourceFile: ts.SourceFile, method: ArkMethod): Type { if (node) { return tsNode2Type(node, sourceFile, method); } else { @@ -367,8 +370,11 @@ export function buildReturnType(node: TypeNode, sourceFile: ts.SourceFile, metho } } -export function tsNode2Type(typeNode: ts.TypeNode | ts.TypeParameterDeclaration, sourceFile: ts.SourceFile, - arkInstance: ArkMethod | ArkClass | ArkField): Type { +export function tsNode2Type( + typeNode: ts.TypeNode | ts.TypeParameterDeclaration, + sourceFile: ts.SourceFile, + arkInstance: ArkMethod | ArkClass | ArkField +): Type { if (ts.isTypeReferenceNode(typeNode)) { const genericTypes: Type[] = []; if (typeNode.typeArguments) { @@ -389,7 +395,7 @@ export function tsNode2Type(typeNode: ts.TypeNode | ts.TypeParameterDeclaration, } } else if (ts.isUnionTypeNode(typeNode) || ts.isIntersectionTypeNode(typeNode)) { let multipleTypePara: Type[] = []; - typeNode.types.forEach((tmpType) => { + typeNode.types.forEach(tmpType => { multipleTypePara.push(tsNode2Type(tmpType, sourceFile, arkInstance)); }); if (ts.isUnionTypeNode(typeNode)) { @@ -464,7 +470,7 @@ export function tsNode2Type(typeNode: ts.TypeNode | ts.TypeParameterDeclaration, } } -export function buildTypeFromPreStr(preStr: string) { +export function buildTypeFromPreStr(preStr: string): Type { let postStr = ''; switch (preStr) { case 'BooleanKeyword': @@ -515,21 +521,20 @@ export function buildTypeFromPreStr(preStr: string) { return TypeInference.buildTypeFromStr(postStr); } -function buildTypeFromTypeOperator(typeOperatorNode: ts.TypeOperatorNode, sourceFile: ts.SourceFile, - arkInstance: ArkMethod | ArkClass | ArkField): Type { +function buildTypeFromTypeOperator(typeOperatorNode: ts.TypeOperatorNode, sourceFile: ts.SourceFile, arkInstance: ArkMethod | ArkClass | ArkField): Type { const typeNode = typeOperatorNode.type; let type = tsNode2Type(typeNode, sourceFile, arkInstance); switch (typeOperatorNode.operator) { - case (ts.SyntaxKind.ReadonlyKeyword): { + case ts.SyntaxKind.ReadonlyKeyword: { if (type instanceof ArrayType || type instanceof TupleType) { type.setReadonlyFlag(true); } return type; } - case (ts.SyntaxKind.KeyOfKeyword): + case ts.SyntaxKind.KeyOfKeyword: return new KeyofTypeExpr(type); - case (ts.SyntaxKind.UniqueKeyword): + case ts.SyntaxKind.UniqueKeyword: return UnknownType.getInstance(); default: return UnknownType.getInstance(); @@ -543,21 +548,27 @@ function buildTypeFromTypeQuery(typeQueryNode: ts.TypeQueryNode, sourceFile: ts. if (exprNameNode.left.getText(sourceFile) === THIS_NAME) { const fieldName = exprNameNode.right.getText(sourceFile); if (arkInstance instanceof ArkMethod) { - const fieldSignature = arkInstance.getDeclaringArkClass().getFieldWithName(fieldName)?.getSignature() ?? + const fieldSignature = + arkInstance.getDeclaringArkClass().getFieldWithName(fieldName)?.getSignature() ?? ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); - const baseLocal = arkInstance.getBody()?.getLocals().get(THIS_NAME) ?? - new Local(THIS_NAME, new ClassType(arkInstance.getDeclaringArkClass().getSignature(), - arkInstance.getDeclaringArkClass().getGenericsTypes())); + const baseLocal = + arkInstance.getBody()?.getLocals().get(THIS_NAME) ?? + new Local( + THIS_NAME, + new ClassType(arkInstance.getDeclaringArkClass().getSignature(), arkInstance.getDeclaringArkClass().getGenericsTypes()) + ); opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature); } else if (arkInstance instanceof ArkClass) { - const fieldSignature = arkInstance.getFieldWithName(fieldName)?.getSignature() ?? - ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); + const fieldSignature = + arkInstance.getFieldWithName(fieldName)?.getSignature() ?? ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); const baseLocal = new Local(THIS_NAME, new ClassType(arkInstance.getSignature(), arkInstance.getGenericsTypes())); opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature); } else { const fieldSignature = arkInstance.getSignature(); - const baseLocal = new Local(THIS_NAME, new ClassType(arkInstance.getDeclaringArkClass().getSignature(), - arkInstance.getDeclaringArkClass().getGenericsTypes())); + const baseLocal = new Local( + THIS_NAME, + new ClassType(arkInstance.getDeclaringArkClass().getSignature(), arkInstance.getDeclaringArkClass().getGenericsTypes()) + ); opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature); } } else { @@ -576,4 +587,4 @@ function buildTypeFromTypeQuery(typeQueryNode: ts.TypeQueryNode, sourceFile: ts. } } return expr; -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/index.ts b/ets2panda/linter/arkanalyzer/src/index.ts index 174ea7c49344e4d4148f18ed462f92075f55c1b5..cb13b2d8122c94855817b096f06b53a8d54f3632 100644 --- a/ets2panda/linter/arkanalyzer/src/index.ts +++ b/ets2panda/linter/arkanalyzer/src/index.ts @@ -121,7 +121,6 @@ export * from './utils/AstTreeUtils'; export { LOG_LEVEL, LOG_MODULE_TYPE } from './utils/logger'; export { default as Logger } from './utils/logger'; - //ohos-typescript import ts from 'ohos-typescript'; -export { ts }; \ No newline at end of file +export { ts }; diff --git a/ets2panda/linter/arkanalyzer/src/save/ArkStream.ts b/ets2panda/linter/arkanalyzer/src/save/ArkStream.ts index 51929115b48108b3cbf9ab0df9e7fb3fa8eae557..a3db074cec3ebb2557c81cd009e5202aad60d1eb 100644 --- a/ets2panda/linter/arkanalyzer/src/save/ArkStream.ts +++ b/ets2panda/linter/arkanalyzer/src/save/ArkStream.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -73,7 +73,7 @@ export class ArkCodeBuffer { return this.output.join(''); } - public clear() { + public clear(): void { this.output = []; } } diff --git a/ets2panda/linter/arkanalyzer/src/save/DotPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/DotPrinter.ts index 2992ff6653c14d9184bbd539bfaef430c304a4e7..e4f218352f779db764e3cfb83bcbb5df7c9b49c2 100644 --- a/ets2panda/linter/arkanalyzer/src/save/DotPrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/DotPrinter.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -72,9 +72,7 @@ export class DotMethodPrinter extends Printer { let name = prefix + index++; blockToNode.set(block, name); /** Node0 [label="entry"]; */ - this.printer - .writeIndent() - .writeLine(`${name} [label="${this.getBlockContent(block, this.printer.getIndent())}"];`); + this.printer.writeIndent().writeLine(`${name} [label="${this.getBlockContent(block, this.printer.getIndent())}"];`); } for (let block of blocks) { diff --git a/ets2panda/linter/arkanalyzer/src/save/GraphPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/GraphPrinter.ts index 20f5938165f1b0cbd7fc504158105f5a55e8f66b..7016d14036bdc6f7a4d0e21ee0d0963c195e1974 100644 --- a/ets2panda/linter/arkanalyzer/src/save/GraphPrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/GraphPrinter.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -23,7 +23,7 @@ function escapeStr(input: string): string { switch (str[i]) { case '\n': str = str.substring(0, i) + '\\n' + str.substring(i + 1); - ++i; + ++i; break; case '\t': str = str.substring(0, i) + ' ' + str.substring(i + 1); @@ -56,7 +56,6 @@ function escapeStr(input: string): string { ++i; break; default: - ; } } return str; @@ -75,7 +74,7 @@ export class GraphPrinter> extends Print } } - public setStartID(n: NodeID) { + public setStartID(n: NodeID): void { this.startID = n; } @@ -109,27 +108,25 @@ export class GraphPrinter> extends Print itor = nodes.values(); } - for(let node of itor) { + for (let node of itor) { let nodeAttr = node.getDotAttr(); if (nodeAttr === '') { continue; } let nodeLabel = escapeStr(node.getDotLabel()); - this.printer.writeLine(`\tNode${node.getID()} [shape=recode,${nodeAttr},label="${nodeLabel}"];`) + this.printer.writeLine(`\tNode${node.getID()} [shape=recode,${nodeAttr},label="${nodeLabel}"];`); for (let edge of node.getOutgoingEdges()) { this.writeEdge(edge); } } - - } public writeEdge(edge: BaseEdge): void { let edgeAttr = edge.getDotAttr(); if (edgeAttr === '') { - return + return; } this.printer.writeLine(`\tNode${edge.getSrcID()} -> Node${edge.getDstID()}[${edgeAttr}]`); } @@ -140,7 +137,6 @@ export class GraphPrinter> extends Print let graphNameStr = `digraph "${escapeStr(this.title || GraphName || 'unnamed')}" {\n`; this.printer.writeLine(graphNameStr); - let labelStr = `\tlabel="${escapeStr(this.title || GraphName)}";\n`; this.printer.writeLine(labelStr); @@ -148,6 +144,6 @@ export class GraphPrinter> extends Print } public writeFooter(): void { - this.printer.writeLine("}\n"); + this.printer.writeLine('}\n'); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/save/JsonPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/JsonPrinter.ts index 3f533f22448c324cf53946e13e2e72da4dec2488..283de26011aae158e95d678fccdac4a6ceed70b4 100644 --- a/ets2panda/linter/arkanalyzer/src/save/JsonPrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/JsonPrinter.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -25,7 +25,8 @@ import { AnnotationType, AnnotationTypeQueryType, AnyType, - ArrayType, BigIntType, + ArrayType, + BigIntType, BooleanType, ClassType, FunctionType, @@ -45,15 +46,7 @@ import { VoidType, } from '../core/base/Type'; import { Value } from '../core/base/Value'; -import { - ArkAssignStmt, - ArkIfStmt, - ArkInvokeStmt, - ArkReturnStmt, - ArkReturnVoidStmt, - ArkThrowStmt, - Stmt, -} from '../core/base/Stmt'; +import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, ArkThrowStmt, Stmt } from '../core/base/Stmt'; import { AbstractBinopExpr, AbstractExpr, @@ -78,14 +71,7 @@ import { Constant } from '../core/base/Constant'; import { MethodParameter } from '../core/model/builder/ArkMethodBuilder'; import { ImportInfo } from '../core/model/ArkImport'; import { ExportInfo } from '../core/model/ArkExport'; -import { - AliasTypeSignature, - ClassSignature, - FieldSignature, - FileSignature, - MethodSignature, - NamespaceSignature, -} from '../core/model/ArkSignature'; +import { AliasTypeSignature, ClassSignature, FieldSignature, FileSignature, MethodSignature, NamespaceSignature } from '../core/model/ArkSignature'; import { LineColPosition } from '../core/base/Position'; import { AbstractFieldRef, AbstractRef, ArkArrayRef, ArkInstanceFieldRef, ArkParameterRef, ArkStaticFieldRef, ArkThisRef } from '../core/base/Ref'; import { Local } from '../core/base/Local'; @@ -108,18 +94,18 @@ export class JsonPrinter extends Printer { private serializeArkFile(file: ArkFile): object { return { signature: this.serializeFileSignature(file.getFileSignature()), - namespaces: file.getNamespaces().map((ns) => this.serializeNamespace(ns)), - classes: file.getClasses().map((cls) => this.serializeClass(cls)), - importInfos: file.getImportInfos().map((info) => this.serializeImportInfo(info)), - exportInfos: file.getExportInfos().map((info) => this.serializeExportInfo(info)), + namespaces: file.getNamespaces().map(ns => this.serializeNamespace(ns)), + classes: file.getClasses().map(cls => this.serializeClass(cls)), + importInfos: file.getImportInfos().map(info => this.serializeImportInfo(info)), + exportInfos: file.getExportInfos().map(info => this.serializeExportInfo(info)), }; } private serializeNamespace(namespace: ArkNamespace): object { return { signature: this.serializeNamespaceSignature(namespace.getSignature()), - classes: namespace.getClasses().map((cls) => this.serializeClass(cls)), - namespaces: namespace.getNamespaces().map((ns) => this.serializeNamespace(ns)), + classes: namespace.getClasses().map(cls => this.serializeClass(cls)), + namespaces: namespace.getNamespaces().map(ns => this.serializeNamespace(ns)), }; } @@ -127,12 +113,12 @@ export class JsonPrinter extends Printer { return { signature: this.serializeClassSignature(clazz.getSignature()), modifiers: clazz.getModifiers(), - decorators: clazz.getDecorators().map((decorator) => this.serializeDecorator(decorator)), - typeParameters: clazz.getGenericsTypes()?.map((type) => this.serializeType(type)), + decorators: clazz.getDecorators().map(decorator => this.serializeDecorator(decorator)), + typeParameters: clazz.getGenericsTypes()?.map(type => this.serializeType(type)), superClassName: clazz.getSuperClassName(), implementedInterfaceNames: clazz.getImplementedInterfaceNames(), - fields: clazz.getFields().map((field) => this.serializeField(field)), - methods: clazz.getMethods(true).map((method) => this.serializeMethod(method)), + fields: clazz.getFields().map(field => this.serializeField(field)), + methods: clazz.getMethods(true).map(method => this.serializeMethod(method)), }; } @@ -140,7 +126,7 @@ export class JsonPrinter extends Printer { return { signature: this.serializeFieldSignature(field.getSignature()), modifiers: field.getModifiers(), - decorators: field.getDecorators().map((decorator) => this.serializeDecorator(decorator)), + decorators: field.getDecorators().map(decorator => this.serializeDecorator(decorator)), questionToken: field.getQuestionToken(), exclamationToken: field.getExclamationToken(), }; @@ -151,7 +137,7 @@ export class JsonPrinter extends Printer { return { signature: this.serializeMethodSignature(method.getSignature()), modifiers: method.getModifiers(), - decorators: method.getDecorators().map((decorator) => this.serializeDecorator(decorator)), + decorators: method.getDecorators().map(decorator => this.serializeDecorator(decorator)), typeParameters: method.getGenericTypes()?.map(type => this.serializeType(type)), body: body && this.serializeMethodBody(body), }; @@ -159,7 +145,7 @@ export class JsonPrinter extends Printer { private serializeMethodBody(body: ArkBody): object { return { - locals: Array.from(body.getLocals().values()).map((local) => this.serializeLocal(local)), + locals: Array.from(body.getLocals().values()).map(local => this.serializeLocal(local)), cfg: this.serializeCfg(body.getCfg()), }; } @@ -232,12 +218,12 @@ export class JsonPrinter extends Printer { } else if (type instanceof UnionType) { return { _: 'UnionType', - types: type.getTypes().map((type) => this.serializeType(type)), + types: type.getTypes().map(type => this.serializeType(type)), }; } else if (type instanceof TupleType) { return { _: 'TupleType', - types: type.getTypes().map((type) => this.serializeType(type)), + types: type.getTypes().map(type => this.serializeType(type)), }; } else if (type instanceof BooleanType) { return { @@ -274,13 +260,13 @@ export class JsonPrinter extends Printer { return { _: 'ClassType', signature: this.serializeClassSignature(type.getClassSignature()), - typeParameters: type.getRealGenericTypes()?.map((type) => this.serializeType(type)), + typeParameters: type.getRealGenericTypes()?.map(type => this.serializeType(type)), }; } else if (type instanceof FunctionType) { return { _: 'FunctionType', signature: this.serializeMethodSignature(type.getMethodSignature()), - typeParameters: type.getRealGenericTypes()?.map((type) => this.serializeType(type)), + typeParameters: type.getRealGenericTypes()?.map(type => this.serializeType(type)), }; } else if (type instanceof ArrayType) { return { @@ -292,7 +278,7 @@ export class JsonPrinter extends Printer { return { _: 'UnclearReferenceType', name: type.getName(), - typeParameters: type.getGenericTypes().map((type) => this.serializeType(type)), + typeParameters: type.getGenericTypes().map(type => this.serializeType(type)), }; } else if (type instanceof GenericType) { let defaultType = type.getDefaultType(); @@ -375,7 +361,7 @@ export class JsonPrinter extends Printer { parameters: method .getMethodSubSignature() .getParameters() - .map((param) => this.serializeMethodParameter(param)), + .map(param => this.serializeMethodParameter(param)), returnType: this.serializeType(method.getType()), }; } @@ -405,20 +391,20 @@ export class JsonPrinter extends Printer { stack.push(...block.getSuccessors()); } return { - blocks: Array.from(visited).map((block) => this.serializeBasicBlock(block)), + blocks: Array.from(visited).map(block => this.serializeBasicBlock(block)), }; } private serializeBasicBlock(block: BasicBlock): object { - const successors = block.getSuccessors().map((succ) => succ.getId()); + const successors = block.getSuccessors().map(succ => succ.getId()); successors.sort((a, b) => a - b); - const predecessors = block.getPredecessors().map((pred) => pred.getId()); + const predecessors = block.getPredecessors().map(pred => pred.getId()); predecessors.sort((a, b) => a - b); return { id: block.getId(), successors, predecessors, - stmts: block.getStmts().map((stmt) => this.serializeStmt(stmt)), + stmts: block.getStmts().map(stmt => this.serializeStmt(stmt)), }; } @@ -493,8 +479,8 @@ export class JsonPrinter extends Printer { const argToBlock = value.getArgToBlock(); return { _: 'PhiExpr', - args: args.map((arg) => this.serializeValue(arg)), - blocks: args.map((arg) => argToBlock.get(arg)!.getId()), + args: args.map(arg => this.serializeValue(arg)), + blocks: args.map(arg => argToBlock.get(arg)!.getId()), type: this.serializeType(value.getType()), }; } else if (value instanceof ArkConditionExpr) { @@ -525,20 +511,20 @@ export class JsonPrinter extends Printer { _: 'InstanceCallExpr', instance: this.serializeValue(value.getBase()), method: this.serializeMethodSignature(value.getMethodSignature()), - args: value.getArgs().map((arg) => this.serializeValue(arg)), + args: value.getArgs().map(arg => this.serializeValue(arg)), }; } else if (value instanceof ArkStaticInvokeExpr) { return { _: 'StaticCallExpr', method: this.serializeMethodSignature(value.getMethodSignature()), - args: value.getArgs().map((arg) => this.serializeValue(arg)), + args: value.getArgs().map(arg => this.serializeValue(arg)), }; } else if (value instanceof ArkPtrInvokeExpr) { return { _: 'PtrCallExpr', ptr: this.serializeValue(value.getFuncPtrLocal()), method: this.serializeMethodSignature(value.getMethodSignature()), - args: value.getArgs().map((arg) => this.serializeValue(arg)), + args: value.getArgs().map(arg => this.serializeValue(arg)), }; } else if (value instanceof AbstractInvokeExpr) { throw new Error('Unhandled CallExpr: ' + util.inspect(value, { showHidden: true, depth: null })); diff --git a/ets2panda/linter/arkanalyzer/src/save/Printer.ts b/ets2panda/linter/arkanalyzer/src/save/Printer.ts index a01b50d55cb28a94216338163af2be31125434aa..fe5087b3f73b85e47e98aeba756b5b8cd58771d7 100644 --- a/ets2panda/linter/arkanalyzer/src/save/Printer.ts +++ b/ets2panda/linter/arkanalyzer/src/save/Printer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 diff --git a/ets2panda/linter/arkanalyzer/src/save/PrinterBuilder.ts b/ets2panda/linter/arkanalyzer/src/save/PrinterBuilder.ts index 96420e0501ccdf13c8d5cf075dc782f45a9dca7c..196d9b77ff4ab7f8e5c07fa4843bb2fe1cdcacdb 100644 --- a/ets2panda/linter/arkanalyzer/src/save/PrinterBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/save/PrinterBuilder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -50,7 +50,7 @@ export class PrinterBuilder { this.outputDir = outputDir; } - public static dump(source: Printer, output: string) { + public static dump(source: Printer, output: string): void { fs.writeFileSync(output, source.dump()); } @@ -62,10 +62,7 @@ export class PrinterBuilder { } } - public dumpToDot( - arkFile: ArkFile, - output: string | undefined = undefined - ): void { + public dumpToDot(arkFile: ArkFile, output: string | undefined = undefined): void { let filename = output; if (filename === undefined) { filename = path.join(this.getOutputDir(arkFile), arkFile.getName() + '.dot'); @@ -76,10 +73,7 @@ export class PrinterBuilder { PrinterBuilder.dump(printer, filename as string); } - public dumpToTs( - arkFile: ArkFile, - output: string | undefined = undefined - ): void { + public dumpToTs(arkFile: ArkFile, output: string | undefined = undefined): void { let filename = output; if (filename === undefined) { filename = path.join(this.getOutputDir(arkFile), arkFile.getName()); @@ -104,17 +98,14 @@ export class PrinterBuilder { PrinterBuilder.dump(printer, filename); } - public dumpToIR( - arkFile: ArkFile, - output: string | undefined = undefined - ): void { + public dumpToIR(arkFile: ArkFile, output: string | undefined = undefined): void { let filename = output; if (filename === undefined) { filename = path.join(this.getOutputDir(arkFile), arkFile.getName()); } - + filename += '.ir'; - + fs.mkdirSync(path.dirname(filename), { recursive: true }); let printer: Printer = new ArkIRFilePrinter(arkFile); @@ -145,26 +136,26 @@ export class ScenePrinter { } } - public dumpToDot() { + public dumpToDot(): void { for (let f of this.scene.getFiles()) { this.printer.dumpToDot(f); } } - public dumpToTs() { + public dumpToTs(): void { for (let f of this.scene.getFiles()) { let relativePath = path.relative(f.getProjectDir(), f.getFilePath()); this.printer.dumpToTs(f, path.join(this.outputDir, relativePath)); } } - public dumpToJson() { + public dumpToJson(): void { for (let f of this.scene.getFiles()) { this.printer.dumpToJson(f); } } - public dumpToIR() { + public dumpToIR(): void { for (let f of this.scene.getFiles()) { this.printer.dumpToIR(f); } diff --git a/ets2panda/linter/arkanalyzer/src/save/ViewTreePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/ViewTreePrinter.ts index 58066a98dfbf5f1dbc717ee0f987fd6d185d1819..7e5cf2f07bb3775909dcddb05a8d34927d310a48 100644 --- a/ets2panda/linter/arkanalyzer/src/save/ViewTreePrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/ViewTreePrinter.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -49,11 +49,7 @@ export class ViewTreePrinter extends Printer { return this.printer.toString(); } - private walk( - item: ViewTreeNode, - parent: ViewTreeNode | null, - map: Map = new Map() - ): void { + private walk(item: ViewTreeNode, parent: ViewTreeNode | null, map: Map = new Map()): void { let skipChildren = this.writeNode(item, parent, map); if (skipChildren) { return; @@ -68,18 +64,12 @@ export class ViewTreePrinter extends Printer { const PRE_FIX_LEN = 5; let label = content.join('|'); if (label.length > MAX_LABEL_LEN) { - return ( - label.substring(0, PRE_FIX_LEN) + '...' + label.substring(label.length - MAX_LABEL_LEN + PRE_FIX_LEN) - ); + return label.substring(0, PRE_FIX_LEN) + '...' + label.substring(label.length - MAX_LABEL_LEN + PRE_FIX_LEN); } return label; } - private writeNode( - item: ViewTreeNode, - parent: ViewTreeNode | null, - map: Map - ): boolean { + private writeNode(item: ViewTreeNode, parent: ViewTreeNode | null, map: Map): boolean { let id = `Node${map.size}`; let hasSameNode = map.has(item) || map.has(item.signature!); @@ -119,7 +109,7 @@ export class ViewTreePrinter extends Printer { if (item.stateValues.size > 0) { let stateValuesId = `${id}val`; let content: string[] = []; - item.stateValues.forEach((value) => { + item.stateValues.forEach(value => { content.push(value.getName()); }); @@ -156,9 +146,7 @@ export class ViewTreePrinter extends Printer { let signatureId = `${id}signature`; let content = [item.signature.toString()]; this.printer.write( - ` ${signatureId} [shape=ellipse label="signature\n${this.escapeDotLabel( - content - )}" fontsize=10 height=.1 style=filled color=".7 .3 1.0" ]\n` + ` ${signatureId} [shape=ellipse label="signature\n${this.escapeDotLabel(content)}" fontsize=10 height=.1 style=filled color=".7 .3 1.0" ]\n` ); this.printer.write(` ${id} -> ${signatureId}\n`); } diff --git a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRClassPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRClassPrinter.ts index d8b49f9f27b48b4f9369bb15d7df57c6225525bb..c67d7e45261130711423ff4d3a853a8f4392636b 100644 --- a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRClassPrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRClassPrinter.ts @@ -53,7 +53,7 @@ export class ArkIRClassPrinter extends BasePrinter { const genericsTypes = this.cls.getGenericsTypes(); if (genericsTypes) { - this.printer.write(`<${genericsTypes.map((v) => v.toString()).join(', ')}>`); + this.printer.write(`<${genericsTypes.map(v => v.toString()).join(', ')}>`); } if (this.cls.getSuperClassName() && !this.cls.hasComponentDecorator()) { this.printer.write(` extends ${this.cls.getSuperClassName()}`); diff --git a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRMethodPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRMethodPrinter.ts index 909755239653df994d8315d9291add0cc2bcd6ee..7b8f7c8b9725bd33f8143a17c8cb3dcccb327b58 100644 --- a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRMethodPrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRMethodPrinter.ts @@ -59,7 +59,7 @@ export class ArkIRMethodPrinter extends BasePrinter { if (cfg) { cfg.getStmts() .reverse() - .forEach((stmt) => stmts.push(stmt)); + .forEach(stmt => stmts.push(stmt)); } for (const stmt of stmts) { if (stmt.getOriginPositionInfo().getLineNo() > 0) { @@ -104,14 +104,14 @@ export class ArkIRMethodPrinter extends BasePrinter { const genericTypes = method.getGenericTypes(); if (genericTypes && genericTypes.length > 0) { let typeParameters: string[] = []; - genericTypes.forEach((genericType) => { + genericTypes.forEach(genericType => { typeParameters.push(genericType.toString()); }); code.write(`<${genericTypes.join(', ')}>`); } let parameters: string[] = []; - method.getParameters().forEach((parameter) => { + method.getParameters().forEach(parameter => { let str: string = parameter.getName(); if (parameter.hasDotDotDotToken()) { str = `...${parameter.getName()}`; @@ -152,7 +152,7 @@ export class ArkIRMethodPrinter extends BasePrinter { this.printer.incIndent(); if (successors.length === 1) { - block.getStmts().map((stmt) => { + block.getStmts().map(stmt => { this.printer.writeIndent().writeLine(stmt.toString()); }); this.printer.writeIndent().writeLine(`goto label${successors[0].getId()}`); @@ -165,7 +165,7 @@ export class ArkIRMethodPrinter extends BasePrinter { } } } else { - block.getStmts().map((stmt) => { + block.getStmts().map(stmt => { this.printer.writeIndent().writeLine(stmt.toString()); }); } diff --git a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRNamespacePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRNamespacePrinter.ts index 3e2fc8d57fdf40412b13c5942590e3437b2a23ad..6490cc7f731f217fb14bdc1a7b07208469ea12a4 100644 --- a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRNamespacePrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRNamespacePrinter.ts @@ -39,20 +39,17 @@ export class ArkIRNamespacePrinter extends BasePrinter { const commentsMetadata = this.ns.getMetadata(ArkMetadataKind.LEADING_COMMENTS); if (commentsMetadata instanceof CommentsMetadata) { const comments = commentsMetadata.getComments(); - comments.forEach((comment) => { + comments.forEach(comment => { this.printer.writeIndent().writeLine(comment.content); }); } - this.printer.writeIndent().writeSpace(this.modifiersToString(this.ns.getModifiers())) - .writeLine(`namespace ${this.ns.getName()} {`); + this.printer.writeIndent().writeSpace(this.modifiersToString(this.ns.getModifiers())).writeLine(`namespace ${this.ns.getName()} {`); this.printer.incIndent(); let items: Dump[] = []; // print class for (let cls of this.ns.getClasses()) { - items.push(new ArkIRClassPrinter(cls, this.printer.getIndent())); - } // print namespace for (let childNs of this.ns.getNamespaces()) { @@ -60,9 +57,7 @@ export class ArkIRNamespacePrinter extends BasePrinter { } // print exportInfos for (let exportInfo of this.ns.getExportInfos()) { - items.push( - new ExportPrinter(exportInfo, this.printer.getIndent()) - ); + items.push(new ExportPrinter(exportInfo, this.printer.getIndent())); } items.sort((a, b) => a.getLine() - b.getLine()); diff --git a/ets2panda/linter/arkanalyzer/src/save/base/BasePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/base/BasePrinter.ts index 551c2f37f2548292b01b188199507bcf2a920037..306f6301d4a44d70bb1e46f8375f6f1564c94890 100644 --- a/ets2panda/linter/arkanalyzer/src/save/base/BasePrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/base/BasePrinter.ts @@ -42,14 +42,14 @@ export abstract class BasePrinter extends Printer implements Dump { abstract getLine(): number; protected printDecorator(docorator: Decorator[]): void { - docorator.forEach((value) => { + docorator.forEach(value => { this.printer.writeIndent().writeLine(value.toString()); }); } protected printComments(commentsMetadata: CommentsMetadata): void { const comments = commentsMetadata.getComments(); - comments.forEach((comment) => { + comments.forEach(comment => { this.printer.writeIndent().writeLine(comment.content); }); } diff --git a/ets2panda/linter/arkanalyzer/src/save/base/ExportPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/base/ExportPrinter.ts index d76e919e82c0980033af4e866bbc7193b09d1250..aa186fa49b0d5bc1df78e51b8a51c54b71978848 100644 --- a/ets2panda/linter/arkanalyzer/src/save/base/ExportPrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/base/ExportPrinter.ts @@ -35,11 +35,10 @@ export class ExportPrinter extends BasePrinter { if (commentsMetadata instanceof CommentsMetadata) { this.printComments(commentsMetadata); } - + if ( - !this.info.getFrom() && (this.info.isExport() || - this.info.getExportClauseType() === ExportType.LOCAL || - this.info.getExportClauseType() === ExportType.TYPE) + !this.info.getFrom() && + (this.info.isExport() || this.info.getExportClauseType() === ExportType.LOCAL || this.info.getExportClauseType() === ExportType.TYPE) ) { return this.printer.toString(); } @@ -47,9 +46,7 @@ export class ExportPrinter extends BasePrinter { if (this.info.getExportClauseName() === '*') { // just like: export * as xx from './yy' if (this.info.getNameBeforeAs() && this.info.getNameBeforeAs() !== '*') { - this.printer - .writeIndent() - .write(`export ${this.info.getNameBeforeAs()} as ${this.info.getExportClauseName()}`); + this.printer.writeIndent().write(`export ${this.info.getNameBeforeAs()} as ${this.info.getExportClauseName()}`); } else { this.printer.writeIndent().write(`export ${this.info.getExportClauseName()}`); } @@ -68,4 +65,4 @@ export class ExportPrinter extends BasePrinter { return this.printer.toString(); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/save/base/ImportPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/base/ImportPrinter.ts index 14d08b429b9baba7c305e065f48a75acb1a2127e..def5cac29fa2962bcdb408cb2ba5415e9e5e6ec8 100644 --- a/ets2panda/linter/arkanalyzer/src/save/base/ImportPrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/base/ImportPrinter.ts @@ -53,9 +53,7 @@ export class ImportPrinter extends BasePrinter { clauseNames.push(`* as ${info.getImportClauseName()}`); } else if (info.getImportType() === 'EqualsImport') { // sample: import mmmm = require('./xxx') - this.printer - .writeIndent() - .writeLine(`import ${info.getImportClauseName()} = require('${info.getFrom() as string}');`); + this.printer.writeIndent().writeLine(`import ${info.getImportClauseName()} = require('${info.getFrom() as string}');`); } else { // sample: import '../xxx' this.printer.writeIndent().writeLine(`import '${info.getFrom() as string}';`); @@ -66,9 +64,7 @@ export class ImportPrinter extends BasePrinter { clauseNames.push(`{${namedImports.join(', ')}}`); } - this.printer - .writeIndent() - .writeLine(`import ${clauseNames.join(', ')} from '${this.infos[0].getFrom() as string}';`); + this.printer.writeIndent().writeLine(`import ${clauseNames.join(', ')} from '${this.infos[0].getFrom() as string}';`); return this.printer.toString(); } @@ -78,7 +74,7 @@ function mergeImportInfos(infos: ImportInfo[]): Map { let map = new Map(); for (let info of infos) { - let key = `${info.getOriginTsPosition().getLineNo()}-${info.getFrom()}` + let key = `${info.getOriginTsPosition().getLineNo()}-${info.getFrom()}`; let merge = map.get(key) || []; merge.push(info); map.set(key, merge); diff --git a/ets2panda/linter/arkanalyzer/src/save/base/PrinterUtils.ts b/ets2panda/linter/arkanalyzer/src/save/base/PrinterUtils.ts index ee019a536e222e3556cee52a0408a9214cbac478..0f92b23bdee278bd1c4ea6e73c06467de6a5ac64 100644 --- a/ets2panda/linter/arkanalyzer/src/save/base/PrinterUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/save/base/PrinterUtils.ts @@ -14,12 +14,7 @@ */ import { Constant } from '../../core/base/Constant'; -import { - ArkInstanceInvokeExpr, - ArkNormalBinopExpr, - ArkStaticInvokeExpr, - NormalBinaryOperator, -} from '../../core/base/Expr'; +import { ArkInstanceInvokeExpr, ArkNormalBinopExpr, ArkStaticInvokeExpr, NormalBinaryOperator } from '../../core/base/Expr'; import { Local } from '../../core/base/Local'; import { ArkAssignStmt, Stmt } from '../../core/base/Stmt'; import { @@ -105,10 +100,7 @@ export class PrinterUtils { let className = invokeExpr.getMethodSignature().getDeclaringClassSignature().getClassName(); let methodName = invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName(); - if ( - methodName === COMPONENT_POP_FUNCTION && - (isEtsSystemComponent(className) || SPECIAL_CONTAINER_COMPONENT.has(className)) - ) { + if (methodName === COMPONENT_POP_FUNCTION && (isEtsSystemComponent(className) || SPECIAL_CONTAINER_COMPONENT.has(className))) { return true; } @@ -119,20 +111,14 @@ export class PrinterUtils { let className = invokeExpr.getMethodSignature().getDeclaringClassSignature().getClassName(); let methodName = invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName(); - if ( - methodName === COMPONENT_CREATE_FUNCTION && - (isEtsSystemComponent(className) || SPECIAL_CONTAINER_COMPONENT.has(className)) - ) { + if (methodName === COMPONENT_CREATE_FUNCTION && (isEtsSystemComponent(className) || SPECIAL_CONTAINER_COMPONENT.has(className))) { return true; } return false; } - public static isComponentAttributeInvoke( - invokeExpr: ArkInstanceInvokeExpr, - visitor: Set = new Set() - ): boolean { + public static isComponentAttributeInvoke(invokeExpr: ArkInstanceInvokeExpr, visitor: Set = new Set()): boolean { if (visitor.has(invokeExpr)) { return false; } diff --git a/ets2panda/linter/arkanalyzer/src/save/serializeArkIR.ts b/ets2panda/linter/arkanalyzer/src/save/serializeArkIR.ts index 1793f879f09657c8c1b30f51324a3008495861df..dd859f8d3dfbadfac57cfb2ce3c92e2f665997da 100644 --- a/ets2panda/linter/arkanalyzer/src/save/serializeArkIR.ts +++ b/ets2panda/linter/arkanalyzer/src/save/serializeArkIR.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -62,11 +62,7 @@ export function serializeArkFile(arkFile: ArkFile, output?: string): void { fs.closeSync(fd); } -export function serializeScene( - scene: Scene, - outDir: string, - verbose: boolean = false, -): void { +export function serializeScene(scene: Scene, outDir: string, verbose: boolean = false): void { let files = scene.getFiles(); console.log(`Serializing Scene with ${files.length} files to '${outDir}'...`); for (let f of files) { @@ -161,11 +157,7 @@ function serializeFile(arkFile: ArkFile, output: string, options: any, scene: Sc } } -function serializeMultipleTsFiles( - inputDir: string, - outDir: string, - options: any, -): void { +function serializeMultipleTsFiles(inputDir: string, outDir: string, options: any): void { console.log(`Serializing multiple TS files to JSON: '${inputDir}' -> '${outDir}'`); if (fs.existsSync(outDir) && !fs.statSync(outDir).isDirectory()) { console.error(`ERROR: Output path must be a directory.`); @@ -183,7 +175,7 @@ function serializeMultipleTsFiles( let files = scene.getFiles(); if (options.verbose) { console.log(`Scene contains ${files.length} files`); - files.forEach((f) => console.log(`- '${f.getName()}'`)); + files.forEach(f => console.log(`- '${f.getName()}'`)); } if (options.inferTypes) { @@ -220,11 +212,7 @@ function serializeMultipleTsFiles( console.log('All done!'); } -function serializeTsProject( - inputDir: string, - outDir: string, - options: any, -): void { +function serializeTsProject(inputDir: string, outDir: string, options: any): void { console.log(`Serializing TS project to JSON: '${inputDir}' -> '${outDir}'`); if (fs.existsSync(outDir) && !fs.statSync(outDir).isDirectory()) { @@ -283,7 +271,6 @@ export const program = new Command() .option('-e, --entrypoint', 'Generate entrypoint for the files', false) .option('-v, --verbose', 'Verbose output', false) .action((input: any, output: any, options: any) => { - // Check for invalid combinations of flags if (options.multi && options.project) { console.error(`ERROR: You cannot provide both the '-m' and '-p' flags.`); diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceBase.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceBase.ts index c2d917f9c70a741bb88a0eaaf11d2b31e2d4f23b..48e794b1eef7e6b86cb1d3a7cf690a0ce09a6931 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceBase.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceBase.ts @@ -23,10 +23,7 @@ import { TransformerContext } from './SourceTransformer'; import { ArkNamespace } from '../../core/model/ArkNamespace'; import { BasePrinter } from '../base/BasePrinter'; -export abstract class SourceBase - extends BasePrinter - implements TransformerContext -{ +export abstract class SourceBase extends BasePrinter implements TransformerContext { protected arkFile: ArkFile; protected inBuilder: boolean = false; @@ -36,7 +33,7 @@ export abstract class SourceBase } public getDeclaringArkNamespace(): ArkNamespace | undefined { - return undefined + return undefined; } public getArkFile(): ArkFile { @@ -72,14 +69,11 @@ export abstract class SourceBase continue; } if (keyword.endsWith('Keyword')) { - keyword = keyword - .substring(0, keyword.length - 'Keyword'.length) - .toLowerCase(); + keyword = keyword.substring(0, keyword.length - 'Keyword'.length).toLowerCase(); } types.push(keyword); } return types.join(' | '); } - } diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceBody.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceBody.ts index 9d048c158e376fff44d32a97fcdeba003a64b241..b33546dce3edac6d742866e3c89ffdc14520ebb6 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceBody.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceBody.ts @@ -223,11 +223,7 @@ export class SourceBody implements StmtPrinterContext { } public getStmts(): SourceStmt[] { - return this.stmts.filter((value) => { - if (!this.skipStmts.has(value.original)) { - return value; - } - }); + return this.stmts.filter(value => !this.skipStmts.has(value.original)); } public pushStmt(stmt: SourceStmt): void { diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceClass.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceClass.ts index 26de6057044ffa50158ac33c9acd8461f7e6086e..99e3d05b88d34fec9a0681377077d113fe0fa28f 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceClass.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceClass.ts @@ -61,7 +61,7 @@ export class SourceClass extends SourceBase { const commentsMetadata = this.cls.getMetadata(ArkMetadataKind.LEADING_COMMENTS); if (commentsMetadata instanceof CommentsMetadata) { const comments = commentsMetadata.getComments(); - comments.forEach((comment) => { + comments.forEach(comment => { this.printer.writeIndent().writeLine(comment.content); }); } @@ -153,10 +153,7 @@ export class SourceClass extends SourceBase { protected printMethods(): Dump[] { let items: Dump[] = []; for (let method of this.cls.getMethods()) { - if ( - method.isGenerated() || - (PrinterUtils.isConstructorMethod(method.getName()) && this.cls.hasViewTree()) - ) { + if (method.isGenerated() || (PrinterUtils.isConstructorMethod(method.getName()) && this.cls.hasViewTree())) { continue; } diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceField.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceField.ts index 50fb363319ac3ffd58f6cc584602d883aeecaa61..41b24a99426ec4feca8e18815affad79046377a6 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceField.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceField.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -42,7 +42,7 @@ export class SourceField extends SourceBase { const commentsMetadata = this.field.getMetadata(ArkMetadataKind.LEADING_COMMENTS); if (commentsMetadata instanceof CommentsMetadata) { const comments = commentsMetadata.getComments(); - comments.forEach((comment) => { + comments.forEach(comment => { this.printer.writeIndent().writeLine(comment.content); }); } diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceFilePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceFilePrinter.ts index 9e7b9c467f909666e49b8ea885c79daefa356e3a..c34fac39d2970fbb7f239108e965538c84ecd624 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceFilePrinter.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceFilePrinter.ts @@ -59,9 +59,7 @@ export class SourceFilePrinter extends Printer { for (let method of cls.getMethods()) { if (method.isDefaultArkMethod()) { this.items.push(...new SourceMethod(method, this.printer.getIndent()).dumpDefaultMethod()); - } else if ( - !PrinterUtils.isAnonymousMethod(method.getName()) - ) { + } else if (!PrinterUtils.isAnonymousMethod(method.getName())) { this.items.push(new SourceMethod(method)); } } diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceMethod.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceMethod.ts index 2d0d70abd0595cb2ffb654a836fae6766aaa28cb..3fff56c0d2316a07513fc87fc8571c6074fcfe28 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceMethod.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceMethod.ts @@ -55,7 +55,7 @@ export class SourceMethod extends SourceBase { const commentsMetadata = this.method.getMetadata(ArkMetadataKind.LEADING_COMMENTS); if (commentsMetadata instanceof CommentsMetadata) { const comments = commentsMetadata.getComments(); - comments.forEach((comment) => { + comments.forEach(comment => { this.printer.writeIndent().writeLine(comment.content); }); } @@ -84,7 +84,7 @@ export class SourceMethod extends SourceBase { if (cfg) { cfg.getStmts() .reverse() - .forEach((stmt) => stmts.push(stmt)); + .forEach(stmt => stmts.push(stmt)); } for (const stmt of stmts) { if (stmt.getOriginPositionInfo().getLineNo() > 0) { @@ -163,7 +163,7 @@ export class SourceMethod extends SourceBase { methodSig .getMethodSubSignature() .getParameters() - .forEach((parameter) => { + .forEach(parameter => { let str: string = parameter.getName(); if (parameter.hasDotDotDotToken()) { str = `...${parameter.getName()}`; @@ -174,17 +174,13 @@ export class SourceMethod extends SourceBase { if (parameter.getType()) { str += ': ' + this.transformer.typeToString(parameter.getType()); } - if (!str.startsWith(LEXICAL_ENV_NAME_PREFIX)) - { + if (!str.startsWith(LEXICAL_ENV_NAME_PREFIX)) { parameters.push(str); } }); code.write(`(${parameters.join(', ')})`); const returnType = methodSig.getMethodSubSignature().getReturnType(); - if ( - methodSig.getMethodSubSignature().getMethodName() !== 'constructor' && - !(returnType instanceof UnknownType) - ) { + if (methodSig.getMethodSubSignature().getMethodName() !== 'constructor' && !(returnType instanceof UnknownType)) { code.write(`: ${this.transformer.typeToString(returnType)}`); } if (PrinterUtils.isAnonymousMethod(methodSig.getMethodSubSignature().getMethodName())) { @@ -197,7 +193,7 @@ export class SourceMethod extends SourceBase { let code = new ArkCodeBuffer(); let parameters: string[] = []; - this.method.getParameters().forEach((parameter) => { + this.method.getParameters().forEach(parameter => { let str: string = parameter.getName(); if (parameter.isOptional()) { str += '?'; diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceNamespace.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceNamespace.ts index d1e608120a07e8921e416b0b42b17d8b8c1930b1..4bbaaedc4b9e6687facb7f8d4c56d0e12d6697fb 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceNamespace.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceNamespace.ts @@ -52,12 +52,11 @@ export class SourceNamespace extends SourceBase { const commentsMetadata = this.ns.getMetadata(ArkMetadataKind.LEADING_COMMENTS); if (commentsMetadata instanceof CommentsMetadata) { const comments = commentsMetadata.getComments(); - comments.forEach((comment) => { + comments.forEach(comment => { this.printer.writeIndent().writeLine(comment.content); }); } - this.printer.writeIndent().writeSpace(this.modifiersToString(this.ns.getModifiers())) - .writeLine(`namespace ${this.ns.getName()} {`); + this.printer.writeIndent().writeSpace(this.modifiersToString(this.ns.getModifiers())).writeLine(`namespace ${this.ns.getName()} {`); this.printer.incIndent(); let items: Dump[] = []; @@ -78,9 +77,7 @@ export class SourceNamespace extends SourceBase { } // print exportInfos for (let exportInfo of this.ns.getExportInfos()) { - items.push( - new ExportPrinter(exportInfo, this.printer.getIndent()) - ); + items.push(new ExportPrinter(exportInfo, this.printer.getIndent())); } items.sort((a, b) => a.getLine() - b.getLine()); diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceStmt.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceStmt.ts index 3007cd765efe2b48f71bd980255d71bb931d7314..6f73ec3dc85405df20be70e1a3dd71bed1852d16 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceStmt.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceStmt.ts @@ -14,25 +14,10 @@ */ import { Constant } from '../../core/base/Constant'; -import { - ArkInstanceInvokeExpr, - ArkNewArrayExpr, - ArkNewExpr, - ArkStaticInvokeExpr, - NormalBinaryOperator, -} from '../../core/base/Expr'; +import { ArkInstanceInvokeExpr, ArkNewArrayExpr, ArkNewExpr, ArkStaticInvokeExpr, NormalBinaryOperator } from '../../core/base/Expr'; import { Local } from '../../core/base/Local'; import { ArkArrayRef, ArkInstanceFieldRef, ArkParameterRef, ArkStaticFieldRef, ClosureFieldRef } from '../../core/base/Ref'; -import { - ArkAliasTypeDefineStmt, - ArkAssignStmt, - ArkIfStmt, - ArkInvokeStmt, - ArkReturnStmt, - ArkReturnVoidStmt, - ArkThrowStmt, - Stmt, -} from '../../core/base/Stmt'; +import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, ArkThrowStmt, Stmt } from '../../core/base/Stmt'; import { AliasType, ClassType, Type } from '../../core/base/Type'; import { Value } from '../../core/base/Value'; import { BasicBlock } from '../../core/graph/BasicBlock'; @@ -90,7 +75,7 @@ export abstract class SourceStmt implements Dump { return this.line; } - public setLine(line: number) { + public setLine(line: number): void { this.line = line; } @@ -110,7 +95,7 @@ export abstract class SourceStmt implements Dump { const commentsMetadata = this.original.getMetadata(ArkMetadataKind.LEADING_COMMENTS); if (commentsMetadata instanceof CommentsMetadata) { const comments = commentsMetadata.getComments(); - comments.forEach((comment) => { + comments.forEach(comment => { content.push(`${this.printer.getIndent()}${comment.content}\n`); }); } @@ -173,7 +158,8 @@ export class SourceAssignStmt extends SourceStmt { if ( (this.leftOp instanceof Local && this.leftOp.getName() === 'this') || (this.rightOp instanceof Constant && this.rightOp.getValue() === 'undefined') || - this.rightOp instanceof ArkParameterRef || this.rightOp instanceof ClosureFieldRef + this.rightOp instanceof ArkParameterRef || + this.rightOp instanceof ClosureFieldRef ) { this.setText(''); this.dumpType = AssignStmtDumpType.NORMAL; @@ -188,10 +174,7 @@ export class SourceAssignStmt extends SourceStmt { this.transferRightNewArrayExpr(); } else if (this.rightOp instanceof ArkStaticInvokeExpr && PrinterUtils.isComponentCreate(this.rightOp)) { this.transferRightComponentCreate(); - } else if ( - this.rightOp instanceof ArkInstanceInvokeExpr && - PrinterUtils.isComponentAttributeInvoke(this.rightOp) - ) { + } else if (this.rightOp instanceof ArkInstanceInvokeExpr && PrinterUtils.isComponentAttributeInvoke(this.rightOp)) { this.transferRightComponentAttribute(); } else { this.rightCode = this.transformer.valueToString(this.rightOp); @@ -201,10 +184,7 @@ export class SourceAssignStmt extends SourceStmt { this.context.setTempCode((this.leftOp as Local).getName(), this.rightCode); } - if ( - (this.leftOp instanceof ArkInstanceFieldRef && this.leftOp.getBase().getName() === 'this') || - this.leftOp instanceof ArkStaticFieldRef - ) { + if ((this.leftOp instanceof ArkInstanceFieldRef && this.leftOp.getBase().getName() === 'this') || this.leftOp instanceof ArkStaticFieldRef) { this.context.setTempCode(this.leftOp.getFieldName(), this.rightCode); } @@ -241,11 +221,7 @@ export class SourceAssignStmt extends SourceStmt { this.setText(`${this.rightCode};`); return; } - if ( - this.leftOp instanceof Local && - this.context.getLocals().has(this.leftOp.getName()) && - !this.isLocalTempValue(this.leftOp) - ) { + if (this.leftOp instanceof Local && this.context.getLocals().has(this.leftOp.getName()) && !this.isLocalTempValue(this.leftOp)) { if (this.context.isLocalDefined(this.leftOp)) { this.setText(`${this.leftCode} = ${this.rightCode};`); return; @@ -320,20 +296,16 @@ export class SourceAssignStmt extends SourceStmt { private handleConstructorInvoke(instanceInvokeExpr: ArkInstanceInvokeExpr, originType?: number): void { let args: string[] = []; - instanceInvokeExpr.getArgs().forEach((v) => { + instanceInvokeExpr.getArgs().forEach(v => { args.push(this.transformer.valueToString(v)); }); if (originType === CLASS_CATEGORY_COMPONENT) { this.rightCode = `${this.transformer.typeToString(this.rightOp.getType())}(${args.join(', ')})`; } else if (originType === ClassCategory.TYPE_LITERAL || originType === ClassCategory.OBJECT) { - this.rightCode = `${this.transformer.literalObjectToString( - this.rightOp.getType() as ClassType - )}`; + this.rightCode = `${this.transformer.literalObjectToString(this.rightOp.getType() as ClassType)}`; } else { - this.rightCode = `new ${this.transformer.typeToString(this.rightOp.getType())}(${args.join( - ', ' - )})`; + this.rightCode = `new ${this.transformer.typeToString(this.rightOp.getType())}(${args.join(', ')})`; } } @@ -597,9 +569,7 @@ export class SourceWhileStmt extends SourceStmt { this.context.setTempVisit(name); } - this.setText( - `for (let [${arrayValueNames.join(', ')}] of ${this.transformer.valueToString(iterator.getBase())}) {` - ); + this.setText(`for (let [${arrayValueNames.join(', ')}] of ${this.transformer.valueToString(iterator.getBase())}) {`); this.context.setTempVisit((temp3 as Local).getName()); return true; @@ -626,18 +596,12 @@ export class SourceWhileStmt extends SourceStmt { if (!(stmt instanceof ArkAssignStmt)) { continue; } - if ( - PrinterUtils.isDeIncrementStmt(stmt, NormalBinaryOperator.Addition) && - (stmt.getLeftOp() as Local).getName() === value.getName() - ) { + if (PrinterUtils.isDeIncrementStmt(stmt, NormalBinaryOperator.Addition) && (stmt.getLeftOp() as Local).getName() === value.getName()) { this.context.setSkipStmt(stmt); return `${value.getName()}++`; } - if ( - PrinterUtils.isDeIncrementStmt(stmt, NormalBinaryOperator.Subtraction) && - (stmt.getLeftOp() as Local).getName() === value.getName() - ) { + if (PrinterUtils.isDeIncrementStmt(stmt, NormalBinaryOperator.Subtraction) && (stmt.getLeftOp() as Local).getName() === value.getName()) { this.context.setSkipStmt(stmt); return `${value.getName()}--`; } @@ -829,7 +793,9 @@ export class SourceTypeAliasStmt extends SourceStmt { if (typeObject instanceof AliasType) { this.setText(`${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${typeObject.getName()}${realGenericTypes};`); } else { - this.setText(`${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${this.transformer.typeToString(typeObject)}${realGenericTypes};`); + this.setText( + `${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${this.transformer.typeToString(typeObject)}${realGenericTypes};` + ); } return; } @@ -842,7 +808,9 @@ export class SourceTypeAliasStmt extends SourceStmt { return; } if (typeObject instanceof Local) { - this.setText(`${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${this.transformer.valueToString(typeObject)}${realGenericTypes};`); + this.setText( + `${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${this.transformer.valueToString(typeObject)}${realGenericTypes};` + ); return; } if (typeObject instanceof ArkClass) { @@ -941,7 +909,7 @@ export class SourceNewArrayExpr { this.values = []; } - public addInitValue(value: string) { + public addInitValue(value: string): void { this.values.push(value); } diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceTransformer.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceTransformer.ts index 51b9736218ec7309876b4fbac166cf1e93df273b..58c999d85b7244db2cb2093eca392863103849af 100644 --- a/ets2panda/linter/arkanalyzer/src/save/source/SourceTransformer.ts +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceTransformer.ts @@ -60,12 +60,7 @@ import { SourceClass } from './SourceClass'; import { Value } from '../../core/base/Value'; import { AbstractRef, ArkArrayRef, ArkInstanceFieldRef, ArkStaticFieldRef, ArkThisRef } from '../../core/base/Ref'; import { ArkFile } from '../../core/model/ArkFile'; -import { - COMPONENT_CREATE_FUNCTION, - COMPONENT_CUSTOMVIEW, - COMPONENT_IF, - COMPONENT_POP_FUNCTION, -} from '../../core/common/EtsConst'; +import { COMPONENT_CREATE_FUNCTION, COMPONENT_CUSTOMVIEW, COMPONENT_IF, COMPONENT_POP_FUNCTION } from '../../core/common/EtsConst'; import { INSTANCE_INIT_METHOD_NAME } from '../../core/common/Const'; import { ArkAssignStmt } from '../../core/base/Stmt'; import { ArkNamespace } from '../../core/model/ArkNamespace'; @@ -118,7 +113,7 @@ export class SourceTransformer { return ''; } let args: string[] = []; - invokeExpr.getArgs().forEach((v) => { + invokeExpr.getArgs().forEach(v => { args.push(this.valueToString(v)); }); let genericCode = this.genericTypesToString(invokeExpr.getRealGenericTypes()); @@ -130,8 +125,7 @@ export class SourceTransformer { return `${this.valueToString(invokeExpr.getBase())}.${methodName}${genericCode}(${args.join(', ')})`; } - private transBuilderMethod(className: string, methodName: string, args: string[], - invokeExpr: ArkStaticInvokeExpr, genericCode: string): string | null { + private transBuilderMethod(className: string, methodName: string, args: string[], invokeExpr: ArkStaticInvokeExpr, genericCode: string): string | null { if (className === COMPONENT_CUSTOMVIEW) { if (methodName === COMPONENT_CREATE_FUNCTION) { // Anonymous @Builder method @@ -181,7 +175,7 @@ export class SourceTransformer { let className = PrinterUtils.getStaticInvokeClassFullName(classSignature, this.context.getDeclaringArkNamespace()); let methodName = methodSignature.getMethodSubSignature().getMethodName(); let args: string[] = []; - invokeExpr.getArgs().forEach((v) => { + invokeExpr.getArgs().forEach(v => { args.push(this.valueToString(v)); }); @@ -199,7 +193,7 @@ export class SourceTransformer { } return `${methodName}${genericCode}(${args.join(', ')})`; } - + private genericTypesToString(types: Type[] | undefined): string { if (!types) { return ''; @@ -214,7 +208,7 @@ export class SourceTransformer { public typeArrayToString(types: Type[], split: string = ', '): string { let typesStr: string[] = []; - types.forEach((t) => { + types.forEach(t => { typesStr.push(this.typeToString(t)); }); @@ -301,11 +295,7 @@ export class SourceTransformer { if (value instanceof ArkArrayRef) { let index = value.getIndex(); - if ( - index instanceof Constant && - index.getType() instanceof StringType && - PrinterUtils.isTemp(index.getValue()) - ) { + if (index instanceof Constant && index.getType() instanceof StringType && PrinterUtils.isTemp(index.getValue())) { return `${this.valueToString(value.getBase())}[${this.valueToString(new Local(index.getValue()))}]`; } return `${this.valueToString(value.getBase())}[${this.valueToString(value.getIndex())}]`; @@ -357,11 +347,7 @@ export class SourceTransformer { } } - if ( - operator === NormalBinaryOperator.Division || - operator === NormalBinaryOperator.Multiplication || - operator === NormalBinaryOperator.Remainder - ) { + if (operator === NormalBinaryOperator.Division || operator === NormalBinaryOperator.Multiplication || operator === NormalBinaryOperator.Remainder) { if (PrinterUtils.isTemp(value.getName())) { let stmt = value.getDeclaringStmt(); if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof ArkNormalBinopExpr) { @@ -537,7 +523,7 @@ export class SourceTransformer { private unclearReferenceType2string(type: UnclearReferenceType): string { let genericTypes = type.getGenericTypes(); if (genericTypes.length > 0) { - return `${type.getName()}<${genericTypes.map((value)=>this.typeToString(value)).join(', ')}>`; + return `${type.getName()}<${genericTypes.map(value => this.typeToString(value)).join(', ')}>`; } return type.getName(); } diff --git a/ets2panda/linter/arkanalyzer/src/transformer/FunctionTransformer.ts b/ets2panda/linter/arkanalyzer/src/transformer/FunctionTransformer.ts index 24dbe1869e8e0483d4c62b1c84e146968e150312..4cfc917d2cb294656aa6635c78bb354f4a280ef3 100644 --- a/ets2panda/linter/arkanalyzer/src/transformer/FunctionTransformer.ts +++ b/ets2panda/linter/arkanalyzer/src/transformer/FunctionTransformer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,7 +13,4 @@ * limitations under the License. */ - -class FunctionTransformer extends Transformer{ - -} \ No newline at end of file +class FunctionTransformer extends Transformer {} diff --git a/ets2panda/linter/arkanalyzer/src/transformer/SceneTransformer.ts b/ets2panda/linter/arkanalyzer/src/transformer/SceneTransformer.ts index 7d29148dd46803121200c1e1587d80232d82a486..caeea5c2624b9e9721fb954fc3961d5d410e9301 100644 --- a/ets2panda/linter/arkanalyzer/src/transformer/SceneTransformer.ts +++ b/ets2panda/linter/arkanalyzer/src/transformer/SceneTransformer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,7 +13,4 @@ * limitations under the License. */ - -class SceneTransformer extends Transformer{ - -} \ No newline at end of file +class SceneTransformer extends Transformer {} diff --git a/ets2panda/linter/arkanalyzer/src/transformer/StaticSingleAssignmentFormer.ts b/ets2panda/linter/arkanalyzer/src/transformer/StaticSingleAssignmentFormer.ts index 0f930f64ea2eca09cd4f3e55d5f41a07e54804b8..2c7e78deec68bd3715c15e00bee27a851f6580d1 100644 --- a/ets2panda/linter/arkanalyzer/src/transformer/StaticSingleAssignmentFormer.ts +++ b/ets2panda/linter/arkanalyzer/src/transformer/StaticSingleAssignmentFormer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -58,9 +58,12 @@ export class StaticSingleAssignmentFormer { } } - private decideBlockToPhiStmts(body: ArkBody, dominanceFinder: DominanceFinder, - blockToDefs: Map>, localToBlocks: Map>): - Map> { + private decideBlockToPhiStmts( + body: ArkBody, + dominanceFinder: DominanceFinder, + blockToDefs: Map>, + localToBlocks: Map> + ): Map> { let blockToPhiStmts = new Map>(); let blockToPhiLocals = new Map>(); let localToPhiBlock = new Map>(); @@ -81,11 +84,15 @@ export class StaticSingleAssignmentFormer { return blockToPhiStmts; } - private handleDf(blockToPhiStmts: Map>, - blockToPhiLocals: Map>, - phiBlocks: Set, df: BasicBlock, local: Local, - blockToDefs: Map>, - blocks: BasicBlock[]): void { + private handleDf( + blockToPhiStmts: Map>, + blockToPhiLocals: Map>, + phiBlocks: Set, + df: BasicBlock, + local: Local, + blockToDefs: Map>, + blocks: BasicBlock[] + ): void { if (!phiBlocks.has(df)) { phiBlocks.add(df); @@ -109,12 +116,14 @@ export class StaticSingleAssignmentFormer { } } - private handleBlockWithSucc(blockToPhiStmts: Map>, - succ: BasicBlock, - blockToDefs: Map>, - block: BasicBlock, - phiArgsNum: Map): void { - for (const phi of (blockToPhiStmts.get(succ) as Set)) { + private handleBlockWithSucc( + blockToPhiStmts: Map>, + succ: BasicBlock, + blockToDefs: Map>, + block: BasicBlock, + phiArgsNum: Map + ): void { + for (const phi of blockToPhiStmts.get(succ) as Set) { let local = phi.getDef() as Local; if (blockToDefs.get(block)?.has(local)) { if (phiArgsNum.has(phi)) { @@ -127,9 +136,7 @@ export class StaticSingleAssignmentFormer { } } - private addPhiStmts(blockToPhiStmts: Map>, cfg: Cfg, - blockToDefs: Map>): void { - + private addPhiStmts(blockToPhiStmts: Map>, cfg: Cfg, blockToDefs: Map>): void { let phiArgsNum = new Map(); for (const block of cfg.getBlocks()) { let succs = Array.from(block.getSuccessors()); @@ -155,8 +162,7 @@ export class StaticSingleAssignmentFormer { } } - private renameUseAndDef(stmt: Stmt, localToNameStack: Map, nextFreeIdx: number, - newLocals: Set, newPhiStmts: Set): number { + private renameUseAndDef(stmt: Stmt, localToNameStack: Map, nextFreeIdx: number, newLocals: Set, newPhiStmts: Set): number { let uses = stmt.getUses(); if (uses.length > 0 && !this.constainsPhiExpr(stmt)) { for (const use of uses) { @@ -185,12 +191,11 @@ export class StaticSingleAssignmentFormer { return nextFreeIdx; } - private renameLocals(body: ArkBody, dominanceTree: DominanceTree, - blockToPhiStmts: Map>): void { + private renameLocals(body: ArkBody, dominanceTree: DominanceTree, blockToPhiStmts: Map>): void { let newLocals = new Set(body.getLocals().values()); let localToNameStack = new Map(); for (const local of newLocals) { - localToNameStack.set(local, new Array()) + localToNameStack.set(local, new Array()); } let blockStack = new Array(); @@ -231,8 +236,7 @@ export class StaticSingleAssignmentFormer { body.setLocals(newLocals); } - private removeVisitedTree(blockStack: BasicBlock[], dominanceTree: DominanceTree, - visited: Set, localToNameStack: Map): void { + private removeVisitedTree(blockStack: BasicBlock[], dominanceTree: DominanceTree, visited: Set, localToNameStack: Map): void { let top = blockStack[blockStack.length - 1]; let children = dominanceTree.getChildren(top); while (this.containsAllChildren(visited, children)) { @@ -308,4 +312,4 @@ export class StaticSingleAssignmentFormer { let phiExpr = new ArkPhiExpr(); return new ArkAssignStmt(local, phiExpr); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/transformer/Transformer.ts b/ets2panda/linter/arkanalyzer/src/transformer/Transformer.ts index 5b4d7f30bb6a9c825e490b340061d2312e32105f..790c9319b5b490c6a2314915f2a7ffda3f507f8e 100644 --- a/ets2panda/linter/arkanalyzer/src/transformer/Transformer.ts +++ b/ets2panda/linter/arkanalyzer/src/transformer/Transformer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,12 +13,9 @@ * limitations under the License. */ - /** - * + * */ class Transformer { - internalTransform() { - - } -} \ No newline at end of file + internalTransform(): void {} +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/AstTreeUtils.ts b/ets2panda/linter/arkanalyzer/src/utils/AstTreeUtils.ts index 8a86f8d57aa373704293737e6a9a6888ee079cd7..8266b8bafe2c8566d8f77c7c301686f0c5f599ae 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/AstTreeUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/AstTreeUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,19 +13,57 @@ * limitations under the License. */ -import { ts } from '..'; +import { ArkFile, ts } from '..'; import { ETS_COMPILER_OPTIONS } from '../core/common/EtsConst'; +import * as crypto from 'crypto'; + +const sourceFileCache: Map = new Map(); export class AstTreeUtils { + /** + * get source file from code segment + * @param fileName source file name + * @param code source code + * @returns ts.SourceFile + */ public static getASTNode(fileName: string, code: string): ts.SourceFile { - const sourceFile = ts.createSourceFile( - fileName, - code, - ts.ScriptTarget.Latest, - true, - undefined, - ETS_COMPILER_OPTIONS - ); + const key = this.getKeyFromCode(code); + let sourceFile = sourceFileCache.get(key); + if (sourceFile) { + return sourceFile; + } + sourceFile = this.createSourceFile(fileName, code); + sourceFileCache.set(key, sourceFile); + return sourceFile; + } + + /** + * get source file from ArkFile + * @param arkFile ArkFile + * @returns ts.SourceFile + */ + public static getSourceFileFromArkFile(arkFile: ArkFile): ts.SourceFile { + const signature = arkFile.getFileSignature().toString(); + const key = this.getKeyFromCode(signature); + let sourceFile = sourceFileCache.get(key); + if (sourceFile) { + return sourceFile; + } + sourceFile = this.createSourceFile(arkFile.getName(), arkFile.getCode()); + sourceFileCache.set(key, sourceFile); return sourceFile; } + + public static createSourceFile(fileName: string, code: string): ts.SourceFile { + return ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true, undefined, ETS_COMPILER_OPTIONS); + } + + /** + * convert source code to hash string + * @param code source code + * @returns string + */ + private static getKeyFromCode(code: string): string { + return crypto.createHash('sha256').update(code).digest('hex'); + } } diff --git a/ets2panda/linter/arkanalyzer/src/utils/CfgStructualAnalysis.ts b/ets2panda/linter/arkanalyzer/src/utils/CfgStructualAnalysis.ts index 886b47ad45075ff648e93db44d779ee2026d24cb..01899770e6241b03dc565ea922340a942670e5ee 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/CfgStructualAnalysis.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/CfgStructualAnalysis.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -81,7 +81,7 @@ export class AbstractFlowGraph { return loop.inc.getBlock()!; } - public preOrder(node: AbstractNode, callback: TraversalCallback, visitor: Set = new Set()) { + public preOrder(node: AbstractNode, callback: TraversalCallback, visitor: Set = new Set()): void { visitor.add(node); node.traversal(callback, CodeBlockType.NORMAL); for (const succ of node.getSucc()) { @@ -456,12 +456,7 @@ export class AbstractFlowGraph { return true; } - if ( - m.getSucc().length === 1 && - loop.control.has(m.getSucc()[0]) && - !loop.control.has(n) && - !this.isIfElseRegion(node, nodeSet) - ) { + if (m.getSucc().length === 1 && loop.control.has(m.getSucc()[0]) && !loop.control.has(n) && !this.isIfElseRegion(node, nodeSet)) { nodeSet.add(node).add(m); return true; } @@ -483,11 +478,7 @@ export class AbstractFlowGraph { if (loop.header === node && loop.getType() === RegionType.FOR_LOOP_REGION) { let forLoop = loop as ForLoopRegion; let blocks = node.getSucc()[0]; - if ( - forLoop.inc.getPred().length === 1 && - forLoop.inc.getPred()[0] === blocks && - blocks.getSucc().length === 1 - ) { + if (forLoop.inc.getPred().length === 1 && forLoop.inc.getPred()[0] === blocks && blocks.getSucc().length === 1) { nodeSet.add(node).add(forLoop.inc).add(blocks); return true; } @@ -507,11 +498,7 @@ export class AbstractFlowGraph { return false; } - private identifyRegionType( - node: AbstractNode, - nodeSet: Set, - scope?: Set - ): RegionType | undefined { + private identifyRegionType(node: AbstractNode, nodeSet: Set, scope?: Set): RegionType | undefined { if (this.isBlockRegion(node, nodeSet, scope)) { return RegionType.BLOCK_REGION; } @@ -668,11 +655,7 @@ export class AbstractFlowGraph { let doWhileLoop = new DoWhileLoopRegion(nodeSet); this.loopMap.set(doWhileLoop.header, doWhileLoop); node = doWhileLoop; - } else if ( - rtype === RegionType.TRY_CATCH_REGION || - rtype === RegionType.TRY_FINALLY_REGION || - rtype === RegionType.TRY_CATCH_FINALLY_REGION - ) { + } else if (rtype === RegionType.TRY_CATCH_REGION || rtype === RegionType.TRY_FINALLY_REGION || rtype === RegionType.TRY_CATCH_FINALLY_REGION) { node = new TrapRegion(nodeSet, rtype); } @@ -727,12 +710,7 @@ export class AbstractFlowGraph { if (!traps) { return []; } - traps.sort( - (a, b) => - a.getTryBlocks().length + - a.getCatchBlocks().length - - (b.getTryBlocks().length + b.getCatchBlocks().length) - ); + traps.sort((a, b) => a.getTryBlocks().length + a.getCatchBlocks().length - (b.getTryBlocks().length + b.getCatchBlocks().length)); let trapRegions: NaturalTrapRegion[] = []; @@ -911,7 +889,7 @@ class AbstractNode { this.type = RegionType.ABSTRACT_NODE; } - public traversal(callback: TraversalCallback, type: CodeBlockType) { + public traversal(callback: TraversalCallback, type: CodeBlockType): void { callback(this.bb, type); } @@ -923,11 +901,11 @@ class AbstractNode { return this.succNodes; } - public addSucc(node: AbstractNode) { + public addSucc(node: AbstractNode): void { this.succNodes.push(node); } - public replaceSucc(src: AbstractNode, dst: AbstractNode) { + public replaceSucc(src: AbstractNode, dst: AbstractNode): void { for (let i = 0; i < this.succNodes.length; i++) { if (this.succNodes[i] === src) { this.succNodes[i] = dst; @@ -936,7 +914,7 @@ class AbstractNode { } } - public removeSucc(src: AbstractNode) { + public removeSucc(src: AbstractNode): void { for (let i = 0; i < this.predNodes.length; i++) { if (this.succNodes[i] === src) { this.succNodes.splice(i, 1); @@ -957,7 +935,7 @@ class AbstractNode { this.predNodes.push(block); } - public replacePred(src: AbstractNode, dst: AbstractNode) { + public replacePred(src: AbstractNode, dst: AbstractNode): void { for (let i = 0; i < this.predNodes.length; i++) { if (this.predNodes[i] === src) { this.predNodes[i] = dst; @@ -966,7 +944,7 @@ class AbstractNode { } } - public removePred(src: AbstractNode) { + public removePred(src: AbstractNode): void { for (let i = 0; i < this.predNodes.length; i++) { if (this.predNodes[i] === src) { this.predNodes.splice(i, 1); @@ -975,7 +953,7 @@ class AbstractNode { } } - public setBlock(bb: BasicBlock) { + public setBlock(bb: BasicBlock): void { this.bb = bb; } @@ -1035,7 +1013,7 @@ class BlockRegion extends Region { this.blocks = Array.from(nset); } - public replace() { + public replace(): void { for (let pred of this.blocks[0].getPred()) { pred.replaceSucc(this.blocks[0], this); this.addPred(pred); @@ -1047,7 +1025,7 @@ class BlockRegion extends Region { } } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { for (const node of this.blocks) { node.traversal(callback, CodeBlockType.NORMAL); } @@ -1111,12 +1089,7 @@ abstract class NaturalLoopRegion extends Region { // add node to loop sets for (const node of this.nset) { for (const succ of node.getSucc()) { - if ( - !this.nset.has(succ) && - succ !== this.getExitNode() && - succ.getSucc().length === 1 && - succ.getSucc()[0] === this.getExitNode() - ) { + if (!this.nset.has(succ) && succ !== this.getExitNode() && succ.getSucc().length === 1 && succ.getSucc()[0] === this.getExitNode()) { this.nset.add(succ); } } @@ -1132,7 +1105,7 @@ class SelfLoopRegion extends NaturalLoopRegion { this.back = this.header; } - public replace() { + public replace(): void { for (let pred of this.header.getPred()) { if (pred !== this.header) { pred.replaceSucc(this.header, this); @@ -1158,7 +1131,7 @@ class WhileLoopRegion extends NaturalLoopRegion { super(nset, RegionType.WHILE_LOOP_REGION); } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { this.header.traversal(callback, CodeBlockType.WHILE); if (this.header !== this.back) { this.back.traversal(callback, CodeBlockType.NORMAL); @@ -1178,7 +1151,7 @@ class DoWhileLoopRegion extends NaturalLoopRegion { this.control.add(this.back); } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { callback(undefined, CodeBlockType.DO); if (this.header !== this.back) { this.header.traversal(callback, CodeBlockType.NORMAL); @@ -1200,7 +1173,7 @@ class ForLoopRegion extends NaturalLoopRegion { this.control.add(this.inc); } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { this.header.traversal(callback, CodeBlockType.FOR); for (const node of this.nset) { if (node !== this.header && node !== this.inc) { @@ -1238,7 +1211,7 @@ class IfRegion extends Region { } } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { this.contition.traversal(callback, CodeBlockType.IF); this.then.traversal(callback, CodeBlockType.NORMAL); callback(undefined, CodeBlockType.COMPOUND_END); @@ -1260,7 +1233,7 @@ class IfExitRegion extends IfRegion { this.type = RegionType.IF_THEN_EXIT_REGION; } - public replace() { + public replace(): void { this.replaceContitionPred(); let succ = this.contition.getSucc()[1]; @@ -1275,7 +1248,7 @@ class IfBreakRegion extends IfRegion { this.type = RegionType.IF_THEN_BREAK_REGION; } - public replace() { + public replace(): void { this.replaceContitionPred(); let succ = this.contition.getSucc()[1]; @@ -1291,7 +1264,7 @@ class IfBreakRegion extends IfRegion { } } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { this.contition.traversal(callback, CodeBlockType.IF); this.then?.traversal(callback, CodeBlockType.NORMAL); callback(undefined, CodeBlockType.BREAK); @@ -1305,7 +1278,7 @@ class IfContinueRegion extends IfBreakRegion { this.type = RegionType.IF_THEN_CONTINUE_REGION; } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { this.contition.traversal(callback, CodeBlockType.IF); this.then?.traversal(callback, CodeBlockType.NORMAL); callback(undefined, CodeBlockType.CONTINUE); @@ -1326,7 +1299,7 @@ class IfElseRegion extends Region { this.else = nodes[2]; } - public replace() { + public replace(): void { for (let pred of this.contition.getPred()) { if (pred !== this.contition) { pred.replaceSucc(this.contition, this); @@ -1343,7 +1316,7 @@ class IfElseRegion extends Region { } } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { this.contition.traversal(callback, CodeBlockType.IF); this.then.traversal(callback, CodeBlockType.NORMAL); callback(undefined, CodeBlockType.ELSE); @@ -1397,7 +1370,7 @@ class TrapRegion extends Region { } } - public traversal(callback: TraversalCallback) { + public traversal(callback: TraversalCallback): void { callback(undefined, CodeBlockType.TRY); this.tryNode.traversal(callback, CodeBlockType.NORMAL); if (this.catchNode) { diff --git a/ets2panda/linter/arkanalyzer/src/utils/FileUtils.ts b/ets2panda/linter/arkanalyzer/src/utils/FileUtils.ts index 4cf756fc0bf1be58980a71db94623e9ee405affb..a4837006ed4512526243608ef0edfd6a714c0686 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/FileUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/FileUtils.ts @@ -25,8 +25,8 @@ const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'FileUtils'); export class FileUtils { public static readonly FILE_FILTER = { ignores: ['.git', '.preview', '.hvigor', '.idea', 'test', 'ohosTest'], - include: /(? { if (!content.dependencies) { return; @@ -72,11 +69,10 @@ export class FileUtils { const key = path.resolve(modulePath, OH_PACKAGE_JSON5); const target = ohPkgContentMap.get(key); if (target) { - moduleMap.set(name, new ModulePath(modulePath, target.main ? - path.resolve(modulePath, target.main as string) : '')); + moduleMap.set(name, new ModulePath(modulePath, target.main ? path.resolve(modulePath, target.main as string) : '')); } }); - }) + }); return moduleMap; } @@ -90,6 +86,8 @@ export class FileUtils { return Language.TYPESCRIPT; case '.ets': return Language.ARKTS1_1; + case '.js': + return Language.JAVASCRIPT; default: return Language.UNKNOWN; } @@ -114,7 +112,7 @@ export function getFileRecursively(srcDir: string, fileName: string, visited: Se } const filesUnderThisDir = fs.readdirSync(srcDir, { withFileTypes: true }); - const realSrc = fs.realpathSync(srcDir) + const realSrc = fs.realpathSync(srcDir); if (visited.has(realSrc)) { return res; } @@ -130,6 +128,7 @@ export function getFileRecursively(srcDir: string, fileName: string, visited: Se } const tmpDir = path.resolve(srcDir, '../'); res = getFileRecursively(tmpDir, fileName, visited); + return res; }); return res; -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/SparseBitVector.ts b/ets2panda/linter/arkanalyzer/src/utils/SparseBitVector.ts index ec36ed6ee8b76920db3707e7829b7bebacc52168..fcb5c816ac5f5b5ef8e9b4f3ace185db43c041c4 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/SparseBitVector.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/SparseBitVector.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -120,7 +120,7 @@ class SparseBitVectorElement { // Count the number of set bits in this element count(): number { let numBits = 0; - this.bits.forEach((word) => { + this.bits.forEach(word => { numBits += this.countBits(word); }); return numBits; @@ -354,7 +354,9 @@ export class SparseBitVector { // Find the first set bit in the vector findFirst(): number { - if (this.elements.size === 0) return -1; + if (this.elements.size === 0) { + return -1; + } const firstElement = this.elements.entries().next().value; if (firstElement) { const firstBit = firstElement[1].findFirst(); @@ -385,10 +387,10 @@ export class SparseBitVector { let element = next.value; if (!element) { return { - next() { + next(): { value: undefined; done: true } { return { value: undefined, done: true }; }, - [Symbol.iterator]() { + [Symbol.iterator](): IterableIterator { return this; // Make the iterator itself iterable }, }; @@ -410,7 +412,7 @@ export class SparseBitVector { } return { value: undefined, done: true }; }, - [Symbol.iterator]() { + [Symbol.iterator](): IterableIterator { return this; // Make the iterator itself iterable }, }; @@ -498,7 +500,7 @@ export class SparseBitVector { } if (needDeleteIdx.size > 0) { - needDeleteIdx.forEach((idx) => this.elements.delete(idx)); + needDeleteIdx.forEach(idx => this.elements.delete(idx)); changed = true; } @@ -529,7 +531,7 @@ export class SparseBitVector { } if (needDeleteIdx.size > 0) { - needDeleteIdx.forEach((idx) => this.elements.delete(idx)); + needDeleteIdx.forEach(idx => this.elements.delete(idx)); changed = true; } diff --git a/ets2panda/linter/arkanalyzer/src/utils/callGraphUtils.ts b/ets2panda/linter/arkanalyzer/src/utils/callGraphUtils.ts index d37b14203c058b68db13b06930bf52611be177fb..c15236a0b39262b735f78b2a3f81b647c536cce5 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/callGraphUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/callGraphUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -48,25 +48,17 @@ export class MethodSignatureManager { public findInProcessedList(signature: MethodSignature): boolean { let result = this.processedList.find(item => item.toString() === signature.toString()); - return typeof result !== "undefined"; + return typeof result !== 'undefined'; } public addToWorkList(signature: MethodSignature): void { - if (!isItemRegistered( - signature, this.workList, - (a, b) => - a.toString() === b.toString() - )) { + if (!isItemRegistered(signature, this.workList, (a, b) => a.toString() === b.toString())) { this.workList.push(signature); } } public addToProcessedList(signature: MethodSignature): void { - if (!isItemRegistered( - signature, this.processedList, - (a, b) => - a === b - )) { + if (!isItemRegistered(signature, this.processedList, (a, b) => a === b)) { this.processedList.push(signature); } } @@ -110,9 +102,10 @@ export class SceneManager { } public getClass(arkClass: ClassSignature): ArkClass | null { - if (typeof arkClass.getClassName() === "undefined") - return null - let classInstance = this._scene.getClass(arkClass) + if (typeof arkClass.getClassName() === 'undefined') { + return null; + } + let classInstance = this._scene.getClass(arkClass); if (classInstance != null) { return classInstance; } @@ -121,22 +114,23 @@ export class SceneManager { if (sdkOrTargetProjectFile != null) { for (let classUnderFile of ModelUtils.getAllClassesInFile(sdkOrTargetProjectFile)) { if (classUnderFile.getSignature().toString() === arkClass.toString()) { - return classUnderFile + return classUnderFile; } } } - return classInstance + return classInstance; } public getExtendedClasses(arkClass: ClassSignature): ArkClass[] { - let sourceClass = this.getClass(arkClass) - let classList = [sourceClass] // 待处理类 - let extendedClasses: ArkClass[] = [] // 已经处理的类 + let sourceClass = this.getClass(arkClass); + let classList = [sourceClass]; // 待处理类 + let extendedClasses: ArkClass[] = []; // 已经处理的类 while (classList.length > 0) { - let tempClass = classList.shift() - if (tempClass == null) - continue + let tempClass = classList.shift(); + if (tempClass == null) { + continue; + } let firstLevelSubclasses: ArkClass[] = Array.from(tempClass.getExtendedClasses().values()); if (!firstLevelSubclasses) { @@ -144,26 +138,18 @@ export class SceneManager { } for (let subclass of firstLevelSubclasses) { - if (!isItemRegistered( - subclass, extendedClasses, - (a, b) => - a.getSignature().toString() === b.getSignature().toString() - )) { + if (!isItemRegistered(subclass, extendedClasses, (a, b) => a.getSignature().toString() === b.getSignature().toString())) { // 子类未处理,加入到classList - classList.push(subclass) + classList.push(subclass); } } // 当前类处理完毕,标记为已处理 - if (!isItemRegistered( - tempClass, extendedClasses, - (a, b) => - a.getSignature().toString() === b.getSignature().toString() - )) { - extendedClasses.push(tempClass) + if (!isItemRegistered(tempClass, extendedClasses, (a, b) => a.getSignature().toString() === b.getSignature().toString())) { + extendedClasses.push(tempClass); } } - return extendedClasses + return extendedClasses; } } @@ -192,7 +178,7 @@ export function splitStringWithRegex(input: string): string[] { export function printCallGraphDetails(methods: Set, calls: Map, rootDir: string): void { // 打印 Methods - logger.info("Call Graph:\n") + logger.info('Call Graph:\n'); logger.info('\tMethods:'); methods.forEach(method => { logger.info(`\t\t${method}`); @@ -210,7 +196,7 @@ export function printCallGraphDetails(methods: Set, calls: Map< const modifiedCalledMethod = `\t\t<${calledMethods[i]}`; logger.info(`\t\t${modifiedCalledMethod}`); } - logger.info("\n") + logger.info('\n'); }); } @@ -220,5 +206,5 @@ export function extractLastBracketContent(input: string): string { if (match && match[1]) { return match[1].trim(); } - return ""; -} \ No newline at end of file + return ''; +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/crypto_utils.ts b/ets2panda/linter/arkanalyzer/src/utils/crypto_utils.ts index 39a64826f0c9d122d424edf5d687f9458f28289f..9563d475b185cfd792bd3f5161f25bc4f5fb372f 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/crypto_utils.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/crypto_utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -16,7 +16,6 @@ import * as crypto from 'crypto'; export class CryptoUtils { - public static sha256(content: string): string { return this.hash(content, 'sha256'); } @@ -28,7 +27,7 @@ export class CryptoUtils { public static hashcode(content: string): number { let h = 0; for (let i = 0; i < content.length; i++) { - h = Math.imul(31, h) + content.charCodeAt(i) | 0; + h = (Math.imul(31, h) + content.charCodeAt(i)) | 0; } return h; } diff --git a/ets2panda/linter/arkanalyzer/src/utils/entryMethodUtils.ts b/ets2panda/linter/arkanalyzer/src/utils/entryMethodUtils.ts index c9bfa8e0d6aad5c034ce07796632a9cc91a42436..b908801378ae05590d4b2af3689d5573caebd8db 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/entryMethodUtils.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/entryMethodUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -45,25 +45,25 @@ export const LIFECYCLE_METHOD_NAME: string[] = [ 'onConfigurationUpdate', 'onAcquireFormState', 'onWindowStageWillDestroy', - ]; +]; export const CALLBACK_METHOD_NAME: string[] = [ - "onClick", // 点击事件,当用户点击组件时触发 - "onTouch", // 触摸事件,当手指在组件上按下、滑动、抬起时触发 - "onAppear", // 组件挂载显示时触发 - "onDisAppear", // 组件卸载消失时触发 - "onDragStart", // 拖拽开始事件,当组件被长按后开始拖拽时触发 - "onDragEnter", // 拖拽进入组件范围时触发 - "onDragMove", // 拖拽在组件范围内移动时触发 - "onDragLeave", // 拖拽离开组件范围内时触发 - "onDrop", // 拖拽释放目标,当在本组件范围内停止拖拽行为时触发 - "onKeyEvent", // 按键事件,当组件获焦后,按键动作触发 - "onFocus", // 焦点事件,当组件获取焦点时触发 - "onBlur", // 当组件失去焦点时触发的回调 - "onHover", // 鼠标悬浮事件,鼠标进入或退出组件时触发 - "onMouse", // 鼠标事件,当鼠标按键点击或在组件上移动时触发 - "onAreaChange", // 组件区域变化事件,组件尺寸、位置变化时触发 - "onVisibleAreaChange", // 组件可见区域变化事件,组件在屏幕中的显示区域面积变化时触发 - ]; + 'onClick', // 点击事件,当用户点击组件时触发 + 'onTouch', // 触摸事件,当手指在组件上按下、滑动、抬起时触发 + 'onAppear', // 组件挂载显示时触发 + 'onDisAppear', // 组件卸载消失时触发 + 'onDragStart', // 拖拽开始事件,当组件被长按后开始拖拽时触发 + 'onDragEnter', // 拖拽进入组件范围时触发 + 'onDragMove', // 拖拽在组件范围内移动时触发 + 'onDragLeave', // 拖拽离开组件范围内时触发 + 'onDrop', // 拖拽释放目标,当在本组件范围内停止拖拽行为时触发 + 'onKeyEvent', // 按键事件,当组件获焦后,按键动作触发 + 'onFocus', // 焦点事件,当组件获取焦点时触发 + 'onBlur', // 当组件失去焦点时触发的回调 + 'onHover', // 鼠标悬浮事件,鼠标进入或退出组件时触发 + 'onMouse', // 鼠标事件,当鼠标按键点击或在组件上移动时触发 + 'onAreaChange', // 组件区域变化事件,组件尺寸、位置变化时触发 + 'onVisibleAreaChange', // 组件可见区域变化事件,组件在屏幕中的显示区域面积变化时触发 +]; export const COMPONENT_LIFECYCLE_METHOD_NAME: string[] = [ 'build', @@ -82,7 +82,7 @@ export const COMPONENT_LIFECYCLE_METHOD_NAME: string[] = [ 'onFormRecover', 'onBackPress', 'pageTransition', - 'onDidBuild' + 'onDidBuild', ]; export interface AbilityMessage { @@ -93,9 +93,11 @@ export interface AbilityMessage { export function getCallbackMethodFromStmt(stmt: Stmt, scene: Scene): ArkMethod | null { const invokeExpr = stmt.getInvokeExpr(); - if (invokeExpr === undefined || + if ( + invokeExpr === undefined || invokeExpr.getMethodSignature().getDeclaringClassSignature().getClassName() !== '' || - !CALLBACK_METHOD_NAME.includes(invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName())) { + !CALLBACK_METHOD_NAME.includes(invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName()) + ) { return null; } @@ -111,7 +113,7 @@ export function getCallbackMethodFromStmt(stmt: Stmt, scene: Scene): ArkMethod | return null; } -export function addCfg2Stmt(method: ArkMethod) { +export function addCfg2Stmt(method: ArkMethod): void { const cfg = method.getCfg(); if (cfg) { for (const block of cfg.getBlocks()) { @@ -120,4 +122,4 @@ export function addCfg2Stmt(method: ArkMethod) { } } } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/getAllFiles.ts b/ets2panda/linter/arkanalyzer/src/utils/getAllFiles.ts index 17823aea7071b1d3074e0cc9a18889623b17744a..fe4af56c9ee242b52cea84b590a4107fc5f76554 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/getAllFiles.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/getAllFiles.ts @@ -27,45 +27,45 @@ const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'getAllFiles'); * @return string[] 提取出的文件的原始路径数组 */ export function getAllFiles( - srcPath: string, - exts: string[], - ignore: string[] = [], - filenameArr: string[] = [], - visited: Set = new Set() + srcPath: string, + exts: string[], + ignore: string[] = [], + filenameArr: string[] = [], + visited: Set = new Set() ): string[] { - let ignoreFiles: Set = new Set(ignore); - // 如果源目录不存在,直接结束程序 - if (!fs.existsSync(srcPath)) { - logger.error(`Input directory ${srcPath} is not exist, please check!`); - return filenameArr; - } - - // 获取src的绝对路径 - const realSrc = fs.realpathSync(srcPath); - if (visited.has(realSrc)) { - return filenameArr; - } - visited.add(realSrc); + let ignoreFiles: Set = new Set(ignore); + // 如果源目录不存在,直接结束程序 + if (!fs.existsSync(srcPath)) { + logger.error(`Input directory ${srcPath} is not exist, please check!`); + return filenameArr; + } - // 遍历src,判断文件类型 - fs.readdirSync(realSrc).forEach(filename => { - if (ignoreFiles.has(filename)) { - return; + // 获取src的绝对路径 + const realSrc = fs.realpathSync(srcPath); + if (visited.has(realSrc)) { + return filenameArr; } - // 拼接文件的绝对路径 - const realFile = path.resolve(realSrc, filename); + visited.add(realSrc); - //TODO: 增加排除文件后缀和目录 + // 遍历src,判断文件类型 + fs.readdirSync(realSrc).forEach(filename => { + if (ignoreFiles.has(filename)) { + return; + } + // 拼接文件的绝对路径 + const realFile = path.resolve(realSrc, filename); - // 如果是目录,递归提取 - if (fs.statSync(realFile).isDirectory()) { - getAllFiles(realFile, exts, ignore, filenameArr, visited); - } else { - // 如果是文件,则判断其扩展名是否在给定的扩展名数组中 - if (exts.includes(path.extname(filename))) { - filenameArr.push(realFile); - } - } - }) - return filenameArr; + //TODO: 增加排除文件后缀和目录 + + // 如果是目录,递归提取 + if (fs.statSync(realFile).isDirectory()) { + getAllFiles(realFile, exts, ignore, filenameArr, visited); + } else { + // 如果是文件,则判断其扩展名是否在给定的扩展名数组中 + if (exts.includes(path.extname(filename))) { + filenameArr.push(realFile); + } + } + }); + return filenameArr; } diff --git a/ets2panda/linter/arkanalyzer/src/utils/json5parser.ts b/ets2panda/linter/arkanalyzer/src/utils/json5parser.ts index 7ca3f86354ba8999ce561e2d8e2055deeb337320..4b581a7e42f4d192e03f6dfaf5345837bcb9b1ac 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/json5parser.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/json5parser.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -19,7 +19,9 @@ import Logger, { LOG_MODULE_TYPE } from './logger'; const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'json5parser'); -export function fetchDependenciesFromFile(filePath: string): { [k: string]: unknown } { +export function fetchDependenciesFromFile(filePath: string): { + [k: string]: unknown; +} { if (!fs.existsSync(filePath)) { return {}; } @@ -62,7 +64,7 @@ function getRootObjectLiteral(file: ts.JsonSourceFile): ts.ObjectLiteralExpressi } const rootObjectLiteralExpression = (expressionStatement as ts.ExpressionStatement).expression; if (!rootObjectLiteralExpression) { - logger.error('The JSON5 file format is incorrect, the first child node is empty.') + logger.error('The JSON5 file format is incorrect, the first child node is empty.'); return undefined; } @@ -100,11 +102,11 @@ function parsePropertyInitializer(node: ts.Expression, file: ts.JsonSourceFile): return undefined; } -function parseArrayLiteral(node: ts.Expression, file: ts.JsonSourceFile) { +function parseArrayLiteral(node: ts.Expression, file: ts.JsonSourceFile): unknown[] { const res: unknown[] = []; (node as ts.ArrayLiteralExpression).elements.forEach(n => { res.push(parsePropertyInitializer(n, file)); - }) + }); return res; } @@ -115,7 +117,6 @@ function parseObjectLiteralExpression(ObjectLiteralExpression: ts.ObjectLiteralE const key = (propNode.name as ts.Identifier).text; const value = parsePropertyInitializer(propNode.initializer, file); res[key] = value; - }) + }); return res; } - diff --git a/ets2panda/linter/arkanalyzer/src/utils/logger.ts b/ets2panda/linter/arkanalyzer/src/utils/logger.ts index 904ffc8a55789a1d0af5e48c3f6bffcf8f1be32b..0e42ac832c41117d9095f21b3de38e6a8dc5998d 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/logger.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/logger.ts @@ -32,10 +32,12 @@ export enum LOG_MODULE_TYPE { } export default class ConsoleLogger { - public static configure(logFilePath: string, - arkanalyzer_level: LOG_LEVEL = LOG_LEVEL.ERROR, - tool_level: LOG_LEVEL = LOG_LEVEL.INFO, - use_console: boolean = false): void { + public static configure( + logFilePath: string, + arkanalyzer_level: LOG_LEVEL = LOG_LEVEL.ERROR, + tool_level: LOG_LEVEL = LOG_LEVEL.INFO, + use_console: boolean = false + ): void { let appendersTypes: string[] = []; if (logFilePath) { appendersTypes.push('file'); @@ -96,4 +98,4 @@ export default class ConsoleLogger { logger.addContext('tag', tag); return logger; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/pathTransfer.ts b/ets2panda/linter/arkanalyzer/src/utils/pathTransfer.ts index 7a491cabb0667c157c46ed3ef4dbe3bb24019a73..65858744c2935a12088c91cce4e6278ee24a3de3 100644 --- a/ets2panda/linter/arkanalyzer/src/utils/pathTransfer.ts +++ b/ets2panda/linter/arkanalyzer/src/utils/pathTransfer.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -15,14 +15,6 @@ import path from 'path'; -export function transfer2UnixPath(path2Do: string) { +export function transfer2UnixPath(path2Do: string): string { return path.posix.join(...path2Do.split(/\\/)); } - -export function getArkAnalyzerModulePath(moduleName: string): string | null { - try { - return path.dirname(path.dirname(require.resolve(moduleName))); - } catch (e) { - return null; - } -} \ No newline at end of file diff --git a/ets2panda/linter/arkanalyzer/vitest.config.ts b/ets2panda/linter/arkanalyzer/vitest.config.ts index 2ba68acd212a1cdbc465b2fe9345c0cc3dc7db8e..d098faa737cf71b7e2295be13220894ded5e938b 100644 --- a/ets2panda/linter/arkanalyzer/vitest.config.ts +++ b/ets2panda/linter/arkanalyzer/vitest.config.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,13 +13,13 @@ * limitations under the License. */ -import { defineConfig } from 'vitest/config' +import { defineConfig } from 'vitest/config'; export default defineConfig({ - test: { - include: ["tests/unit/**/*.test.ts"], - coverage: { - include: ["src/**"] - } - } -}) \ No newline at end of file + test: { + include: ['tests/unit/**/*.test.ts'], + coverage: { + include: ['src/**'], + }, + }, +}); diff --git a/ets2panda/linter/build_linter.py b/ets2panda/linter/build_linter.py index 943721cf82754115bd1a3a043368cce1125269fa..cfc970134ce210b74707b51b6b07175bf34cb7c9 100755 --- a/ets2panda/linter/build_linter.py +++ b/ets2panda/linter/build_linter.py @@ -19,6 +19,7 @@ import shutil import subprocess import sys import tarfile +import time def copy_files(source_path, dest_path, is_file=False): @@ -45,6 +46,19 @@ def run_cmd(cmd, execution_path=None): return stdout +def run_cmd_with_retry(max_retries, wait_time, cmd, execution_path=None): + retry_count = 0 + while retry_count < max_retries: + try: + run_cmd(cmd, execution_path) + break + except Exception: + retry_count += 1 + time.sleep(wait_time) + if retry_count >= max_retries: + raise Exception("Failed to run cmd: " + cmd) + + def is_npm_newer_than_6(options): cmd = [options.npm, '-v'] stdout = run_cmd(cmd, options.source_path) @@ -115,6 +129,54 @@ def clean_old_packages(directory, prefix, suffix): return res +def backup_package_files(source_path): + package_name = 'package.json' + package_back_name = 'package.json.bak' + aa_path = os.path.join(source_path, 'arkanalyzer') + hc_path = os.path.join(source_path, 'homecheck') + linter_path = source_path + copy_files(os.path.join(aa_path, package_name), os.path.join(aa_path, package_back_name), True) + copy_files(os.path.join(hc_path, package_name), os.path.join(hc_path, package_back_name), True) + copy_files(os.path.join(linter_path, package_name), os.path.join(linter_path, package_back_name), True) + + +def clean_env(source_path): + package_name = 'package.json' + package_back_name = 'package.json.bak' + package_lock_name = 'package-lock.json' + aa_path = os.path.join(source_path, 'arkanalyzer') + hc_path = os.path.join(source_path, 'homecheck') + linter_path = source_path + try: + copy_files(os.path.join(aa_path, package_back_name), os.path.join(aa_path, package_name), True) + copy_files(os.path.join(hc_path, package_back_name), os.path.join(hc_path, package_name), True) + copy_files(os.path.join(linter_path, package_back_name), os.path.join(linter_path, package_name), True) + os.remove(os.path.join(hc_path, package_lock_name)) + os.remove(os.path.join(linter_path, package_lock_name)) + os.remove(os.path.join(aa_path, package_back_name)) + os.remove(os.path.join(hc_path, package_back_name)) + os.remove(os.path.join(linter_path, package_back_name)) + except Exception: + return False + return True + + +def aa_copy_lib_files(options): + aa_path = os.path.join(options.source_path, 'arkanalyzer') + source_file_1 = os.path.join(aa_path, 'node_modules', 'ohos-typescript', 'lib', 'lib.es5.d.ts') + dest_path = os.path.join(aa_path, 'builtIn', 'typescript', 'api', '@internal') + copy_files(source_file_1, dest_path, True) + source_file_2 = os.path.join(aa_path, 'node_modules', 'ohos-typescript', 'lib', 'lib.es2015.collection.d.ts') + copy_files(source_file_2, dest_path, True) + + +def hc_copy_lib_files(options): + hc_path = os.path.join(options.source_path, 'homecheck') + source_file = os.path.join(hc_path, 'node_modules', 'ohos-typescript', 'lib', 'lib.es5.d.ts') + dest_path = os.path.join(hc_path, 'resources', 'internalSdk', '@internal') + copy_files(source_file, dest_path, True) + + def pack_arkanalyzer(options, new_npm): aa_path = os.path.join(options.source_path, 'arkanalyzer') tsc_file = 'file:' + options.typescript @@ -123,17 +185,18 @@ def pack_arkanalyzer(options, new_npm): clean_old_packages(aa_path, pack_prefix, pack_suffix) if new_npm: - ts_install_cmd = [options.npm, 'install', tsc_file, '--legacy-peer-deps', '--offline'] + ts_install_cmd = [options.npm, 'install', '--no-save', tsc_file, '--legacy-peer-deps', '--offline'] else: - ts_install_cmd = [options.npm, 'install', tsc_file] + ts_install_cmd = [options.npm, 'install', '--no-save', tsc_file] compile_cmd = [options.npm, 'run', 'compile'] pack_cmd = [options.npm, 'pack'] run_cmd(ts_install_cmd, aa_path) + aa_copy_lib_files(options) run_cmd(compile_cmd, aa_path) run_cmd(pack_cmd, aa_path) -def install_homecheck(options): +def install_homecheck(options, max_retries, wait_time): new_npm = is_npm_newer_than_6(options) pack_arkanalyzer(options, new_npm) aa_path = os.path.join(options.source_path, 'arkanalyzer') @@ -148,7 +211,7 @@ def install_homecheck(options): aa_install_cmd = [options.npm, 'install', aa_file, '--legacy-peer-deps', '--offline'] else: aa_install_cmd = [options.npm, 'install', aa_file] - run_cmd(aa_install_cmd, hc_path) + run_cmd_with_retry(max_retries, wait_time, aa_install_cmd, hc_path) else: raise Exception('Failed to find arkanalyzer npm package') @@ -160,7 +223,8 @@ def install_homecheck(options): ts_install_cmd = [options.npm, 'install', '--no-save', tsc_file] pack_cmd = [options.npm, 'pack'] compile_cmd = [options.npm, 'run', 'compile'] - run_cmd(ts_install_cmd, hc_path) + run_cmd_with_retry(max_retries, wait_time, ts_install_cmd, hc_path) + hc_copy_lib_files(options) run_cmd(compile_cmd, hc_path) run_cmd(pack_cmd, hc_path) exist_hc_packs = find_files_by_prefix_suffix(hc_path, hc_pack_prefix, pack_suffix) @@ -170,7 +234,7 @@ def install_homecheck(options): hc_install_cmd = [options.npm, 'install', hc_file, '--legacy-peer-deps', '--offline'] else: hc_install_cmd = [options.npm, 'install', hc_file] - run_cmd(hc_install_cmd, options.source_path) + run_cmd_with_retry(max_retries, wait_time, hc_install_cmd, options.source_path) else: raise Exception('Failed to find homecheck npm package') @@ -201,15 +265,15 @@ def parse_args(): def main(): options = parse_args() - install_homecheck(options) + backup_package_files(options.source_path) + install_homecheck(options, 5, 3) install_typescript(options) node_modules_path = os.path.join(options.source_path, "node_modules") extract(options.typescript, node_modules_path, "typescript") build(options) copy_output(options) + clean_env(options.source_path) if __name__ == '__main__': sys.exit(main()) - - diff --git a/ets2panda/linter/eslint.config.mjs b/ets2panda/linter/eslint.config.mjs index d39b40f91acd82e96fb12103e042a8a5cefd5199..f5afd19191dc75d8699931ba67a7c70f8acd2ab1 100644 --- a/ets2panda/linter/eslint.config.mjs +++ b/ets2panda/linter/eslint.config.mjs @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 diff --git a/ets2panda/linter/homecheck/.prettierrc b/ets2panda/linter/homecheck/.prettierrc new file mode 100644 index 0000000000000000000000000000000000000000..727d5c6ae24fce2bbfa0ef12e33d29fb5fbc59f9 --- /dev/null +++ b/ets2panda/linter/homecheck/.prettierrc @@ -0,0 +1,10 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "useTabs": false, + "semi": true, + "singleQuote": true, + "printWidth": 160, + "quoteProps": "as-needed", + "arrowParens": "avoid" +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/README.en.md b/ets2panda/linter/homecheck/README.en.md new file mode 100644 index 0000000000000000000000000000000000000000..656170858d3454e855b959947945fa16649be376 --- /dev/null +++ b/ets2panda/linter/homecheck/README.en.md @@ -0,0 +1,36 @@ +# arkcheck + +#### Description +ArkTS代码高性能反模式静态扫描工具 + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/ets2panda/linter/homecheck/README.md b/ets2panda/linter/homecheck/README.md new file mode 100644 index 0000000000000000000000000000000000000000..63099bd3a431ab77211159873c9ef6922254e57f --- /dev/null +++ b/ets2panda/linter/homecheck/README.md @@ -0,0 +1,201 @@ +# homecheck + +## 项目简介 + +该项目(homecheck)专为提升代码质量而设计,能高效识别代码缺陷并提出方案;其核心功能是对应用工程项目执行静态代码分析,评估代码在安全性、性能等方面上的表现,精准定位问题及其在代码中的位置。 + +## 目录 + +``` +homecheck +├─config/ # 项目配置 +├─document/ # 项目文档 +├─resources/ # 依赖库 +├─src/ +│ ├─checker/ # 项目检测规则功能代码 +│ ├─codeFix/ # 修复 +│ ├─matcher/ # 匹配类型 +│ ├─model/ # 模块 +│ ├─utils/ # 公共接口 +│ └─run.ts # 项目入口 +└─test/ # 测试目录 +``` + +## 项目主体流程 + +1.读取配置文件projectConfig.json和ruleConfig.json + +2.使用**ArkAnalyzer**项目构建**sence** + +3.根据配置文件参数,获取需要检测的文件 + +4.前处理 + +5.进行检测 + +6.后处理 + +## QuickStart + +### 1.下载本项目 + +### 2.进入项目根目录,打开终端 + +``` +cmd +``` + +### 3.安装依赖库 + +``` +npm install +``` + +### 4.修改配置 + +**config\projectConfig.json**中修改项目配置 +示例: + +``` +{ + "projectName": "TestProject", + "projectPath": "/path/to/project", + "logPath": "./HomeCheck.log", + "ohosSdkPath": "/path/to/ohosSdk", + "hmsSdkPath": "/path/to/hmsSdk", + "checkPath": "", + "sdkVersion": 14, + "fix": "true", + "npmPath": "", + "sdksThirdParty": [ + { + "name": "thirdParty", + "path": "./resources/thirdPartyModules", + "moduleName": "" + } + ] +} +``` +字段说明: +``` +projectName:需要检测工程的名字 +projectPath:需要检测工程的路径 +logPath:日志输出路径 +ohosSdkPath:ohossdk路径,比如DevEco Studio安装目录下的sdk\default\openharmony\ets +hmsSdkPath:hmssdk路径,比如DevEco Studio安装目录下的sdk\default\hms\ets +checkPath:解析指定的文件 +sdkVersion:sdk版本 +fix:是否修复 +npmPath:自定义规则npm路径 +sdksThirdParty:sdk三方库,name:库名称,path:库路径,moduleName:模块名称 +``` + +**config\ruleConfig.json**中修改规则配置 +示例: + +``` +{ + "files": [ + "**/*.ets", + "**/*.ts" + ], + "ignore": [ + "**/ohosTest/**/*", + "**/node_modules/**/*", + "**/build/**/*", + "**/hvigorfile/**/*", + "**/oh_modules/**/*", + "**/.preview/**/*" + ], + "rules": { + "@performance/foreach-args-check":3 + }, + "ruleSet": [ + "plugin:@performance/all", + "plugin:@correctness/all" + ], + "overrides": [], + "extRuleSet": [] +} +``` + +字段说明: + +``` +files:待检测文件类型 +ignore:过滤文件 +rules:可以基于ruleSet配置的规则集,新增额外规则项 +ruleSet:规则集 +overrides:定制化检查的规则 +extRuleSet:自定义规则 +``` +extRuleSet:自定义规则,参考[自定义规则](#自定义规则) + +### 5.启动项目 + +注意修改projectConfig.json和ruleConfig.json文件路径 + +#### 5.1 命令行启动,示例: + +根目录下执行 +``` +node -r ts-node/register ./src/run.ts --projectConfigPath=./config/projectConfig.json --configPath=./config/ruleConfig.json +``` + +#### 5.2 vscode启动: + +根目录新建.vscode目录,并新建launch.json文件,内容参考.vscode_sample\launch.json + +点击左侧运行和调试按钮,点击启动程序,开始运行,运行结束查看HomeCheck.log +#### 5.3 webstorm启动: + +## 新增规则 + +### 自定义规则 +参考:[自定义规则开发指南](document/ExtRule自定义规则开发指南.md) + +### 检测规则 +参考:[新增检测规则开发指南](document/规则开发指南.md) + +## api +参考:[api说明](doc/globals.md) + +## 打包 + +根目录下执行命令: + +``` +npm pack +``` +产物,根目录下: + +homecheck-1.0.0.tgz + +## 安装与使用 + +参考:[homecheck安装与使用指南](document/homecheck安装与使用指南.md) + +## HomeCheck附带工具使用指南 + +参考:[HomeCheck附带工具使用指南](document/HomeCheck附带工具使用指南.md) + +### 日志 + +运行结果请查看根目录下的HomeCheck.log + +## 代码上库 +遵守openharmony-sig代码上库规范, 操作方法请参考:[创建pr指南](document/PR指南.md) + +## Issues +提交Issues请参考:[Issues指南](document/Issues指南.md)。 + +## 添加自验证测试用例 +自验证用例请参考:[单元测试用例开发指南](document/单元测试用例开发指南.md) + +## 相关仓 + +[ArkAnalyzer](https://gitcode.com/openharmony-sig/arkanalyzer) + +## 欢迎加入homecheck社区开发讨论 + +![homecheck社区开发讨论](document/img/homecheck社区开发讨论.JPG) \ No newline at end of file diff --git a/ets2panda/linter/homecheck/config/projectConfig.json b/ets2panda/linter/homecheck/config/projectConfig.json index 55aac136dae9f68b8d1c6fb021a1cf92893a7afa..2bfa7d765f0510e842207f436ed62ae85bbbcb88 100644 --- a/ets2panda/linter/homecheck/config/projectConfig.json +++ b/ets2panda/linter/homecheck/config/projectConfig.json @@ -19,5 +19,7 @@ "moduleName": "" } ], - "fileOrFolderToCheck": [ "D:\\arkProject" ] + "fileOrFolderToCheck": [ "D:\\arkProject" ], + "logLevel": "INFO", + "arkAnalyzerLogLevel": "ERROR" } \ No newline at end of file diff --git a/ets2panda/linter/homecheck/config/ruleConfig.json b/ets2panda/linter/homecheck/config/ruleConfig.json index 141445e7136f3e9a5bd77de3b318f490a5f5d523..3f724aeebf8f0d1f96f385fc032548c5099591f4 100644 --- a/ets2panda/linter/homecheck/config/ruleConfig.json +++ b/ets2panda/linter/homecheck/config/ruleConfig.json @@ -1,7 +1,8 @@ { "files": [ "**/*.ets", - "**/*.ts" + "**/*.ts", + "**/*.js" ], "ignore": [ "**/ohosTest/**/*", diff --git a/ets2panda/linter/homecheck/package.json b/ets2panda/linter/homecheck/package.json index 0a5b274695d6a5a65bd09d13508e1213734a1947..ae47a9e950e04f2fffdffb639519b65f7ac3138f 100644 --- a/ets2panda/linter/homecheck/package.json +++ b/ets2panda/linter/homecheck/package.json @@ -7,15 +7,11 @@ "pack": "npm pack" }, "dependencies": { - "commander": "11.0.0", - "fs-extra": "11.2.0" - }, - "devDependencies": { - "@types/fs-extra": "9.0.13", - "ts-node": "10.9.1", - "typedoc": "^0.25.13", - "vite-tsconfig-paths": "4.3.1", - "vitest": "1.5.1" + "arkanalyzer": "file:../arkanalyzer", + "commander": "^9.4.0", + "fs-extra": "11.2.0", + "log4js": "^6.4.0", + "json5": "2.2.3" }, "name": "homecheck", "version": "0.9.11-arkts1.2", diff --git a/ets2panda/linter/homecheck/resources/internalSdk/@internal/es5.d.ts b/ets2panda/linter/homecheck/resources/internalSdk/@internal/es5.d.ts deleted file mode 100644 index 5972cfdced9ed4bfeba88475da8f0d1b86b1a5a6..0000000000000000000000000000000000000000 --- a/ets2panda/linter/homecheck/resources/internalSdk/@internal/es5.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -interface ObjectConstructor { - new (value?: any): Object; - (): any; - (value: any): any; - - readonly prototype: Object; - - getPrototypeOf(o: any): any; - - getOwnPropertyDescriptor(o: any, p: PropertyKey): PropertyDescriptor | undefined; - - getOwnPropertyNames(o: any): string[]; - - create(o: object | null): any; - - create(o: object | null, properties: PropertyDescriptorMap & ThisType): any; - - defineProperty(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType): T; - - defineProperties(o: T, properties: PropertyDescriptorMap & ThisType): T; - - seal(o: T): T; - - freeze(f: T): T; - - freeze(o: T): Readonly; - - freeze(o: T): Readonly; - - preventExtensions(o: T): T; - - isSealed(o: any): boolean; - - isFrozen(o: any): boolean; - - isExtensible(o: any): boolean; - - keys(o: object): string[]; -} - -declare var Object: ObjectConstructor; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/resources/thirdPartyModules/@hview/moment/index.d.ts b/ets2panda/linter/homecheck/resources/thirdPartyModules/@hview/moment/index.d.ts index 8e41abd4a3d5b5435d4a0736a6a590c9b651a58a..d5cac4b311493e55ebe8156a1898cac3bab18df5 100644 --- a/ets2panda/linter/homecheck/resources/thirdPartyModules/@hview/moment/index.d.ts +++ b/ets2panda/linter/homecheck/resources/thirdPartyModules/@hview/moment/index.d.ts @@ -20,6 +20,6 @@ export default function moment(): moment.Moment; declare namespace moment { interface Moment extends Object { utcOffset(): number; - utcOffset(b: number|string, keepLocalTime?: boolean): Moment; + utcOffset(b: number | string, keepLocalTime?: boolean): Moment; } } \ No newline at end of file diff --git a/ets2panda/linter/homecheck/ruleSet.json b/ets2panda/linter/homecheck/ruleSet.json index 197cfacae12a441636869ddd77024fe1f54ba5e8..adfc2898b56f1dc1b440bbe682d6abdf1d9c2fa0 100644 --- a/ets2panda/linter/homecheck/ruleSet.json +++ b/ets2panda/linter/homecheck/ruleSet.json @@ -198,10 +198,16 @@ "plugin:@migration/all": { "@migration/arkts-obj-literal-generate-class-instance": 1, "@migration/arkts-instance-method-bind-this": 1, - "@migration/arkui-data-observation-2": 1, + "@migration/arkts-no-ts-like-as": 1, + "@migration/arkui-data-observation": 1, "@migration/arkui-stateful-appstorage": 1, - "@migration/arkui-no-update-in-rending": 1, - "@migration/arkui-custombuiler": 1, - "@migration/no-method-overriding-field-check": 1 + "@migration/arkui-no-update-in-build": 1, + "@migration/arkui-custombuilder-passing": 1, + "@migration/no-method-overriding-field-check": 1, + "@migration/interop-backward-dfa": 1, + "@migration/interop-dynamic-object-literals": 1, + "@migration/interop-assign": 1, + "@migration/interop-boxed-type-check": 1, + "@migration/interop-js-modify-property": 1 } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/Index.ts b/ets2panda/linter/homecheck/src/Index.ts index f2ca91bcba2f742aee5756f47d0eaf375b084ba7..6ad78b6bfe25006f6ab5f366effe38a2e7136803 100644 --- a/ets2panda/linter/homecheck/src/Index.ts +++ b/ets2panda/linter/homecheck/src/Index.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -25,7 +25,8 @@ export * from './matcher/Matchers'; // models export { CheckerStorage } from './utils/common/CheckerStorage'; export { Rule } from './model/Rule'; -export { Defects, IssueReport, FileReports } from './model/Defects'; +export { Defects, IssueReport, FileIssues, FileReports } from './model/Defects'; +export { RuleFix } from './model/Fix'; export { Message, MessageType } from './model/Message'; export { ProjectConfig } from './model/ProjectConfig'; export { RuleConfig } from './model/RuleConfig'; @@ -42,4 +43,3 @@ export { Utils } from './utils/common/Utils'; // tools export { runTool, Tools } from './tools/toolEntry'; export { MigrationTool } from './tools/migrationTool/MigrationTool'; -export { ProblemInfo, AutoFix } from './tools/migrationTool/ExportIssue'; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/Main.ts b/ets2panda/linter/homecheck/src/Main.ts index b706c8e150b942d1534ed508cc46e4849d583db0..0cd340554dc3bdb610cfda124c54b2c7e56e0572 100644 --- a/ets2panda/linter/homecheck/src/Main.ts +++ b/ets2panda/linter/homecheck/src/Main.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,21 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; -import { processAfterCheck } from "./utils/common/AfterCheck"; -import { CheckEntry, checkEntryBuilder, getSelectFileList } from "./utils/common/CheckEntry"; -import { ConfigUtils } from "./utils/common/ConfigUtils"; -import { defaultMessage } from "./model/Message"; -import { Utils } from "./utils/common/Utils"; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { processAfterCheck } from './utils/common/AfterCheck'; +import { CheckEntry, checkEntryBuilder, getSelectFileList } from './utils/common/CheckEntry'; +import { ConfigUtils } from './utils/common/ConfigUtils'; +import { DefaultMessage } from './model/Message'; +import { Utils } from './utils/common/Utils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Main'); export async function start(checkEntry: CheckEntry): Promise { // 外部没有建立消息通道,使用默认通道 if (!checkEntry.message) { - checkEntry.message = new defaultMessage(); + checkEntry.message = new DefaultMessage(); } - + // 前处理 if (!await checkEntryBuilder(checkEntry)) { return false; diff --git a/ets2panda/linter/homecheck/src/checker/BaseChecker.ts b/ets2panda/linter/homecheck/src/checker/BaseChecker.ts index 930c88f5c7c3c3bea8377580de033947f035c83b..fb7d3375236a6c3b6aedda1611cbcd1ff2361eb3 100644 --- a/ets2panda/linter/homecheck/src/checker/BaseChecker.ts +++ b/ets2panda/linter/homecheck/src/checker/BaseChecker.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,10 +13,10 @@ * limitations under the License. */ -import { ArkFile } from "arkanalyzer"; -import { Rule } from "../model/Rule"; -import { MatcherCallback } from "../matcher/Matchers"; -import { IssueReport } from "../model/Defects"; +import { ArkFile } from 'arkanalyzer'; +import { Rule } from '../model/Rule'; +import { MatcherCallback } from '../matcher/Matchers'; +import { IssueReport } from '../model/Defects'; export interface BaseMetaData { severity: number, diff --git a/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts index 91186ddc1aa18d8f6827b2312d52b352782d48ba..693f8914126a9a7d9a5da0d9e697963b77e5e460 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts @@ -13,41 +13,32 @@ * limitations under the License. */ -import { ArkInstanceInvokeExpr, ArkMethod, ArkStaticInvokeExpr, CallGraph, CallGraphBuilder, Stmt, Value } from 'arkanalyzer/lib'; +import { + ArkInstanceInvokeExpr, + ArkMethod, + ArkStaticInvokeExpr, + CallGraph, + CallGraphBuilder, + Stmt, + Value, +} from 'arkanalyzer/lib'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; import { BaseChecker, BaseMetaData } from '../BaseChecker'; import { Rule, Defects, ClassMatcher, MethodMatcher, MatcherTypes, MatcherCallback } from '../../Index'; import { IssueReport } from '../../model/Defects'; +import { CALL_DEPTH_LIMIT, CALLBACK_METHOD_NAME, CallGraphHelper } from './Utils'; +import { WarnInfo } from '../../utils/common/Utils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'AppStorageGetCheck'); const gMetaData: BaseMetaData = { severity: 1, ruleDocPath: '', - description: 'Get State of AppStorage in component build function, it will update UI interface when the state of AppStorage is changed.' + description: + 'Get State of AppStorage in component build function, it will update UI interface when the state of AppStorage is changed', }; -const APP_STORAGE_STR = "AppStorage"; -const API_SET: Set = new Set(['Has', 'has', 'Get', 'get', - 'Keys', 'keys', 'IsMutable', 'Size', 'size']); - -const CALLBACK_METHOD_NAME: string[] = [ - "onClick", // 点击事件,当用户点击组件时触发 - "onTouch", // 触摸事件,当手指在组件上按下、滑动、抬起时触发 - "onAppear", // 组件挂载显示时触发 - "onDisAppear", // 组件卸载消失时触发 - "onDragStart", // 拖拽开始事件,当组件被长按后开始拖拽时触发 - "onDragEnter", // 拖拽进入组件范围时触发 - "onDragMove", // 拖拽在组件范围内移动时触发 - "onDragLeave", // 拖拽离开组件范围内时触发 - "onDrop", // 拖拽释放目标,当在本组件范围内停止拖拽行为时触发 - "onKeyEvent", // 按键事件,当组件获焦后,按键动作触发 - "onFocus", // 焦点事件,当组件获取焦点时触发 - "onBlur", // 当组件失去焦点时触发的回调 - "onHover", // 鼠标悬浮事件,鼠标进入或退出组件时触发 - "onMouse", // 鼠标事件,当鼠标按键点击或在组件上移动时触发 - "onAreaChange", // 组件区域变化事件,组件尺寸、位置变化时触发 - "onVisibleAreaChange", // 组件可见区域变化事件,组件在屏幕中的显示区域面积变化时触发 -]; +const APP_STORAGE_STR = 'AppStorage'; +const API_SET: Set = new Set(['has', 'get', 'keys', 'size']); export class AppStorageGetCheck implements BaseChecker { readonly metaData: BaseMetaData = gMetaData; @@ -63,36 +54,40 @@ export class AppStorageGetCheck implements BaseChecker { private buildMatcher: MethodMatcher = { matcherType: MatcherTypes.METHOD, class: [this.classMatcher], - name: ["build"] + name: ['build'], }; public registerMatchers(): MatcherCallback[] { const matchBuildCb: MatcherCallback = { matcher: this.buildMatcher, - callback: this.check + callback: this.check, }; return [matchBuildCb]; } - public check = (targetMtd: ArkMethod) => { + public check = (targetMtd: ArkMethod): void => { const scene = targetMtd.getDeclaringArkFile().getScene(); - let callGraph = new CallGraph(scene); + let callGraph = CallGraphHelper.getCGInstance(scene); let callGraphBuilder = new CallGraphBuilder(callGraph, scene); - callGraphBuilder.buildClassHierarchyCallGraph([targetMtd.getSignature()], true); + callGraphBuilder.buildClassHierarchyCallGraph([targetMtd.getSignature()]); this.checkMethod(targetMtd, callGraph); - } + }; - private checkMethod(targetMtd: ArkMethod, cg: CallGraph, depth: number = 0) { - if (depth > 2) { + private checkMethod(targetMtd: ArkMethod, cg: CallGraph, depth: number = 0): void { + if (depth > CALL_DEPTH_LIMIT) { return; } const stmts = targetMtd.getBody()?.getCfg().getStmts() ?? []; for (const stmt of stmts) { - this.checkAppStorageGet(stmt) + this.checkAppStorageGet(stmt); const invokeExpr = stmt.getInvokeExpr(); if (invokeExpr && invokeExpr instanceof ArkInstanceInvokeExpr) { - if (CALLBACK_METHOD_NAME.includes(invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName())) { + if ( + CALLBACK_METHOD_NAME.includes( + invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName() + ) + ) { continue; } } @@ -102,11 +97,11 @@ export class AppStorageGetCheck implements BaseChecker { if (callee) { this.checkMethod(callee, cg, depth + 1); } - }) + }); } } - private checkAppStorageGet(stmt: Stmt) { + private checkAppStorageGet(stmt: Stmt): void { let invokeExpr = stmt.getInvokeExpr(); if (!(invokeExpr instanceof ArkStaticInvokeExpr)) { return; @@ -121,15 +116,29 @@ export class AppStorageGetCheck implements BaseChecker { this.addIssueReport(stmt, invokeExpr); } - private addIssueReport(stmt: Stmt, operand: Value) { + private addIssueReport(stmt: Stmt, operand: Value): void { const severity = this.rule.alert ?? this.metaData.severity; const warnInfo = this.getLineAndColumn(stmt, operand); - let defects = new Defects(warnInfo.line, warnInfo.startCol, warnInfo.endCol, this.metaData.description, severity, this.rule.ruleId, - warnInfo.filePath, this.metaData.ruleDocPath, true, false, false); + const problem = 'AppStorageSpecChanged'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); this.issues.push(new IssueReport(defects, undefined)); } - private getLineAndColumn(stmt: Stmt, operand: Value) { + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { @@ -143,4 +152,4 @@ export class AppStorageGetCheck implements BaseChecker { } return { line: -1, startCol: -1, endCol: -1, filePath: '' }; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts index f022bc63c81a8bce5704fd0d740d0085a9cec29e..b8dcb06db7d2c47226110a65dfc9298937fdc42c 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts @@ -13,17 +13,37 @@ * limitations under the License. */ -import { ArkAssignStmt, Scene, Local, Stmt, Type, ArkMethod, AliasType, AbstractInvokeExpr, Value } from "arkanalyzer"; +import { + ArkAssignStmt, + Scene, + Local, + Stmt, + Type, + ArkMethod, + AliasType, + AbstractInvokeExpr, + Value, + ArkFile, + AstTreeUtils, + ts, + FunctionType, + ArkClass, + ANONYMOUS_METHOD_PREFIX, + ArkInvokeStmt, +} from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { BaseChecker, BaseMetaData } from "../BaseChecker"; -import { Rule, Defects, MatcherTypes, MatcherCallback, MethodMatcher } from "../../Index"; -import { IssueReport } from "../../model/Defects"; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MatcherCallback, MethodMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { FixInfo, RuleFix } from '../../model/Fix'; +import { FixPosition, FixUtils } from '../../utils/common/FixUtils'; +import { WarnInfo } from '../../utils/common/Utils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CustomBuilderCheck'); const gMetaData: BaseMetaData = { severity: 1, - ruleDocPath: "", - description: 'The CustomBuilder type parameter only accepts functions annotated with @Builder.' + ruleDocPath: '', + description: 'The CustomBuilder type parameter only accepts functions annotated with @Builder', }; export class CustomBuilderCheck implements BaseChecker { @@ -33,13 +53,13 @@ export class CustomBuilderCheck implements BaseChecker { public issues: IssueReport[] = []; private buildMatcher: MethodMatcher = { - matcherType: MatcherTypes.METHOD + matcherType: MatcherTypes.METHOD, }; public registerMatchers(): MatcherCallback[] { const matchBuildCb: MatcherCallback = { matcher: this.buildMatcher, - callback: this.check + callback: this.check, }; return [matchBuildCb]; } @@ -49,6 +69,7 @@ export class CustomBuilderCheck implements BaseChecker { const stmts = target.getBody()?.getCfg().getStmts() ?? []; let locals = new Set(); for (const stmt of stmts) { + // 场景1:函数调用赋值给CustomBuilder类型的对象 const local = this.isCallToBuilder(stmt, scene); if (local) { locals.add(local); @@ -58,9 +79,52 @@ export class CustomBuilderCheck implements BaseChecker { if (usage) { this.addIssueReport(usage.getDeclaringStmt()!, usage); } + + // 场景2:函数调用包在箭头函数中赋值给CustomBuilder类型的对象 + if (stmt instanceof ArkAssignStmt) { + const arrowMethod = this.findPotentialArrowFunction(stmt, target.getDeclaringArkClass()); + if (arrowMethod !== null && this.isCallToBuilderWrapWithArrow(arrowMethod)) { + this.addIssueReport(stmt, stmt.getRightOp()); + } + } } }; + // 只有当赋值语句leftOp为CustomBuilder类型时,若rightOp是匿名箭头函数,则返回该箭头函数 + private findPotentialArrowFunction(stmt: Stmt, arkClass: ArkClass): ArkMethod | null { + if (!(stmt instanceof ArkAssignStmt) || !this.isCustomBuilderTy(stmt.getLeftOp().getType())) { + return null; + } + + const rightOpType = stmt.getRightOp().getType(); + if (!(rightOpType instanceof FunctionType)) { + return null; + } + + const methodName = rightOpType.getMethodSignature().getMethodSubSignature().getMethodName(); + const method = arkClass.getMethodWithName(methodName); + if (method === null || !method.isAnonymousMethod()) { + return null; + } + return method; + } + + private isCallToBuilderWrapWithArrow(arrowMethod: ArkMethod): boolean { + const scene = arrowMethod.getDeclaringArkFile().getScene(); + const stmts = arrowMethod.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkInvokeStmt)) { + continue; + } + const invokeExpr = stmt.getInvokeExpr(); + const method = scene.getMethod(invokeExpr.getMethodSignature()); + if (method && method.hasBuilderDecorator()) { + return true; + } + } + return false; + } + private isCallToBuilder(stmt: Stmt, scene: Scene): Local | undefined { if (!(stmt instanceof ArkAssignStmt)) { return undefined; @@ -80,13 +144,13 @@ export class CustomBuilderCheck implements BaseChecker { return undefined; } - private isCumtomBuilderTy(ty: Type) { + private isCustomBuilderTy(ty: Type): boolean { return ty instanceof AliasType && ty.getName() === 'CustomBuilder'; } private isPassToCustomBuilder(stmt: Stmt, locals: Set): Local | undefined { if (stmt instanceof ArkAssignStmt) { - if (!this.isCumtomBuilderTy(stmt.getLeftOp().getType())) { + if (!this.isCustomBuilderTy(stmt.getLeftOp().getType())) { return undefined; } const rightOp = stmt.getRightOp(); @@ -99,7 +163,7 @@ export class CustomBuilderCheck implements BaseChecker { const paramTys = invokeExpr.getMethodSignature().getMethodSubSignature().getParameterTypes(); const args = invokeExpr.getArgs(); for (let i = 0; i < paramTys.length && i < args.length; ++i) { - if (!this.isCumtomBuilderTy(paramTys[i])) { + if (!this.isCustomBuilderTy(paramTys[i])) { continue; } const arg = args[i]; @@ -111,15 +175,39 @@ export class CustomBuilderCheck implements BaseChecker { return undefined; } - private addIssueReport(stmt: Stmt, operand: Value) { + private addIssueReport(stmt: Stmt, operand: Value): void { const severity = this.rule.alert ?? this.metaData.severity; const warnInfo = this.getLineAndColumn(stmt, operand); - let defects = new Defects(warnInfo.line, warnInfo.startCol, warnInfo.endCol, this.metaData.description, severity, this.rule.ruleId, - warnInfo.filePath, this.metaData.ruleDocPath, true, false, false); - this.issues.push(new IssueReport(defects, undefined)); + const problem = 'CustomBuilderTypeChanged'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + true + ); + const fixPosition: FixPosition = { + startLine: warnInfo.line, + startCol: warnInfo.startCol, + endLine: -1, + endCol: -1, + }; + const ruleFix = this.generateRuleFix(fixPosition, stmt) ?? undefined; + this.issues.push(new IssueReport(defects, ruleFix)); + if (ruleFix === undefined) { + defects.fixable = false; + } } - private getLineAndColumn(stmt: Stmt, operand: Value) { + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { @@ -133,4 +221,65 @@ export class CustomBuilderCheck implements BaseChecker { } return { line: -1, startCol: -1, endCol: -1, filePath: '' }; } -} \ No newline at end of file + + private generateRuleFix(fixPosition: FixPosition, stmt: Stmt): RuleFix | null { + let ruleFix: RuleFix = new RuleFix(); + const endPosition = this.getEndPositionOfStmt(stmt); + if (endPosition) { + fixPosition.endLine = endPosition.line; + fixPosition.endCol = endPosition.col; + } + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), arkFile.getCode()); + const range = FixUtils.getRangeWithAst(sourceFile, fixPosition); + ruleFix.range = range; + const originalText = FixUtils.getSourceWithRange(sourceFile, range); + if (originalText !== null) { + ruleFix.text = this.generateReplaceText(sourceFile, originalText, fixPosition); + } else { + return null; + } + return ruleFix; + } + + private getEndPositionOfStmt(stmt: Stmt): { line: number; col: number } | null { + const allPositions = stmt.getOperandOriginalPositions(); + if (allPositions === undefined) { + return null; + } + let res = { line: -1, col: -1 }; + allPositions.forEach(position => { + if (position.getLastLine() > res.line) { + res = { line: position.getLastLine(), col: position.getLastCol() }; + return; + } + if (position.getLastLine() === res.line && position.getLastCol() > res.col) { + res = { line: position.getLastLine(), col: position.getLastCol() }; + return; + } + }); + return res; + } + + private generateReplaceText(sourceFile: ts.SourceFile, originalText: string, fixPosition: FixPosition): string { + // 已经是箭头函数的场景,无需任何处理 + if (originalText.includes('=>')) { + return originalText; + } + + // 非箭头函数包裹的函数调用,需要使用箭头函数包裹 + const eol = FixUtils.getEolSymbol(sourceFile, fixPosition.startLine); + const startLineIndent = FixUtils.getIndentOfLine(sourceFile, fixPosition.startLine) ?? 0; + const increaseSpaces = FixUtils.getIndentWidth(sourceFile, fixPosition.startLine); + const space = ' '; + + let res = `() => {${eol}`; + const originalLineStrs = originalText.split(eol); + res += `${space.repeat(startLineIndent + increaseSpaces)}${originalLineStrs[0]}${eol}`; + for (let index = 1; index < originalLineStrs.length; index++) { + res += `${space.repeat(increaseSpaces)}${originalLineStrs[index]}${eol}`; + } + res += `${space.repeat(startLineIndent)}}`; + return res; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..e1645a7e6a8e410f199133a8e33f148be69d3ea5 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Type, + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + FunctionType, + ClassType, + ArkNamespace, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, DVFGHelper, GlobalCallGraphHelper } from './Utils'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropAssignCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: 'Should not pass or assign a dynamic object to a variable of static type', +}; + +const RULE_ID = 'arkts-interop-s2d-dynamic-args-to-static'; + +export class InteropAssignCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + for (let arkFile of scene.getFiles()) { + for (let clazz of arkFile.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, scene); + } + } + for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, scene); + } + } + }; + + public processNameSpace(namespace: ArkNamespace, scene: Scene): void { + for (let clazz of namespace.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, scene); + } + } + } + + public processArkMethod(target: ArkMethod, scene: Scene): void { + if (target.getLanguage() === Language.ARKTS1_2) { + this.checkPassToFunction(target, scene); + } else if (target.getLanguage() === Language.ARKTS1_1) { + this.checkAssignToField(target, scene); + } + } + + private checkPassToFunction(target: ArkMethod, scene: Scene) { + const callsites = this.cg.getInvokeStmtByMethod(target.getSignature()); + callsites.forEach(cs => { + let hasTargetArg = false; + const invoke = cs.getInvokeExpr()!; + const csMethod = cs.getCfg()?.getDeclaringMethod(); + invoke.getArgs().forEach(arg => { + const argTy = arg.getType(); + const argTyLang = this.getTypeDefinedLang(argTy, scene) ?? csMethod?.getLanguage() ?? Language.UNKNOWN; + if (argTyLang === Language.ARKTS1_1) { + hasTargetArg = true; + } + }); + if (!hasTargetArg) { + return; + } + let line = cs.getOriginPositionInfo().getLineNo(); + let column = cs.getOriginPositionInfo().getColNo(); + const problem = 'Interop'; + const desc = `${this.metaData.description} (${RULE_ID})`; + const severity = this.metaData.severity; + const ruleId = this.rule.ruleId; + const filePath = csMethod?.getDeclaringArkFile()?.getFilePath() ?? ''; + const defeats = new Defects( + line, + column, + column, + problem, + desc, + severity, + ruleId, + filePath, + '', + true, + false, + false + ); + this.issues.push(new IssueReport(defeats, undefined)); + }); + } + + private checkAssignToField(target: ArkMethod, scene: Scene) { + const assigns: Stmt[] = this.collectAssignToObjectField(target, scene); + assigns.forEach(assign => { + let result: Stmt[] = []; + let visited: Set = new Set(); + this.checkFromStmt(assign, scene, result, visited); + if (result.length === 0) { + // 这句 a.data = y 右侧的值没有从 1.1 传入的可能 + return; + } + let line = assign.getOriginPositionInfo().getLineNo(); + let column = assign.getOriginPositionInfo().getColNo(); + const problem = 'Interop'; + const desc = `${this.metaData.description} (${RULE_ID})`; + const severity = this.metaData.severity; + const ruleId = this.rule.ruleId; + const filePath = assign.getCfg()?.getDeclaringMethod().getDeclaringArkFile()?.getFilePath() ?? ''; + const defeats = new Defects( + line, + column, + column, + problem, + desc, + severity, + ruleId, + filePath, + '', + true, + false, + false + ); + this.issues.push(new IssueReport(defeats, undefined)); + }); + } + + private collectAssignToObjectField(method: ArkMethod, scene: Scene): Stmt[] { + const res: Stmt[] = []; + const stmts = method.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof ArkInstanceFieldRef)) { + continue; + } + if (!this.isObjectTy(leftOp.getType())) { + continue; + } + const baseTy = leftOp.getBase().getType(); + if (baseTy instanceof ClassType) { + const klass = scene.getClass(baseTy.getClassSignature()); + if (!klass) { + logger.warn( + `check field of type 'Object' failed: cannot find arkclass by sig ${baseTy + .getClassSignature() + .toString()}` + ); + } else if (klass.getLanguage() === Language.ARKTS1_2) { + res.push(stmt); + } + } else { + logger.warn(`check field of type 'Object' failed: unexpected base type ${baseTy.toString()}`); + } + } + return res; + } + + private checkFromStmt(stmt: Stmt, scene: Scene, res: Stmt[], visited: Set, depth: number = 0): void { + if (depth > CALL_DEPTH_LIMIT) { + return; + } + const node = DVFGHelper.getOrNewDVFGNode(stmt, scene); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (currentStmt instanceof ArkAssignStmt) { + const rightOpTy = currentStmt.getRightOp().getType(); + if (!this.isObjectTy(rightOpTy) && this.getTypeDefinedLang(rightOpTy, scene) === Language.ARKTS1_1) { + res.push(currentStmt); + continue; + } + } + const callsite = this.cg.getCallSiteByStmt(currentStmt); + callsite.forEach(cs => { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + return; + } + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + declaringMtd.getReturnStmt().forEach(r => this.checkFromStmt(r, scene, res, visited, depth + 1)); + }); + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + const callsites = this.cg.getInvokeStmtByMethod( + currentStmt.getCfg().getDeclaringMethod().getSignature() + ); + callsites.forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + }); + this.collectArgDefs(paramIdx, callsites, scene).forEach(d => + this.checkFromStmt(d, scene, res, visited, depth + 1) + ); + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + } + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private collectArgDefs(argIdx: number, callsites: Stmt[], scene: Scene): Stmt[] { + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + return callsites.flatMap(callsite => { + const target: Value | FieldSignature = getKey(callsite.getInvokeExpr()!.getArg(argIdx)); + return Array.from(DVFGHelper.getOrNewDVFGNode(callsite, scene).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); + }); + }); + } + + private isObjectTy(ty: Type): boolean { + return ty instanceof ClassType && ty.getClassSignature().getClassName() === 'Object'; + } + + private getTypeDefinedLang(type: Type, scene: Scene): Language | undefined { + let file = undefined; + if (type instanceof ClassType) { + file = scene.getFile(type.getClassSignature().getDeclaringFileSignature()); + } else if (type instanceof FunctionType) { + file = scene.getFile(type.getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature()); + } + if (file) { + return file.getLanguage(); + } else { + logger.error(`fail to identify which file the type definition ${type.toString()} is in.`); + } + return undefined; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropBackwardDFACheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropBackwardDFACheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..d80cc3aeb509dfdb6e3bbee43a4acd7515a553f5 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropBackwardDFACheck.ts @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Type, + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + AnyType, + ClassType, + ArkStaticInvokeExpr, + AbstractInvokeExpr, + FunctionType, + UnknownType, + Local, + ArkClass, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, GlobalCallGraphHelper, DVFGHelper } from './Utils'; +import { findInteropRule } from './InteropRuleInfo'; +import { ArkFile, Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropBackwardDFACheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +const REFLECT_API: Map = new Map([ + ['apply', 0], + ['construct', 0], + ['defineProperty', 0], + ['deleteProperty', 0], + ['get', 0], + ['getOwnPropertyDescriptor', 0], + ['getPrototypeOf', 0], + ['has', 0], + ['isExtensible', 0], + ['ownKeys', 0], + ['preventExtensions', 0], + ['set', 0], + ['setPrototypeOf', 0], +]); + +const OBJECT_API: Map = new Map([ + ['getOwnPropertyDescriptor', 0], + ['getOwnPropertyDescriptors', 0], + ['getOwnPropertyNames', 0], + ['isExtensible', 0], + ['isFrozen', 0], + ['isSealed', 0], + ['keys', 0], + ['setPrototypeOf', 0], + ['values', 0], + ['assign', 1], + ['entries', 0], +]); + +class ObjDefInfo { + problemStmt: Stmt; + objLanguage: Language; +} + +export class InteropBackwardDFACheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + for (let arkFile of scene.getFiles()) { + const importVarMap: Map = new Map(); + this.collectImportedVar(importVarMap, arkFile, scene); + const topLevelVarMap: Map = new Map(); + this.collectTopLevelVar(topLevelVarMap, arkFile, scene); + + const handleClass = (cls: ArkClass): void => { + cls.getMethods().forEach(m => this.processArkMethod(m, scene, importVarMap, topLevelVarMap)); + }; + + arkFile.getClasses().forEach(cls => handleClass(cls)); + arkFile.getAllNamespacesUnderThisFile().forEach(n => n.getClasses().forEach(cls => handleClass(cls))); + } + }; + + private collectImportedVar(importVarMap: Map, file: ArkFile, scene: Scene) { + file.getImportInfos().forEach(importInfo => { + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return; + } + const arkExport = exportInfo.getArkExport(); + if (!arkExport || !(arkExport instanceof Local)) { + return; + } + const declaringStmt = arkExport.getDeclaringStmt(); + if (!declaringStmt) { + return; + } + const definedLang = this.getTypeDefinedLang(arkExport.getType(), scene) ?? file.getLanguage(); + importVarMap.set(arkExport.getName(), definedLang); + }); + } + + private collectTopLevelVar(topLevelVarMap: Map, file: ArkFile, scene: Scene) { + const defaultMethod = file.getDefaultClass().getDefaultArkMethod(); + if (defaultMethod) { + DVFGHelper.buildSingleDVFG(defaultMethod, scene); + const stmts = defaultMethod.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof Local)) { + continue; + } + const name = leftOp.getName(); + if (name.startsWith('%') || name === 'this') { + continue; + } + topLevelVarMap.set(name, [...(topLevelVarMap.get(name) ?? []), stmt]); + } + } + } + + private processArkMethod( + target: ArkMethod, + scene: Scene, + importVarMap: Map, + topLevelVarMap: Map + ): void { + const currentLang = target.getLanguage(); + if (currentLang === Language.UNKNOWN) { + logger.warn(`cannot find the language for method: ${target.getSignature()}`); + return; + } + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + const invoke = stmt.getInvokeExpr(); + let isReflect = false; + let paramIdx = -1; + if (invoke && invoke instanceof ArkInstanceInvokeExpr) { + if (invoke.getBase().getName() === 'Reflect') { + isReflect = true; + paramIdx = + REFLECT_API.get(invoke.getMethodSignature().getMethodSubSignature().getMethodName()) ?? -1; + } + } + if (invoke && invoke instanceof ArkStaticInvokeExpr) { + const methodSig = invoke.getMethodSignature(); + const classSig = methodSig.getDeclaringClassSignature(); + if (classSig.getClassName() === 'ObjectConstructor' || classSig.getClassName() === 'Object') { + paramIdx = + OBJECT_API.get(invoke.getMethodSignature().getMethodSubSignature().getMethodName()) ?? -1; + } + } + if (paramIdx === -1) { + continue; + } + DVFGHelper.buildSingleDVFG(target, scene); + + const argDefs = this.findArgumentDef(stmt, paramIdx, currentLang, importVarMap, topLevelVarMap, scene); + if (this.isLanguage(argDefs)) { + this.reportIssue({ problemStmt: stmt, objLanguage: argDefs as Language }, currentLang, isReflect); + } else { + argDefs.forEach(def => { + let result: ObjDefInfo[] = []; + let visited: Set = new Set(); + this.checkFromStmt(def, currentLang, result, visited, importVarMap, topLevelVarMap, scene); + result.forEach(objDefInfo => { + this.reportIssue(objDefInfo, currentLang, isReflect); + }); + }); + } + } + } + + private reportIssue(objDefInfo: ObjDefInfo, apiLang: Language, isReflect: boolean) { + const problemStmt = objDefInfo.problemStmt; + const problemStmtMtd = problemStmt.getCfg()?.getDeclaringMethod(); + const problemStmtLang = problemStmtMtd?.getLanguage(); + const objLanguage = objDefInfo.objLanguage; + if (objLanguage === Language.UNKNOWN || problemStmtLang === Language.UNKNOWN) { + logger.warn(`cannot find the language for def: ${problemStmt.toString()}`); + return; + } + const interopRule = findInteropRule(apiLang, objLanguage, problemStmtLang, isReflect); + if (!interopRule) { + return; + } + const line = problemStmt.getOriginPositionInfo().getLineNo(); + const column = problemStmt.getOriginPositionInfo().getColNo(); + const problem = 'Interop'; + const desc = `${interopRule.description} (${interopRule.ruleId})`; + const severity = interopRule.severity; + const ruleId = this.rule.ruleId; + const filePath = problemStmtMtd?.getDeclaringArkFile()?.getFilePath() ?? ''; + const defeats = new Defects( + line, + column, + column, + problem, + desc, + severity, + ruleId, + filePath, + '', + true, + false, + false + ); + this.issues.push(new IssueReport(defeats, undefined)); + } + + private checkFromStmt( + stmt: Stmt, + apiLanguage: Language, + res: ObjDefInfo[], + visited: Set, + importVarMap: Map, + topLevelVarMap: Map, + scene: Scene, + depth: number = 0 + ): void { + if (depth > CALL_DEPTH_LIMIT) { + return; + } + const node = DVFGHelper.getOrNewDVFGNode(stmt, scene); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (currentStmt instanceof ArkAssignStmt) { + const rightOp = currentStmt.getRightOp(); + if (rightOp instanceof ArkInstanceFieldRef) { + // 处理 Reflect.apply(obj.getName, {a : 12}) + const base = rightOp.getBase(); + if (base instanceof Local && base.getDeclaringStmt()) { + worklist.push(DVFGHelper.getOrNewDVFGNode(base.getDeclaringStmt()!, scene)); + continue; + } + } + if (rightOp instanceof Local && !rightOp.getDeclaringStmt()) { + const name = rightOp.getName(); + if (importVarMap.has(name)) { + res.push({ problemStmt: currentStmt, objLanguage: importVarMap.get(name)! }); + continue; + } + } + const rightOpTy = rightOp.getType(); + if (!this.isIrrelevantType(rightOpTy)) { + const rightOpTyLang = this.getTypeDefinedLang(rightOpTy, scene); + if (rightOpTyLang && rightOpTyLang !== apiLanguage) { + res.push({ problemStmt: currentStmt, objLanguage: rightOpTyLang }); + continue; + } + } + } + const callsite = this.cg.getCallSiteByStmt(currentStmt); + if (callsite.length > 0) { + callsite.forEach(cs => { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + return; + } + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + declaringMtd + .getReturnStmt() + .forEach(r => + this.checkFromStmt( + r, + apiLanguage, + res, + visited, + importVarMap, + topLevelVarMap, + scene, + depth + 1 + ) + ); + }); + continue; + } + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + this.cg.getInvokeStmtByMethod(currentStmt.getCfg().getDeclaringMethod().getSignature()).forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + const argDefs = this.findArgumentDef( + cs, + paramIdx, + apiLanguage, + importVarMap, + topLevelVarMap, + scene + ); + if (this.isLanguage(argDefs)) { + // imported var + res.push({ problemStmt: cs, objLanguage: argDefs as Language }); + } else { + argDefs.forEach(d => { + this.checkFromStmt( + d, + apiLanguage, + res, + visited, + importVarMap, + topLevelVarMap, + scene, + depth + 1 + ); + }); + } + }); + continue; + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + if (stmt instanceof ArkAssignStmt) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && !rightOp.getDeclaringStmt()) { + (topLevelVarMap.get(rightOp.getName()) ?? []).forEach(def => { + worklist.push(DVFGHelper.getOrNewDVFGNode(def, scene)); + }); + } + } + } + } + + private isIrrelevantType(ty: Type): boolean { + const isObjectTy = (ty: Type): boolean => { + return ty instanceof ClassType && ty.getClassSignature().getClassName() === 'Object'; + }; + const isESObjectTy = (ty: Type): boolean => { + return ty.toString() === 'ESObject'; + }; + const isAnyTy = (ty: Type): ty is AnyType => { + return ty instanceof AnyType; + }; + const isUnkwonTy = (ty: Type): ty is UnknownType => { + return ty instanceof UnknownType; + }; + return isObjectTy(ty) || isESObjectTy(ty) || isAnyTy(ty) || isUnkwonTy(ty); + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private isLanguage(value: Stmt[] | Language): value is Language { + return Object.values(Language).includes(value as Language); + } + + private findArgumentDef( + stmt: Stmt, + argIdx: number, + apiLanguage: Language, + importVarMap: Map, + topLevelVarMap: Map, + scene: Scene + ): Stmt[] | Language { + const invoke = stmt.getInvokeExpr(); + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + const arg: Value | FieldSignature = getKey((invoke as AbstractInvokeExpr).getArg(argIdx)); + if (!arg) { + logger.error(`arg${argIdx} of invoke ${stmt.toString()} is undefined`); + return []; + } + if (arg instanceof Local && arg.getDeclaringStmt() instanceof ArkAssignStmt) { + // 特殊处理,obj.getName 的类型有 bug + const rightOp = (arg.getDeclaringStmt() as ArkAssignStmt).getRightOp(); + if (rightOp instanceof ArkInstanceFieldRef) { + const base = rightOp.getBase(); + if (base instanceof Local && base.getDeclaringStmt()) { + return [base.getDeclaringStmt()!]; + } + } + } + const argTy = arg.getType(); + if (!this.isIrrelevantType(argTy)) { + const argTyLang = this.getTypeDefinedLang(argTy, scene); + if (argTyLang && argTyLang !== apiLanguage) { + return argTyLang; + } + } + if (arg instanceof Local && !arg.getDeclaringStmt()) { + const name = arg.getName(); + return topLevelVarMap.get(name) ?? importVarMap.get(name) ?? []; + } + return Array.from(DVFGHelper.getOrNewDVFGNode(stmt, scene).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && arg === getKey(s.getLeftOp()); + }); + } + + private getTypeDefinedLang(type: Type, scene: Scene): Language | undefined { + let file = undefined; + if (type instanceof ClassType) { + file = scene.getFile(type.getClassSignature().getDeclaringFileSignature()); + } else if (type instanceof FunctionType) { + file = scene.getFile(type.getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature()); + } + if (file) { + return file.getLanguage(); + } + return undefined; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..42b4dc0973a789fe6d96f7a86e20bb8323dbbdf0 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule } from '../../model/Rule'; +import { Defects, IssueReport } from '../../model/Defects'; +import { FileMatcher, MatcherCallback, MatcherTypes } from '../../matcher/Matchers'; +import { + AbstractInvokeExpr, + ArkAssignStmt, + ArkClass, + ArkFile, + ArkMethod, + ArkNamespace, + ArkNewExpr, + ClassType, + FunctionType, + ImportInfo, + Local, + LOG_MODULE_TYPE, + Logger, + Scene, + Stmt, + Type, +} from 'arkanalyzer'; +import { ExportType } from 'arkanalyzer/lib/core/model/ArkExport'; +import { WarnInfo } from '../../utils/common/Utils'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { getLanguageStr } from './Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ObservedDecoratorCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +const ruleId: string = '@migration/interop-boxed-type-check'; +const s2dRuleId: string = 'arkts-interop-s2d-boxed-type'; +const d2sRuleId: string = 'arkts-interop-d2s-boxed-type'; +const ts2sRuleId: string = 'arkts-interop-ts2s-boxed-type'; +const js2RuleId: string = 'arkts-interop-js2s-boxed-type'; + +const BOXED_SET: Set = new Set(['String', 'Boolean', 'Number']); + +type CheckedObj = { + namespaces: Map; + classes: Map; + methods: Map; +}; + +export class InteropBoxedTypeCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private fileMatcher: FileMatcher = { + matcherType: MatcherTypes.FILE, + }; + + public registerMatchers(): MatcherCallback[] { + const fileMatcher: MatcherCallback = { + matcher: this.fileMatcher, + callback: this.check, + }; + return [fileMatcher]; + } + + public check = (arkFile: ArkFile): void => { + let hasChecked: CheckedObj = { + namespaces: new Map(), + classes: new Map(), + methods: new Map(), + }; + const scene = arkFile.getScene(); + // Import对象对应的Export信息的推导在类型推导过程中是懒加载机制,调用getLazyExportInfo接口会自动进行推导 + arkFile.getImportInfos().forEach(importInfo => { + const exportInfo = importInfo.getLazyExportInfo(); + // TODO: import * from xxx是如何表示的? + if (exportInfo === null) { + // 导入内置库时为null + return; + } + const arkExport = exportInfo.getArkExport(); + if (arkExport === null || arkExport === undefined) { + // 按正常流程,上面的exportInfo不为null时,这里一定会将实际找到的export对象set为arkExport,所以这里应该走不到 + // import三方包时为null,未推导为undefined,推导后无结果为null + return; + } + + const exportType = arkExport.getExportType(); + // 如果import的是sdk,exportType可能是namespace等,但是找不到body体等详细赋值语句等内容,所以不影响如下的判断 + switch (exportType) { + case ExportType.NAME_SPACE: + this.findBoxedTypeInNamespace(importInfo, arkExport as ArkNamespace, scene, hasChecked); + return; + case ExportType.CLASS: + this.findBoxedTypeInClass(importInfo, arkExport as ArkClass, scene, hasChecked); + return; + case ExportType.METHOD: + this.findBoxedTypeWithMethodReturn(importInfo, arkExport as ArkMethod, scene, hasChecked); + return; + case ExportType.LOCAL: + this.findBoxedTypeWithLocal(importInfo, arkExport as Local, scene, hasChecked); + return; + default: + return; + } + }); + }; + + private findBoxedTypeInNamespace( + importInfo: ImportInfo, + arkNamespace: ArkNamespace, + scene: Scene, + hasChecked: CheckedObj + ): boolean | null { + // 判断namespace是否已查找过,避免陷入死循环 + const existing = hasChecked.namespaces.get(arkNamespace.getSignature().toString()); + if (existing !== undefined) { + return existing; + } + hasChecked.namespaces.set(arkNamespace.getSignature().toString(), null); + const exports = arkNamespace.getExportInfos(); + let found: boolean | null = null; + for (const exportInfo of exports) { + const arkExport = exportInfo.getArkExport(); + if (arkExport === undefined) { + continue; + } + + if (arkExport === null) { + // ArkAnalyzer此处有一个问题,无法区分export local是来自arkfile还是arknamespace,导致类型推导推出来是null + continue; + } + if (arkExport instanceof Local) { + found = this.findBoxedTypeWithLocal(importInfo, arkExport, scene, hasChecked); + } else if (arkExport instanceof ArkMethod) { + found = this.findBoxedTypeWithMethodReturn(importInfo, arkExport, scene, hasChecked); + } else if (arkExport instanceof ArkClass) { + found = this.findBoxedTypeInClass(importInfo, arkExport, scene, hasChecked); + } else if (arkExport instanceof ArkNamespace) { + found = this.findBoxedTypeInNamespace(importInfo, arkExport, scene, hasChecked); + } + if (found) { + hasChecked.namespaces.set(arkNamespace.getSignature().toString(), true); + return true; + } + } + hasChecked.namespaces.set(arkNamespace.getSignature().toString(), false); + return false; + } + + private isClassHasBoxedType(arkClass: ArkClass, scene: Scene, hasChecked: CheckedObj): boolean | null { + // step0: 判断class是否已查找过,避免陷入死循环 + const existing = hasChecked.classes.get(arkClass.getSignature().toString()); + if (existing !== undefined) { + return existing; + } + hasChecked.classes.set(arkClass.getSignature().toString(), null); + // step1: 查找class中的所有field,包含static和非static,判断initialized stmts中是否会用boxed类型对象给field赋值 + const allFields = arkClass.getFields(); + for (const field of allFields) { + // 此处不检查field signature中的Type,因为type直接写String时也表示成Class Type,无法区分是否为new String()生成的 + const initializer = field.getInitializer(); + if (initializer.length < 1) { + continue; + } + const lastStmt = initializer[initializer.length - 1]; + if (!(lastStmt instanceof ArkAssignStmt)) { + continue; + } + if (this.isValueAssignedByBoxed(lastStmt, initializer.slice(0, -1).reverse(), scene, hasChecked)) { + // 这里没有顺着field的定义语句中使用到的import对象去寻找原始的Boxed类型定义所在的文件的Language,而是直接使用field所在的语言 + // 应该也是ok的,因为上述import chain如何不合法,也会有告警在其import的地方给出 + hasChecked.classes.set(arkClass.getSignature().toString(), true); + return true; + } + } + + // step2: 查找class中的所有非generated method,判断所有的return操作符类型是否为boxed + const methods = arkClass.getMethods(); + for (const method of methods) { + const found = this.isMethodReturnHasBoxedType(method, scene, hasChecked); + if (found) { + hasChecked.classes.set(arkClass.getSignature().toString(), true); + return true; + } + } + hasChecked.classes.set(arkClass.getSignature().toString(), false); + return false; + } + + private isMethodReturnHasBoxedType(arkMethod: ArkMethod, scene: Scene, hasChecked: CheckedObj): boolean | null { + // 判断method是否已查找过,避免陷入死循环 + const existing = hasChecked.methods.get(arkMethod.getSignature().toString()); + if (existing !== undefined) { + return existing; + } + hasChecked.methods.set(arkMethod.getSignature().toString(), null); + const returnOps = arkMethod.getReturnValues(); + for (const op of returnOps) { + if (this.isBoxedType(op.getType())) { + hasChecked.methods.set(arkMethod.getSignature().toString(), true); + return true; + } + if (op instanceof Local && this.isLocalHasBoxedType(op, scene, hasChecked)) { + hasChecked.methods.set(arkMethod.getSignature().toString(), true); + return true; + } + } + hasChecked.methods.set(arkMethod.getSignature().toString(), false); + return false; + } + + // 此处不检查local的Type,因为type直接写String时也表示成Class Type,无法区分是否为new String()生成的 + private isLocalHasBoxedType(local: Local, scene: Scene, hasChecked: CheckedObj): boolean { + const method = local.getDeclaringStmt()?.getCfg().getDeclaringMethod(); + if (method === undefined) { + return false; + } + const stmts = method.getCfg()?.getStmts().reverse(); + if (stmts === undefined || stmts.length < 1) { + return false; + } + + const declaringStmt = local.getDeclaringStmt(); + if ( + declaringStmt !== null && + declaringStmt instanceof ArkAssignStmt && + this.isValueAssignedByBoxed(declaringStmt, stmts, scene, hasChecked) + ) { + return true; + } + for (const stmt of local.getUsedStmts()) { + if (stmt instanceof ArkAssignStmt) { + const leftOp = stmt.getLeftOp(); + if ( + leftOp instanceof Local && + leftOp.toString() === local.toString() && + this.isValueAssignedByBoxed(stmt, stmts, scene, hasChecked) + ) { + return true; + } + } + } + return false; + } + + private findBoxedTypeInClass( + importInfo: ImportInfo, + arkClass: ArkClass, + scene: Scene, + hasChecked: CheckedObj + ): boolean { + const importOpPosition = importInfo.getOriginTsPosition(); + const warnInfo: WarnInfo = { + line: importOpPosition.getLineNo(), + startCol: importOpPosition.getColNo(), + endCol: importOpPosition.getColNo(), + filePath: importInfo.getDeclaringArkFile().getFilePath(), + }; + const currLanguage = importInfo.getLanguage(); + const result = this.isClassHasBoxedType(arkClass, scene, hasChecked); + if (result) { + this.addIssueReport(warnInfo, currLanguage, arkClass.getLanguage()); + return true; + } + return false; + } + + private findBoxedTypeWithMethodReturn( + importInfo: ImportInfo, + arkMethod: ArkMethod, + scene: Scene, + hasChecked: CheckedObj + ): boolean { + const importOpPostion = importInfo.getOriginTsPosition(); + const warnInfo: WarnInfo = { + line: importOpPostion.getLineNo(), + startCol: importOpPostion.getColNo(), + endCol: importOpPostion.getColNo(), + filePath: importInfo.getDeclaringArkFile().getFilePath(), + }; + const currLanguage = importInfo.getLanguage(); + + // 此处不检查method signature中的return Type,因为return type直接写String时也表示成Class Type,无法区分是否为new String()生成的 + if (this.isMethodReturnHasBoxedType(arkMethod, scene, hasChecked)) { + this.addIssueReport(warnInfo, currLanguage, arkMethod.getLanguage()); + return true; + } + return false; + } + + private findBoxedTypeWithLocal( + importInfo: ImportInfo, + local: Local, + scene: Scene, + hasChecked: CheckedObj + ): boolean { + const importOpPosition = importInfo.getOriginTsPosition(); + const warnInfo: WarnInfo = { + line: importOpPosition.getLineNo(), + startCol: importOpPosition.getColNo(), + endCol: importOpPosition.getColNo(), + filePath: importInfo.getDeclaringArkFile().getFilePath(), + }; + const currLanguage = importInfo.getLanguage(); + const method = local.getDeclaringStmt()?.getCfg().getDeclaringMethod(); + if (method === undefined) { + return false; + } + if (this.isLocalHasBoxedType(local, scene, hasChecked)) { + this.addIssueReport(warnInfo, currLanguage, method.getLanguage()); + return true; + } + return false; + } + + private isBoxedType(checkType: Type): boolean { + // ArkAnalyzer表示new String()形式的类型为ClassType,Class Name为String、Boolean、Number + // TODO: 此处底座有一个bug,表示String()时推导为Unknown Type,正确的应该为string,但是不影响本规则的判断 + return checkType instanceof ClassType && BOXED_SET.has(checkType.getClassSignature().getClassName()); + } + + private addIssueReport(warnInfo: WarnInfo, currLanguage: Language, targetLanguage: Language): void { + const interopRule = this.getInteropRule(currLanguage, targetLanguage); + if (interopRule === null) { + return; + } + const severity = this.metaData.severity; + const currLanStr = getLanguageStr(currLanguage); + const targetLanStr = getLanguageStr(targetLanguage); + const problem = 'Interop'; + const describe = `Could not import object with boxed type from ${targetLanStr} to ${currLanStr} (${interopRule})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + describe, + severity, + ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getInteropRule(currLanguage: Language, targetLanguage: Language): string | null { + if (currLanguage === Language.ARKTS1_1) { + if (targetLanguage === Language.ARKTS1_2) { + return s2dRuleId; + } + } else if (currLanguage === Language.ARKTS1_2) { + if (targetLanguage === Language.TYPESCRIPT) { + return ts2sRuleId; + } + if (targetLanguage === Language.ARKTS1_1) { + return d2sRuleId; + } + if (targetLanguage === Language.JAVASCRIPT) { + return js2RuleId; + } + } + return null; + } + + // lastStmt为当前需要查找的对象的赋值语句,左值为查找对象,右值为往前继续查找的赋值起点 + // reverseStmtChain为以待查找对象为起点,所有一系列赋值语句的倒序排列 + private isValueAssignedByBoxed( + lastStmt: ArkAssignStmt, + previousReverseChain: Stmt[], + scene: Scene, + hasChecked: CheckedObj + ): boolean { + let locals: Set = new Set(); + const targetLocal = lastStmt.getRightOp(); + const targetLocalType = targetLocal.getType(); + if (this.isBoxedType(targetLocalType)) { + return true; + } + if (targetLocalType instanceof ClassType) { + const arkClass = scene.getClass(targetLocalType.getClassSignature()); + if (arkClass !== null && this.isClassHasBoxedType(arkClass, scene, hasChecked)) { + return true; + } + } + if (targetLocalType instanceof FunctionType) { + const arkMethod = scene.getMethod(targetLocalType.getMethodSignature()); + if (arkMethod !== null && this.isMethodReturnHasBoxedType(arkMethod, scene, hasChecked)) { + return true; + } + } + + if (!(targetLocal instanceof Local)) { + return false; + } + locals.add(targetLocal); + + const rightOp = lastStmt.getRightOp(); + if (!(rightOp instanceof Local)) { + return false; + } + locals.add(rightOp); + for (const stmt of previousReverseChain) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + const rightOp = stmt.getRightOp(); + if (!(leftOp instanceof Local) || !locals.has(leftOp)) { + continue; + } + if (rightOp instanceof Local) { + locals.add(rightOp); + continue; + } + if (rightOp instanceof ArkNewExpr) { + if (this.isBoxedType(rightOp.getClassType())) { + return true; + } + continue; + } + if (rightOp instanceof AbstractInvokeExpr) { + if (this.isBoxedType(rightOp.getType())) { + return true; + } + continue; + } + } + return false; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..3b59046d94a0f620aa22c6d27ffd8ef02c2addc3 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + DVFGBuilder, + ArkInstanceOfExpr, + ArkNewExpr, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + ClassType, + ArkNamespace, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFG, DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, getLanguageStr, getLineAndColumn, GlobalCallGraphHelper } from './Utils'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropObjectLiteralCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +const d2sRuleId: string = 'arkts-interop-d2s-object-literal'; +const ts2sRuleId: string = 'arkts-interop-ts2s-object-literal'; + +export class InteropObjectLiteralCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + private dvfg: DVFG; + private dvfgBuilder: DVFGBuilder; + private visited: Set = new Set(); + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + this.dvfg = new DVFG(this.cg); + this.dvfgBuilder = new DVFGBuilder(this.dvfg, scene); + + for (let arkFile of scene.getFiles()) { + if (arkFile.getLanguage() !== Language.ARKTS1_2) { + continue; + } + for (let clazz of arkFile.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, scene); + } + } + for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, scene); + } + } + }; + + public processNameSpace(namespace: ArkNamespace, scene: Scene): void { + for (let clazz of namespace.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, scene); + } + } + } + + public processArkMethod(target: ArkMethod, scene: Scene): void { + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceOfExpr)) { + continue; + } + if (!this.visited.has(target)) { + this.dvfgBuilder.buildForSingleMethod(target); + this.visited.add(target); + } + + let result: Stmt[] = []; + let checkAll = { value: true }; + let visited: Set = new Set(); + this.checkFromStmt(stmt, scene, result, checkAll, visited); + // 对于待检查的instanceof语句,其检查对象存在用字面量赋值的情况,需要判断对象声明时的类型注解的来源,满足interop场景时需在此处告警 + if (result.length > 0) { + const opType = rightOp.getOp().getType(); + if (!(opType instanceof ClassType)) { + continue; + } + const opTypeClass = scene.getClass(opType.getClassSignature()); + if (opTypeClass === null || opTypeClass.getCategory() === ClassCategory.OBJECT) { + continue; + } + if ( + opTypeClass.getLanguage() === Language.TYPESCRIPT || + opTypeClass.getLanguage() === Language.ARKTS1_1 + ) { + this.addIssueReport(stmt, rightOp, result, opTypeClass.getLanguage()); + } + } + } + } + + private checkFromStmt( + stmt: Stmt, + scene: Scene, + res: Stmt[], + checkAll: { value: boolean }, + visited: Set, + depth: number = 0 + ): void { + if (depth > CALL_DEPTH_LIMIT) { + checkAll.value = false; + return; + } + const node = this.dvfg.getOrNewDVFGNode(stmt); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (this.isObjectLiteral(currentStmt, scene)) { + res.push(currentStmt); + continue; + } + const callsite = this.cg.getCallSiteByStmt(currentStmt); + callsite.forEach(cs => { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + return; + } + if (!this.visited.has(declaringMtd)) { + this.dvfgBuilder.buildForSingleMethod(declaringMtd); + this.visited.add(declaringMtd); + } + declaringMtd + .getReturnStmt() + .forEach(r => this.checkFromStmt(r, scene, res, checkAll, visited, depth + 1)); + }); + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + const callsites = this.cg.getInvokeStmtByMethod( + currentStmt.getCfg().getDeclaringMethod().getSignature() + ); + this.processCallsites(callsites); + this.collectArgDefs(paramIdx, callsites).forEach(d => + this.checkFromStmt(d, scene, res, checkAll, visited, depth + 1) + ); + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + } + } + + private processCallsites(callsites: Stmt[]): void { + callsites.forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + if (!this.visited.has(declaringMtd)) { + this.dvfgBuilder.buildForSingleMethod(declaringMtd); + this.visited.add(declaringMtd); + } + }); + } + + private isObjectLiteral(stmt: Stmt, scene: Scene): boolean { + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkNewExpr)) { + return false; + } + const classSig = rightOp.getClassType().getClassSignature(); + return scene.getClass(classSig)?.getCategory() === ClassCategory.OBJECT; + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private collectArgDefs(argIdx: number, callsites: Stmt[]): Stmt[] { + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + return callsites.flatMap(callsite => { + const target: Value | FieldSignature = getKey(callsite.getInvokeExpr()!.getArg(argIdx)); + return Array.from(this.dvfg.getOrNewDVFGNode(callsite).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); + }); + }); + } + + private addIssueReport(stmt: Stmt, operand: Value, result: Stmt[], targetLanguage: Language): void { + const interopRuleId = this.getInteropRule(targetLanguage); + if (interopRuleId === null) { + return; + } + const severity = this.metaData.severity; + const warnInfo = getLineAndColumn(stmt, operand); + let targetLan = getLanguageStr(targetLanguage); + + const resPos: number[] = []; + result.forEach(stmt => resPos.push(stmt.getOriginPositionInfo().getLineNo())); + const problem = 'Interop'; + const desc = `instanceof including object literal with class type from ${targetLan} (${interopRuleId})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getInteropRule(targetLanguage: Language): string | null { + if (targetLanguage === Language.TYPESCRIPT) { + return ts2sRuleId; + } + if (targetLanguage === Language.ARKTS1_1) { + return d2sRuleId; + } + return null; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..3b912361f2bb7896b526e8a434388ddb7de83703 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Type, + ArkMethod, + ArkAssignStmt, + Scene, + ArkInstanceFieldRef, + FunctionType, + ClassType, + MethodSignature, + ArkParameterRef, + Value, + Stmt, + ArkDeleteExpr, + FieldSignature, + ArkNamespace, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { ArkFile, Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { CALL_DEPTH_LIMIT, DVFGHelper } from './Utils'; +import { DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropJSModifyPropertyCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: 'The layout of staic objects should not be modified', +}; + +const RULE_ID = 'arkts-interop-js2s-js-add-detele-static-prop'; + +class ParamInfo { + flag: boolean; + paramAssign: ArkAssignStmt; + callsites: Set; +} + +export class InteropJSModifyPropertyCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + const targetMethods: Map = new Map(); + this.collectTargetMethods(targetMethods, scene); + this.checkTargetMethods(targetMethods, scene); + }; + + private collectTargetMethods(targetMethods: Map, scene: Scene): void { + scene.getFiles().forEach(file => { + // 只处理 ArkTS1.2 import JS 函数的情况 + if (file.getLanguage() !== Language.ARKTS1_2) { + return; + } + file.getImportInfos().forEach(importInfo => { + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return; + } + const arkExport = exportInfo.getArkExport(); + if (arkExport === null || arkExport === undefined) { + return; + } + if (!(arkExport instanceof ArkMethod && arkExport.getLanguage() === Language.JAVASCRIPT)) { + return; + } + // 创建初始化的参数标志位信息(标志位代表该参数是否被传入了 1.2 对象,默认为 false) + const paramInfo = this.createParamInfo(arkExport); + if (paramInfo.length > 0) { + targetMethods.set(arkExport.getSignature(), paramInfo); + } + }); + + // 寻找 JS 函数的被调用点,检查是否传入 ArkTS1.2 类型的对象并维护参数标志位信息 + for (let clazz of file.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.findCallsite(mtd, targetMethods, scene); + } + } + for (let namespace of file.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, targetMethods, scene); + } + }); + + // 跨函数检查 ArkTS1.2 类型对象是否被跨函数传到其他 JS 函数 + for (let i = 0; i < CALL_DEPTH_LIMIT; ++i) { + this.collectInterprocedualCallSites(targetMethods, scene); + } + } + + public processNameSpace( + namespace: ArkNamespace, + targetMethods: Map, + scene: Scene + ): void { + for (let clazz of namespace.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.findCallsite(mtd, targetMethods, scene); + } + } + } + + private createParamInfo(method: ArkMethod): ParamInfo[] { + // 初始化参数标志数组 + const idxFlag = new Array(method.getParameters().length).fill(false); + // 寻找参数对应的 xxx = parameter 语句 + const paramAssigns = (method.getCfg()?.getStmts() ?? []) + .filter(s => s instanceof ArkAssignStmt && s.getRightOp() instanceof ArkParameterRef) + .map(s => s as ArkAssignStmt); + if (idxFlag.length !== paramAssigns.length) { + logger.error('param index num != param assign num'); + return []; + } + const result: ParamInfo[] = []; + for (let i = 0; i < idxFlag.length; i++) { + result.push({ flag: idxFlag[i], paramAssign: paramAssigns[i], callsites: new Set() }); + } + return result; + } + + private findCallsite(method: ArkMethod, targets: Map, scene: Scene): void { + const stmts = method.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + const invoke = stmt.getInvokeExpr(); + if (!invoke) { + continue; + } + const methodSig = invoke.getMethodSignature(); + if (!targets.has(methodSig)) { + continue; + } + invoke.getArgs().forEach((arg, idx): void => { + if (this.getTypeDefinedLang(arg.getType(), method.getDeclaringArkFile(), scene) !== Language.ARKTS1_2) { + return; + } + targets.get(methodSig)![idx].flag = true; + targets.get(methodSig)![idx].callsites.add(stmt); + }); + } + } + + private collectInterprocedualCallSites(targets: Map, scene: Scene): void { + new Map(targets).forEach((paramInfo, sig) => { + const method = scene.getMethod(sig)!; + DVFGHelper.buildSingleDVFG(method, scene); + paramInfo.forEach((paramInfo): void => { + if (paramInfo.flag) { + this.checkIfParamPassedToOtherMethod(paramInfo, targets, scene); + } + }); + }); + } + + private checkIfParamPassedToOtherMethod( + callerParamInfo: ParamInfo, + targets: Map, + scene: Scene + ): void { + const worklist: DVFGNode[] = [DVFGHelper.getOrNewDVFGNode(callerParamInfo.paramAssign, scene)]; + const visited: Set = new Set(); + while (worklist.length > 0) { + const current = worklist.shift()!; + const cunrrentStmt = current.getStmt(); + if (visited.has(cunrrentStmt)) { + continue; + } + visited.add(cunrrentStmt); + if (!(cunrrentStmt instanceof ArkAssignStmt)) { + continue; + } + current.getOutgoingEdges().forEach(edge => { + const dst = edge.getDstNode() as DVFGNode; + const dstStmt = dst.getStmt(); + // 假设有 JS 函数声明: function foo(obj),其中 obj 为受关注的参数 + // 只有类似 let obj2 = obj 或者 goo(obj) 这样的语句受到关注 + if (dstStmt instanceof ArkAssignStmt && dstStmt.getRightOp() === cunrrentStmt.getLeftOp()) { + worklist.push(dst); + return; + } + const invoke = dstStmt.getInvokeExpr(); + if (!invoke) { + return; + } + const calleeSig = invoke.getMethodSignature(); + const callee = scene.getMethod(calleeSig); + if (!callee || !callee.getCfg() || callee.getLanguage() !== Language.JAVASCRIPT) { + return; + } + if (!targets.has(calleeSig)) { + targets.set(calleeSig, this.createParamInfo(callee)); + } + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + invoke.getArgs().forEach((arg, idx) => { + if (getKey(arg) === getKey(cunrrentStmt.getLeftOp())) { + targets.get(calleeSig)![idx].flag = true; + callerParamInfo.callsites.forEach(cs => { + targets.get(calleeSig)![idx].callsites.add(cs); + }); + } + }); + }); + } + } + + private checkTargetMethods(targetMethods: Map, scene: Scene): void { + targetMethods.forEach((paramInfos, methodSig): void => { + const method = scene.getMethod(methodSig); + if (!method) { + logger.error(`cannot find ark method by method sig: ${methodSig.toString()}`); + return; + } + const targetParams = paramInfos + .filter(paramInfo => paramInfo.flag) + .map(paramInfo => paramInfo.paramAssign.getLeftOp()); + const stmts = method.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + let paramIdx = -1; + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkDeleteExpr) { + const fieldRef = rightOp.getField(); + if (fieldRef instanceof ArkInstanceFieldRef) { + paramIdx = targetParams.findIndex(p => p === fieldRef.getBase()); + } + } + const leftOp = stmt.getLeftOp(); + if (leftOp instanceof ArkInstanceFieldRef) { + paramIdx = targetParams.findIndex(p => p === leftOp.getBase()); + } + if (paramIdx !== -1) { + const callers = paramInfos[paramIdx]!; + callers.callsites.forEach(cs => this.reportIssue(cs)); + } + } + }); + } + + private getTypeDefinedLang(type: Type, defaultFile: ArkFile, scene: Scene): Language { + let file; + if (type instanceof ClassType) { + file = scene.getFile(type.getClassSignature().getDeclaringFileSignature()); + } else if (type instanceof FunctionType) { + file = scene.getFile(type.getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature()); + } else { + file = defaultFile; + } + if (file) { + return file.getLanguage(); + } else { + logger.error(`fail to identify which file the type definition ${type.toString()} is in.`); + return Language.UNKNOWN; + } + } + + private reportIssue(problemStmt: Stmt) { + const line = problemStmt.getOriginPositionInfo().getLineNo(); + const column = problemStmt.getOriginPositionInfo().getColNo(); + const problem = 'Interop'; + const desc = `${this.metaData.description} (${RULE_ID})`; + const severity = this.metaData.severity; + const ruleId = this.rule.ruleId; + const filePath = problemStmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile()?.getFilePath() ?? ''; + const defeats = new Defects( + line, + column, + column, + problem, + desc, + severity, + ruleId, + filePath, + '', + true, + false, + false + ); + this.issues.push(new IssueReport(defeats, undefined)); + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..15269d7208e461c9b04075d8aa33f4c96eb3e7cd --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +export class InteropRuleInfo { + ruleId: string; + severity: number; + description: string; +} + +// 1.2 import 1.1 +// 1.1 Object => ArkTS 1.2 对象 +export const D2S_DYNAMIC_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-d2s-dynamic-object-on-static-instance', + severity: 1, + description: "ArkTS 1.1 Object's built-in methods work on ArkTS 1.2 objects", +}; + +// 1.2 import 1.1 +// 1.1 Reflect => ArkTS 1.2 对象 +export const D2S_DYNAMIC_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-d2s-dynamic-reflect-on-static-instance', + severity: 1, + description: "ArkTS 1.1 Reflect's built-in methods work on ArkTS 1.2 objects", +}; + +// 1.2 import 1.1 +// 1.2 Object => ArkTS 1.1 对象 +export const D2S_STATIC_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-d2s-static-object-on-dynamic-instance', + severity: 1, + description: "ArkTS 1.2 Object's built-in methods work on ArkTS 1.1 objects", +}; + +// 1.2 import 1.1 +// 1.2 Reflect => ArkTS 1.1 对象 +export const D2S_STATIC_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-d2s-static-reflect-on-dynamic-instance', + severity: 1, + description: "ArkTS 1.2 Reflect's built-in methods work on ArkTS 1.1 objects", +}; + +// 1.1 import 1.2 +// 1.1 Object => ArkTS 1.2 对象 +export const S2D_DYNAMIC_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-s2d-dynamic-object-on-static-instance', + severity: 1, + description: "ArkTS 1.1 Object's built-in methods work on ArkTS 1.2 objects", +}; + +// 1.1 import 1.2 +// 1.1 Reflect => ArkTS 1.2 对象 +export const S2D_DYNAMIC_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-s2d-dynamic-reflect-on-static-instance', + severity: 1, + description: "ArkTS 1.1 Reflect's built-in methods work on ArkTS 1.2 objects", +}; + +// 1.1 import 1.2 +// 1.2 Object => 1.1 对象 +export const S2D_STATIC_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-s2d-static-object-on-dynamic-instance', + severity: 1, + description: "ArkTS 1.2 Object's built-in methods work on ArkTS 1.1 objects", +}; + +// 1.1 import 1.2 +// 1.2 Reflect => 1.1 对象 +export const S2D_STATIC_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-s2d-static-reflect-on-dynamic-instance', + severity: 1, + description: "ArkTS 1.2 Reflect's built-in methods work on ArkTS 1.1 objects", +}; + +export const TS_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-ts2s-ts-object-on-static-instance', + severity: 1, + description: "TypeScript Object's built-in methods work on ArkTS objects", +}; + +export const TS_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-ts2s-ts-reflect-on-static-instance', + severity: 1, + description: "TypeScript Reflect's built-in methods work on ArkTS objects", +}; + +export const JS_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-js2s-js-object-on-static-instance', + severity: 1, + description: "JavaScript Object's built-in methods work on ArkTS objects", +}; + +export const JS_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-js2s-js-reflect-on-static-instance', + severity: 1, + description: "JavaScript Reflect's built-in methods work on ArkTS objects", +}; + +export function findInteropRule( + methodLang: Language, + typeDefLang: Language, + problemStmtLang: Language, + isReflect: boolean +): InteropRuleInfo | undefined { + if (methodLang === Language.ARKTS1_2 && typeDefLang === Language.ARKTS1_1) { + if (problemStmtLang === Language.ARKTS1_1) { + // 包含 object API 的 1.2 函数被导出到 1.1 文件使用 + return isReflect ? S2D_STATIC_REFLECT : S2D_STATIC_OBJECT; + } else { + return isReflect ? D2S_STATIC_REFLECT : D2S_STATIC_OBJECT; + } + } + if (methodLang === Language.ARKTS1_1 && typeDefLang === Language.ARKTS1_2) { + if (problemStmtLang === Language.ARKTS1_2) { + // 包含 object API 的 1.1 函数被导出到 1.2 文件使用 + return isReflect ? D2S_DYNAMIC_REFLECT : D2S_DYNAMIC_OBJECT; + } else { + return isReflect ? S2D_DYNAMIC_REFLECT: S2D_DYNAMIC_OBJECT ; + } + } + if (methodLang === Language.TYPESCRIPT && typeDefLang === Language.ARKTS1_2) { + return isReflect ? TS_REFLECT : TS_OBJECT; + } + if (methodLang === Language.JAVASCRIPT && typeDefLang === Language.ARKTS1_2) { + return isReflect ? JS_REFLECT : JS_OBJECT; + } + return undefined; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts index 09e8f03c758ed8f70c9c5ba15aa09301d8d98618..c25cc59611ec6e7b8182054beace616da724ba7a 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts @@ -13,17 +13,30 @@ * limitations under the License. */ -import { ArkAssignStmt, ArkInstanceFieldRef, Local, Stmt, Value, FieldSignature, ArkMethod } from "arkanalyzer"; +import { + ArkAssignStmt, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + CallGraph, + CallGraphBuilder, + Local, + Stmt, + Value, + FieldSignature, + ArkMethod, +} from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { BaseChecker, BaseMetaData } from "../BaseChecker"; -import { Rule, Defects, MatcherTypes, MatcherCallback, ClassMatcher, MethodMatcher } from "../../Index"; -import { IssueReport } from "../../model/Defects"; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MatcherCallback, ClassMatcher, MethodMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { CALL_DEPTH_LIMIT, CALLBACK_METHOD_NAME, CallGraphHelper } from './Utils'; +import { WarnInfo } from '../../utils/common/Utils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ModifyStateVarCheck'); const gMetaData: BaseMetaData = { severity: 1, - ruleDocPath: "", - description: 'It is not allowed to update state when the view is changing.' + ruleDocPath: '', + description: 'It is not allowed to update state when the build function is running', }; export class ModifyStateVarCheck implements BaseChecker { @@ -40,23 +53,58 @@ export class ModifyStateVarCheck implements BaseChecker { private buildMatcher: MethodMatcher = { matcherType: MatcherTypes.METHOD, class: [this.classMatcher], - name: ["build"] + name: ['build'], }; public registerMatchers(): MatcherCallback[] { const matchBuildCb: MatcherCallback = { matcher: this.buildMatcher, - callback: this.check + callback: this.check, }; return [matchBuildCb]; } public check = (target: ArkMethod): void => { + const scene = target.getDeclaringArkFile().getScene(); + let callGraph = CallGraphHelper.getCGInstance(scene); + let callGraphBuilder = new CallGraphBuilder(callGraph, scene); + callGraphBuilder.buildClassHierarchyCallGraph([target.getSignature()]); + const arkClass = target.getDeclaringArkClass(); - const stateVars = new Set(arkClass.getFields().filter(f => f.hasDecorator('State')).map(f => f.getSignature())); + const stateVars = new Set( + arkClass + .getFields() + .filter(f => f.hasDecorator('State')) + .map(f => f.getSignature()) + ); + if (stateVars.size > 0) { + this.checkMethod(target, callGraph, stateVars); + } + }; + + private checkMethod(target: ArkMethod, cg: CallGraph, stateVars: Set, depth: number = 0): void { + if (depth > CALL_DEPTH_LIMIT) { + return; + } let aliases = new Set(); const stmts = target.getBody()?.getCfg().getStmts() ?? []; for (const stmt of stmts) { + const invokeExpr = stmt.getInvokeExpr(); + if (invokeExpr && invokeExpr instanceof ArkInstanceInvokeExpr) { + if ( + CALLBACK_METHOD_NAME.includes( + invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName() + ) + ) { + continue; + } + } + cg.getCallSiteByStmt(stmt).forEach(cs => { + const callee = cg.getArkMethodByFuncID(cs.calleeFuncID); + if (callee) { + this.checkMethod(callee, cg, stateVars, depth + 1); + } + }); if (!(stmt instanceof ArkAssignStmt)) { continue; } @@ -69,7 +117,7 @@ export class ModifyStateVarCheck implements BaseChecker { } } } - }; + } private isAssignToStateVar(stmt: ArkAssignStmt, stateVars: Set, aliases: Set): boolean { const leftOp = stmt.getLeftOp(); @@ -82,7 +130,11 @@ export class ModifyStateVarCheck implements BaseChecker { return false; } - private isAliasOfStateVar(stmt: ArkAssignStmt, stateVars: Set, aliases: Set): Local | undefined { + private isAliasOfStateVar( + stmt: ArkAssignStmt, + stateVars: Set, + aliases: Set + ): Local | undefined { const leftOp = stmt.getLeftOp(); const rightOp = stmt.getRightOp(); if (leftOp instanceof Local && rightOp instanceof ArkInstanceFieldRef) { @@ -96,15 +148,29 @@ export class ModifyStateVarCheck implements BaseChecker { return undefined; } - private addIssueReport(stmt: Stmt, operand: Value) { + private addIssueReport(stmt: Stmt, operand: Value): void { const severity = this.rule.alert ?? this.metaData.severity; const warnInfo = this.getLineAndColumn(stmt, operand); - let defects = new Defects(warnInfo.line, warnInfo.startCol, warnInfo.endCol, this.metaData.description, severity, this.rule.ruleId, - warnInfo.filePath, this.metaData.ruleDocPath, true, false, false); + const problem = 'NoStateUpdateDuringRender'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); this.issues.push(new IssueReport(defects, undefined)); } - private getLineAndColumn(stmt: Stmt, operand: Value) { + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { @@ -118,4 +184,4 @@ export class ModifyStateVarCheck implements BaseChecker { } return { line: -1, startCol: -1, endCol: -1, filePath: '' }; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/NoMethodOverridingFieldCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NoMethodOverridingFieldCheck.ts index aeb6ae0a5a161373cff43202ea62ffbdb2acb81b..6c848ece77ea0fb2d598b1c0c00f3d71351c39d9 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/NoMethodOverridingFieldCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/NoMethodOverridingFieldCheck.ts @@ -13,18 +13,31 @@ * limitations under the License. */ -import { ArkAssignStmt, ArkClass, ArkFile, ArkIfStmt, ArkInstanceFieldRef, ArkInstanceInvokeExpr, ArkMethod, ClassType, FunctionType, Local, Stmt, Value } from "arkanalyzer"; +import { + ArkAssignStmt, + ArkClass, + ArkFile, + ArkIfStmt, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + ArkMethod, + ClassType, + FunctionType, + Local, + Stmt, + Value, +} from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { BaseChecker, BaseMetaData } from "../BaseChecker"; -import { Rule, Defects, MatcherTypes, MethodMatcher, MatcherCallback, ClassMatcher } from "../../Index"; -import { IssueReport } from "../../model/Defects"; -import { ClassCategory } from "arkanalyzer/lib/core/model/ArkClass"; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MethodMatcher, MatcherCallback, ClassMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoMethodOverridingFieldCheck'); const gMetaData: BaseMetaData = { severity: 1, - ruleDocPath: "", - description: '' + ruleDocPath: '', + description: '', }; export class NoMethodOverridingFieldCheck implements BaseChecker { @@ -35,28 +48,31 @@ export class NoMethodOverridingFieldCheck implements BaseChecker { private classMetcher: ClassMatcher = { matcherType: MatcherTypes.CLASS, - ClassCategory: [ClassCategory.CLASS] + ClassCategory: [ClassCategory.CLASS], }; public registerMatchers(): MatcherCallback[] { const methodCb: MatcherCallback = { matcher: this.classMetcher, - callback: this.check - } + callback: this.check, + }; return [methodCb]; } - public check = (target: ArkClass) => { + public check = (target: ArkClass): void => { const interfaces = target.getAllHeritageClasses().filter(c => c.getCategory() === ClassCategory.INTERFACE); for (const i of interfaces) { - const fields = i.getFields().filter(f => f.getType() instanceof FunctionType).map(f => f.getName()); + const fields = i + .getFields() + .filter(f => f.getType() instanceof FunctionType) + .map(f => f.getName()); fields.forEach(f => { const method = target.getMethodWithName(f); if (method) { // record class // console.log(`111`) } - }) + }); } - } -} \ No newline at end of file + }; +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/NoOptionalMethodCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NoOptionalMethodCheck.ts index 252c001dfdcf9ea4cd228925f1a085527d0fa79b..4be0d03726baa9979bed14e1cafdc3fa04a17c39 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/NoOptionalMethodCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/NoOptionalMethodCheck.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { ArkClass, ArkMethod} from "arkanalyzer"; +import { ArkClass, ArkMethod } from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { BaseChecker, BaseMetaData } from "../BaseChecker"; -import { Rule, Defects, MatcherTypes, MatcherCallback, ClassMatcher } from "../../Index"; -import { IssueReport } from "../../model/Defects"; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MatcherCallback, ClassMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoOptionalMethodCheck'); const gMetaData: BaseMetaData = { severity: 1, - ruleDocPath: "", - description: '' + ruleDocPath: '', + description: '', }; export class NoOptionalMethodCheck implements BaseChecker { @@ -33,32 +33,48 @@ export class NoOptionalMethodCheck implements BaseChecker { public issues: IssueReport[] = []; private classMetcher: ClassMatcher = { - matcherType: MatcherTypes.CLASS + matcherType: MatcherTypes.CLASS, }; public registerMatchers(): MatcherCallback[] { const classCb: MatcherCallback = { matcher: this.classMetcher, - callback: this.check - } + callback: this.check, + }; return [classCb]; } - public check = (target: ArkClass) => { - target.getMethods().filter(m => m.getQuestionToken()).forEach(m => { - const posInfo = this.getMethodPos(m); - this.addIssueReport(posInfo); - }); - } + public check = (target: ArkClass): void => { + target + .getMethods() + .filter(m => m.getQuestionToken()) + .forEach(m => { + const posInfo = this.getMethodPos(m); + this.addIssueReport(posInfo); + }); + }; - private addIssueReport(warnInfo: { line: number; startCol: number; endCol: number; filePath: string; }) { + private addIssueReport(warnInfo: { line: number; startCol: number; endCol: number; filePath: string }): void { + const problem = ''; const severity = this.rule.alert ?? this.metaData.severity; - let defects = new Defects(warnInfo.line, warnInfo.startCol, warnInfo.endCol, this.metaData.description, severity, this.rule.ruleId, - warnInfo.filePath, this.metaData.ruleDocPath, true, false, false); + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + this.metaData.description, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); this.issues.push(new IssueReport(defects, undefined)); } - private getMethodPos(cls: ArkMethod): { line: number; startCol: number; endCol: number; filePath: string; } { + private getMethodPos(cls: ArkMethod): { line: number; startCol: number; endCol: number; filePath: string } { const line = cls.getLineCol() ?? -1; const startCol = cls.getColumn() ?? -1; const endCol = startCol; @@ -70,4 +86,4 @@ export class NoOptionalMethodCheck implements BaseChecker { return { line, startCol, endCol, filePath: '' }; } } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..f45c63723cfb7b492c0972d4079cd9d6ef5d6740 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts @@ -0,0 +1,584 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import path from 'path'; +import { + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + DVFGBuilder, + ArkInstanceOfExpr, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + ArkNamespace, + Local, + ArkCastExpr, + ClassType, + classSignatureCompare, + ArkField, + fileSignatureCompare, + Cfg, + BasicBlock, + ArkIfStmt, + ArkUnopExpr, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFG, DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, getGlobalsDefineInDefaultMethod, GlobalCallGraphHelper } from './Utils'; +import { WarnInfo } from '../../utils/common/Utils'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoTSLikeAsCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +export class NoTSLikeAsCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + private dvfg: DVFG; + private dvfgBuilder: DVFGBuilder; + private visited: Set = new Set(); + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + this.dvfg = new DVFG(this.cg); + this.dvfgBuilder = new DVFGBuilder(this.dvfg, scene); + + for (let arkFile of scene.getFiles()) { + // 此规则仅对arkts1.1和arkts1.2进行检查,typescript在编译阶段会报错,javascript没有类型断言语法 + if (!(arkFile.getLanguage() === Language.ARKTS1_1 || arkFile.getLanguage() === Language.ARKTS1_2)) { + continue; + } + const defaultMethod = arkFile.getDefaultClass().getDefaultArkMethod(); + let globalVarMap: Map = new Map(); + if (defaultMethod) { + this.dvfgBuilder.buildForSingleMethod(defaultMethod); + globalVarMap = getGlobalsDefineInDefaultMethod(defaultMethod); + } + for (let clazz of arkFile.getClasses()) { + for (let field of clazz.getFields()) { + this.processClassField(field, globalVarMap, scene); + } + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, globalVarMap, scene); + } + } + for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, globalVarMap, scene); + } + } + }; + + public processNameSpace(namespace: ArkNamespace, globalVarMap: Map, scene: Scene): void { + for (let ns of namespace.getNamespaces()) { + this.processNameSpace(ns, globalVarMap, scene); + } + for (let clazz of namespace.getClasses()) { + for (let field of clazz.getFields()) { + this.processClassField(field, globalVarMap, scene); + } + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, globalVarMap, scene); + } + } + } + + public processClassField(field: ArkField, globalVarMap: Map, scene: Scene): void { + const stmts = field.getInitializer(); + for (const stmt of stmts) { + const castExpr = this.getCastExpr(stmt); + if (castExpr === null) { + continue; + } + // 判断cast类型断言的类型是否是class,非class的场景不在本规则检查范围内 + if (!(castExpr.getType() instanceof ClassType)) { + continue; + } + let checkAll = { value: true }; + let visited: Set = new Set(); + const result = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited); + if (result !== null) { + this.addIssueReport(stmt, castExpr, result); + } else { + if (!checkAll.value) { + this.addIssueReport(stmt, castExpr); + } + } + } + } + + public processArkMethod(target: ArkMethod, globalVarMap: Map, scene: Scene): void { + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + // cast表达式所在语句为sink点,从该点开始进行逆向数据流分析 + const castExpr = this.getCastExpr(stmt); + if (castExpr === null) { + continue; + } + // 判断cast类型断言的类型是否是class,非class的场景不在本规则检查范围内 + if (!(castExpr.getType() instanceof ClassType)) { + continue; + } + if (this.hasCheckedWithInstanceof(stmt.getCfg(), stmt)) { + continue; + } + if (!this.visited.has(target)) { + this.dvfgBuilder.buildForSingleMethod(target); + this.visited.add(target); + } + + let checkAll = { value: true }; + let visited: Set = new Set(); + const result = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited); + if (result !== null) { + this.addIssueReport(stmt, castExpr, result); + } else { + if (!checkAll.value) { + this.addIssueReport(stmt, castExpr); + } + } + } + } + + private hasCheckedWithInstanceof(cfg: Cfg, stmt: Stmt): boolean { + const castExpr = this.getCastExpr(stmt); + if (castExpr === null) { + return false; + } + for (const block of cfg.getBlocks()) { + // 这里仅判断了cast op是否进行了instanceof判断,如果op是由op1赋值,op1进行了instanceof判断,此处不认为是做了有效检查 + // TODO: 还需进行复杂条件中包含类型守卫判断的情况,涉及&&,||等的复合 + const positiveCheck = this.isCastExprWithTypeAssurancePositive(block, castExpr); + const negativeCheck = this.isCastExprWithTypeAssuranceNegative(block, castExpr); + if (!(positiveCheck || negativeCheck)) { + continue; + } + let checkedBB: Set = new Set(); + let needCheckBB: number[] = []; + checkedBB.add(block.getId()); + const allSuccessors = block.getSuccessors(); + if (allSuccessors.length > 0 && positiveCheck) { + needCheckBB.push(allSuccessors[0].getId()); + } + if (allSuccessors.length > 1 && negativeCheck) { + needCheckBB.push(allSuccessors[1].getId()); + } + while (needCheckBB.length > 0) { + const bbId = needCheckBB.shift(); + if (bbId === undefined) { + break; + } + if (checkedBB.has(bbId)) { + continue; + } + checkedBB.add(bbId); + const bb = this.getBlockWithId(bbId, cfg); + if (bb === null) { + continue; + } + if (this.isStmtInBlock(stmt, bb)) { + return true; + } else { + bb.getSuccessors().forEach(b => needCheckBB.push(b.getId())); + } + } + } + return false; + } + + private isStmtInBlock(stmt: Stmt, block: BasicBlock): boolean { + for (const s of block.getStmts()) { + if (s === stmt) { + return true; + } + } + return false; + } + + private getBlockWithId(id: number, cfg: Cfg): BasicBlock | null { + const blocks = cfg.getBlocks(); + for (const bb of blocks) { + if (bb.getId() === id) { + return bb; + } + } + return null; + } + + private isCastExprWithTypeAssurancePositive(bb: BasicBlock, castExpr: ArkCastExpr): boolean { + for (const stmt of bb.getStmts()) { + if (!(stmt instanceof ArkIfStmt)) { + continue; + } + const conditionExpr = stmt.getConditionExpr(); + const op1 = conditionExpr.getOp1(); + const op2 = conditionExpr.getOp2(); + if (op1 instanceof Local) { + const declareStmt = op1.getDeclaringStmt(); + if (declareStmt !== null && this.isStmtWithTypeAssurancePositive(declareStmt, castExpr)) { + return true; + } + } + if (op2 instanceof Local) { + const declareStmt = op2.getDeclaringStmt(); + if (declareStmt !== null && this.isStmtWithTypeAssurancePositive(declareStmt, castExpr)) { + return true; + } + } + } + return false; + } + + private isCastExprWithTypeAssuranceNegative(bb: BasicBlock, castExpr: ArkCastExpr): boolean { + for (const stmt of bb.getStmts()) { + if (!(stmt instanceof ArkIfStmt)) { + continue; + } + const conditionExpr = stmt.getConditionExpr(); + const op1 = conditionExpr.getOp1(); + const op2 = conditionExpr.getOp2(); + if (op1 instanceof Local) { + const declareStmt = op1.getDeclaringStmt(); + if (declareStmt !== null && this.isStmtWithTypeAssuranceNegative(declareStmt, castExpr)) { + return true; + } + } + if (op2 instanceof Local) { + const declareStmt = op2.getDeclaringStmt(); + if (declareStmt !== null && this.isStmtWithTypeAssuranceNegative(declareStmt, castExpr)) { + return true; + } + } + } + return false; + } + + private isStmtWithTypeAssurancePositive(declareStmt: Stmt, castExpr: ArkCastExpr): boolean { + if (!(declareStmt instanceof ArkAssignStmt)) { + return false; + } + const rightOp = declareStmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceOfExpr)) { + return false; + } + const castOp = castExpr.getOp(); + const castType = castExpr.getType(); + const instanceofType = rightOp.getCheckType(); + if (castType.getTypeString() !== instanceofType.getTypeString()) { + return false; + } + const instanceofOp = rightOp.getOp(); + if (!(castOp instanceof Local && instanceofOp instanceof Local)) { + return false; + } + return castOp.getName() === instanceofOp.getName(); + } + + private isStmtWithTypeAssuranceNegative(declareStmt: Stmt, castExpr: ArkCastExpr): boolean { + if (!(declareStmt instanceof ArkAssignStmt)) { + return false; + } + const rightOp = declareStmt.getRightOp(); + if (!(rightOp instanceof ArkUnopExpr && rightOp.getOperator() === '!')) { + return false; + } + const unaryOp = rightOp.getOp(); + if (!(unaryOp instanceof Local)) { + return false; + } + const unaryOpDeclareStmt = unaryOp.getDeclaringStmt(); + if (unaryOpDeclareStmt === null || !(unaryOpDeclareStmt instanceof ArkAssignStmt)) { + return false; + } + const unaryOpRightOp = unaryOpDeclareStmt.getRightOp(); + if (!(unaryOpRightOp instanceof ArkInstanceOfExpr)) { + return false; + } + const castOp = castExpr.getOp(); + const castType = castExpr.getType(); + const instanceofType = unaryOpRightOp.getCheckType(); + if (castType.getTypeString() !== instanceofType.getTypeString()) { + return false; + } + const instanceofOp = unaryOpRightOp.getOp(); + if (!(castOp instanceof Local && instanceofOp instanceof Local)) { + return false; + } + return castOp.getName() === instanceofOp.getName(); + } + + private checkFromStmt( + stmt: Stmt, + scene: Scene, + globalVarMap: Map, + checkAll: { value: boolean }, + visited: Set, + depth: number = 0 + ): Stmt | null { + if (depth > CALL_DEPTH_LIMIT) { + checkAll.value = false; + return null; + } + const node = this.dvfg.getOrNewDVFGNode(stmt); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (this.isWithInterfaceAnnotation(currentStmt, scene)) { + return currentStmt; + } + const gv = this.checkIfCastOpIsGlobalVar(currentStmt); + if (gv) { + const globalDefs = globalVarMap.get(gv.getName()); + if (globalDefs === undefined) { + const importValue = this.checkIfCastOpIsFromImport(currentStmt); + if (importValue && importValue.getDeclaringStmt() !== null) { + worklist.push(this.dvfg.getOrNewDVFGNode(importValue.getDeclaringStmt()!)); + } + } else { + globalDefs.forEach(d => worklist.push(this.dvfg.getOrNewDVFGNode(d))); + } + continue; + } + + const callsite = this.cg.getCallSiteByStmt(currentStmt); + for (const cs of callsite) { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + continue; + } + if (!this.visited.has(declaringMtd)) { + this.dvfgBuilder.buildForSingleMethod(declaringMtd); + this.visited.add(declaringMtd); + } + const returnStmts = declaringMtd.getReturnStmt(); + for (const stmt of returnStmts) { + const res = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited, depth + 1); + if (res !== null) { + return res; + } + } + } + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + const callsites = this.cg.getInvokeStmtByMethod( + currentStmt.getCfg().getDeclaringMethod().getSignature() + ); + this.processCallsites(callsites); + const argDefs = this.collectArgDefs(paramIdx, callsites); + for (const stmt of argDefs) { + const res = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited, depth + 1); + if (res !== null) { + return res; + } + } + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + } + return null; + } + + private checkIfCastOpIsGlobalVar(stmt: Stmt): Local | undefined { + const obj = this.getCastOp(stmt); + if (obj instanceof Local && !obj.getDeclaringStmt()) { + return obj; + } + return undefined; + } + + private checkIfCastOpIsFromImport(stmt: Stmt): Local | undefined { + const obj = this.getCastOp(stmt); + if (obj === null || !(obj instanceof Local)) { + return undefined; + } + const importInfos = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile().getImportInfos(); + for (const importInfo of importInfos) { + if (importInfo.getImportClauseName() === obj.getName()) { + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return undefined; + } + const arkExport = exportInfo.getArkExport(); + if (arkExport === null || arkExport === undefined) { + return undefined; + } + if (!(arkExport instanceof Local)) { + return undefined; + } + return arkExport; + } + } + return undefined; + } + + private processCallsites(callsites: Stmt[]): void { + callsites.forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + if (!this.visited.has(declaringMtd)) { + this.dvfgBuilder.buildForSingleMethod(declaringMtd); + this.visited.add(declaringMtd); + } + }); + } + + // 判断语句是否为赋值语句,且左值的类型注解为Interface,右值的类型与左值不一样 + private isWithInterfaceAnnotation(stmt: Stmt, scene: Scene): boolean { + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + const leftOpType = stmt.getLeftOp().getType(); + if (!(leftOpType instanceof ClassType)) { + return false; + } + const leftOpTypeclass = scene.getClass(leftOpType.getClassSignature()); + if (leftOpTypeclass === null) { + return false; + } + if (leftOpTypeclass.getCategory() !== ClassCategory.INTERFACE) { + return false; + } + const rightOpType = stmt.getRightOp().getType(); + if (!(rightOpType instanceof ClassType)) { + return true; + } + return !classSignatureCompare(leftOpType.getClassSignature(), rightOpType.getClassSignature()); + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private getCastOp(stmt: Stmt): Value | null { + if (!(stmt instanceof ArkAssignStmt)) { + return null; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkCastExpr)) { + return null; + } + return rightOp.getOp(); + } + + private getCastExpr(stmt: Stmt): ArkCastExpr | null { + // method中使用as断言的地方可能是body体中,函数调用的实参,返回值,均会表示成ArkAssignStmt + if (!(stmt instanceof ArkAssignStmt)) { + return null; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkCastExpr)) { + return null; + } + return rightOp; + } + + private collectArgDefs(argIdx: number, callsites: Stmt[]): Stmt[] { + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + return callsites.flatMap(callsite => { + const target: Value | FieldSignature = getKey(callsite.getInvokeExpr()!.getArg(argIdx)); + return Array.from(this.dvfg.getOrNewDVFGNode(callsite).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); + }); + }); + } + + private addIssueReport(stmt: Stmt, operand: ArkCastExpr, relatedStmt?: Stmt): void { + const severity = this.rule.alert ?? this.metaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'As'; + const descPrefix = 'The value in type assertion is assigned by value with interface annotation'; + let desc = `(${this.rule.ruleId.replace('@migration/', '')})`; + + if (relatedStmt === undefined) { + desc = `Can not find all assignments of the value in type assertion, please check it manually ` + desc; + } else { + const sinkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); + const relatedFile = relatedStmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); + if (fileSignatureCompare(sinkFile.getFileSignature(), relatedFile.getFileSignature())) { + desc = `${descPrefix} in Line ${relatedStmt.getOriginPositionInfo().getLineNo()} ` + desc; + } else { + desc = `${descPrefix} in file ${path.normalize(relatedFile.getName())}: ${relatedStmt.getOriginPositionInfo().getLineNo()} ` + desc; + } + } + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts index f1cb46c4990edb9cd8baa89a6f95c52a43eaf30e..66a5c66380b92443cde465bcf577ad4e05791028 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts @@ -13,18 +13,38 @@ * limitations under the License. */ -import { ArkMethod, ArkAssignStmt, FieldSignature, Stmt, Scene, Value, DVFGBuilder, ArkInstanceOfExpr, ArkNewExpr, CallGraph, CallGraphBuilder, ArkParameterRef, ArkInstanceFieldRef } from "arkanalyzer/lib"; +import { + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + ArkClass, + ArkFile, + ArkInstanceOfExpr, + ArkNewExpr, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + AbstractFieldRef, + Local, + ArkArrayRef, + ClassSignature, +} from 'arkanalyzer/lib'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { BaseChecker, BaseMetaData } from "../BaseChecker"; -import { Rule, Defects, MatcherCallback } from "../../Index"; -import { IssueReport } from "../../model/Defects"; -import { DVFG, DVFGNode } from "arkanalyzer/lib/VFG/DVFG"; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { DVFGHelper, CALL_DEPTH_LIMIT, GlobalCallGraphHelper } from './Utils'; +import { WarnInfo } from '../../utils/common/Utils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ObjectLiteralCheck'); const gMetaData: BaseMetaData = { severity: 1, - ruleDocPath: "", - description: 'Object literal shall generate instance of a specific class.' + ruleDocPath: '', + description: 'Object literal shall generate instance of a specific class', }; export class ObjectLiteralCheck implements BaseChecker { @@ -33,44 +53,34 @@ export class ObjectLiteralCheck implements BaseChecker { public defects: Defects[] = []; public issues: IssueReport[] = []; private cg: CallGraph; - private dvfg: DVFG; + private visited: Set = new Set(); public registerMatchers(): MatcherCallback[] { const matchBuildCb: MatcherCallback = { matcher: undefined, - callback: this.check - } + callback: this.check, + }; return [matchBuildCb]; } - public check = (scene: Scene) => { - this.cg = new CallGraph(scene); - let cgBuilder = new CallGraphBuilder(this.cg, scene); - cgBuilder.buildDirectCallGraphForScene(); - let entries = this.cg.getEntries().map(funcId => this.cg.getArkMethodByFuncID(funcId)!.getSignature()); - cgBuilder.buildClassHierarchyCallGraph(entries, true); - - this.dvfg = new DVFG(this.cg); - const dvfgBuilder = new DVFGBuilder(this.dvfg, scene); - dvfgBuilder.build(); + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); for (let arkFile of scene.getFiles()) { - for (let clazz of arkFile.getClasses()) { - for (let mtd of clazz.getMethods()) { - this.processArkMethod(mtd, scene); - } - } - for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { - for (let clazz of namespace.getClasses()) { - for (let mtd of clazz.getMethods()) { - this.processArkMethod(mtd, scene); - } - } - } + const topLevelVarMap: Map = new Map(); + this.collectImportedVar(topLevelVarMap, arkFile); + this.collectTopLevelVar(topLevelVarMap, arkFile, scene); + + const handleClass = (cls: ArkClass): void => { + cls.getMethods().forEach(m => this.processArkMethod(m, topLevelVarMap, scene)); + }; + + arkFile.getClasses().forEach(cls => handleClass(cls)); + arkFile.getAllNamespacesUnderThisFile().forEach(n => n.getClasses().forEach(cls => handleClass(cls))); } - } + }; - public processArkMethod(target: ArkMethod, scene: Scene) { + public processArkMethod(target: ArkMethod, topLevelVarMap: Map, scene: Scene): void { const stmts = target.getBody()?.getCfg().getStmts() ?? []; for (const stmt of stmts) { if (!(stmt instanceof ArkAssignStmt)) { @@ -80,46 +90,164 @@ export class ObjectLiteralCheck implements BaseChecker { if (!(rightOp instanceof ArkInstanceOfExpr)) { continue; } + if (!this.visited.has(target)) { + DVFGHelper.buildSingleDVFG(target, scene); + this.visited.add(target); + } + let result: Stmt[] = []; let checkAll = { value: true }; - this.checkFromStmt(stmt, scene, result, checkAll); + let visited: Set = new Set(); + this.checkFromStmt(stmt, scene, result, topLevelVarMap, checkAll, visited); result.forEach(s => this.addIssueReport(s, (s as ArkAssignStmt).getRightOp())); if (!checkAll.value) { this.addIssueReport(stmt, rightOp); } } + } + private collectImportedVar(importVarMap: Map, file: ArkFile) { + file.getImportInfos().forEach(importInfo => { + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return; + } + const arkExport = exportInfo.getArkExport(); + if (!arkExport || !(arkExport instanceof Local)) { + return; + } + const declaringStmt = arkExport.getDeclaringStmt(); + if (!declaringStmt) { + return; + } + importVarMap.set(arkExport.getName(), [declaringStmt]); + }); } - private checkFromStmt(stmt: Stmt, scene: Scene, res: Stmt[], checkAll: { value: boolean }, depth: number = 0) { - if (depth > 2) { + private collectTopLevelVar(topLevelVarMap: Map, file: ArkFile, scene: Scene) { + const defaultMethod = file.getDefaultClass().getDefaultArkMethod(); + if (!defaultMethod) { + return; + } + DVFGHelper.buildSingleDVFG(defaultMethod, scene); + const stmts = defaultMethod.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof Local)) { + continue; + } + const name = leftOp.getName(); + if (name.startsWith('%') || name === 'this') { + continue; + } + topLevelVarMap.set(name, [...(topLevelVarMap.get(name) ?? []), stmt]); + } + } + + private checkFromStmt( + stmt: Stmt, + scene: Scene, + res: Stmt[], + topLevelVarMap: Map, + checkAll: { value: boolean }, + visited: Set, + depth: number = 0 + ): void { + if (depth > CALL_DEPTH_LIMIT) { checkAll.value = false; return; } - const node = this.dvfg.getOrNewDVFGNode(stmt); + const node = DVFGHelper.getOrNewDVFGNode(stmt, scene); let worklist: DVFGNode[] = [node]; while (worklist.length > 0) { const current = worklist.shift()!; const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); if (this.isObjectLiteral(currentStmt, scene)) { res.push(currentStmt); continue; } + const isClsField = this.isClassField(currentStmt, scene); + if (isClsField) { + isClsField.forEach(d => worklist.push(DVFGHelper.getOrNewDVFGNode(d, scene))); + continue; + } + const isArrayField = this.isArrayField(currentStmt, topLevelVarMap); + if (isArrayField) { + isArrayField.forEach(d => worklist.push(DVFGHelper.getOrNewDVFGNode(d, scene))); + continue; + } + const gv = this.checkIfIsTopLevelVar(currentStmt); + if (gv) { + const globalDefs = topLevelVarMap.get(gv.getName()); + globalDefs?.forEach(d => { + worklist.push(DVFGHelper.getOrNewDVFGNode(d, scene)); + }); + continue; + } const callsite = this.cg.getCallSiteByStmt(currentStmt); callsite.forEach(cs => { - let returnStmts = this.cg.getArkMethodByFuncID(cs.calleeFuncID)?.getReturnStmt(); - returnStmts?.forEach(r => this.checkFromStmt(r, scene, res, checkAll, depth + 1)); - }) + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + return; + } + if (!this.visited.has(declaringMtd)) { + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + this.visited.add(declaringMtd); + } + declaringMtd + .getReturnStmt() + .forEach(r => this.checkFromStmt(r, scene, res, topLevelVarMap, checkAll, visited, depth + 1)); + }); const paramRef = this.isFromParameter(currentStmt); if (paramRef) { const paramIdx = paramRef.getIndex(); - const callsites = this.cg.getInvokeStmtByMethod(currentStmt.getCfg().getDeclaringMethod().getSignature()); - this.collectArgDefs(paramIdx, callsites).forEach(d => this.checkFromStmt(d, scene, res, checkAll, depth + 1)); + const callsites = this.cg.getInvokeStmtByMethod( + currentStmt.getCfg().getDeclaringMethod().getSignature() + ); + this.processCallsites(callsites, scene); + this.collectArgDefs(paramIdx, callsites, scene).forEach(d => + this.checkFromStmt(d, scene, res, topLevelVarMap, checkAll, visited, depth + 1) + ); } current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); } } + private checkIfIsTopLevelVar(stmt: Stmt): Local | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && !rightOp.getDeclaringStmt()) { + return rightOp; + } + if (!(rightOp instanceof ArkInstanceOfExpr)) { + return undefined; + } + const obj = rightOp.getOp(); + if (obj instanceof Local && !obj.getDeclaringStmt()) { + return obj; + } + return undefined; + } + + private processCallsites(callsites: Stmt[], scene: Scene): void { + callsites.forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + if (!this.visited.has(declaringMtd)) { + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + this.visited.add(declaringMtd); + } + }); + } + private isObjectLiteral(stmt: Stmt, scene: Scene): boolean { if (!(stmt instanceof ArkAssignStmt)) { return false; @@ -135,6 +263,77 @@ export class ObjectLiteralCheck implements BaseChecker { return false; } + private isClassField(stmt: Stmt, scene: Scene): Stmt[] | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const clsField = stmt.getRightOp(); + if (!(clsField instanceof AbstractFieldRef)) { + return undefined; + } + if (clsField instanceof ArkInstanceFieldRef && clsField.getBase().getName() !== 'this') { + return undefined; + } + const fieldSig = clsField.getFieldSignature(); + const clsSig = fieldSig.getDeclaringSignature(); + if (!(clsSig instanceof ClassSignature)) { + return undefined; + } + const cls = scene.getClass(clsSig); + if (!cls) { + logger.error(`cannot find class based on class sig: ${clsSig.toString()}`); + return undefined; + } + const field = cls.getField(fieldSig); + if (!field) { + logger.error(`cannot find field based on field sig: ${fieldSig.toString()}`); + return undefined; + } + if (!field.isStatic()) { + DVFGHelper.buildSingleDVFG(cls.getInstanceInitMethod(), scene); + } else { + DVFGHelper.buildSingleDVFG(cls.getStaticInitMethod(), scene); + } + return field.getInitializer().slice(-1); + } + + private isArrayField(stmt: Stmt, topLevelVarMap: Map): Stmt[] | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const arrField = stmt.getRightOp(); + if (!(arrField instanceof ArkArrayRef)) { + return undefined; + } + const arr = arrField.getBase(); + const index = arrField.getIndex(); + let arrDeclarations: Stmt[] = []; + if (arr.getDeclaringStmt()) { + arrDeclarations.push(arr.getDeclaringStmt()!); + } else if (topLevelVarMap.has(arr.getName())) { + arrDeclarations = topLevelVarMap.get(arr.getName())!; + } + const res: Stmt[] = arrDeclarations.flatMap(d => { + // arr = %0 + // %0[0] = ... + if (!(d instanceof ArkAssignStmt)) { + return []; + } + const arrVal = d.getRightOp(); + if (!(arrVal instanceof Local)) { + return []; + } + return arrVal.getUsedStmts().filter(u => { + if (!(u instanceof ArkAssignStmt)) { + return false; + } + const left = u.getLeftOp(); + return left instanceof ArkArrayRef && left.getBase() === arrVal && left.getIndex() === index; + }); + }); + return res; + } + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { if (!(stmt instanceof ArkAssignStmt)) { return undefined; @@ -146,13 +345,13 @@ export class ObjectLiteralCheck implements BaseChecker { return undefined; } - private collectArgDefs(argIdx: number, callsites: Stmt[]): Stmt[] { - const getKey = (v: Value) => { - return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v + private collectArgDefs(argIdx: number, callsites: Stmt[], scene: Scene): Stmt[] { + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; }; return callsites.flatMap(callsite => { const target: Value | FieldSignature = getKey(callsite.getInvokeExpr()!.getArg(argIdx)); - return Array.from(this.dvfg.getOrNewDVFGNode(callsite).getIncomingEdge()) + return Array.from(DVFGHelper.getOrNewDVFGNode(callsite, scene).getIncomingEdge()) .map(e => (e.getSrcNode() as DVFGNode).getStmt()) .filter(s => { return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); @@ -160,15 +359,29 @@ export class ObjectLiteralCheck implements BaseChecker { }); } - private addIssueReport(stmt: Stmt, operand: Value) { + private addIssueReport(stmt: Stmt, operand: Value): void { const severity = this.rule.alert ?? this.metaData.severity; const warnInfo = this.getLineAndColumn(stmt, operand); - let defects = new Defects(warnInfo.line, warnInfo.startCol, warnInfo.endCol, this.metaData.description, severity, this.rule.ruleId, - warnInfo.filePath, this.metaData.ruleDocPath, true, false, false); + const problem = 'ObjectLiteral'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); this.issues.push(new IssueReport(defects, undefined)); } - private getLineAndColumn(stmt: Stmt, operand: Value) { + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { @@ -182,4 +395,4 @@ export class ObjectLiteralCheck implements BaseChecker { } return { line: -1, startCol: -1, endCol: -1, filePath: '' }; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts index 9b4ed0092ebcd3190f330be97cb42abef7360207..a6a56e9b4d2ef3d9d95783a0f6d5e03f4fd5004e 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts @@ -13,20 +13,50 @@ * limitations under the License. */ -import { ArkAssignStmt, ArkClass, ArkField, ArkNewExpr, ClassType, Local, Scene } from "arkanalyzer"; +import path from 'path'; +import { + AbstractInvokeExpr, + ArkAssignStmt, + ArkClass, + ArkField, + ArkNewExpr, + ArkReturnStmt, + AstTreeUtils, + ClassType, + fileSignatureCompare, + Local, + Scene, + Type, +} from 'arkanalyzer'; import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { BaseChecker, BaseMetaData } from "../BaseChecker"; -import { Rule, Defects, ClassMatcher, MatcherTypes, MatcherCallback } from "../../Index"; -import { IssueReport } from "../../model/Defects"; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, ClassMatcher, MatcherTypes, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { RuleFix } from '../../model/Fix'; +import { FixUtils } from '../../utils/common/FixUtils'; +import { WarnInfo } from '../../utils/common/Utils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ObservedDecoratorCheck'); const gMetaData: BaseMetaData = { severity: 1, - ruleDocPath: "", - description: '' + ruleDocPath: '', + description: '', }; +const DECORATOR_SET: Set = new Set([ + 'State', + 'Prop', + 'Link', + 'Provide', + 'Consume', + 'LocalStorageProp', + 'LocalStorageLink', + 'StorageProp', + 'StorageLink', +]); + +// TODO: 需要考虑type alias、union type、intersection type中涉及class的场景 export class ObservedDecoratorCheck implements BaseChecker { readonly metaData: BaseMetaData = gMetaData; public rule: Rule; @@ -35,12 +65,13 @@ export class ObservedDecoratorCheck implements BaseChecker { private clsMatcher: ClassMatcher = { matcherType: MatcherTypes.CLASS, + category: [ClassCategory.STRUCT], }; public registerMatchers(): MatcherCallback[] { const matchClsCb: MatcherCallback = { matcher: this.clsMatcher, - callback: this.check + callback: this.check, }; return [matchClsCb]; } @@ -48,22 +79,30 @@ export class ObservedDecoratorCheck implements BaseChecker { public check = (arkClass: ArkClass): void => { const scene = arkClass.getDeclaringArkFile().getScene(); for (const field of arkClass.getFields()) { - if (!field.getDecorators().some(d => d.getKind() === 'State')) { + if (!field.getDecorators().some(d => DECORATOR_SET.has(d.getKind()))) { continue; } + // usedClasses用于记录field的初始化中涉及的所有class + let usedClasses: Set = new Set(); + // issueClasses用于记录usedClasses以及他们的所有父类 + let issueClasses: Set = new Set(); + // ArkAnalyzer此处有问题,若field的类型注解为unclear type,会用右边的替换左边的。 const fieldType = field.getType(); - if (!(fieldType instanceof ClassType)) { + const initializers = field.getInitializer(); + let canFindAllTargets = true; + + let locals: Set = new Set(); + + // field的初始化语句的最后一句,一定是将右边的value赋值给field,此处仍然判断一次,排除其他场景或者初始化语句为空的场景 + const lastStmt = initializers[initializers.length - 1]; + if (!(lastStmt instanceof ArkAssignStmt)) { continue; } - const fieldClass = scene.getClass(fieldType.getClassSignature()); - const initializers = field.getInitializer(); - let canfindAllTargets = true; - let targets: Set = new Set(); - if (fieldClass?.getCategory() === ClassCategory.CLASS) { - targets.add(fieldClass); + const start = lastStmt.getRightOp(); + // 直接对属性进行常量赋值属于这种场景 + if (!(start instanceof Local)) { + continue; } - let locals: Set = new Set(); - let start = (initializers[initializers.length - 1] as ArkAssignStmt).getRightOp() as Local; locals.add(start); for (const stmt of initializers.slice(0, -1).reverse()) { if (!(stmt instanceof ArkAssignStmt)) { @@ -81,46 +120,173 @@ export class ObservedDecoratorCheck implements BaseChecker { if (rightOp instanceof Local) { locals.add(rightOp); } else if (rightOp instanceof ArkNewExpr) { - canfindAllTargets = this.handleNewExpr(scene, rightOp, targets); + // 此处需要区分field = new cls()和field = {}两种场景,查找完毕需继续遍历stmts以解析条件表达式造成的多赋值场景 + canFindAllTargets = canFindAllTargets && this.handleNewExpr(scene, fieldType, rightOp, usedClasses); + } else if (rightOp instanceof AbstractInvokeExpr) { + canFindAllTargets = + canFindAllTargets && this.handleInvokeExpr(scene, fieldType, rightOp, usedClasses); } else { - canfindAllTargets = false; + // 对应场景为使用条件表达式cond ? 123 : 456赋值时 + continue; } } - for (const target of targets) { + for (const cls of usedClasses) { + issueClasses.add(cls); + this.getAllSuperClasses( + cls, + superCls => superCls.getCategory() === ClassCategory.CLASS && issueClasses.add(superCls) + ); + } + + for (const target of issueClasses) { + if (target.hasDecorator('Observed')) { + continue; + } const pos = this.getClassPos(target); - this.addIssueReport(pos); + const description = this.generateIssueDescription(field, target); + const ruleFix = this.generateRuleFix(pos, target) ?? undefined; + this.addIssueReport(pos, description, ruleFix); } - if (!canfindAllTargets) { + if (!canFindAllTargets) { const pos = this.getFieldPos(field); - this.addIssueReport(pos); + const description = this.generateIssueDescription(field, null, false); + this.addIssueReport(pos, description); } } }; - private handleNewExpr(scene: Scene, rightOp: ArkNewExpr, targets: Set): boolean { - let canfindAllTargets = true; - + // 此处需要区分field = new cls()和field = {}两种场景 + // 对于field = new cls()场景,需要查找此右边class的所有父class + // 对于field = {}场景,需要查找左边field类型为class时的所有父class + private handleNewExpr(scene: Scene, fieldType: Type, rightOp: ArkNewExpr, targets: Set): boolean { const target = scene.getClass(rightOp.getClassType().getClassSignature()); - if (target && !target.isAnonymousClass()) { + if (target === null) { + return false; + } + + if (!target.isAnonymousClass()) { + // 理论上来说ArkNewExpr中的class一定ClassCategory.CLASS,此处仍然显式的检查一次 + if (target.getCategory() !== ClassCategory.CLASS) { + return true; + } targets.add(target); - const superClasses = target.getAllHeritageClasses(); - for (const superCls of superClasses) { - if (superCls.getCategory() === ClassCategory.CLASS) { - targets.add(superCls); + return true; + } + + // 处理匿名类场景,若右边为object literal时,需考虑左边是什么类型注解,将涉及的class找出 + if (target.getCategory() !== ClassCategory.OBJECT) { + return true; + } + if (!(fieldType instanceof ClassType)) { + return true; + } + const fieldClass = scene.getClass(fieldType.getClassSignature()); + if (fieldClass === null) { + return false; + } + if (fieldClass.getCategory() !== ClassCategory.CLASS) { + return true; + } + targets.add(fieldClass); + return true; + } + + // 遍历此处的调用方法的所有return stmts,查找class + // 此处需要区分返回值为class和object literal两种场景 + // 对于返回值为class的场景,需要查找此class的所有父class + // 对于存在返回值为object literal的场景,需要查找左边field类型为class时的所有父class + private handleInvokeExpr( + scene: Scene, + fieldType: Type, + invokeExpr: AbstractInvokeExpr, + targets: Set + ): boolean { + let canFindAllTargets = true; + const callMethod = scene.getMethod(invokeExpr.getMethodSignature()); + if (callMethod === null) { + return false; + } + const stmts = callMethod.getBody()?.getCfg().getStmts(); + if (stmts === undefined) { + return false; + } + for (const stmt of stmts) { + if (!(stmt instanceof ArkReturnStmt)) { + continue; + } + const opType = stmt.getOp().getType(); + if (!(opType instanceof ClassType)) { + continue; + } + const returnClass = scene.getClass(opType.getClassSignature()); + if (returnClass === null) { + canFindAllTargets = false; + continue; + } + if (returnClass.getCategory() === ClassCategory.CLASS) { + targets.add(returnClass); + } else if (returnClass.getCategory() === ClassCategory.OBJECT) { + if (!(fieldType instanceof ClassType)) { + continue; + } + const leftClass = scene.getClass(fieldType.getClassSignature()); + if (leftClass === null) { + canFindAllTargets = false; + continue; + } + if (leftClass.getCategory() === ClassCategory.CLASS) { + targets.add(leftClass); } } + } + return canFindAllTargets; + } + + // 采用广度优先遍历方式,逐层获取该class的所有父类,一直查找到基类 + // arkanalyzer getAllHeritageClasses有点问题,对于未能推出来的父类会忽略,不加入列表中返回。 + private getAllSuperClasses(arkClass: ArkClass, callback: (value: ArkClass) => void): void { + let superClasses: Set = new Set(); + const classes = arkClass.getAllHeritageClasses(); + while (classes.length > 0) { + const superCls = classes.shift()!; + const superSuperCls = superCls.getAllHeritageClasses(); + callback(superCls); + + if (superSuperCls.length > 0) { + classes.push(...superSuperCls); + } + } + } + + private generateIssueDescription( + field: ArkField, + issueClass: ArkClass | null, + canFindAllTargets: boolean = true + ): string { + if (issueClass === null || !canFindAllTargets) { + return `can not find all classes, please check this field manually`; + } + const fieldLine = field.getOriginPosition().getLineNo(); + const fieldColumn = field.getOriginPosition().getColNo(); + + const fieldFileSig = field.getDeclaringArkClass().getDeclaringArkFile().getFileSignature(); + const issueClassSig = issueClass.getDeclaringArkFile().getFileSignature(); + let res = `but it's not be annotated by @Observed (arkui-data-observation)`; + if (fileSignatureCompare(fieldFileSig, issueClassSig)) { + res = `The class is used by state property in [${fieldLine}, ${fieldColumn}], ` + res; } else { - canfindAllTargets = false; + const filePath = path.normalize(fieldFileSig.getFileName()); + res = `The class is used by state property in file ${filePath} [${fieldLine}, ${fieldColumn}], ` + res; } - return canfindAllTargets; + return res; } - private getClassPos(cls: ArkClass): { line: number; startCol: number; endCol: number; filePath: string; } { + private getClassPos(cls: ArkClass): WarnInfo { const arkFile = cls.getDeclaringArkFile(); if (arkFile) { - const originPath = arkFile.getFilePath(); + const originPath = path.normalize(arkFile.getFilePath()); const line = cls.getLine(); const startCol = cls.getColumn(); const endCol = startCol; @@ -131,7 +297,7 @@ export class ObservedDecoratorCheck implements BaseChecker { } } - private getFieldPos(field: ArkField): { line: number; startCol: number; endCol: number; filePath: string; } { + private getFieldPos(field: ArkField): WarnInfo { const arkFile = field.getDeclaringArkClass().getDeclaringArkFile(); const pos = field.getOriginPosition(); if (arkFile && pos) { @@ -146,10 +312,52 @@ export class ObservedDecoratorCheck implements BaseChecker { } } - private addIssueReport(warnInfo: { line: number; startCol: number; endCol: number; filePath: string; }) { + private addIssueReport(warnInfo: WarnInfo, description: string, ruleFix?: RuleFix): void { + const problem = 'DataObservationNeedObserved'; const severity = this.rule.alert ?? this.metaData.severity; - let defects = new Defects(warnInfo.line, warnInfo.startCol, warnInfo.endCol, this.metaData.description, severity, this.rule.ruleId, - warnInfo.filePath, this.metaData.ruleDocPath, true, false, false); - this.issues.push(new IssueReport(defects, undefined)); + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + description, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + true + ); + this.issues.push(new IssueReport(defects, ruleFix)); + if (ruleFix === undefined) { + defects.fixable = false; + } + } + + private generateRuleFix(warnInfo: WarnInfo, targetClass: ArkClass): RuleFix | null { + const arkFile = targetClass.getDeclaringArkFile(); + const sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), arkFile.getCode()); + const startLineRange = FixUtils.getLineRange(sourceFile, warnInfo.line); + if (startLineRange === null) { + return null; + } + + const ruleFix = new RuleFix(); + ruleFix.range = startLineRange; + + const startLineStr = FixUtils.getSourceWithRange(sourceFile, startLineRange); + if (startLineStr === null) { + return null; + } + + const eol = FixUtils.getEolSymbol(sourceFile, warnInfo.line); + const startLineIndent = FixUtils.getIndentOfLine(sourceFile, warnInfo.line); + if (startLineIndent === null) { + return null; + } + const space = ' '; + ruleFix.text = `@Observed${eol}${space.repeat(startLineIndent)}${startLineStr}`; + return ruleFix; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts index 65bb480443feb81a90d68e64e571f391fb276e1c..d7496fca0a4763ba96f27fc036c85bed179f9959 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts @@ -13,40 +13,66 @@ * limitations under the License. */ -import { ArkAssignStmt, ArkIfStmt, ArkInstanceFieldRef, ArkInstanceInvokeExpr, ArkMethod, ClassType, FunctionType, Local, Stmt, Value } from "arkanalyzer"; +import { + ArkAssignStmt, + ArkIfStmt, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + ArkMethod, + ClassType, + FunctionType, + Local, + Stmt, + Value, + Scene, + ArkNewArrayExpr, + ArkNewExpr, + ArkClass, + ClassSignature, +} from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { BaseChecker, BaseMetaData } from "../BaseChecker"; -import { Rule, Defects, MatcherTypes, MethodMatcher, MatcherCallback } from "../../Index"; -import { IssueReport } from "../../model/Defects"; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MethodMatcher, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { WarnInfo } from '../../utils/common/Utils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ThisBindCheck'); -const gMetaData: BaseMetaData = { + +const ARKTS_RULE_ID = '@migration/arkts-instance-method-bind-this'; +const arktsMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: "Instance method shall bind the 'this' by default", +}; + +const ARKUI_RULE_ID = '@migration/arkui-buildparam-passing'; +const arkuiMetaData: BaseMetaData = { severity: 1, - ruleDocPath: "", - description: 'Instance method shall bind the \'this\' by dafault.' + ruleDocPath: '', + description: 'The execution context of the function annotated with @Builder is determined at the time of declaration. Please check the code carefully to ensure the correct function context', }; export class ThisBindCheck implements BaseChecker { - readonly metaData: BaseMetaData = gMetaData; + readonly metaData: BaseMetaData = arktsMetaData; public rule: Rule; public defects: Defects[] = []; public issues: IssueReport[] = []; private methodMatcher: MethodMatcher = { - matcherType: MatcherTypes.METHOD + matcherType: MatcherTypes.METHOD, }; public registerMatchers(): MatcherCallback[] { const methodCb: MatcherCallback = { matcher: this.methodMatcher, - callback: this.check - } + callback: this.check, + }; return [methodCb]; } - public check = (targetMtd: ArkMethod) => { + public check = (targetMtd: ArkMethod): void => { const file = targetMtd.getDeclaringArkFile(); - if (file.getName().includes("test.ets")) { + if (file.getName().includes('.test.ets')) { return; } const scene = file.getScene(); @@ -74,17 +100,15 @@ export class ThisBindCheck implements BaseChecker { if (!method || !method.getCfg() || !this.useThisInBody(method)) { continue; } - if (base.getName() === "this" && targetMtd.isAnonymousMethod()) { - continue; - } + const isBuilder = method.hasBuilderDecorator() || method.hasDecorator('LocalBuilder'); const leftOp = stmt.getLeftOp(); if (i + 1 >= stmts.length || !this.hasBindThis(leftOp, stmts[i + 1])) { if (!this.isSafeUse(leftOp)) { - this.addIssueReport(stmt, base); + this.addIssueReport(stmt, isBuilder, base, scene); } } } - } + }; private useThisInBody(method: ArkMethod): boolean { const thisInstance = (method.getThisInstance() as Local)!; @@ -128,21 +152,202 @@ export class ThisBindCheck implements BaseChecker { if (rightOp.getBase() !== base) { return false; } - if (rightOp.getMethodSignature().getMethodSubSignature().getMethodName() !== "bind") { + if (rightOp.getMethodSignature().getMethodSubSignature().getMethodName() !== 'bind') { return false; } return true; } - private addIssueReport(stmt: Stmt, operand: Value) { + private addIssueReport(stmt: ArkAssignStmt, isBuilder: boolean, operand: Value, scene: Scene): void { + if (isBuilder && this.isAssignToBuilderParam(stmt, scene)) { + this.reportArkUIIssue(stmt, operand); + } else { + this.reportArkTSIssue(stmt, operand); + } + } + + private isAssignToBuilderParam(assign: ArkAssignStmt, scene: Scene): boolean { + /** + * class CA { + * @Builder builder() { ... } + * build() { + * Column() { CB({ content: this.builder }) } + * } + * } + * class CB { + * @BuilderParam content: () => void + * } + * + * ================================================== + * class %AC2$CA.build { + * constructor() { ... } + * %instInit() { + * %0 = this.builder + * this.content = %0 + * } + * } + * class CA { + * ... + * build() { + * ... + * %3 = new %AC2$CA.build + * %3.constructor() + * %4 = new CB + * %4.constructor(%3) + * ... + * } + * ... + * } + */ + const currentMethod = assign.getCfg().getDeclaringMethod(); + if (currentMethod.getName() !== '%instInit') { + return false; + } + const currentClass = currentMethod.getDeclaringArkClass(); + if (!currentClass.isAnonymousClass()) { + return false; + } + const currentClassSig = currentClass.getSignature(); + + const leftOp = assign.getLeftOp(); + if (!(leftOp instanceof Local)) { + return false; + } + const usedStmts = leftOp.getUsedStmts(); + if (usedStmts.length !== 1) { + return false; + } + const usedStmt = usedStmts[0]; + if (!(usedStmt instanceof ArkAssignStmt)) { + return false; + } + const target = usedStmt.getLeftOp(); + if (!(target instanceof ArkInstanceFieldRef)) { + return false; + } + const baseTy = target.getBase().getType(); + if (!(baseTy instanceof ClassType)) { + return false; + } + if ((baseTy as ClassType).getClassSignature() !== currentClassSig) { + return false; + } + const fieldName = target.getFieldName(); + + const declaringClassName = currentClassSig.getDeclaringClassName(); + if (declaringClassName === currentClass.getName()) { + return false; + } + const declaringClass = currentClass.getDeclaringArkFile().getClassWithName(declaringClassName); + if (!declaringClass) { + return false; + } + let targetClassSig = this.findDefinitionOfAnonymousClass(declaringClass, currentClassSig); + if (!targetClassSig) { + return false; + } + const targetClass = scene.getClass(targetClassSig); + if (!targetClass) { + return false; + } + const arkField = targetClass.getFieldWithName(fieldName); + if (!arkField) { + return false; + } + return arkField.hasBuilderParamDecorator(); + } + + private findDefinitionOfAnonymousClass( + declaringClass: ArkClass, + anonymousClassSig: ClassSignature + ): ClassSignature | undefined { + for (const m of declaringClass.getMethods()) { + const stmts = m.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkNewExpr)) { + continue; + } + if (rightOp.getClassType().getClassSignature() !== anonymousClassSig) { + continue; + } + const local = stmt.getLeftOp() as Local; + const classSignature = this.processUsedStmts(local, anonymousClassSig); + if (!classSignature) { + continue; + } + return classSignature; + } + } + return undefined; + } + + private processUsedStmts(local: Local, anonymousClassSig: ClassSignature): ClassSignature | null { + for (const usedStmt of local.getUsedStmts()) { + const invoke = usedStmt.getInvokeExpr(); + if (!invoke) { + continue; + } + const sig = invoke.getMethodSignature(); + if (sig.getMethodSubSignature().getMethodName() !== 'constructor') { + continue; + } + if (sig.getDeclaringClassSignature() === anonymousClassSig) { + continue; + } + return sig.getDeclaringClassSignature(); + } + return null; + } + + private reportArkTSIssue(stmt: ArkAssignStmt, operand: Value): void { const severity = this.rule.alert ?? this.metaData.severity; const warnInfo = this.getLineAndColumn(stmt, operand); - let defects = new Defects(warnInfo.line, warnInfo.startCol, warnInfo.endCol, this.metaData.description, severity, this.rule.ruleId, - warnInfo.filePath, this.metaData.ruleDocPath, true, false, false); + const problem = 'DefaultBindThis'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + ARKTS_RULE_ID, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private reportArkUIIssue(stmt: ArkAssignStmt, operand: Value): void { + const severity = this.rule.alert ?? arkuiMetaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'BuilderParamContextChanged'; + const desc = `${arkuiMetaData.description} (${ARKUI_RULE_ID.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + ARKUI_RULE_ID, + warnInfo.filePath, + arkuiMetaData.ruleDocPath, + true, + false, + false + ); this.issues.push(new IssueReport(defects, undefined)); } - private getLineAndColumn(stmt: Stmt, operand: Value) { + private getLineAndColumn(stmt: ArkAssignStmt, operand: Value): WarnInfo { const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { @@ -156,4 +361,4 @@ export class ThisBindCheck implements BaseChecker { } return { line: -1, startCol: -1, endCol: -1, filePath: '' }; } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/Utils.ts b/ets2panda/linter/homecheck/src/checker/migration/Utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..0992bcbe88d2748a8d25a3b7b12b9c8b6492578c --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/Utils.ts @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ArkAssignStmt, ArkMethod, CallGraph, CallGraphBuilder, Local, LOG_MODULE_TYPE, Logger, Scene, Stmt, Value } from 'arkanalyzer/lib'; +import { WarnInfo } from '../../utils/common/Utils'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { DVFG, DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { DVFGBuilder } from 'arkanalyzer/lib/VFG/builder/DVFGBuilder'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Utils'); + +export const CALL_DEPTH_LIMIT = 2; +export class CallGraphHelper { + private static cgInstance: CallGraph | null = null; + + public static getCGInstance(scene: Scene): CallGraph { + if (!this.cgInstance) { + this.cgInstance = new CallGraph(scene); + } + return this.cgInstance; + } +} + +export class GlobalCallGraphHelper { + private static cgInstance: CallGraph | null = null; + + public static getCGInstance(scene: Scene): CallGraph { + if (!this.cgInstance) { + this.cgInstance = new CallGraph(scene); + let cgBuilder = new CallGraphBuilder(this.cgInstance, scene); + cgBuilder.buildCHA4WholeProject(true); + } + return this.cgInstance; + } +} + +export class DVFGHelper { + private static dvfgInstance: DVFG; + private static dvfgBuilder: DVFGBuilder; + private static built: Set = new Set(); + + private static createDVFGInstance(scene: Scene): void { + if (!this.dvfgInstance) { + this.dvfgInstance = new DVFG(GlobalCallGraphHelper.getCGInstance(scene)); + this.dvfgBuilder = new DVFGBuilder(this.dvfgInstance, scene); + } + } + + public static buildSingleDVFG(method: ArkMethod, scene: Scene): void { + if (!this.dvfgInstance) { + this.createDVFGInstance(scene); + } + if (!this.built.has(method)) { + this.dvfgBuilder.buildForSingleMethod(method); + this.built.add(method); + } + } + + public static getOrNewDVFGNode(stmt: Stmt, scene: Scene): DVFGNode { + if (!this.dvfgInstance) { + this.createDVFGInstance(scene); + } + return this.dvfgInstance!.getOrNewDVFGNode(stmt); + } +} + +export const CALLBACK_METHOD_NAME: string[] = [ + 'onClick', // 点击事件,当用户点击组件时触发 + 'onTouch', // 触摸事件,当手指在组件上按下、滑动、抬起时触发 + 'onAppear', // 组件挂载显示时触发 + 'onDisAppear', // 组件卸载消失时触发 + 'onDragStart', // 拖拽开始事件,当组件被长按后开始拖拽时触发 + 'onDragEnter', // 拖拽进入组件范围时触发 + 'onDragMove', // 拖拽在组件范围内移动时触发 + 'onDragLeave', // 拖拽离开组件范围内时触发 + 'onDrop', // 拖拽释放目标,当在本组件范围内停止拖拽行为时触发 + 'onKeyEvent', // 按键事件,当组件获焦后,按键动作触发 + 'onFocus', // 焦点事件,当组件获取焦点时触发 + 'onBlur', // 当组件失去焦点时触发的回调 + 'onHover', // 鼠标悬浮事件,鼠标进入或退出组件时触发 + 'onMouse', // 鼠标事件,当鼠标按键点击或在组件上移动时触发 + 'onAreaChange', // 组件区域变化事件,组件尺寸、位置变化时触发 + 'onVisibleAreaChange', // 组件可见区域变化事件,组件在屏幕中的显示区域面积变化时触发 +]; + +export function getLanguageStr(language: Language): string { + let targetLan: string = ''; + switch (language) { + case Language.JAVASCRIPT: + targetLan = 'javascript'; + break; + case Language.TYPESCRIPT: + targetLan = 'typescript'; + break; + case Language.ARKTS1_1: + targetLan = 'arkts1.1'; + break; + case Language.ARKTS1_2: + targetLan = 'arkts1.2'; + break; + default: + break; + } + return targetLan; +} + +export function getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; +} + +export function getGlobalsDefineInDefaultMethod(defaultMethod: ArkMethod): Map { + const globalVarMap: Map = new Map(); + const stmts = defaultMethod.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof Local)) { + continue; + } + const name = leftOp.getName(); + if (name.startsWith('%') || name === 'this') { + continue; + } + globalVarMap.set(name, [...(globalVarMap.get(name) ?? []), stmt]); + } + return globalVarMap; +} diff --git a/ets2panda/linter/homecheck/src/codeFix/FixEngine.ts b/ets2panda/linter/homecheck/src/codeFix/FixEngine.ts index 6b312508d71cf9720b95fac0c928369bcce292d5..483a60a3de20cbd0fcdb574c77998bd963aa6af2 100644 --- a/ets2panda/linter/homecheck/src/codeFix/FixEngine.ts +++ b/ets2panda/linter/homecheck/src/codeFix/FixEngine.ts @@ -13,11 +13,11 @@ * limitations under the License. */ -import { Engine } from "../model/Engine"; -import { FixMode } from "../model/Fix"; -import { AIFixEngine } from "./engines/AIFixEngine"; -import { EsLintFixEngine } from "./engines/EsLintFixEngine"; -import { HomeCheckFixEngine } from "./engines/HomeCheckFixEngine"; +import { Engine } from '../model/Engine'; +import { FixMode } from '../model/Fix'; +import { AIFixEngine } from './engines/AIFixEngine'; +import { EsLintFixEngine } from './engines/EsLintFixEngine'; +import { HomeCheckFixEngine } from './engines/HomeCheckFixEngine'; export class FixEngine { public getEngine(mode: FixMode): Engine { diff --git a/ets2panda/linter/homecheck/src/codeFix/engines/AIFixEngine.ts b/ets2panda/linter/homecheck/src/codeFix/engines/AIFixEngine.ts index bcfd58c7a5bc9eb44a18ea80858281a15b7a13c3..786d2863f3de728485f3f08426dd4168887c248b 100644 --- a/ets2panda/linter/homecheck/src/codeFix/engines/AIFixEngine.ts +++ b/ets2panda/linter/homecheck/src/codeFix/engines/AIFixEngine.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { ArkFile } from "arkanalyzer"; -import { FileReports, IssueReport } from "../../model/Defects"; -import { Engine } from "../../model/Engine"; -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; +import { ArkFile } from 'arkanalyzer'; +import { FileReports, IssueReport } from '../../model/Defects'; +import { Engine } from '../../model/Engine'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'EsLintFixEngine'); diff --git a/ets2panda/linter/homecheck/src/codeFix/engines/EsLintFixEngine.ts b/ets2panda/linter/homecheck/src/codeFix/engines/EsLintFixEngine.ts index 0c1583ed96c96d0d8fa7f2c0192386d40dd9b7b7..a5f055289c04ba9e3b7529c111ba56b5a0713f5e 100644 --- a/ets2panda/linter/homecheck/src/codeFix/engines/EsLintFixEngine.ts +++ b/ets2panda/linter/homecheck/src/codeFix/engines/EsLintFixEngine.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { ArkFile } from "arkanalyzer"; -import { FileReports, IssueReport } from "../../model/Defects"; -import { Engine } from "../../model/Engine"; -import { RuleFix } from "../../model/Fix"; -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; -import { FixUtils } from "../../utils/common/FixUtils"; +import { ArkFile } from 'arkanalyzer'; +import { FileReports, IssueReport } from '../../model/Defects'; +import { Engine } from '../../model/Engine'; +import { RuleFix } from '../../model/Fix'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FixUtils } from '../../utils/common/FixUtils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'EsLintFixEngine'); const BOM = '\uFEFF'; @@ -28,9 +28,10 @@ let eof = '\r\n'; export class EsLintFixEngine implements Engine { applyFix(arkFile: ArkFile, fixIssues: IssueReport[], remainIssues: IssueReport[]): FileReports { let sourceText = arkFile.getCode(); - const bom = sourceText.startsWith(BOM) ? BOM : "", - text = bom ? sourceText.slice(1) : sourceText; - let lastPos = Number.NEGATIVE_INFINITY, output = bom; + const bom = sourceText.startsWith(BOM) ? BOM : ''; + let text = bom ? sourceText.slice(1) : sourceText; + let lastPos = Number.NEGATIVE_INFINITY; + let output = bom; eof = FixUtils.getTextEof(text) || eof; // issue非法数据检查及排序 const ret = this.checkAndSortIssues(fixIssues, remainIssues); @@ -53,11 +54,12 @@ export class EsLintFixEngine implements Engine { this.updateRemainIssues(text, issue, remainIssues, remainIssuesCopy); } output += text.slice(Math.max(0, lastPos)); - return { defects: remainIssues.map((issue => issue.defect)), output: bom + output, filePath: arkFile.getFilePath() } + return { defects: remainIssues.map((issue => issue.defect)), output: bom + output, filePath: arkFile.getFilePath() }; } private checkAndSortIssues(fixIssues: IssueReport[], remainIssues: IssueReport[]): { - fixIssues: IssueReport[], remainIssues: IssueReport[] } { + fixIssues: IssueReport[], remainIssues: IssueReport[] + } { const fixIssuesValid: IssueReport[] = []; fixIssues.forEach((issue) => { const fix = issue.fix as RuleFix; @@ -70,7 +72,7 @@ export class EsLintFixEngine implements Engine { return { fixIssues: fixIssuesValid.sort(this.compareIssueByRange), remainIssues: remainIssues.sort(this.compareIssueByLocation) }; } - private compareIssueByRange(issue1: IssueReport, issue2: IssueReport) { + private compareIssueByRange(issue1: IssueReport, issue2: IssueReport): number { let fix1 = issue1.fix; let fix2 = issue2.fix; if (FixUtils.isRuleFix(fix1) && FixUtils.isRuleFix(fix2)) { @@ -80,7 +82,7 @@ export class EsLintFixEngine implements Engine { } } - private compareIssueByLocation(a: IssueReport, b: IssueReport) { + private compareIssueByLocation(a: IssueReport, b: IssueReport): number { return a.defect.reportLine - b.defect.reportLine || a.defect.reportColumn - b.defect.reportColumn; } diff --git a/ets2panda/linter/homecheck/src/codeFix/engines/HomeCheckFixEngine.ts b/ets2panda/linter/homecheck/src/codeFix/engines/HomeCheckFixEngine.ts index bb634e8eb6f821485bcfd662eb8d83a3333b2221..51268a1bc49038d967f3faf099be85168670ecb3 100644 --- a/ets2panda/linter/homecheck/src/codeFix/engines/HomeCheckFixEngine.ts +++ b/ets2panda/linter/homecheck/src/codeFix/engines/HomeCheckFixEngine.ts @@ -13,15 +13,16 @@ * limitations under the License. */ -import { ArkFile, SourceFilePrinter } from "arkanalyzer"; -import { FileReports, IssueReport } from "../../model/Defects"; -import { Engine } from "../../model/Engine"; -import { FunctionFix } from "../../model/Fix"; -import path from "path"; -import { removeSync } from "fs-extra"; -import { FileUtils, WriteFileMode } from "../../utils/common/FileUtils"; -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; -import { FixUtils } from "../../utils/common/FixUtils"; +import { ArkFile, SourceFilePrinter } from 'arkanalyzer'; +import { FileReports, IssueReport } from '../../model/Defects'; +import { Engine } from '../../model/Engine'; +import { FunctionFix } from '../../model/Fix'; +import path from 'path'; +// @ts-ignore +import { removeSync } from 'fs-extra'; +import { FileUtils, WriteFileMode } from '../../utils/common/FileUtils'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FixUtils } from '../../utils/common/FixUtils'; const FIX_OUTPUT_DIR = './fixedCode'; @@ -61,7 +62,7 @@ export class HomeCheckFixEngine implements Engine { break; } } - return {defects: remainIssues.map((issue => issue.defect)), output: '', filePath: fixPath}; + return { defects: remainIssues.map((issue => issue.defect)), output: '', filePath: fixPath }; } private arkFileToFile(arkFile: ArkFile, outputPath: string): boolean { diff --git a/ets2panda/linter/homecheck/src/matcher/Matchers.ts b/ets2panda/linter/homecheck/src/matcher/Matchers.ts index c817e6c1357a3923be3210b0b70e30af765456b1..2a651d2d1f5fa28306aeacf633399d1721943bcb 100644 --- a/ets2panda/linter/homecheck/src/matcher/Matchers.ts +++ b/ets2panda/linter/homecheck/src/matcher/Matchers.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,8 +13,8 @@ * limitations under the License. */ -import { ArkField, ArkFile, ArkMethod, ArkNamespace, Scene } from "arkanalyzer"; -import { ArkClass, ClassCategory } from "arkanalyzer/lib/core/model/ArkClass"; +import { ArkField, ArkFile, ArkMethod, ArkNamespace, Scene } from 'arkanalyzer'; +import { ArkClass, ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; export enum MethodCategory { Accessor = 0, diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts index e9bb0cf5238e9eaec40899419457ad0f70f24791..1e1565a7c11baa8e3724136b4dbf4440a6161f89 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -16,7 +16,7 @@ import { ArkClass, ArkFile } from 'arkanalyzer'; import { ClassMatcher, isMatchedFile, isMatchedNamespace, isMatchedClass } from '../Matchers'; -export function matchClass(arkFiles: ArkFile[], matcher: ClassMatcher, callback: Function) { +export function matchClass(arkFiles: ArkFile[], matcher: ClassMatcher, callback: Function): void { for (let arkFile of arkFiles) { if (matcher.file && !isMatchedFile(arkFile, matcher.file)) { continue; @@ -31,7 +31,7 @@ export function matchClass(arkFiles: ArkFile[], matcher: ClassMatcher, callback: } } -function matchClassProcess(matcher: ClassMatcher, classes: ArkClass[], callback: Function) { +function matchClassProcess(matcher: ClassMatcher, classes: ArkClass[], callback: Function): void { for (const arkClass of classes) { if (isMatchedClass(arkClass, [matcher])) { callback(arkClass); diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts index 5e4d3496ab644191b9fad2da89018922ec0f5eee..f42fd5d7031c4764bedf8cb9a7d68bfc4606cf79 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -17,7 +17,7 @@ import { ArkClass, ArkFile } from 'arkanalyzer'; import { isMatchedFile, isMatchedNamespace, isMatchedClass, FieldMatcher, isMatchedField } from '../Matchers'; -export function matchFields(arkFiles: ArkFile[], matcher: FieldMatcher, callback: Function) { +export function matchFields(arkFiles: ArkFile[], matcher: FieldMatcher, callback: Function): void { for (let arkFile of arkFiles) { if (matcher.file && !isMatchedFile(arkFile, matcher.file)) { continue; @@ -32,7 +32,7 @@ export function matchFields(arkFiles: ArkFile[], matcher: FieldMatcher, callback } } -function matchFieldsInClasses(matcher: FieldMatcher, classes: ArkClass[], callback: Function) { +function matchFieldsInClasses(matcher: FieldMatcher, classes: ArkClass[], callback: Function): void { for (const arkClass of classes) { if (matcher.class && !isMatchedClass(arkClass, matcher.class)) { continue; diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts index cd56ad20d05cc76cc8c05813f868b43a1d7c57c5..560fa54470b8a7becc532bc7b8d19410ad9aad55 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -16,7 +16,7 @@ import { ArkFile } from 'arkanalyzer'; import { FileMatcher, isMatchedFile } from '../Matchers'; -export function matchFiles(arkFiles: ArkFile[], matcher: FileMatcher, callback: Function) { +export function matchFiles(arkFiles: ArkFile[], matcher: FileMatcher, callback: Function): void { for (let arkFile of arkFiles) { if (isMatchedFile(arkFile, [matcher])) { callback(arkFile); diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchMethods.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchMethods.ts index 881cab942f53839c3cba859163c0e7fdeb7cadfd..de9b782bf6365e0d42dfc6a1b67e9b18bb2df2e5 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchMethods.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchMethods.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -17,7 +17,7 @@ import { ArkClass, ArkFile } from 'arkanalyzer'; import { MethodMatcher, isMatchedFile, isMatchedNamespace, isMatchedClass, isMatchedMethod } from '../Matchers'; -export function matchMethods(arkFiles: ArkFile[], matcher: MethodMatcher, callback: Function) { +export function matchMethods(arkFiles: ArkFile[], matcher: MethodMatcher, callback: Function): void { for (let arkFile of arkFiles) { if (matcher.file && !isMatchedFile(arkFile, matcher.file)) { continue; @@ -32,7 +32,7 @@ export function matchMethods(arkFiles: ArkFile[], matcher: MethodMatcher, callba } } -function matchMethodsInClasses(matcher: MethodMatcher, classes: ArkClass[], callback: Function) { +function matchMethodsInClasses(matcher: MethodMatcher, classes: ArkClass[], callback: Function): void { for (const arkClass of classes) { if (matcher.class && !isMatchedClass(arkClass, matcher.class)) { continue; diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts index 4b628c28ba8e2646d983aa4ae06672b4e1b30af2..82b42d2ad657e52a7fed48627ea98a31605c8321 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -16,7 +16,7 @@ import { ArkFile } from 'arkanalyzer'; import { NamespaceMatcher, isMatchedFile, isMatchedNamespace } from '../Matchers'; -export function matchNameSpaces(arkFiles: ArkFile[], matcher: NamespaceMatcher, callback: Function) { +export function matchNameSpaces(arkFiles: ArkFile[], matcher: NamespaceMatcher, callback: Function): void { for (let arkFile of arkFiles) { if (matcher.file && !isMatchedFile(arkFile, matcher.file)) { continue; diff --git a/ets2panda/linter/homecheck/src/model/Defects.ts b/ets2panda/linter/homecheck/src/model/Defects.ts index 0338b8ae301c168792ea0b12a53e4aa327f9d49a..cf38e10affcba61e4b4bc93e7b8e9d6ee4d606f9 100644 --- a/ets2panda/linter/homecheck/src/model/Defects.ts +++ b/ets2panda/linter/homecheck/src/model/Defects.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,31 +12,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { AIFix, FunctionFix, RuleFix } from "./Fix"; +import { AIFix, FunctionFix, RuleFix } from './Fix'; export const engine = { engineName: '' -} +}; export class Defects { reportLine: number; reportColumn: number; + problem: string = ''; description: string = ''; - severity: number = -1; // 0:info, 1:warning, 2:error + severity: number = -1; // 0:info, 1:warning, 2:error ruleId: string = '@perforce/'; - mergeKey: string = ''; // 文件路径%行号%开始列号%结束列号%规则%规则描述 + mergeKey: string = ''; // 文件路径%行号%开始列号%结束列号%规则%规则描述 ruleDocPath: string = 'doc/.md'; disabled: boolean = true; checked: boolean = false; - fixable: boolean = false; // 是否可以修复 - fixKey: string = ''; // 行号%开始列号%结束列号%规则id + fixable: boolean = false; // 是否可以修复 + fixKey: string = ''; // 行号%开始列号%结束列号%规则id showIgnoreIcon: boolean = true; engineName: string = engine.engineName; - constructor(reportLine: number, reportColumn: number, endColumn: number, description: string, severity: number, ruleId: string, + constructor(reportLine: number, reportColumn: number, endColumn: number, problem: string, description: string, severity: number, ruleId: string, filePath: string, ruleDocPath: string, disabled: boolean, checked: boolean, fixable: boolean, showIgnoreIcon: boolean = true) { this.reportLine = reportLine; this.reportColumn = reportColumn; + this.problem = problem; this.description = description; this.severity = severity; this.ruleId = ruleId; diff --git a/ets2panda/linter/homecheck/src/model/Engine.ts b/ets2panda/linter/homecheck/src/model/Engine.ts index 64c09751f97ec7dc638fade1902a087ca98af946..7231f9faddc7e846b7534a4299e4bcb289c4adf8 100644 --- a/ets2panda/linter/homecheck/src/model/Engine.ts +++ b/ets2panda/linter/homecheck/src/model/Engine.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,8 +13,8 @@ * limitations under the License. */ -import { ArkFile } from "arkanalyzer"; -import { FileReports, IssueReport } from "./Defects"; +import { ArkFile } from 'arkanalyzer'; +import { FileReports, IssueReport } from './Defects'; export interface Engine { /** diff --git a/ets2panda/linter/homecheck/src/model/File2Check.ts b/ets2panda/linter/homecheck/src/model/File2Check.ts index 87465db69c90b8cf486d6daa132146d4d2a2ae57..ecfc86270a7f9738fe6afd6ca45319a27f073504 100644 --- a/ets2panda/linter/homecheck/src/model/File2Check.ts +++ b/ets2panda/linter/homecheck/src/model/File2Check.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,24 +12,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ArkFile } from "arkanalyzer"; -import { BaseChecker } from "../checker/BaseChecker"; -import { MatcherTypes } from "../matcher/Matchers"; -import { matchFiles } from "../matcher/matcherAdapter/matchFiles"; -import { matchNameSpaces } from "../matcher/matcherAdapter/matchNameSpaces"; -import { matchClass } from "../matcher/matcherAdapter/matchClass"; -import { matchMethods } from "../matcher/matcherAdapter/matchMethods"; -import { matchFields } from "../matcher/matcherAdapter/matchFields"; -import { FileUtils } from "../utils/common/FileUtils"; -import { filterDisableIssue } from "../utils/common/Disable"; -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; -import { IssueReport } from "./Defects"; +import { ArkFile } from 'arkanalyzer'; +import { BaseChecker } from '../checker/BaseChecker'; +import { MatcherTypes } from '../matcher/Matchers'; +import { matchFiles } from '../matcher/matcherAdapter/matchFiles'; +import { matchNameSpaces } from '../matcher/matcherAdapter/matchNameSpaces'; +import { matchClass } from '../matcher/matcherAdapter/matchClass'; +import { matchMethods } from '../matcher/matcherAdapter/matchMethods'; +import { matchFields } from '../matcher/matcherAdapter/matchFields'; +import { FileUtils } from '../utils/common/FileUtils'; +import { filterDisableIssue } from '../utils/common/Disable'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { IssueReport } from './Defects'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'File2Check'); export class File2Check { public arkFile: ArkFile; - public enabledRuleCheckerMap: Map = new Map(); // TODO: key改为枚举 + public enabledRuleCheckerMap: Map = new Map(); // TODO: key改为枚举 public issues: IssueReport[] = []; private flMatcherMap = new Map(); @@ -38,14 +38,13 @@ export class File2Check { private mtdMatcherMap = new Map(); private fieldMatcherMap = new Map(); - constructor() { - } + constructor() {} - public addChecker(ruleId: string, checker: BaseChecker) { + public addChecker(ruleId: string, checker: BaseChecker): void { this.enabledRuleCheckerMap.set(ruleId, checker); } - public collectMatcherCallbacks() { + public collectMatcherCallbacks(): void { this.enabledRuleCheckerMap.forEach(checker => { const matcherCallbacks = checker.registerMatchers(); matcherCallbacks.forEach(obj => { @@ -68,50 +67,52 @@ export class File2Check { this.fieldMatcherMap.set(matcher, callback); break; } - }) + }); }); } - public async emitCheck() { + public async emitCheck(): Promise { this.flMatcherMap.forEach((callback, matcher) => { - matchFiles([this.arkFile], matcher, callback) + matchFiles([this.arkFile], matcher, callback); }); this.nsMatcherMap.forEach((callback, matcher) => { - matchNameSpaces([this.arkFile], matcher, callback) + matchNameSpaces([this.arkFile], matcher, callback); }); this.clsMatcherMap.forEach((callback, matcher) => { - matchClass([this.arkFile], matcher, callback) + matchClass([this.arkFile], matcher, callback); }); this.mtdMatcherMap.forEach((callback, matcher) => { - matchMethods([this.arkFile], matcher, callback) + matchMethods([this.arkFile], matcher, callback); }); this.fieldMatcherMap.forEach((callback, matcher) => { - matchFields([this.arkFile], matcher, callback) + matchFields([this.arkFile], matcher, callback); }); } - public collectIssues() { + public collectIssues(): void { this.enabledRuleCheckerMap.forEach((v, k) => { - this.issues.push(...(v.issues?.reduce((acc, cur) => { - if (acc.some((item) => item.defect.mergeKey === cur.defect.mergeKey)) { - logger.debug('Skip the repeated issue, please check. issue.mergeKey = ' + cur.defect.mergeKey); - } else { - acc.push(cur); - } - return acc; - }, [] as IssueReport[]))); + this.issues.push( + ...v.issues?.reduce((acc, cur) => { + if (acc.some(item => item.defect.mergeKey === cur.defect.mergeKey)) { + logger.debug('Skip the repeated issue, please check. issue.mergeKey = ' + cur.defect.mergeKey); + } else { + acc.push(cur); + } + return acc; + }, [] as IssueReport[]) + ); }); } - public async checkDisable() { + public async checkDisable(): Promise { const fileLineList = await FileUtils.readLinesFromFile(this.arkFile.getFilePath()); - this.issues = filterDisableIssue(fileLineList, this.issues); + this.issues = await filterDisableIssue(fileLineList, this.issues, this.arkFile.getFilePath()); } - public async run() { + public async run(): Promise { this.collectMatcherCallbacks(); await this.emitCheck(); this.collectIssues(); await this.checkDisable(); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/model/Fix.ts b/ets2panda/linter/homecheck/src/model/Fix.ts index 12dcdc415202f61aa39bf019d3aba449e2b6cb55..459037c22055f12a6572afd2066b1a6f5cfcea91 100644 --- a/ets2panda/linter/homecheck/src/model/Fix.ts +++ b/ets2panda/linter/homecheck/src/model/Fix.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/model/Interfaces.ts b/ets2panda/linter/homecheck/src/model/Interfaces.ts index f0da83d853702462b604ff8ff249d0234fd95735..e357b58377cdcbf623ec90fd985655ab183cec03 100644 --- a/ets2panda/linter/homecheck/src/model/Interfaces.ts +++ b/ets2panda/linter/homecheck/src/model/Interfaces.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -21,11 +21,11 @@ export interface ImageInfo { export type ImagesInfo = { images?: ImageInfo[] -} & ImageInfo +} & ImageInfo; export interface ImageData { validate: (intput: Uint8Array) => boolean; - calculate: (input: Uint8Array, filepath?: string) => ImagesInfo + calculate: (input: Uint8Array, filepath?: string) => ImagesInfo; } export interface IAttributes { diff --git a/ets2panda/linter/homecheck/src/model/Message.ts b/ets2panda/linter/homecheck/src/model/Message.ts index a0a3a4d16de4b23af6d6fc5db1f5dfed90d7c68a..b5591503548528c18b047f6454638fa84c9794ee 100644 --- a/ets2panda/linter/homecheck/src/model/Message.ts +++ b/ets2panda/linter/homecheck/src/model/Message.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -25,7 +25,7 @@ export interface Message { progressNotify(progress: number, msg: string): void; } -export class defaultMessage implements Message { +export class DefaultMessage implements Message { /** * 发送消息 * diff --git a/ets2panda/linter/homecheck/src/model/NumberValue.ts b/ets2panda/linter/homecheck/src/model/NumberValue.ts index 67d6cf499567692f00978f4e2421154de8aac98e..bf791036459c8a031ea5cea9d6b698ce0ae7938a 100644 --- a/ets2panda/linter/homecheck/src/model/NumberValue.ts +++ b/ets2panda/linter/homecheck/src/model/NumberValue.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/model/Project2Check.ts b/ets2panda/linter/homecheck/src/model/Project2Check.ts index 6aad5f1aaedc1c78f3ba0aad78ad363cbedc4734..3e9c1bf9ed811aeca8b3a79474ba520156a057d6 100644 --- a/ets2panda/linter/homecheck/src/model/Project2Check.ts +++ b/ets2panda/linter/homecheck/src/model/Project2Check.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,25 +12,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ArkFile } from "arkanalyzer"; -import { BaseChecker } from "../checker/BaseChecker"; -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; -import { MatcherTypes } from "../matcher/Matchers"; -import { matchFiles } from "../matcher/matcherAdapter/matchFiles"; -import { matchNameSpaces } from "../matcher/matcherAdapter/matchNameSpaces"; -import { matchClass } from "../matcher/matcherAdapter/matchClass"; -import { matchMethods } from "../matcher/matcherAdapter/matchMethods"; -import { matchFields } from "../matcher/matcherAdapter/matchFields"; -import { FileUtils } from "../utils/common/FileUtils"; -import { filterDisableIssue } from "../utils/common/Disable"; -import { IssueReport } from "./Defects"; -import { Rule } from "./Rule"; + +import * as fs from 'fs'; +import { ArkFile } from 'arkanalyzer'; +import { BaseChecker } from '../checker/BaseChecker'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { MatcherTypes } from '../matcher/Matchers'; +import { matchFiles } from '../matcher/matcherAdapter/matchFiles'; +import { matchNameSpaces } from '../matcher/matcherAdapter/matchNameSpaces'; +import { matchClass } from '../matcher/matcherAdapter/matchClass'; +import { matchMethods } from '../matcher/matcherAdapter/matchMethods'; +import { matchFields } from '../matcher/matcherAdapter/matchFields'; +import { FileUtils } from '../utils/common/FileUtils'; +import { filterDisableIssue } from '../utils/common/Disable'; +import { IssueReport } from './Defects'; +import { Rule } from './Rule'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Project2Check'); export class Project2Check { public arkFiles: ArkFile[]; - public enabledRuleCheckerMap: Map = new Map(); // TODO: key改为枚举 + // TODO: key改为枚举 + public enabledRuleCheckerMap: Map = new Map(); public issues: IssueReport[] = []; public ruleMap: Map = new Map(); @@ -44,11 +47,11 @@ export class Project2Check { constructor() { } - public addChecker(ruleId: string, checker: BaseChecker) { + public addChecker(ruleId: string, checker: BaseChecker): void { this.enabledRuleCheckerMap.set(ruleId, checker); } - public collectMatcherCallbacks() { + public collectMatcherCallbacks(): void { this.enabledRuleCheckerMap.forEach(checker => { const matcherCallbacks = checker.registerMatchers(); matcherCallbacks.forEach(obj => { @@ -77,28 +80,28 @@ export class Project2Check { default: break; } - }) + }); }); } - public async emitCheck() { + public async emitCheck(): Promise { await Promise.all(Array.from(this.enabledRuleCheckerMap.values()).map(checker => { try { this.processSceneCallbacks(); this.flMatcherMap.forEach((callback, matcher) => { - matchFiles(this.arkFiles, matcher, callback) + matchFiles(this.arkFiles, matcher, callback); }); this.nsMatcherMap.forEach((callback, matcher) => { - matchNameSpaces(this.arkFiles, matcher, callback) + matchNameSpaces(this.arkFiles, matcher, callback); }); this.clsMatcherMap.forEach((callback, matcher) => { - matchClass(this.arkFiles, matcher, callback) + matchClass(this.arkFiles, matcher, callback); }); this.mtdMatcherMap.forEach((callback, matcher) => { - matchMethods(this.arkFiles, matcher, callback) + matchMethods(this.arkFiles, matcher, callback); }); this.fieldMatcherMap.forEach((callback, matcher) => { - matchFields(this.arkFiles, matcher, callback) + matchFields(this.arkFiles, matcher, callback); }); } catch (error) { logger.error(`Checker ${checker.rule.ruleId} error: `, error); @@ -118,7 +121,7 @@ export class Project2Check { } } - public collectIssues() { + public collectIssues(): void { this.enabledRuleCheckerMap.forEach((v, k) => { this.issues.push(...(v.issues?.reduce((acc, cur) => { if (acc.some((item) => item.defect.mergeKey === cur.defect.mergeKey)) { @@ -157,12 +160,15 @@ export class Project2Check { this.issues = Array.from(issueMap.values()); } - public async checkDisable() { + public async checkDisable(): Promise { let filtedIssues: IssueReport[] = []; for (const issue of this.issues) { const filePath = issue.defect.mergeKey.split('%')[0]; + if (!fs.existsSync(filePath)) { + continue; + } const fileLineList = await FileUtils.readLinesFromFile(filePath); - const filtedResult = filterDisableIssue(fileLineList, [issue]); + const filtedResult = await filterDisableIssue(fileLineList, [issue], filePath); if (filtedResult.length > 0) { filtedIssues = filtedIssues.concat(filtedResult[0]); } @@ -170,7 +176,7 @@ export class Project2Check { this.issues = filtedIssues; } - public async run() { + public async run(): Promise { this.collectMatcherCallbacks(); await this.emitCheck(); this.collectIssues(); diff --git a/ets2panda/linter/homecheck/src/model/ProjectConfig.ts b/ets2panda/linter/homecheck/src/model/ProjectConfig.ts index 5d17f94620fe2fe963e7fb4251f3a36f876619ab..7a5c7cbdfbd091e3c905e4c51099d5e2639f06c4 100644 --- a/ets2panda/linter/homecheck/src/model/ProjectConfig.ts +++ b/ets2panda/linter/homecheck/src/model/ProjectConfig.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,6 +13,7 @@ * limitations under the License. */ +import { LOG_LEVEL } from 'arkanalyzer'; import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; export class ProjectConfig { @@ -31,6 +32,9 @@ export class ProjectConfig { sdksThirdParty: string[]; arkCheckPath: string; product: string; + logLevel: LOG_LEVEL; + arkAnalyzerLogLevel: LOG_LEVEL; + // [filePath, languageTag] or [folderPath, languageTag] languageTags: Map; @@ -55,6 +59,8 @@ export class ProjectConfig { this.product = config.product ?? ''; this.languageTags = config.languageTags ?? new Map(); this.fileOrFolderToCheck = config.fileOrFolderToCheck ?? []; + this.logLevel = config.logLevel ?? LOG_LEVEL.INFO; + this.arkAnalyzerLogLevel = config.arkAnalyzerLogLevel ?? LOG_LEVEL.ERROR; } } diff --git a/ets2panda/linter/homecheck/src/model/Rule.ts b/ets2panda/linter/homecheck/src/model/Rule.ts index 71a912835f39a51a28b503bc4194072db343bbb7..b0275c3c4f5aa0fa98b79efcbb5c1322d8e5fcb6 100644 --- a/ets2panda/linter/homecheck/src/model/Rule.ts +++ b/ets2panda/linter/homecheck/src/model/Rule.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -16,9 +16,9 @@ export class Rule { ruleId: string; alert: ALERT_LEVEL; - allowExpressions: boolean - ignoreRestArgs: boolean - option: Object[] = [] + allowExpressions: boolean; + ignoreRestArgs: boolean; + option: Object[] = []; constructor(ruleId: string, alert: ALERT_LEVEL = ALERT_LEVEL.SUGGESTION) { this.ruleId = ruleId; diff --git a/ets2panda/linter/homecheck/src/model/RuleConfig.ts b/ets2panda/linter/homecheck/src/model/RuleConfig.ts index 281f4bc08a85e98c87a2c33c8d137675ab32a886..16d5f737aabb5d964ba070606d55113bd5cc95fc 100644 --- a/ets2panda/linter/homecheck/src/model/RuleConfig.ts +++ b/ets2panda/linter/homecheck/src/model/RuleConfig.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,7 +13,7 @@ * limitations under the License. */ -import { GlobMatch } from "../utils/common/GlobMatch"; +import { GlobMatch } from '../utils/common/GlobMatch'; export class RuleConfig { public files: GlobMatch; diff --git a/ets2panda/linter/homecheck/src/model/Scope.ts b/ets2panda/linter/homecheck/src/model/Scope.ts index 0710a9a41f7c4db0e89d374087cbdcfe4249f6ae..3f4a98ca501dfcffe4505b3136a4bc7d4303b745 100644 --- a/ets2panda/linter/homecheck/src/model/Scope.ts +++ b/ets2panda/linter/homecheck/src/model/Scope.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BasicBlock } from "arkanalyzer"; +import { BasicBlock } from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { Variable } from "./Variable"; +import { Variable } from './Variable'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Scope'); diff --git a/ets2panda/linter/homecheck/src/model/SparseArrayValue.ts b/ets2panda/linter/homecheck/src/model/SparseArrayValue.ts index 59f6931abd1358b5b3495e1bc9186512f826d020..16aa478599d5e30d70bc0f8a8a68124fdb7ab7d2 100644 --- a/ets2panda/linter/homecheck/src/model/SparseArrayValue.ts +++ b/ets2panda/linter/homecheck/src/model/SparseArrayValue.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -24,11 +24,11 @@ export class SparseArrayValue { this.baseStr = baseStr; this.valStr = valStr; this.fulBaseStr = this.baseStr + this.valStr; - if (this.sparseArrayType == SparseArrayType.NEW_ARRAY) { + if (this.sparseArrayType === SparseArrayType.NEW_ARRAY) { this.fulStmtStr = this.fulBaseStr + ')'; - } else if (this.sparseArrayType == SparseArrayType.ARRAY_RIGHT) { + } else if (this.sparseArrayType === SparseArrayType.ARRAY_RIGHT) { this.fulStmtStr = this.fulBaseStr + ']'; - } else if (this.sparseArrayType == SparseArrayType.ARRAY_LEFT) { + } else if (this.sparseArrayType === SparseArrayType.ARRAY_LEFT) { this.fulStmtStr = this.fulBaseStr + ']'; } else { this.fulStmtStr = this.fulBaseStr; diff --git a/ets2panda/linter/homecheck/src/model/StmtExt.ts b/ets2panda/linter/homecheck/src/model/StmtExt.ts index 2d87c87ae43512ba9bd8435b3498c43c9abdbe9a..4cc55501037629fd63a41598abdcc37125649c27 100644 --- a/ets2panda/linter/homecheck/src/model/StmtExt.ts +++ b/ets2panda/linter/homecheck/src/model/StmtExt.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Stmt } from "arkanalyzer"; -import { Scope } from "./Scope"; +import { Stmt } from 'arkanalyzer'; +import { Scope } from './Scope'; export class StmtExt extends Stmt { scope: Scope; diff --git a/ets2panda/linter/homecheck/src/model/VarInfo.ts b/ets2panda/linter/homecheck/src/model/VarInfo.ts index 33534649b25c8abd372a2f221bf41f5c85336213..f0b4d33849310a857505d5c0182a2c9a1ffab711 100644 --- a/ets2panda/linter/homecheck/src/model/VarInfo.ts +++ b/ets2panda/linter/homecheck/src/model/VarInfo.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Stmt } from "arkanalyzer"; -import { Scope } from "./Scope"; +import { Stmt } from 'arkanalyzer'; +import { Scope } from './Scope'; export class VarInfo { stmt: Stmt; diff --git a/ets2panda/linter/homecheck/src/model/Variable.ts b/ets2panda/linter/homecheck/src/model/Variable.ts index 2066a30d58fadf335b3e020ae3cc5f63baaf21f7..b9d4ea86e632918b0f7d07340036be436372a9b3 100644 --- a/ets2panda/linter/homecheck/src/model/Variable.ts +++ b/ets2panda/linter/homecheck/src/model/Variable.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Local, Stmt } from "arkanalyzer"; -import { VarInfo } from "./VarInfo"; +import { Local, Stmt } from 'arkanalyzer'; +import { VarInfo } from './VarInfo'; export class Variable { defStmt: Stmt; @@ -27,6 +27,6 @@ export class Variable { } public getName(): string { - return (this.defStmt.getDef() as Local).getName(); + return (this.defStmt.getDef() as Local).getName(); } } \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/run.ts b/ets2panda/linter/homecheck/src/run.ts index 5196e1de7dd781a39fe4e0cfbd0f319648aebc3c..6b468c10889e1cc3e97fb4438cfd4d9360d43208 100644 --- a/ets2panda/linter/homecheck/src/run.ts +++ b/ets2panda/linter/homecheck/src/run.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,6 +13,6 @@ * limitations under the License. */ -import { run } from "./Main"; +import { run } from './Main'; run(); \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/runTool.ts b/ets2panda/linter/homecheck/src/runTool.ts index 530d825115ea4da6cf7893f60a1d338d9465641c..766a459f7cadb5ffa473cf4e64b1b84c97022c25 100644 --- a/ets2panda/linter/homecheck/src/runTool.ts +++ b/ets2panda/linter/homecheck/src/runTool.ts @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ConfigUtils } from "./utils/common/ConfigUtils"; -import { Utils } from "./utils/common/Utils"; -import { MigrationTool } from "./tools/migrationTool/MigrationTool"; +import { ConfigUtils } from './utils/common/ConfigUtils'; +import { Utils } from './utils/common/Utils'; +import { MigrationTool } from './tools/migrationTool/MigrationTool'; async function run(): Promise { const argvObj = Utils.parseCliOptions(process.argv); diff --git a/ets2panda/linter/homecheck/src/tools/BuildModuleChains.ts b/ets2panda/linter/homecheck/src/tools/BuildModuleChains.ts index 1bb83d46724dd8b34f69b31ed9b5a828c21b1850..2d0d6ef9c4c1195c6d5bc428da92077487da6f5b 100644 --- a/ets2panda/linter/homecheck/src/tools/BuildModuleChains.ts +++ b/ets2panda/linter/homecheck/src/tools/BuildModuleChains.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,10 +13,12 @@ * limitations under the License. */ -import { AbstractFieldRef, ArkAssignStmt, ArkFile, ArkIfStmt, ArkInvokeStmt, ArkMethod, ArkNamespace, ArkNewExpr, +import { + AbstractFieldRef, ArkAssignStmt, ArkFile, ArkIfStmt, ArkInvokeStmt, ArkMethod, ArkNamespace, ArkNewExpr, ArkNormalBinopExpr, ArkStaticInvokeExpr, ArkUnopExpr, ClassSignature, ClassType, DEFAULT_ARK_CLASS_NAME, FunctionType, LocalSignature, MethodSignature, NamespaceSignature, Scene, Signature, TEMP_LOCAL_PREFIX, Value, - transfer2UnixPath } from 'arkanalyzer'; + transfer2UnixPath +} from 'arkanalyzer'; import { ArkClass, ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; import { ExportSignature } from 'arkanalyzer/lib/core/model/ArkExport'; import { Local } from 'arkanalyzer/lib/core/base/Local'; @@ -70,7 +72,7 @@ export function buildModuleChains(scene: Scene, arkFiles: ArkFile[], outputDirPa return isOutput; } -function clearGlobalMem() { +function clearGlobalMem(): void { gFinishScanMap.clear(); gNodeMap.clear(); gModuleIdMap.clear(); @@ -93,7 +95,7 @@ function genUniqueId(): string { return Math.random().toString(36).substring(2); } -function genJsonNode(scene: Scene, module: ModuleSignature, uniqueId: string) { +function genJsonNode(scene: Scene, module: ModuleSignature, uniqueId: string): void { const nodeInfo = genNodeInfo(scene, module); if (nodeInfo) { gNodeMap.set(uniqueId, { nodeInfo: nodeInfo, nextNodes: [] }); @@ -166,7 +168,7 @@ function genNodeInfo(scene: Scene, module: ModuleSignature): NodeInfo | null { } else if (module instanceof MethodSignature) { let className = module.getDeclaringClassSignature()?.getClassName(); if (className === DEFAULT_ARK_CLASS_NAME) { - className = module.getDeclaringClassSignature().getDeclaringNamespaceSignature()?.getNamespaceName() ?? '' + className = module.getDeclaringClassSignature().getDeclaringNamespaceSignature()?.getNamespaceName() ?? ''; } let methodName = module.getMethodSubSignature().getMethodName(); const methodLine = scene.getMethod(module)?.getLine(); @@ -225,7 +227,7 @@ function genResultForChains(arkFile: ArkFile): boolean { return false; } -function genChain(module: ModuleSignature, headChain: string = '') { +function genChain(module: ModuleSignature, headChain: string = ''): void { const nextNodes = gFinishScanMap.get(module); if (nextNodes) { for (const nextNode of nextNodes) { @@ -241,7 +243,7 @@ function genChain(module: ModuleSignature, headChain: string = '') { } } -function fileProcess(arkFile: ArkFile, busyArray: Array) { +function fileProcess(arkFile: ArkFile, busyArray: Array): void { const filePath = path.join('@' + arkFile.getProjectName(), transfer2UnixPath(arkFile.getName())); if (!busyArray.includes(filePath) && !repeatFilePath.includes(filePath)) { repeatFilePath.push(filePath); @@ -268,7 +270,7 @@ function fileProcess(arkFile: ArkFile, busyArray: Array) { } } -function findGlobalDef(dfltMethod: ArkMethod | null, busyArray: Array) { +function findGlobalDef(dfltMethod: ArkMethod | null, busyArray: Array): void { const stmts = dfltMethod?.getBody()?.getCfg().getStmts(); for (const stmt of stmts ?? []) { if (stmt instanceof ArkInvokeStmt) { @@ -279,7 +281,7 @@ function findGlobalDef(dfltMethod: ArkMethod | null, busyArray: Array, scene: Scene ) { +function moduleDeeplyProcess(moduleSign: Signature, busyArray: Array, scene: Scene): void { if (moduleSign instanceof ClassSignature) { classProcess(scene.getClass(moduleSign), busyArray); } else if (moduleSign instanceof MethodSignature) { @@ -293,7 +295,7 @@ function moduleDeeplyProcess(moduleSign: Signature, busyArray: Array) { +function namespaceProcess(ns: ArkNamespace | null, busyArray: Array): void { if (!ns || busyArray.includes(ns.getSignature())) { return; } @@ -321,7 +323,7 @@ function namespaceProcess(ns: ArkNamespace | null, busyArray: Array) { +function classProcess(arkClass: ArkClass | null, busyArray: Array): void { if (!arkClass || busyArray.includes(arkClass.getSignature())) { return; } @@ -330,7 +332,7 @@ function classProcess(arkClass: ArkClass | null, busyArray: Array) { +function methodProcess(arkMethod: ArkMethod | null | undefined, busyArray: Array): void { if (!arkMethod || busyArray.includes(arkMethod.getSignature())) { return; } @@ -388,7 +390,7 @@ function methodProcess(arkMethod: ArkMethod | null | undefined, busyArray: Array busyArray.pop(); } -function staticExprProcess(invokeExpr: ArkStaticInvokeExpr, arkFile: ArkFile, busyArray: Array) { +function staticExprProcess(invokeExpr: ArkStaticInvokeExpr, arkFile: ArkFile, busyArray: Array): void { const methodSignature = invokeExpr.getMethodSignature(); const classSignature = methodSignature.getDeclaringClassSignature(); const methodName = methodSignature.getMethodSubSignature().getMethodName(); @@ -413,7 +415,7 @@ function staticExprProcess(invokeExpr: ArkStaticInvokeExpr, arkFile: ArkFile, bu } } -function ifStmtProcess(stmt: ArkIfStmt, curFile: ArkFile, busyArray: Array) { +function ifStmtProcess(stmt: ArkIfStmt, curFile: ArkFile, busyArray: Array): void { const op1 = stmt.getConditionExpr().getOp1(); const op2 = stmt.getConditionExpr().getOp2(); if (op1 instanceof Local) { @@ -424,7 +426,7 @@ function ifStmtProcess(stmt: ArkIfStmt, curFile: ArkFile, busyArray: Array) { +function superClassProcess(arkClass: ArkClass, busyArray: Array): void { const superName = arkClass.getSuperClass()?.getName(); if (!superName || busyArray.includes(arkClass.getSuperClass()?.getSignature()!)) { return; @@ -437,9 +439,9 @@ function superClassProcess(arkClass: ArkClass, busyArray: Array } } -function arkFieldProcess(arkClass: ArkClass, busyArray: Array) { +function arkFieldProcess(arkClass: ArkClass, busyArray: Array): void { const arkFields = arkClass.getFields(); - for ( const arkField of arkFields) { + for (const arkField of arkFields) { const fieldStmts = arkField.getInitializer(); for (const stmt of fieldStmts) { if (stmt instanceof ArkAssignStmt) { @@ -449,7 +451,7 @@ function arkFieldProcess(arkClass: ArkClass, busyArray: Array) } } -function rightOpProcess(rightOp: Value, curFile: ArkFile, busyArray: Array) { +function rightOpProcess(rightOp: Value, curFile: ArkFile, busyArray: Array): void { if (rightOp instanceof ArkNewExpr) { // 右值为new class场景 const type = rightOp.getType(); @@ -484,7 +486,7 @@ function rightOpProcess(rightOp: Value, curFile: ArkFile, busyArray: Array) { +function newExprProcess(type: ClassType, arkFile: ArkFile, busyArray: Array): void { const classSign = type.getClassSignature(); const className = classSign.getClassName(); const curFilePath = arkFile.getFilePath(); @@ -507,7 +509,7 @@ function newExprProcess(type: ClassType, arkFile: ArkFile, busyArray: Array) { +function localProcess(rightOp: Local, curFile: ArkFile, busyArray: Array): void { const type = rightOp.getType(); // todo: Local变量为方法或者类地址,let a = class1,目前右值type为unknown,走else分支 if (type instanceof ClassType) { @@ -532,7 +534,7 @@ function isAnonymous(module: ModuleSignature): boolean { return module.toString().includes('%A'); } -function addLastNodeToMap(busyArray: Array) { +function addLastNodeToMap(busyArray: Array): void { let index = busyArray.length - 2; let lastModule = busyArray[index]; while (isAnonymous(lastModule) && index > 0) { @@ -561,7 +563,7 @@ function outputNodeList(fileName: string): boolean { } } -function outputStorage() { +function outputStorage(): boolean { try { FileUtils.writeToFile(path.join(gOutPutDirPath, FILE_NAME_CHAINS_TXT), gOutStorage); return true; diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/builder.ts b/ets2panda/linter/homecheck/src/tools/depGraph/builder.ts index 720b240465d0163a50c9b7849fb7e9240eee9f83..b234cf945f9d9b1df4aea746006122b3b5f53bf4 100644 --- a/ets2panda/linter/homecheck/src/tools/depGraph/builder.ts +++ b/ets2panda/linter/homecheck/src/tools/depGraph/builder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/fileComponent.ts b/ets2panda/linter/homecheck/src/tools/depGraph/fileComponent.ts index 04e8ad97ac5e58e23d691880b638e7515552b867..efeed1febeb1db2d5697027c68e5947c5bab1c04 100644 --- a/ets2panda/linter/homecheck/src/tools/depGraph/fileComponent.ts +++ b/ets2panda/linter/homecheck/src/tools/depGraph/fileComponent.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/fileDeps.ts b/ets2panda/linter/homecheck/src/tools/depGraph/fileDeps.ts index 2e3f9a5304610bbdec53888dc7a9a20d996b0c76..1b6d7bb8424384125e3bd48c51366bfb4cb741f1 100644 --- a/ets2panda/linter/homecheck/src/tools/depGraph/fileDeps.ts +++ b/ets2panda/linter/homecheck/src/tools/depGraph/fileDeps.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/moduleComponent.ts b/ets2panda/linter/homecheck/src/tools/depGraph/moduleComponent.ts index 61e8f671a192f4debb027fe268f044da96741694..e44b256cc765d6d89f92618072c7e30b18b7f643 100644 --- a/ets2panda/linter/homecheck/src/tools/depGraph/moduleComponent.ts +++ b/ets2panda/linter/homecheck/src/tools/depGraph/moduleComponent.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/moduleDeps.ts b/ets2panda/linter/homecheck/src/tools/depGraph/moduleDeps.ts index 1a84a2c2895c3fba28dbe24ebd6586f0857ba47f..d603a7b8bd3672cecc8bbb288540075631356b76 100644 --- a/ets2panda/linter/homecheck/src/tools/depGraph/moduleDeps.ts +++ b/ets2panda/linter/homecheck/src/tools/depGraph/moduleDeps.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/utils.ts b/ets2panda/linter/homecheck/src/tools/depGraph/utils.ts index 0fbd2ae0af669af056bec5ca62707c93969b5e4b..a71dd517753ae93659dfff202aacfdf934db8ce3 100644 --- a/ets2panda/linter/homecheck/src/tools/depGraph/utils.ts +++ b/ets2panda/linter/homecheck/src/tools/depGraph/utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/tools/migrationTool/ExportIssue.ts b/ets2panda/linter/homecheck/src/tools/migrationTool/ExportIssue.ts deleted file mode 100644 index 7d3b3bb62f2e775bb3a1eaccd14647d62f32b29b..0000000000000000000000000000000000000000 --- a/ets2panda/linter/homecheck/src/tools/migrationTool/ExportIssue.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { CheckEntry } from '../../utils/common/CheckEntry'; - -export interface ProblemInfo { - line: number; - column: number, - endLine: number; - endColumn: number; - start?: number; - end?: number; - type?: string; - severity: number; - problem: string; - suggest: string; - rule: string; - ruleTag: number; - autofixable?: boolean; - aotufix?: AutoFix[]; - autofixTitle?: string; -} - -export interface AutoFix { - replacementText: string; - start: number; - end: number; -} - -export async function exportIssues(checkEntry: CheckEntry): Promise> { - let result = new Map(); - checkEntry.sortIssues().forEach(fileIssue => { - const problemInfos: ProblemInfo[] = fileIssue.issues.map(issueReport => { - const defect = issueReport.defect; - const line = defect.reportLine; - const column = defect.reportColumn; - const endLine = line; - const endColumn = column; - const severity = defect.severity; - const problem = defect.description; - const suggest = ''; - const rule = defect.ruleId; - const ruleTag = -1; - const autofixable = false; - return { line, column, endLine, endColumn, severity, problem, suggest, rule, ruleTag, autofixable }; - }); - result.set(fileIssue.filePath, problemInfos); - }); - return result; -} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts b/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts index 6c5ab6f581b8bf540a24379d433d625a95e22d67..5c3f6478eda979502d63bbb9e1cd817ead03cd0e 100644 --- a/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts +++ b/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts @@ -20,8 +20,8 @@ import { Utils } from '../../utils/common/Utils'; import { CheckerStorage } from '../../utils/common/CheckerStorage'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; import { FileUtils } from '../../utils/common/FileUtils'; -import { defaultMessage } from '../../model/Message'; -import { exportIssues, ProblemInfo } from './ExportIssue'; +import { DefaultMessage } from '../../model/Message'; +import { FileIssues } from "../../model/Defects"; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'MigrationTool'); @@ -37,10 +37,12 @@ export class MigrationTool { } public async buildCheckEntry(): Promise { - logger.info(`buildCheckEntry start`); // 日志配置 const logPath = this.checkEntry.projectConfig.logPath; - Utils.setLogPath(logPath.length === 0 ? './HomeCheck.log' : logPath); + Utils.setLogConfig(logPath.length === 0 ? './HomeCheck.log' : logPath, + this.checkEntry.projectConfig.arkAnalyzerLogLevel, + this.checkEntry.projectConfig.logLevel); + logger.info(`buildCheckEntry start`); // api版本配置 CheckerStorage.getInstance().setApiVersion(this.checkEntry.projectConfig.apiVersion); // product配置 @@ -50,7 +52,7 @@ export class MigrationTool { // 外部没有建立消息通道,使用默认通道 if (!this.checkEntry.message) { - this.checkEntry.message = new defaultMessage(); + this.checkEntry.message = new DefaultMessage(); } // 前处理 @@ -61,11 +63,11 @@ export class MigrationTool { return true; } - public async start(): Promise> { + public async start(): Promise { logger.info(`MigrationTool run start`); await this.checkEntry.runAll(); - let result = await exportIssues(this.checkEntry); + let result = this.checkEntry.sortIssues(); logger.info(`MigrationTool run end`); return result; } diff --git a/ets2panda/linter/homecheck/src/tools/toolEntry.ts b/ets2panda/linter/homecheck/src/tools/toolEntry.ts index 1fc8811c892855a805d23ab416c2b93229dc9269..797900cece80693463163dce0b78eefdc35e73d0 100644 --- a/ets2panda/linter/homecheck/src/tools/toolEntry.ts +++ b/ets2panda/linter/homecheck/src/tools/toolEntry.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/tools/toolRun.ts b/ets2panda/linter/homecheck/src/tools/toolRun.ts index c896db61da396582e9577b8fe4cf7c609ccc3ae5..37d80e9a22201d21fadabd8fe58ccb64b1bbe25b 100644 --- a/ets2panda/linter/homecheck/src/tools/toolRun.ts +++ b/ets2panda/linter/homecheck/src/tools/toolRun.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,10 +13,10 @@ * limitations under the License. */ -import {Utils} from '../utils/common/Utils'; -import {runTool, Tools} from './toolEntry'; +import { Utils } from '../utils/common/Utils'; +import { runTool, Tools } from './toolEntry'; -(function run() { +(function run(): void { const argvObj = Utils.parseCliOptions(process.argv); runTool(Tools.DepGraph, argvObj); })(); \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/AbilityInterface.ts b/ets2panda/linter/homecheck/src/utils/checker/AbilityInterface.ts index 0055d844d56ee185f5c3bf0fc88340e503503f6d..8ec07bce61ea0639ce9662916ec9e24a4d34639e 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/AbilityInterface.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/AbilityInterface.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/utils/checker/BytesUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/BytesUtils.ts index 4be9d506a17c13bcac517b0776cc8a3afbc4194c..3da521fffc187e79ce34c6f41b1be86fdacab248 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/BytesUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/BytesUtils.ts @@ -18,40 +18,40 @@ export const toUTF8String = ( input: Uint8Array, start = 0, end = input.length -) => decoder.decode(input.slice(start, end)); +): string => decoder.decode(input.slice(start, end)); export const toHexString = ( input: Uint8Array, start = 0, end = input.length -) => input.slice(start, end).reduce((memo, i) => memo + `0${i.toString(16)}`.slice(-2), ''); +): string => input.slice(start, end).reduce((memo, i) => memo + `0${i.toString(16)}`.slice(-2), ''); const getView = ( input: Uint8Array, offset: number -) => new DataView(input.buffer, input.byteOffset + offset); +): DataView => new DataView(input.buffer, input.byteOffset + offset); -export const readInt16LE = (input: Uint8Array, offset = 0) => +export const readInt16LE = (input: Uint8Array, offset = 0): number => getView(input, offset).getInt16(0, true); -export const readUInt16BE = (input: Uint8Array, offset = 0) => +export const readUInt16BE = (input: Uint8Array, offset = 0): number => getView(input, offset).getUint16(0, false); -export const readUInt16LE = (input: Uint8Array, offset = 0) => +export const readUInt16LE = (input: Uint8Array, offset = 0): number => getView(input, offset).getUint16(0, true); -export const readUInt24LE = (input: Uint8Array, offset = 0) => { +export const readUInt24LE = (input: Uint8Array, offset = 0): number => { const view = getView(input, offset); return view.getUint16(0, true) + (view.getUint8(2) << 16); }; -export const readInt32LE = (input: Uint8Array, offset = 0) => +export const readInt32LE = (input: Uint8Array, offset = 0): number => getView(input, offset).getInt32(0, true); -export const readUInt32BE = (input: Uint8Array, offset = 0) => +export const readUInt32BE = (input: Uint8Array, offset = 0): number => getView(input, offset).getUint32(0, false); -export const readUInt32LE = (input: Uint8Array, offset = 0) => +export const readUInt32LE = (input: Uint8Array, offset = 0): number => getView(input, offset).getUint32(0, true); export const readUInt64 = ( @@ -65,7 +65,7 @@ const methods = { readUInt16LE, readUInt32BE, readUInt32LE -} as const +} as const; type MethodName = keyof typeof methods; @@ -92,7 +92,7 @@ const units: Record = { pc: 96 / 72 / 12, pt: 96 / 72, px: 1, -} +}; const unitsReg = new RegExp(`^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join('|')})?$`,); export function getLength(len: string): number | undefined { diff --git a/ets2panda/linter/homecheck/src/utils/checker/CheckerUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/CheckerUtils.ts index 97e7ff487a190c7ac4ac617b47c9269d09442f40..58d2028b5fdc0911feae53c40dde01ef9a7cfdaa 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/CheckerUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/CheckerUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/utils/checker/ImageUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/ImageUtils.ts index bd90155706f226aeda04d0ce5c2a4af78c8df819..f4d35c24646f0c3f4d5ce7b40ad30b5a65cf006e 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/ImageUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/ImageUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -42,7 +42,7 @@ const keys = Object.keys(typeHandlers) as imageType[]; export function readImageInfo(filePath: string): ImageInfo | undefined { const input = readFileSync(filePath); - if (!input) return undefined; + if (!input) { return undefined; } const type = detector(input); if (typeof type === 'undefined') { return undefined; @@ -91,7 +91,7 @@ function detector(input: Uint8Array): imageType | undefined { return type; } } - const finder = (key: imageType) => typeHandlers[key].validate(input); + const finder = (key: imageType): boolean => typeHandlers[key].validate(input); return keys.find(finder); } catch (error) { return undefined; diff --git a/ets2panda/linter/homecheck/src/utils/checker/NumberUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/NumberUtils.ts index c8cc62f88e9c411f386ad826fc5c65b5e9f963d1..4afca0d4f3b5027fcf7abf9c6c493b24e95818ad 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/NumberUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/NumberUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,16 +13,16 @@ * limitations under the License. */ -import { AbstractExpr, ArkAssignStmt, ArkFile, ArkNormalBinopExpr, ArkStaticFieldRef, ArkUnopExpr, ClassSignature, Constant, ImportInfo, Local, NumberType, Stmt, Value } from "arkanalyzer"; -import { VarInfo } from "../../model/VarInfo"; -import { CheckerStorage } from "../common/CheckerStorage"; -import { NumberValue, ValueType } from "../../model/NumberValue"; -import { StmtExt } from "../../model/StmtExt"; +import { AbstractExpr, ArkAssignStmt, ArkFile, ArkNormalBinopExpr, ArkStaticFieldRef, ArkUnopExpr, ClassSignature, Constant, ImportInfo, Local, NumberType, Stmt, Value } from 'arkanalyzer'; +import { VarInfo } from '../../model/VarInfo'; +import { CheckerStorage } from '../common/CheckerStorage'; +import { NumberValue, ValueType } from '../../model/NumberValue'; +import { StmtExt } from '../../model/StmtExt'; export class NumberUtils { - public static readonly mBinopList: string[] = ["+", "-", "*", "/", "%", "<<", ">>", "&", "|", "^", ">>>"]; + public static readonly mBinopList: string[] = ['+', '-', '*', '/', '%', '<<', '>>', '&', '|', '^', '>>>']; - private static isSupportOperator(operator: string) { + private static isSupportOperator(operator: string): boolean { return this.mBinopList.includes(operator); } @@ -39,12 +39,12 @@ export class NumberUtils { } else if (value instanceof AbstractExpr && value.getType() instanceof NumberType) { return NumberUtils.isExprSupportCalculate(arkFile, valueStmtInfo, value); } else if (value instanceof ArkStaticFieldRef && value.getType() instanceof NumberType) { - return true + return true; } return false; } - private static isExprSupportCalculate(arkFile: ArkFile, valueStmtInfo: VarInfo, value: AbstractExpr) { + private static isExprSupportCalculate(arkFile: ArkFile, valueStmtInfo: VarInfo, value: AbstractExpr): boolean { if (value instanceof ArkNormalBinopExpr && this.isSupportOperator(value.getOperator())) { return NumberUtils.isValueSupportCalculation(arkFile, valueStmtInfo, value.getOp1()) && NumberUtils.isValueSupportCalculation(arkFile, valueStmtInfo, value.getOp2()); @@ -94,7 +94,7 @@ export class NumberUtils { return false; } - private static isImportValueSupportCalculate(arkFile: ArkFile, importInfo: ImportInfo, value: Local) { + private static isImportValueSupportCalculate(arkFile: ArkFile, importInfo: ImportInfo, value: Local): boolean { let exportInfo = importInfo.getLazyExportInfo(); let importArkFile = exportInfo?.getDeclaringArkFile(); if (!importArkFile) { @@ -106,7 +106,7 @@ export class NumberUtils { } for (let varDef of scope.defList) { if (varDef.getName() !== value.getName()) { - continue + continue; } let stmt = varDef.defStmt; if (stmt instanceof ArkAssignStmt) { @@ -118,10 +118,10 @@ export class NumberUtils { return false; } - private static getValueImportInfo(arkFile: ArkFile, value: Local) { + private static getValueImportInfo(arkFile: ArkFile, value: Local): any { let importInfos = arkFile.getImportInfos(); for (let importInfo of importInfos) { - if (importInfo.getImportClauseName() == value.getName()) { + if (importInfo.getImportClauseName() === value.getName()) { return importInfo; } } @@ -133,21 +133,21 @@ export class NumberUtils { let valueStr = value.getValue(); let numberValue = Number(valueStr); if (valueStr.includes('.')) { - return new NumberValue(numberValue, ValueType.DOUBLE) + return new NumberValue(numberValue, ValueType.DOUBLE); } else { - return new NumberValue(numberValue, ValueType.INT) + return new NumberValue(numberValue, ValueType.INT); } } else if (value instanceof Local) { let importInfo = this.getValueImportInfo(arkFile, value); if (importInfo) { - return this.getImportNumberValue(arkFile, importInfo, value) + return this.getImportNumberValue(arkFile, importInfo, value); } else { - return this.getMethodNumberValue(arkFile, valueStmtInfo, value) + return this.getMethodNumberValue(arkFile, valueStmtInfo, value); } } else if (value instanceof AbstractExpr && value.getType() instanceof NumberType) { - return this.getExprNumberValue(arkFile, valueStmtInfo, value) + return this.getExprNumberValue(arkFile, valueStmtInfo, value); } else if (value instanceof ArkStaticFieldRef && value.getType() instanceof NumberType) { - return this.getStaticNumberValue(arkFile, valueStmtInfo, value) + return this.getStaticNumberValue(arkFile, valueStmtInfo, value); } return new NumberValue(0, ValueType.UNKNOWN); } @@ -170,7 +170,7 @@ export class NumberUtils { if (stmt instanceof ArkAssignStmt) { let defStmtInfo = new VarInfo(stmt, scope); let rightOp = stmt.getRightOp(); - return this.getNumberByScope(importArkFile, defStmtInfo, rightOp) + return this.getNumberByScope(importArkFile, defStmtInfo, rightOp); } } return new NumberValue(0, ValueType.UNKNOWN); @@ -204,18 +204,18 @@ export class NumberUtils { let stmt = nearReDefStmtInfo.stmt; if (stmt instanceof ArkAssignStmt) { let rightOp = stmt.getRightOp(); - return this.getNumberByScope(arkFile, nearReDefStmtInfo, rightOp) + return this.getNumberByScope(arkFile, nearReDefStmtInfo, rightOp); } } if (!hasFind && scope.parentScope != null) { let defStmtInfo = new VarInfo(valueStmt, scope.parentScope); - return this.getNumberByScope(arkFile, defStmtInfo, value) + return this.getNumberByScope(arkFile, defStmtInfo, value); } return new NumberValue(0, ValueType.UNKNOWN); } - private static getExprNumberValue(arkFile: ArkFile, stmeInfo: VarInfo, value: AbstractExpr) { + private static getExprNumberValue(arkFile: ArkFile, stmeInfo: VarInfo, value: AbstractExpr): NumberValue { if (value instanceof ArkNormalBinopExpr) { if (this.isSupportOperator(value.getOperator())) { let valueOfOp1 = this.getNumberByScope(arkFile, stmeInfo, value.getOp1()); @@ -258,7 +258,7 @@ export class NumberUtils { return new NumberValue(0, ValueType.UNKNOWN); } - private static getStaticNumberValue(arkFile: ArkFile, valueStmtInfo: VarInfo, value: ArkStaticFieldRef) { + private static getStaticNumberValue(arkFile: ArkFile, valueStmtInfo: VarInfo, value: ArkStaticFieldRef): NumberValue { let classSignature = value.getFieldSignature().getDeclaringSignature(); if (!(classSignature instanceof ClassSignature)) { return new NumberValue(0, ValueType.UNKNOWN); @@ -284,7 +284,7 @@ export class NumberUtils { } let stmt = stmts[0]; - new VarInfo(stmt, (stmt as StmtExt).scope) + new VarInfo(stmt, (stmt as StmtExt).scope); if (!(stmt instanceof ArkAssignStmt)) { return new NumberValue(0, ValueType.UNKNOWN); } @@ -298,7 +298,7 @@ export class NumberUtils { public static getOriginalValueText(stmt: Stmt, value: Value): string { let valStr = ''; if (value instanceof Constant) { - valStr = value.toString() + valStr = value.toString(); } else if (value instanceof Local) { if (!value.toString().includes('%')) { valStr = value.toString(); @@ -314,13 +314,13 @@ export class NumberUtils { } else { let originalPosition = stmt.getOperandOriginalPosition(value); if (!originalPosition) { - return this.getOriginalValueText(stmt, value.getOp1()) + ' ' + value.getOperator() + ' ' - + this.getOriginalValueText(stmt, value.getOp2()); + return this.getOriginalValueText(stmt, value.getOp1()) + ' ' + value.getOperator() + ' ' + + this.getOriginalValueText(stmt, value.getOp2()); } const text = stmt.getOriginalText(); if (!text || text.length === 0) { - return this.getOriginalValueText(stmt, value.getOp1()) + ' ' + value.getOperator() + ' ' - + this.getOriginalValueText(stmt, value.getOp2()); + return this.getOriginalValueText(stmt, value.getOp1()) + ' ' + value.getOperator() + ' ' + + this.getOriginalValueText(stmt, value.getOp2()); } let startColum = stmt.getOriginPositionInfo().getColNo(); return text.substring(originalPosition.getFirstCol() - startColum, originalPosition.getLastCol() - startColum); diff --git a/ets2panda/linter/homecheck/src/utils/checker/StringUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/StringUtils.ts index 9d2069102764fd8aff33d9f4630b9fb7682a6f6e..f6ddea74b0f2935e8dd38c13ca54f0409d4617f8 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/StringUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/StringUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,12 +13,12 @@ * limitations under the License. */ -import { AbstractExpr, ArkAssignStmt, ArkFile, ArkNormalBinopExpr, ArkStaticFieldRef, ClassSignature, ClassType, Constant, ImportInfo, Local, Stmt, StringType, Value } from "arkanalyzer"; -import { ClassCategory } from "arkanalyzer/lib/core/model/ArkClass"; -import { VarInfo } from "../../model/VarInfo"; -import { StmtExt } from "../../model/StmtExt"; -import { CheckerStorage } from "../common/CheckerStorage"; -import { Scope } from "../../model/Scope"; +import { AbstractExpr, ArkAssignStmt, ArkFile, ArkNormalBinopExpr, ArkStaticFieldRef, ClassSignature, ClassType, Constant, ImportInfo, Local, Stmt, StringType, Value } from 'arkanalyzer'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { VarInfo } from '../../model/VarInfo'; +import { StmtExt } from '../../model/StmtExt'; +import { CheckerStorage } from '../common/CheckerStorage'; +import { Scope } from '../../model/Scope'; export class StringUtils { public static getStringByScope(arkFile: ArkFile, valueStmtInfo: VarInfo, value: Value): string { diff --git a/ets2panda/linter/homecheck/src/utils/checker/TypeUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/TypeUtils.ts index f535e04f4878bcc1ff47d23cdb558cdd4403c844..d592f86fc190bf570e63918c71fd55182d82a6e8 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/TypeUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/TypeUtils.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { AliasType, ArrayType, ClassType, FunctionType, GenericType, TupleType, Type, UnclearReferenceType, UnionType } from "arkanalyzer"; +import { AliasType, ArrayType, ClassType, FunctionType, GenericType, TupleType, Type, UnclearReferenceType, UnionType } from 'arkanalyzer'; /** * 检查类型是否为指定类型 diff --git a/ets2panda/linter/homecheck/src/utils/checker/ViewTreeTool.ts b/ets2panda/linter/homecheck/src/utils/checker/ViewTreeTool.ts index b69f6e7b0ebc9ca3b6df9fcbdea3fba478d0dd3f..b0efc7e602205375faa7644acd9ba6927adda6d0 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/ViewTreeTool.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/ViewTreeTool.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ViewTreeNode } from "arkanalyzer" -import { ArkClass } from "arkanalyzer" +import { ViewTreeNode } from 'arkanalyzer'; +import { ArkClass } from 'arkanalyzer'; export class ViewTreeTool { - private recordMap: Map + private recordMap: Map; constructor() { this.recordMap = new Map(); diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/bmp.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/bmp.ts index 6a3d40e3594e15896a5706749df971bca9d97452..58a20fcc462a727f2edcd55b791b55d4ab3ecf9e 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/bmp.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/bmp.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/jpg.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/jpg.ts index aaa92f977ac04ed40cc168fbccad0f812aac7ffe..04950560341cde2b4f4b70e4e1b572360e839257 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/jpg.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/jpg.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -33,37 +33,38 @@ function extractSize(input: Uint8Array, index: number): ImageInfo { return { height: readUInt16BE(input, index), width: readUInt16BE(input, index + 2), - } + }; } -function extractOrientation(exifBlock: Uint8Array, isBigEndian: boolean) { +function extractOrientation(exifBlock: Uint8Array, isBigEndian: boolean): number | undefined { const idfOffset = 8; const offset = EXIF_HEADER_BYTES + idfOffset; const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian); - for(let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { + for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES; const end = start + IDF_ENTRY_BYTES; if (start > exifBlock.length) { - return; + return undefined; } const block = exifBlock.slice(start, end); const tagNumber = readUInt(block, 16, 0, isBigEndian); if (tagNumber === 274) { const dataFormat = readUInt(block, 16, 2, isBigEndian); if (dataFormat !== 3) { - return; + return undefined; } const numberOfComponents = readUInt(block, 32, 4, isBigEndian); if (numberOfComponents !== 1) { - return; + return undefined; } return readUInt(block, 16, 8, isBigEndian); } } + return undefined; } -function validateExifBlock(input: Uint8Array, index: number) { +function validateExifBlock(input: Uint8Array, index: number): number | undefined { const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index); const byteAlign = toHexString(exifBlock, EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES); const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN; @@ -71,6 +72,7 @@ function validateExifBlock(input: Uint8Array, index: number) { if (isBigEndian || isLittleEndian) { return extractOrientation(exifBlock, isBigEndian); } + return undefined; } function validateInput(input: Uint8Array, index: number): void { @@ -86,13 +88,13 @@ export const JPG: ImageData = { let input = _input.slice(4); let orientation: number | undefined; let next: number; - while(input.length) { + while (input.length) { const i = readUInt16BE(input, 0); if (input[i] !== 0xff) { input = input.slice(1); continue; } - if(isEXIF(input)) { + if (isEXIF(input)) { orientation = validateExifBlock(input, i); } validateInput(input, i); @@ -106,7 +108,7 @@ export const JPG: ImageData = { height: size.height, orientation, width: size.width, - } + }; } input = input.slice(i + 2); } diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/png.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/png.ts index 3da480305547ec34d3ceacbdc212569dbdd74474..81b12981e46e62e45e12dadb866b7ff0dae22901 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/png.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/png.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -40,11 +40,11 @@ export const PNG: ImageData = { return { height: readUInt32BE(input, 36), width: readUInt32BE(input, 32), - } + }; } return { height: readUInt32BE(input, 20), width: readUInt32BE(input, 16), - } + }; }, }; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/svg.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/svg.ts index ea97b3179e559ab0f0533fc487bf3d4a7a7ff511..7c681289422140334459d7da3e93a24ba39377d5 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/svg.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/svg.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -28,8 +28,8 @@ function parseViewbox(viewbox: string): IAttributes | undefined { const bounds = viewbox.split(' '); let tmpWeight = getLength(bounds[3]); let tmpWidth = getLength(bounds[2]); - if(tmpWidth && tmpWeight) { - return {height: tmpWeight, width: tmpWidth}; + if (tmpWidth && tmpWeight) { + return { height: tmpWeight, width: tmpWidth }; } return undefined; } @@ -46,7 +46,7 @@ function getAttirbutes(root: string): IAttributes | undefined { height: heights && tempHeight, viewbox: viewbox && parseViewbox(viewbox[2]), width: widths && tmpWidth, - } + }; } } return undefined; @@ -56,7 +56,7 @@ function calculateByDimensions(attrs: IAttributes): ImageInfo { return { height: attrs.height as number, width: attrs.width as number, - } + }; } function calculateByViewbox(attrs: IAttributes, viewbox: IAttributes): ImageInfo { @@ -65,17 +65,17 @@ function calculateByViewbox(attrs: IAttributes, viewbox: IAttributes): ImageInfo return { height: attrs.height, width: Math.floor(attrs.height * ratio) - } + }; } else if (attrs.width) { return { height: Math.floor(attrs.width * ratio), width: attrs.width, - } + }; } else { return { height: viewbox.height as number, width: viewbox.width as number, - } + }; } } diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/webp.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/webp.ts index 2c575cc595f236ff95e2f1218a359452e85e5d12..554281816ff323234b677830fa7a3bac33c49178 100644 --- a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/webp.ts +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/webp.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -16,25 +16,25 @@ import type { ImageInfo, ImageData } from '../../../model/Interfaces'; import { readInt16LE, readUInt24LE, toHexString, toUTF8String } from '../BytesUtils'; -function calculateExtended(input: Uint8Array) : ImageInfo { +function calculateExtended(input: Uint8Array): ImageInfo { return { height: 1 + readUInt24LE(input, 7), width: 1 + readUInt24LE(input, 4), - } + }; } function calculateLossLess(input: Uint8Array): ImageInfo { return { height: 1 + (((input[4] & 0xf) << 10) | (input[3] << 2) | ((input[2] & 0xc0) >> 6)), width: 1 + (((input[2] & 0x3f) << 8) | input[1]), - } + }; } function calculateLossy(input: Uint8Array): ImageInfo { return { height: readInt16LE(input, 8) & 0x3fff, width: readInt16LE(input, 6) & 0x3fff, - } + }; } export const WEBP: ImageData = { diff --git a/ets2panda/linter/homecheck/src/utils/common/AfterCheck.ts b/ets2panda/linter/homecheck/src/utils/common/AfterCheck.ts index 72257923bc7811a4daee082238066cfbadd79ad9..762f51232073302fc22b4ccdc80da666537288c8 100644 --- a/ets2panda/linter/homecheck/src/utils/common/AfterCheck.ts +++ b/ets2panda/linter/homecheck/src/utils/common/AfterCheck.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import { FileReports } from "../../Index"; -import { CheckEntry } from "./CheckEntry"; +import { FileReports } from '../../Index'; +import { CheckEntry } from './CheckEntry'; -export async function processAfterCheck(checkEntry: CheckEntry) { +export async function processAfterCheck(checkEntry: CheckEntry): Promise { // 按规则维度统计告警信息,按文件维度汇总告警信息 const fileIssues = checkEntry.sortIssues(); let fileReports: FileReports[] = []; diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckBuilder.ts b/ets2panda/linter/homecheck/src/utils/common/CheckBuilder.ts index cbc34a3e42b82dfe537a2d888f0bc0e4adceba1b..1fa55aca999d6b2d851c879497439d33d1e1a10c 100644 --- a/ets2panda/linter/homecheck/src/utils/common/CheckBuilder.ts +++ b/ets2panda/linter/homecheck/src/utils/common/CheckBuilder.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,17 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; -import { ArkFile } from "arkanalyzer"; -import { Rule, BaseChecker } from "../../Index"; -import { File2Check } from "../../model/File2Check"; -import { Project2Check } from "../../model/Project2Check"; -import { CheckerFactory } from "./CheckerFactory"; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { ArkFile } from 'arkanalyzer'; +import { Rule, BaseChecker } from '../../Index'; +import { File2Check } from '../../model/File2Check'; +import { Project2Check } from '../../model/Project2Check'; +import { CheckerFactory } from './CheckerFactory'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CheckBuilder'); -export function fileCheckBuilder(arkFile: ArkFile, enabledRules: Rule[]) { +export function fileCheckBuilder(arkFile: ArkFile, enabledRules: Rule[]): File2Check { let checkIns = new File2Check(); checkIns.arkFile = arkFile; enabledRules.forEach(rule => { @@ -36,7 +36,7 @@ export function fileCheckBuilder(arkFile: ArkFile, enabledRules: Rule[]) { return checkIns; } -export function projectCheckBuilder(arkFiles: ArkFile[], enabledRules: Rule[]) { +export function projectCheckBuilder(arkFiles: ArkFile[], enabledRules: Rule[]): Project2Check { let checkIns = new Project2Check(); checkIns.arkFiles = arkFiles; enabledRules.forEach(rule => { diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts b/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts index 6b3fa93aa306f811bdacbce9e9ab278e70b911b5..e08dbb90f7327a8e624256650a80fbfc70c3d4fb 100644 --- a/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts +++ b/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,24 +13,24 @@ * limitations under the License. */ -import { Scene } from "arkanalyzer"; -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; -import { SceneConfig } from "arkanalyzer"; -import { fileRuleMapping } from "./FileRuleMapping"; -import { RuleConfig } from "../../model/RuleConfig"; -import { ProjectConfig, SelectedFileInfo } from "../../model/ProjectConfig"; -import { Project2Check } from "../../model/Project2Check"; -import { File2Check } from "../../model/File2Check"; -import { DisableText } from "./Disable"; -import { Message } from "../../model/Message"; -import { FileUtils } from "./FileUtils"; -import { ScopeHelper } from "./ScopeHelper"; -import { RuleListUtil } from "./DefectsList"; -import { FixMode } from "../../model/Fix"; -import { FileIssues, FileReports, IssueReport, engine } from "../../model/Defects"; -import { FixUtils } from "./FixUtils"; -import { FixEngine } from "../../codeFix/FixEngine"; -import { CheckerUtils } from "../checker/CheckerUtils"; +import { Scene } from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { SceneConfig } from 'arkanalyzer'; +import { fileRuleMapping } from './FileRuleMapping'; +import { RuleConfig } from '../../model/RuleConfig'; +import { ProjectConfig, SelectedFileInfo } from '../../model/ProjectConfig'; +import { Project2Check } from '../../model/Project2Check'; +import { File2Check } from '../../model/File2Check'; +import { DisableText } from './Disable'; +import { Message } from '../../model/Message'; +import { FileUtils } from './FileUtils'; +import { ScopeHelper } from './ScopeHelper'; +import { RuleListUtil } from './DefectsList'; +import { FixMode } from '../../model/Fix'; +import { FileIssues, FileReports, IssueReport, engine } from '../../model/Defects'; +import { FixUtils } from './FixUtils'; +import { FixEngine } from '../../codeFix/FixEngine'; +import { CheckerUtils } from '../checker/CheckerUtils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CheckEntry'); @@ -210,12 +210,12 @@ export async function checkEntryBuilder(checkEntry: CheckEntry): Promise file.filePath); if (checkFileList.length === 0) { - checkFileList = FileUtils.getAllFiles(checkEntry.projectConfig.projectPath, ['.ts', '.ets', '.json5']); + checkFileList = FileUtils.getAllFiles(checkEntry.projectConfig.projectPath, ['.ts', '.ets', '.js', '.json5']); } - + // 2、文件过滤和文件级屏蔽处理 checkFileList = await FileUtils.getFiltedFiles(checkFileList, checkEntry.ruleConfig); - logger.info("File count: " + checkFileList.length); + logger.info('File count: ' + checkFileList.length); if (checkFileList.length === 0) { checkEntry.message?.progressNotify(1, 'No file to check.'); return false; @@ -236,7 +236,7 @@ export async function checkEntryBuilder(checkEntry: CheckEntry): Promise = new Map(Object.entries(fileRu export const project2CheckRuleMap: Map = new Map(Object.entries(projectRules)); export class ProxyChecker { - static getClass(ruleId: string) { + static getClass(ruleId: string): any { const checker = file2CheckRuleMap.get(ruleId) ?? project2CheckRuleMap.get(ruleId); if (!checker) { logger.error(`${ruleId} is not matched to any checker`); @@ -51,4 +63,4 @@ export class ProxyChecker { } return new checker(); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckerStorage.ts b/ets2panda/linter/homecheck/src/utils/common/CheckerStorage.ts index e21b994bbbafad44f227db836d97129f7375a91c..f3bedd5017d59910d6579916b5fb00d2a2f1a9c3 100644 --- a/ets2panda/linter/homecheck/src/utils/common/CheckerStorage.ts +++ b/ets2panda/linter/homecheck/src/utils/common/CheckerStorage.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Scope } from "../../model/Scope"; +import { Scope } from '../../model/Scope'; export class CheckerStorage { private static instance: CheckerStorage; @@ -45,7 +45,7 @@ export class CheckerStorage { * 设置Scope映射 * @param scopeMap - Scope映射,类型为 Map */ - public setScopeMap(scopeMap: Map) { + public setScopeMap(scopeMap: Map): void { this.scopeMap = scopeMap; } diff --git a/ets2panda/linter/homecheck/src/utils/common/ConfigUtils.ts b/ets2panda/linter/homecheck/src/utils/common/ConfigUtils.ts index f79ac650d18ff1908b7d26d5011d539050f8480d..79d18b719741c68ef60459e3160cb7b46f1386ee 100644 --- a/ets2panda/linter/homecheck/src/utils/common/ConfigUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/common/ConfigUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,21 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ALERT_LEVEL, ExtRuleSet, Rule } from "../../model/Rule"; -import { FileUtils } from "./FileUtils"; +import { ALERT_LEVEL, ExtRuleSet, Rule } from '../../model/Rule'; +import { FileUtils } from './FileUtils'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { Utils } from "./Utils"; -import { execSync } from "child_process"; -import { Json5parser } from "./Json5parser"; -import { OptionValues } from "commander"; -import { CheckerStorage } from "./CheckerStorage"; -import path from "path"; -import { CheckEntry } from "./CheckEntry"; -import { RuleConfig } from "../../model/RuleConfig"; -import { ProjectConfig } from "../../model/ProjectConfig"; -import { file2CheckRuleMap, project2CheckRuleMap } from "./CheckerIndex"; -import fs from "fs"; -import { Message, MessageType } from "../../model/Message"; +import { Utils } from './Utils'; +import { execSync } from 'child_process'; +import { Json5parser } from './Json5parser'; +import { OptionValues } from 'commander'; +import { CheckerStorage } from './CheckerStorage'; +import path from 'path'; +import { CheckEntry } from './CheckEntry'; +import { RuleConfig } from '../../model/RuleConfig'; +import { ProjectConfig } from '../../model/ProjectConfig'; +import { file2CheckRuleMap, project2CheckRuleMap } from './CheckerIndex'; +import fs from 'fs'; +import { Message, MessageType } from '../../model/Message'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ConfigUtils'); @@ -125,7 +125,7 @@ export class ConfigUtils { // 解析自定义规则集配置 this.parseExtRuleConfig(ruleConfig, projectConfig, message, allRules, ruleMap); - return ruleMap;; + return ruleMap; } /** @@ -197,7 +197,7 @@ export class ConfigUtils { } /** - * 通过单个规则配置生成Rule对象,eg: "@ruleSet/ruleName": "error" | ["error", []...] + * 通过单个规则配置生成Rule对象,eg: '@ruleSet/ruleName': 'error' | ['error', []...] * @param ruleCfg - 规则配置,格式为 [string, any] * @returns Rule | null - 生成的规则对象或 null */ @@ -242,7 +242,7 @@ export class ConfigUtils { */ static isOnlineRule(ruleId: string, allRules: Map): boolean { for (const [ruleSet, rules] of allRules) { - if (rules.hasOwnProperty(ruleId)) { + if (Object.keys(rules).includes(ruleId)) { return true; } } diff --git a/ets2panda/linter/homecheck/src/utils/common/DefectsList.ts b/ets2panda/linter/homecheck/src/utils/common/DefectsList.ts index 4d798e5ddcfbe2930213334f450312baf776b1dc..e21b56f6dea429a4b12c58f22292b70304ef00ff 100644 --- a/ets2panda/linter/homecheck/src/utils/common/DefectsList.ts +++ b/ets2panda/linter/homecheck/src/utils/common/DefectsList.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -7,24 +7,24 @@ * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an 'AS IS' BASIS, + * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Defects } from '../../model/Defects'; -import Logger, { LOG_MODULE_TYPE } from "arkanalyzer/lib/utils/logger"; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CheckEntry'); namespace DefectsList { let defects: Defects[] = []; - export function add(defect: Defects) { + export function add(defect: Defects): void { defects.push(defect); } - export function updateDefectByIndex(index: number, defect: Defects) { + export function updateDefectByIndex(index: number, defect: Defects): void { defects[index] = defect; } @@ -32,20 +32,20 @@ namespace DefectsList { return defects; } - export function clear() { + export function clear(): void { defects = []; } } export class RuleListUtil { - static push(defect: Defects) { + static push(defect: Defects): void { } - static updateDefect(defect: Defects) { + static updateDefect(defect: Defects): void { } - static printDefects() { + static printDefects(): void { } static isFilter(ruleId: string): boolean { diff --git a/ets2panda/linter/homecheck/src/utils/common/Disable.ts b/ets2panda/linter/homecheck/src/utils/common/Disable.ts index 9ed537c6991fa53c801aa50631569dec908c40b9..e8f86a26181832606afabbf6b5748401fd0220e1 100644 --- a/ets2panda/linter/homecheck/src/utils/common/Disable.ts +++ b/ets2panda/linter/homecheck/src/utils/common/Disable.ts @@ -13,25 +13,36 @@ * limitations under the License. */ -import { IssueReport } from "../../model/Defects"; +import * as fs from 'fs'; +import path from 'path'; +import { IssueReport } from '../../model/Defects'; +import { FileUtils } from '../../Index'; export const DisableText = { - FILE_DISABLE_TEXT: "\/* homecheck-disable *\/", - NEXT_LINE_DISABLE_TEXT: "\/\/ homecheck-disable-next-line ", + FILE_DISABLE_TEXT: '\/* homecheck-disable *\/', + NEXT_LINE_DISABLE_TEXT: '\/\/ homecheck-disable-next-line ', }; -export function filterDisableIssue(lineList: string[], issues: IssueReport[]): IssueReport[] { +export async function filterDisableIssue(lineList: string[], issues: IssueReport[], filePath: string): Promise { let filtedIssues: IssueReport[] = []; - issues.forEach(issue => { + for (const issue of issues) { + // @migration/arkui-data-observation规则的自动修复是在定义处,存在跨文件场景 + const actualFilePath = path.normalize(issue.defect.mergeKey.split('%')[0]); + if (path.normalize(actualFilePath) !== path.normalize(filePath)) { + if (!fs.existsSync(actualFilePath)) { + continue; + } + lineList = await FileUtils.readLinesFromFile(actualFilePath); + } // 有些特殊规则允许返回行列号为0 if (issue.defect.reportLine < 0 || issue.defect.reportLine - 1 > lineList.length) { - return; + continue; } const text = lineList[issue.defect.reportLine - 2]; if (!isDisableIssue(text, issue.defect.ruleId)) { filtedIssues.push(issue); } - }); + } return filtedIssues; } diff --git a/ets2panda/linter/homecheck/src/utils/common/FileRuleMapping.ts b/ets2panda/linter/homecheck/src/utils/common/FileRuleMapping.ts index 548a248142745476430801389b75768fa821e3e7..b78400ff292dbaaab5766115337c445051df003b 100644 --- a/ets2panda/linter/homecheck/src/utils/common/FileRuleMapping.ts +++ b/ets2panda/linter/homecheck/src/utils/common/FileRuleMapping.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,16 +13,16 @@ * limitations under the License. */ -import { ArkFile } from "arkanalyzer"; -import { CheckEntry } from "./CheckEntry"; -import { ConfigUtils } from "./ConfigUtils"; -import { CheckerUtils } from "../checker/CheckerUtils"; -import { file2CheckRuleMap, project2CheckRuleMap } from "./CheckerIndex"; -import { Rule } from "../../model/Rule"; -import { RuleConfig } from "../../model/RuleConfig"; -import { fileCheckBuilder, projectCheckBuilder } from "./CheckBuilder"; +import { ArkFile } from 'arkanalyzer'; +import { CheckEntry } from './CheckEntry'; +import { ConfigUtils } from './ConfigUtils'; +import { CheckerUtils } from '../checker/CheckerUtils'; +import { file2CheckRuleMap, project2CheckRuleMap } from './CheckerIndex'; +import { Rule } from '../../model/Rule'; +import { RuleConfig } from '../../model/RuleConfig'; +import { fileCheckBuilder, projectCheckBuilder } from './CheckBuilder'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { FileUtils } from "./FileUtils"; +import { FileUtils } from './FileUtils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'fileRuleMapping'); @@ -30,7 +30,7 @@ export async function fileRuleMapping(checkFileList: string[], checkEntry: Check // 获取规则配置文件的规则,除了override const allRulesMap = ConfigUtils.getRuleMap(checkEntry.ruleConfig, checkEntry.projectConfig, checkEntry.message); if (allRulesMap.size === 0) { - checkEntry.message?.progressNotify(1, "No rule to check"); + checkEntry.message?.progressNotify(1, 'No rule to check'); return false; } diff --git a/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts b/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts index 5b32b9f0486de5e1020f1fb05aa02b86143280be..48b06a414dc94e9e5474890f8a89dd32be5116fd 100644 --- a/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,15 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import * as fs from "fs"; -import * as path from "path"; -import { createInterface } from "readline"; -import { DisableText } from "./Disable"; -import { Sdk } from "arkanalyzer/lib/Config"; +import * as fs from 'fs'; +import * as path from 'path'; +import { createInterface, Interface } from 'readline'; +import { DisableText } from './Disable'; +import { Sdk } from 'arkanalyzer/lib/Config'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; import { FileToCheck, ProjectConfig, SelectedFileInfo } from '../../model/ProjectConfig'; -import { RuleConfig } from "../../model/RuleConfig"; -import { GlobMatch } from "./GlobMatch"; +import { RuleConfig } from '../../model/RuleConfig'; +import { GlobMatch } from './GlobMatch'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'FileUtils'); export class FileUtils { @@ -91,8 +91,9 @@ export class FileUtils { let lines: string[] = []; let readLineNo = 1; - let rl = createInterface({ - input: fs.createReadStream(filePath), + const readStream = fs.createReadStream(filePath); + const rl = createInterface({ + input: readStream, crlfDelay: Infinity }); @@ -111,13 +112,36 @@ export class FileUtils { rl.on('line', handleLine); rl.on('close', () => { + readStream.destroy(); resolve(lines); }); rl.on('error', (err) => { + readStream.destroy(); reject(err); }); - }) + + readStream.on('error', (err) => { + rl.close(); + reject(err); + }); + }); + } + + private processHandleLine(lineNo: number | undefined, readLineNo: number, lines: string[], rl: Interface): void { + const handleLine = (line: string): void => { + if (lineNo) { + if (readLineNo === lineNo) { + lines.push(line); + rl.close(); + } + } else { + lines.push(line); + } + readLineNo++; + }; + + rl.on('line', handleLine); } /** @@ -153,15 +177,15 @@ export class FileUtils { public static getFileInfoFromFileList(fileOrFolderList: string[]): SelectedFileInfo[] { const fileInfoList: SelectedFileInfo[] = []; fileOrFolderList.forEach((fileOrFolderPath) => { - if (fs.statSync(fileOrFolderPath).isFile()){ - fileInfoList.push(new FileToCheck(fileOrFolderPath)) - }else { + if (fs.statSync(fileOrFolderPath).isFile()) { + fileInfoList.push(new FileToCheck(fileOrFolderPath)); + } else { const filesInFolder = FileUtils.getAllFiles(fileOrFolderPath, []); filesInFolder.forEach((filePath) => { - fileInfoList.push(new FileToCheck(filePath)) - }) + fileInfoList.push(new FileToCheck(filePath)); + }); } - }) + }); return fileInfoList; } @@ -203,7 +227,7 @@ export class FileUtils { filenameArr.push(realFile); } } - }) + }); return filenameArr; } @@ -268,7 +292,7 @@ export class FileUtils { * @param content 写入的内容 * @param mode 写入模式,不传默认为追加模式 **/ - public static writeToFile(filePath: string, content: string, mode: WriteFileMode = WriteFileMode.APPEND) { + public static writeToFile(filePath: string, content: string, mode: WriteFileMode = WriteFileMode.APPEND): void { const dirName = path.dirname(filePath); if (!fs.existsSync(dirName)) { fs.mkdirSync(dirName, { recursive: true }); diff --git a/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts b/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts index 234825a056853f2e5e42a26874549a0d59806548..3dc2fc66733fdae58cb1bfce65f1c6f142202226 100644 --- a/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts @@ -13,8 +13,15 @@ * limitations under the License. */ -import { ArkClass, ArkFile, ArkMethod, ExportInfo, ImportInfo, Stmt } from "arkanalyzer"; -import { AIFix, FunctionFix, RuleFix } from "../../model/Fix"; +import { ArkClass, ArkFile, ArkMethod, AstTreeUtils, ExportInfo, ImportInfo, Stmt, ts } from 'arkanalyzer'; +import { AIFix, FunctionFix, Range, RuleFix } from '../../model/Fix'; + +export type FixPosition = { + startLine: number, + startCol: number, + endLine: number, + endCol: number +}; export class FixUtils { @@ -26,11 +33,11 @@ export class FixUtils { lineNum = originalPosition.getLineNo(); startColumn = originalPosition.getColNo(); } else if (codeNode instanceof ArkMethod) { - lineNum = codeNode.getLine()?? 0; - startColumn = codeNode.getColumn()?? 0; + lineNum = codeNode.getLine() ?? 0; + startColumn = codeNode.getColumn() ?? 0; } else if (codeNode instanceof ArkClass) { - lineNum = codeNode.getLine()?? 0; - startColumn = codeNode.getColumn()?? 0; + lineNum = codeNode.getLine() ?? 0; + startColumn = codeNode.getColumn() ?? 0; } else if (codeNode instanceof ExportInfo) { let originalPosition = codeNode.getOriginTsPosition(); lineNum = originalPosition.getLineNo(); @@ -46,7 +53,7 @@ export class FixUtils { let lineBreak = this.getTextEof(code); let cnt = 0; if (lineBreak.length > 0) { - for(let index = 1; index !== lineNum; index++) { + for (let index = 1; index !== lineNum; index++) { cnt = code.indexOf(lineBreak, cnt + 1); } } @@ -54,6 +61,125 @@ export class FixUtils { return start; } + // 根据输入的代码片段的起始、结束行列号信息,计算此代码片段在该文件中的起始偏移量、结束偏移量数据 + public static getRangeWithAst(sourceFile: ts.SourceFile, fixPosition: FixPosition): Range { + const startNumber = ts.getPositionOfLineAndCharacter(sourceFile, fixPosition.startLine - 1, fixPosition.startCol - 1); + const endNumber = ts.getPositionOfLineAndCharacter(sourceFile, fixPosition.endLine - 1, fixPosition.endCol - 1); + return [startNumber, endNumber]; + } + + // 根据输入的起始行号信息,计算该行的起始偏移量、结束偏移量数据 + public static getLineRange(sourceFile: ts.SourceFile, lineNumber: number): Range | null { + const lineStarts = sourceFile.getLineStarts(); + + // 验证行号范围 + if (lineNumber < 1 || lineNumber > lineStarts.length) { + return null; + } + + const startPos = lineStarts[lineNumber - 1]; + let endPos: number; + + // 处理文件最后一行 + if (lineNumber === lineStarts.length) { + endPos = sourceFile.text.length; + } else { + endPos = lineStarts[lineNumber] - 1; + } + return [startPos, endPos]; + } + + // 根据给定的起始、结束偏移量数据,获取此段代码片段的源码字符串,位置信息不合法则返回null + public static getSourceWithRange(sourceFile: ts.SourceFile, range: Range): string | null { + const start = range[0]; + const end = range[1]; + if (start < 0 || end > sourceFile.text.length || start > end) { + return null; + } + return sourceFile.text.substring(start, end); + } + + // 根据给定的行号,获取该行的源码字符串,行号不合法则返回null + public static getLineText(sourceFile: ts.SourceFile, lineNumber: number): string | null { + const range = this.getLineRange(sourceFile, lineNumber); + if (range === null) { + return null; + } + + return sourceFile.text.substring(range[0], range[1]); + } + + // 根据给定的行号,获取该行的换行符,获取失败则使用默认的'\n'换行符 + public static getEolSymbol(sourceFile: ts.SourceFile, lineNumber: number): string { + let res = '\n'; + const lineStr = this.getLineText(sourceFile, lineNumber); + if (lineStr === null) { + return res; + } + + const lfIndex = lineStr.indexOf('\n'); + if (lfIndex > 0 && lineStr[lfIndex - 1] === '\r') { + res = '\r\n'; + } + return res; + } + + // 根据给定的行号,获取该行的缩进数量,采用空格缩进时为空格数量,采用tab缩进时为tab数量,行号不合法则返回null + public static getIndentOfLine(sourceFile: ts.SourceFile, lineNumber: number): number | null { + const lineStr = this.getLineText(sourceFile, lineNumber); + if (lineStr === null) { + return null; + } + + const space = ' '; + let res = 0; + for (const char of lineStr) { + if (char === space) { + res++; + } else { + break; + } + } + return res; + } + + // 根据给定的行号,获取该行附近的缩进宽度,采用空格缩进时为空格数量,采用tab缩进时为tab数量,无法找到则返回2 + public static getIndentWidth(sourceFile: ts.SourceFile, lineNumber: number): number { + const lineIndent = FixUtils.getIndentOfLine(sourceFile, lineNumber); + let indentWidth = 0; + + // 从当前行向上寻找最近的缩进量 + let currLineIndent = lineIndent; + let previousLine = lineNumber - 1; + while (indentWidth <= 0 && previousLine > 0 && currLineIndent !== null) { + const previousLineIndent = FixUtils.getIndentOfLine(sourceFile, previousLine); + if (previousLineIndent !== null) { + indentWidth = Math.abs(currLineIndent - previousLineIndent); + } + currLineIndent = previousLineIndent; + previousLine--; + } + if (indentWidth > 0) { + return indentWidth; + } + + // 从当前行向下寻找最近的缩进量 + currLineIndent = lineIndent; + let nextLine = lineNumber + 1; + while (indentWidth <= 0 && nextLine < sourceFile.getLineStarts().length && currLineIndent !== null) { + const nextLineIndent = FixUtils.getIndentOfLine(sourceFile, nextLine); + if (nextLineIndent !== null) { + indentWidth = Math.abs(nextLineIndent - currLineIndent); + } + currLineIndent = nextLineIndent; + nextLine++; + } + if (indentWidth > 0) { + return indentWidth; + } + return 2; + } + public static getTextEof(text: string): string { if (text.includes('\r\n')) { return '\r\n'; @@ -67,18 +193,18 @@ export class FixUtils { } public static isRuleFix(object: any): object is RuleFix { - return typeof object === "object" && 'range' in object && 'text' in object; + return typeof object === 'object' && 'range' in object && 'text' in object; } public static isFunctionFix(object: any): object is FunctionFix { - return typeof object === "object" && 'fix' in object; + return typeof object === 'object' && 'fix' in object; } public static isAIFix(object: any): object is AIFix { - return typeof object === "object" && 'text' in object; + return typeof object === 'object' && 'text' in object; } - public static hasOwnProperty(object: any, key: string): boolean { - return typeof object === "object" && key in object; + public static hasOwnPropertyOwn(object: any, key: string): boolean { + return typeof object === 'object' && key in object; } } diff --git a/ets2panda/linter/homecheck/src/utils/common/GeneratingJsonFile.ts b/ets2panda/linter/homecheck/src/utils/common/GeneratingJsonFile.ts index 33c2b381939a7eae04b166748f03d4031a2b8bff..7df577806fb8c15739047e1125ef398d4f3e1cc8 100644 --- a/ets2panda/linter/homecheck/src/utils/common/GeneratingJsonFile.ts +++ b/ets2panda/linter/homecheck/src/utils/common/GeneratingJsonFile.ts @@ -23,7 +23,7 @@ const severitys: string[] = ['OFF', 'WARN', 'ERROR', 'SUGGESTION']; const FILE_NAMING_RULE = '@hw-stylistic/file-naming-convention'; export class GeneratingJsonFile { - public static generatingJsonFile(filePath: string, fileReports: FileReports[]) { + public static generatingJsonFile(filePath: string, fileReports: FileReports[]): void { const fileDefectInfos = this.format(fileReports); let results: Map = new Map(); for (let fileDefectInfo of fileDefectInfos) { @@ -49,7 +49,7 @@ export class GeneratingJsonFile { const fileDefectInfo: FileDefectInfo = { filePath: fileReport.filePath, defects: [] - } + }; for (const defect of fileReport.defects) { const defectInfo: DefectInfo = { reportLine: defect.reportLine, @@ -59,7 +59,7 @@ export class GeneratingJsonFile { mergeKey: defect.mergeKey, description: defect.description, ruleDocPath: defect.ruleDocPath - } + }; fileDefectInfo.defects.push(defectInfo); } fileDefectInfos.push(fileDefectInfo); @@ -67,7 +67,7 @@ export class GeneratingJsonFile { return fileDefectInfos; } - private static addResult(defect: FileDefectInfo, results: Map) { + private static addResult(defect: FileDefectInfo, results: Map): void { const normalizedPath = path.normalize(defect.filePath).toLocaleLowerCase(); if (!results.has(normalizedPath)) { results.set(normalizedPath, defect); @@ -92,13 +92,13 @@ export class GeneratingJsonFile { }); } - private static format2(results: Map) { + private static format2(results: Map): string { const jsonResults: JsonResult[] = []; for (let result of results) { const oneResult: JsonResult = { filePath: '', messages: [] - } + }; oneResult.filePath = result[1].filePath; let defects = result[1].defects; for (let defect of defects) { @@ -108,7 +108,7 @@ export class GeneratingJsonFile { severity: '', message: '', rule: '', - } + }; oneDefect.line = defect.reportLine; oneDefect.column = defect.reportColumn; oneDefect.severity = defect.severity; diff --git a/ets2panda/linter/homecheck/src/utils/common/GlobMatch.ts b/ets2panda/linter/homecheck/src/utils/common/GlobMatch.ts index c1f25cdc7c18bedcee7d114c4a77382e219eea71..4b45e07d3a533ed5af91b97f6c759428d7a5fe9f 100644 --- a/ets2panda/linter/homecheck/src/utils/common/GlobMatch.ts +++ b/ets2panda/linter/homecheck/src/utils/common/GlobMatch.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -34,14 +34,14 @@ export class GlobMatch { const char = glob[i]; if (char === '*') { if (!isStar) { - regexp += '.*'; // 匹配任意字符序列,包括空字符串。 + regexp += '.*'; // 匹配任意字符序列,包括空字符串。 } isStar = true; continue; } else if (char === '?') { - regexp += '.'; // 匹配任意单个字符。 + regexp += '.'; // 匹配任意单个字符。 } else if (specialChars.has(char)) { - regexp += `\\${char}`; // 转义特殊字符。 + regexp += `\\${char}`; // 转义特殊字符。 } else { regexp += char; } diff --git a/ets2panda/linter/homecheck/src/utils/common/Json5parser.ts b/ets2panda/linter/homecheck/src/utils/common/Json5parser.ts index 78d4ef7bdfbf7a9012aa7f4086b2660d637d4869..712ee7728bed50972d384a777e24413185063451 100644 --- a/ets2panda/linter/homecheck/src/utils/common/Json5parser.ts +++ b/ets2panda/linter/homecheck/src/utils/common/Json5parser.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -13,7 +13,7 @@ * limitations under the License. */ -import { ts } from "arkanalyzer"; +import { ts } from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Json5parser'); @@ -106,7 +106,7 @@ export class Json5parser { * @param file - 所属的 JSON 源文件 * @returns 解析后的数组 */ - private static parseArrayLiteral(node: ts.Expression, file: ts.JsonSourceFile) { + private static parseArrayLiteral(node: ts.Expression, file: ts.JsonSourceFile): unknown[] { const res: unknown[] = []; (node as ts.ArrayLiteralExpression).elements.forEach(n => { res.push(this.parsePropertyInitializer(n, file)); diff --git a/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts b/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts index 9bf9c6526036cddb39e01493a897f213096775aa..4c481600dd009dad67fafa8ca5b435c070501d5d 100644 --- a/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts +++ b/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,12 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ArkArrayRef, ArkAssignStmt, ArkClass, ArkIfStmt, ArkThisRef, BasicBlock, DEFAULT_ARK_METHOD_NAME, Local, Scene, Stmt } from "arkanalyzer"; +import { ArkArrayRef, ArkAssignStmt, ArkClass, ArkIfStmt, ArkThisRef, BasicBlock, DEFAULT_ARK_METHOD_NAME, Local, Scene, Stmt } from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; -import { CheckerStorage, CheckerUtils, Scope, ScopeType, TempLocation } from "../../Index"; -import { Variable } from "../../model/Variable"; -import { VarInfo } from "../../model/VarInfo"; -import { FixUtils } from "./FixUtils"; +import { CheckerStorage, CheckerUtils, Scope, ScopeType, TempLocation } from '../../Index'; +import { Variable } from '../../model/Variable'; +import { VarInfo } from '../../model/VarInfo'; +import { FixUtils } from './FixUtils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ScopeHelper'); @@ -49,7 +49,7 @@ export class ScopeHelper { this.finishBlockSet = new Set(); this.firstBlock = method.getBody()?.getCfg()?.getStartingBlock(); if (!this.firstBlock) { - logger.debug(`${clazz.getName()}::${method.getName()} has no body.`); + logger.trace(`${clazz.getName()}::${method.getName()} has no body.`); continue; } let curScope = firstScope; @@ -84,7 +84,7 @@ export class ScopeHelper { curScope = this.genChildScope(curScope, ScopeType.FOR_CONDITION_TYPE); nextScopeType = ScopeType.UNKNOWN_TYPE; } - if (!FixUtils.hasOwnProperty(stmt, 'scope')) { + if (!FixUtils.hasOwnPropertyOwn(stmt, 'scope')) { Object.defineProperty(stmt, 'scope', { value: curScope }); } if (stmt instanceof ArkAssignStmt && !this.assignStmtProcess(stmt, curScope)) { diff --git a/ets2panda/linter/homecheck/src/utils/common/Utils.ts b/ets2panda/linter/homecheck/src/utils/common/Utils.ts index 555f05ec86ff04e77bbd948ff348f63a09fc7346..3dcd8e695dd64f97ac29613b27d93040d7bcabc1 100644 --- a/ets2panda/linter/homecheck/src/utils/common/Utils.ts +++ b/ets2panda/linter/homecheck/src/utils/common/Utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 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 @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import Logger, {LOG_LEVEL, LOG_MODULE_TYPE} from 'arkanalyzer/lib/utils/logger'; -import {Command, OptionValues} from 'commander'; +import Logger, { LOG_LEVEL, LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { Command, OptionValues } from 'commander'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Utils'); @@ -48,10 +48,17 @@ export class Utils { * 设置日志路径 * @param logPath 日志路径 */ - static setLogPath(logPath: string) { + static setLogPath(logPath: string): void { Logger.configure(logPath, LOG_LEVEL.INFO, LOG_LEVEL.INFO); } + /** + * 设置日志信息,包含路径、arkanalyzer日志级别、homecheck日志级别 + */ + static setLogConfig(logPath: string, aaLevel: LOG_LEVEL, hcLevel: LOG_LEVEL): void { + Logger.configure(logPath, aaLevel, hcLevel); + } + /** * 获取枚举类型的值 * @param value - 枚举值,可以是字符串或数字 @@ -60,7 +67,7 @@ export class Utils { */ static getEnumValues(value: string | number, enumType: any): any { const key = Object.keys(enumType).find(k => k.toLowerCase() === value || enumType[k as string] === value); - return enumType[key as string] + return enumType[key as string]; } /** @@ -78,3 +85,10 @@ export class Utils { return colA - colB; } } + +export type WarnInfo = { + line: number, + startCol: number, + endCol: number, + filePath: string +}; diff --git a/ets2panda/linter/homecheck/vitest.config.ts b/ets2panda/linter/homecheck/vitest.config.ts index fe1725a625d215515ed253b474d67187e7b39f52..211d2a840e8089701e0c9af0b6dce42addf44a8a 100644 --- a/ets2panda/linter/homecheck/vitest.config.ts +++ b/ets2panda/linter/homecheck/vitest.config.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import tsconfigPaths from 'vite-tsconfig-paths' -import { defineConfig } from 'vitest/config' +import tsconfigPaths from 'vite-tsconfig-paths'; +import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { @@ -23,4 +23,4 @@ export default defineConfig({ plugins: [ tsconfigPaths() ] -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/ets2panda/linter/package.json b/ets2panda/linter/package.json index e56918d6e13a0d2a9d5bf5307effb5703bd873c8..73dd2a41801b56968d0cb0ccc2a58ec9b46110bb 100644 --- a/ets2panda/linter/package.json +++ b/ets2panda/linter/package.json @@ -16,15 +16,15 @@ "compile": "npm run tsc", "postcompile": "node scripts/testRunner/post-compile.mjs", "build": "npm run clean && npm run compile && npm run webpack && npm run pack:linter", - "preinstall": "npm install --prefix arkanalyzer && npm install --prefix homecheck", "install-ohos-typescript": "node scripts/install-ohos-typescript-and-homecheck.mjs", "pack:linter": "rimraf bundle && mkdir bundle && npm pack --pack-destination bundle", "pretest": " npm run fix", "test": "npm run test_all && npm run test_ts_import_ets", - "test_all": "npm run testrunner -- -d test/main,test/rules,test/regression,test/extended_features,test/ohmurl,test/interop,test/sdkwhite", + "test_all": "npm run testrunner -- -d test/main,test/rules,test/regression,test/extended_features,test/migration,test/ohmurl,test/interop,test/sdkwhite,test/concurrent,test/builtin", "test_main": "npm run testrunner -- -d test/main", "test_ohmurl": "npm run testrunner -- -d test/ohmurl", "test_interop": "npm run testrunner -- -d test/interop", + "test_concurrent": "npm run testrunner -- -d test/concurrent", "test_rules": "npm run testrunner -- -d test/rules", "test_regression": "npm run testrunner -- -d test/regression", "test_extended_features": "npm run testrunner -- -d test/extended_features", @@ -33,9 +33,9 @@ "test_regression_sdk": "npm run testrunner -- -d test/regression --sdk", "test_rules_sdk": "npm run testrunner -- -d test/rules --sdk", "test_ts_import_ets": "npm run testrunner -- -d test/ts_import_ets/ts --sdk --interop-mode", - "test_migration": "npm run testrunner -- -d test/migrate", + "test_migration": "npm run testrunner -- -d test/migration", "testrunner": "npm run compile && node build/testRunner/TestRunner.js", - "update-tests": "node scripts/update-test-results.mjs test/main test/rules test/regression test/extended_features test/ts_import_ets/ts", + "update-tests": "node scripts/update-test-results.mjs test/main test/rules test/regression test/extended_features test/ts_import_ets/ts test/migration test/ohmurl test/interop test/sdkwhite test/concurrent test/builtin", "eslint-check": "npx eslint .", "eslint-fix": "npm run eslint-check -- --fix", "prettier-fix": "npx prettier --write .", @@ -43,8 +43,11 @@ }, "dependencies": { "commander": "^9.4.0", + "homecheck": "file:./homecheck", "log4js": "^6.4.0", - "yup": "^1.4.0" + "yup": "^1.4.0", + "fs-extra": "11.2.0", + "json5": "2.2.3" }, "devDependencies": { "@eslint/compat": "latest", diff --git a/ets2panda/linter/scripts/install-ohos-typescript-and-homecheck.mjs b/ets2panda/linter/scripts/install-ohos-typescript-and-homecheck.mjs index 0852d74006d8c286c052e80371ba03774cb03d9b..d4271589fe49d4c84f4a1a3d416fad99a9d68f93 100644 --- a/ets2panda/linter/scripts/install-ohos-typescript-and-homecheck.mjs +++ b/ets2panda/linter/scripts/install-ohos-typescript-and-homecheck.mjs @@ -34,13 +34,17 @@ function sleep(waitTime) { function detectOS() { let windowsPlatforms = ['win32', 'win64', 'windows', 'wince'] let linuxPlatforms = ['linux'] + let macosPlatforms = ['darwin'] + let detectedOS = null - const opetaringSystemName = os.platform().toLowerCase() + const operatingSystemName = os.platform().toLowerCase() - if (windowsPlatforms.indexOf(opetaringSystemName) !== -1) { + if (windowsPlatforms.indexOf(operatingSystemName) !== -1) { detectedOS = 'Windows' - } else if (linuxPlatforms.indexOf(opetaringSystemName) !== -1) { + } else if (linuxPlatforms.indexOf(operatingSystemName) !== -1) { detectedOS = 'Linux' + } else if (macosPlatforms.indexOf(operatingSystemName) !== -1) { + detectedOS = 'macOS' } return detectedOS @@ -49,12 +53,12 @@ function detectOS() { function backupPackageJson(dirPath) { const pkgPath = path.join(dirPath, 'package.json') const backupName = `package.json.bak-${Date.now()}` - + if (!fs.existsSync(pkgPath)) { console.error(`[ERROR] package.json not found in ${dirPath}`) process.exit(1) } - + fs.copyFileSync(pkgPath, path.join(dirPath, backupName)) return backupName } @@ -75,25 +79,25 @@ function restorePackageJson(dirPath, backupFile) { function getTypescript(detectedOS) { const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); - + const linter = __dirname + '/..' const third_party = __dirname + '/../third_party' const typescript_dir = third_party + '/third_party_typescript' const arkanalyzer = __dirname + '/../arkanalyzer' const homecheck = __dirname + '/../homecheck' - + if (!fs.existsSync(third_party)) { fs.mkdirSync(third_party); } let branch = process.env.TYPESCRIPT_BRANCH ?? 'master' - if (detectedOS === 'Linux') { + if (detectedOS === 'Linux' || detectedOS === 'macOS') { let timeToWait = 5000 const iterations = 4 if (!fs.existsSync(typescript_dir)) { for (let i = 0; i <= iterations; i++) { - shell.exec(`git clone --depth=1 https://gitee.com/openharmony/third_party_typescript.git ${typescript_dir}`, { stdio: 'ignore', fatal: true } ) + shell.exec(`git clone --depth=1 https://gitee.com/openharmony/third_party_typescript.git -b ${branch} ${typescript_dir}`, { stdio: 'ignore', fatal: true } ) if (fs.existsSync(typescript_dir) || i === iterations) { break; } @@ -131,9 +135,9 @@ function getTypescript(detectedOS) { console.log('OS was detected, but was not expected') exit(1) } - + const npm_typescript_package = shell.exec('npm pack').stdout.trim() - + shell.cd(arkanalyzer) const arkanalyzerBackFile = backupPackageJson(arkanalyzer) shell.exec(`npm install ${typescript_dir}/${npm_typescript_package}`) @@ -141,7 +145,7 @@ function getTypescript(detectedOS) { const npm_arkanalyzer_package = shell.exec('npm pack').stdout.trim() restorePackageJson(arkanalyzer, arkanalyzerBackFile) shell.rm('-rf', 'lib') - + shell.cd(homecheck) const homecheckBackFile = backupPackageJson(homecheck) @@ -154,11 +158,15 @@ function getTypescript(detectedOS) { shell.cd(linter) shell.exec(`npm install --no-save ${typescript_dir}/${npm_typescript_package} ${homecheck}/${npm_homecheck_package}`) - + const node_modules = linter + '/node_modules' - + fs.rmSync(node_modules + '/typescript', {recursive: true, force: true}) - shell.exec(`tar -xzf "${typescript_dir}/${npm_typescript_package}" -C node_modules --strip-components 1 --one-top-level=typescript`) + + const targetDir = path.join('node_modules', 'typescript') + fs.mkdirSync(targetDir, { recursive: true }) + + shell.exec(`tar -xzf "${typescript_dir}/${npm_typescript_package}" -C "${targetDir}" --strip-components 1`) shell.rm(`${typescript_dir}/${npm_typescript_package}`) shell.rm(`${arkanalyzer}/${npm_arkanalyzer_package}`) shell.rm(`${homecheck}/${npm_homecheck_package}`) diff --git a/ets2panda/linter/scripts/update-test-results.mjs b/ets2panda/linter/scripts/update-test-results.mjs index a76bc1b09da43ac06ab122f1c3f41a3e904cfcb7..19cbb231f3a4dfa463d2b016e6e4c92e21c1e661 100644 --- a/ets2panda/linter/scripts/update-test-results.mjs +++ b/ets2panda/linter/scripts/update-test-results.mjs @@ -17,24 +17,26 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; const TS_EXT = ".ts"; -const ETS_EXT = ".ets"; -const TSX_EXT = ".tsx"; -const ETSX_EXT = ".etsx"; const D_TS_EXT = '.d.ts'; +const TSX_EXT = ".tsx"; +const ETS_EXT = ".ets"; class Mode { - static DEFAULT = 1; - static AUTOFIX = 2; - static ARKTS2 = 3; + static DEFAULT = 1; + static AUTOFIX = 2; + static ARKTS2 = 3; + static MIGRATE = 4; } -const RESULT_EXT = []; -RESULT_EXT[Mode.DEFAULT] = '.json'; -RESULT_EXT[Mode.AUTOFIX] = '.autofix.json'; -RESULT_EXT[Mode.ARKTS2] = '.arkts2.json'; +const LINT_RESULT_EXT = []; +LINT_RESULT_EXT[Mode.DEFAULT] = '.json'; +LINT_RESULT_EXT[Mode.AUTOFIX] = '.autofix.json'; +LINT_RESULT_EXT[Mode.ARKTS2] = '.arkts2.json'; +LINT_RESULT_EXT[Mode.MIGRATE] = '.migrate.json'; const DIFF_EXT = '.diff'; const RESULTS_DIR = 'results'; const TEST_ARGS_EXT = '.args.json'; +const MIGRATE_RESULT_SUFFIX = '.migrate'; let testDirs = []; @@ -42,96 +44,138 @@ let testDirs = []; let force_update = false; for (let arg of process.argv.slice(2)) { - if (arg === '--force') - force_update = true; - else - testDirs.push(arg); + if (arg === '--force') + force_update = true; + else + testDirs.push(arg); } -const DEFAULT_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." +const DEFAULT_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." ]; function readJsonFile(filePath) { - try { - let resultFile = fs.readFileSync(filePath).toString(); - return JSON.parse(resultFile); - } catch (error) { - return undefined; - } + try { + let resultFile = fs.readFileSync(filePath).toString(); + return JSON.parse(resultFile); + } catch (error) { + return undefined; + } } function updateTestFile(testDir, testFile) { - let testModes = [Mode.DEFAULT]; - - const testArgsFile = path.join(testDir, testFile + TEST_ARGS_EXT); - if (fs.existsSync(testArgsFile)) { - const testArgs = readJsonFile(testArgsFile); - if (testArgs?.mode?.autofix !== undefined) testModes.push(Mode.AUTOFIX); - if (testArgs?.mode?.arkts2 !== undefined) testModes.push(Mode.ARKTS2); - } - - for (const mode of testModes) { - updateTest(testDir, testFile, mode); - } + let testModes = [Mode.DEFAULT]; + + const testArgsFile = path.join(testDir, testFile + TEST_ARGS_EXT); + if (fs.existsSync(testArgsFile)) { + const testArgs = readJsonFile(testArgsFile); + if (testArgs?.mode?.autofix !== undefined) testModes.push(Mode.AUTOFIX); + if (testArgs?.mode?.arkts2 !== undefined) testModes.push(Mode.ARKTS2); + if (testArgs?.mode?.migrate !== undefined) testModes.push(Mode.MIGRATE); + } + + for (const mode of testModes) { + updateTest(testDir, testFile, mode); + } } function updateTest(testDir, testFile, mode) { - let resultExt = RESULT_EXT[mode]; - let resultFileWithExt = testFile + resultExt; - let resultFilePath = path.join(testDir, resultFileWithExt); - - // Update test result when: - // - '.diff' exists - // - expected '.json' for specified test mode doesn't exist - // - 'force' option is enabled - if (fs.existsSync(resultFilePath) && !fs.existsSync(path.join(testDir, RESULTS_DIR, resultFileWithExt + DIFF_EXT)) && !force_update) { - return; - } - - let expectedResult = readJsonFile(resultFilePath); - - const copyright = expectedResult?.copyright ?? DEFAULT_COPYRIGHT; - - let actualResult = readJsonFile(path.join(testDir, RESULTS_DIR, resultFileWithExt)); - if (!actualResult || !actualResult.result) { - console.log(`Failed to update ${resultFileWithExt}: couldn't process ACTUAL result file.`); - return; - } - - // Write file with actual test results. - let newResultJSON = JSON.stringify({ copyright, result: actualResult.result }, null, 4); + updateLintResult(testDir, testFile, mode); + if (mode === Mode.MIGRATE) { + updateMigrateResult(testDir, testFile); + } +} + +function updateLintResult(testDir, testFile, mode) { + let resultExt = LINT_RESULT_EXT[mode]; + let resultFileWithExt = testFile + resultExt; + let resultFilePath = path.join(testDir, resultFileWithExt); + + // Update test result when: + // - '.diff' exists + // - expected '.json' for specified test mode doesn't exist + // - 'force' option is enabled + if (fs.existsSync(resultFilePath) && !fs.existsSync(path.join(testDir, RESULTS_DIR, resultFileWithExt + DIFF_EXT)) && !force_update) { + return; + } + + let expectedResult = readJsonFile(resultFilePath); + + const copyright = expectedResult?.copyright ?? DEFAULT_COPYRIGHT; + + let actualResult = readJsonFile(path.join(testDir, RESULTS_DIR, resultFileWithExt)); + if (!actualResult || !actualResult.result) { + console.log(`Failed to update ${resultFileWithExt}: couldn't process ACTUAL result file.`); + return; + } + + // Write file with actual test results. + try { + const newResultJSON = JSON.stringify({ copyright, result: actualResult.result }, null, 4); fs.writeFileSync(resultFilePath, newResultJSON); + } + catch (e) { + console.log(`Failed to update ${resultFileWithExt}: ${e.message || e}`); + return; + } + + + console.log(`Updated ${resultFileWithExt}`); +} - console.log(`Updated ${resultFileWithExt}`); +function updateMigrateResult(testDir, testFile) { + let resultExt = MIGRATE_RESULT_SUFFIX + path.extname(testFile); + let resultFileWithExt = testFile + resultExt; + let resultFilePath = path.join(testDir, resultFileWithExt); + + // Update test result when: + // - '.diff' exists + // - expected result file doesn't exist + // - 'force' option is enabled + if (fs.existsSync(resultFilePath) && !fs.existsSync(path.join(testDir, RESULTS_DIR, resultFileWithExt + DIFF_EXT)) && !force_update) { + return; + } + + try { + const actualResultFilePath = path.join(testDir, RESULTS_DIR, resultFileWithExt); + fs.copyFileSync(actualResultFilePath, resultFilePath); + } + catch (e) { + console.log(`Failed to update ${resultFileWithExt}: ${e.message || e}`); + return; + } + + console.log(`Updated ${resultFileWithExt}`); } for (let testDir of testDirs) { - if (!fs.existsSync(path.join(testDir, RESULTS_DIR))) continue; - - // Get tests from test directory. - let testFiles = fs.readdirSync(testDir).filter(x => - (x.trimEnd().endsWith(TS_EXT) && !x.trimEnd().endsWith(D_TS_EXT)) || - x.trimEnd().endsWith(TSX_EXT) || - x.trimEnd().endsWith(ETS_EXT) || - x.trimEnd().endsWith(ETSX_EXT) - ); - - if (!testFiles) continue; - - // Update result for each test: - for (let testFile of testFiles) { - updateTestFile(testDir, testFile); - } + if (!fs.existsSync(path.join(testDir, RESULTS_DIR))) continue; + + // Get tests from test directory. + let testFiles = fs.readdirSync(testDir).filter(x => { + const file = x.trimEnd(); + return ( + (file.endsWith(TS_EXT) && !file.endsWith(D_TS_EXT)) || + file.endsWith(TSX_EXT) || + file.endsWith(ETS_EXT) + ) && !file.endsWith(MIGRATE_RESULT_SUFFIX + path.extname(file)) + }); + + if (!testFiles) continue; + + // Update result for each test: + for (let testFile of testFiles) { + updateTestFile(testDir, testFile); + } } \ No newline at end of file diff --git a/ets2panda/linter/src/cli/CommandLineParser.ts b/ets2panda/linter/src/cli/CommandLineParser.ts index 1c82cf92eb86fc991271da623118aa1418ffed31..d7af2c1be3d1a9287db9411d448923deb2566b28 100644 --- a/ets2panda/linter/src/cli/CommandLineParser.ts +++ b/ets2panda/linter/src/cli/CommandLineParser.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -16,6 +16,7 @@ import { Logger } from '../lib/Logger'; import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import { ARKTS_IGNORE_DIRS_OH_MODULES } from '../lib/utils/consts/ArktsIgnorePaths'; import type { OptionValues } from 'commander'; import { Command, Option } from 'commander'; import * as ts from 'typescript'; @@ -25,6 +26,7 @@ import * as path from 'node:path'; const TS_EXT = '.ts'; const TSX_EXT = '.tsx'; const ETS_EXT = '.ets'; +const JS_EXT = '.js'; interface CommanderParseOptions { exitOnFail?: boolean; @@ -43,6 +45,9 @@ interface ParsedCommand { const getFiles = (dir: string): string[] => { const resultFiles: string[] = []; + if (dir.includes(ARKTS_IGNORE_DIRS_OH_MODULES)) { + return []; + } const files = fs.readdirSync(dir); for (let i = 0; i < files.length; ++i) { @@ -51,7 +56,7 @@ const getFiles = (dir: string): string[] => { resultFiles.push(...getFiles(name)); } else { const extension = path.extname(name); - if (extension === TS_EXT || extension === TSX_EXT || extension === ETS_EXT) { + if (extension === TS_EXT || extension === TSX_EXT || extension === ETS_EXT || extension === JS_EXT) { resultFiles.push(name); } } @@ -87,18 +92,36 @@ function parseCommand(program: Command, cmdArgs: string[]): ParsedCommand { }; } -function formOptionPaths(cmdlOptions: CommandLineOptions, options: OptionValues): CommandLineOptions { - const opts = cmdlOptions; - if (options.sdkExternalApiPath) { - opts.sdkExternalApiPath = options.sdkExternalApiPath; +function formSdkOptions(cmdOptions: CommandLineOptions, commanderOpts: OptionValues): void { + if (commanderOpts.sdkExternalApiPath) { + cmdOptions.sdkExternalApiPath = commanderOpts.sdkExternalApiPath; } - if (options.sdkDefaultApiPath) { - opts.sdkDefaultApiPath = options.sdkDefaultApiPath; + if (commanderOpts.sdkDefaultApiPath) { + cmdOptions.sdkDefaultApiPath = commanderOpts.sdkDefaultApiPath; } - if (options.arktsWholeProjectPath) { - opts.arktsWholeProjectPath = options.arktsWholeProjectPath; + if (commanderOpts.arktsWholeProjectPath) { + cmdOptions.arktsWholeProjectPath = commanderOpts.arktsWholeProjectPath; + } +} + +function formMigrateOptions(cmdOptions: CommandLineOptions, commanderOpts: OptionValues): void { + if (commanderOpts.migrate) { + cmdOptions.linterOptions.migratorMode = true; + cmdOptions.linterOptions.enableAutofix = true; + } + if (commanderOpts.migrationBackupFile === false) { + cmdOptions.linterOptions.noMigrationBackupFile = true; + } + if (commanderOpts.migrationMaxPass) { + const num = Number(commanderOpts.migrationMaxPass); + cmdOptions.linterOptions.migrationMaxPass = isNaN(num) ? 0 : num; + } + if (commanderOpts.migrationReport) { + cmdOptions.linterOptions.migrationReport = true; + } + if (commanderOpts.arktsWholeProjectPath) { + cmdOptions.linterOptions.wholeProjectPath = commanderOpts.arktsWholeProjectPath; } - return opts; } function formCommandLineOptions(parsedCmd: ParsedCommand): CommandLineOptions { @@ -114,7 +137,7 @@ function formCommandLineOptions(parsedCmd: ParsedCommand): CommandLineOptions { opts.logTscErrors = true; } if (options.devecoPluginMode) { - opts.linterOptions.ideMode = true; + opts.devecoPluginModeDeprecated = true; } if (options.checkTsAsSource !== undefined) { opts.linterOptions.checkTsAsSource = options.checkTsAsSource; @@ -140,14 +163,15 @@ function formCommandLineOptions(parsedCmd: ParsedCommand): CommandLineOptions { if (options.ideInteractive) { opts.linterOptions.ideInteractive = true; } - if (options.migrate !== undefined) { - opts.linterOptions.migratorMode = options.migrate; - opts.linterOptions.enableAutofix = true; + if (options.checkTsAndJs) { + opts.linterOptions.checkTsAndJs = true; } if (options.homecheck) { opts.homecheck = true; } - return formOptionPaths(opts, options); + formSdkOptions(opts, options); + formMigrateOptions(opts, options); + return opts; } function createCommand(): Command { @@ -161,7 +185,6 @@ function createCommand(): Command { program. option('-E, --TSC_Errors', 'show error messages from Tsc'). option('--check-ts-as-source', 'check TS files as source files'). - option('--deveco-plugin-mode', 'run as IDE plugin'). option('-p, --project ', 'path to TS project config file'). option( '-f, --project-folder ', @@ -178,6 +201,10 @@ function createCommand(): Command { option('-w, --arkts-whole-project-path ', 'path to whole project'). option('--migrate', 'run as ArkTS migrator'). option('--homecheck', 'added homecheck rule validation'). + option('--no-migration-backup-file', 'Disable the backup files in migration mode'). + option('--migration-max-pass ', 'Maximum number of migration passes'). + option('--migration-report', 'Generate migration report'). + option('--check-ts-and-js', 'check ts and js files'). addOption(new Option('--warnings-as-errors', 'treat warnings as errors').hideHelp(true)). addOption(new Option('--no-check-ts-as-source', 'check TS files as third-party libary').hideHelp(true)). addOption(new Option('--no-use-rt-logic', 'run linter with SDK logic').hideHelp(true)). diff --git a/ets2panda/linter/src/cli/LinterCLI.ts b/ets2panda/linter/src/cli/LinterCLI.ts index 5738d486629b7617f9ecdc87edff6ec738c87a88..b5e981722115d5e71285605def30368aedf828c3 100644 --- a/ets2panda/linter/src/cli/LinterCLI.ts +++ b/ets2panda/linter/src/cli/LinterCLI.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -21,14 +21,12 @@ import type { CommandLineOptions } from '../lib/CommandLineOptions'; import { lint } from '../lib/LinterRunner'; import { Logger } from '../lib/Logger'; import type { ProblemInfo } from '../lib/ProblemInfo'; -import { TypeScriptLinter } from '../lib/TypeScriptLinter'; import { parseCommandLine } from './CommandLineParser'; -import { compileLintOptions } from './Compiler'; -import type { LinterConfig } from '../lib/LinterConfig'; +import { compileLintOptions, getEtsLoaderPath } from '../lib/ts-compiler/Compiler'; +import { logStatistics } from '../lib/statistics/StatisticsLogger'; import { arkts2Rules } from '../lib/utils/consts/ArkTS2Rules'; -import type { ProblemInfo as HomeCheckProblemInfo } from 'homecheck'; import { MigrationTool } from 'homecheck'; -import { getHomeCheckConfigInfo } from '../lib/HomeCheck'; +import { getHomeCheckConfigInfo, transferIssues2ProblemInfo } from '../lib/HomeCheck'; export function run(): void { const commandLineArgs = process.argv.slice(2); @@ -39,30 +37,32 @@ export function run(): void { const cmdOptions = parseCommandLine(commandLineArgs); - TypeScriptLinter.initGlobals(); - - if (!cmdOptions.linterOptions.ideMode && !cmdOptions.linterOptions.ideInteractive) { - const compileOptions = compileLintOptions(cmdOptions); - const result = lint(compileOptions, getEtsLoaderPath(compileOptions)); - process.exit(result.errorNodes > 0 ? 1 : 0); + if (cmdOptions.devecoPluginModeDeprecated) { + runIdeModeDeprecated(cmdOptions); } else if (cmdOptions.linterOptions.ideInteractive) { - runMigrationCliMode(cmdOptions); + runIdeInteractiveMode(cmdOptions); } else { - runIDEMode(cmdOptions); + const compileOptions = compileLintOptions(cmdOptions); + const result = lint(compileOptions); + logStatistics(result.projectStats); + process.exit(result.hasErrors ? 1 : 0); } } -async function runMigrationCliMode(cmdOptions: CommandLineOptions): Promise { +async function runIdeInteractiveMode(cmdOptions: CommandLineOptions): Promise { + cmdOptions.followSdkSettings = true; + cmdOptions.disableStrictDiagnostics = true; const compileOptions = compileLintOptions(cmdOptions); - const result = lint(compileOptions, getEtsLoaderPath(compileOptions)); - const mergedProblems = new Map(); + let homeCheckResult = new Map(); + const mergedProblems = new Map(); if (cmdOptions.homecheck === true) { const { ruleConfigInfo, projectConfigInfo } = getHomeCheckConfigInfo(cmdOptions); const migrationTool = new MigrationTool(ruleConfigInfo, projectConfigInfo); await migrationTool.buildCheckEntry(); - const homeCheckResult = await migrationTool.start(); + const result = await migrationTool.start(); + homeCheckResult = transferIssues2ProblemInfo(result); for (const [filePath, problems] of homeCheckResult) { if (!mergedProblems.has(filePath)) { mergedProblems.set(filePath, []); @@ -70,30 +70,40 @@ async function runMigrationCliMode(cmdOptions: CommandLineOptions): Promise { - return arkts2Rules.includes(problem.ruleTag); - }); + let filteredProblems = problems; + if (cmdOptions.linterOptions.arkts2) { + filteredProblems = problems.filter((problem) => { + return arkts2Rules.includes(problem.ruleTag); + }); + } mergedProblems.get(filePath)!.push(...filteredProblems); } + const reportData = Object.fromEntries(mergedProblems); + await generateReportFile(reportData); for (const [filePath, problems] of mergedProblems) { - await processSyncOut( - JSON.stringify({ - filePath, - problems - }) + '\n' - ); + const reportLine = JSON.stringify({ filePath, problems }) + '\n'; + await processSyncOut(reportLine); } await processSyncErr('{"content":"report finish","messageType":1,"indictor":1}\n'); process.exit(0); } +async function generateReportFile(reportData): Promise { + const reportFilePath = path.join('scan-report.json'); + try { + await fs.promises.writeFile(reportFilePath, JSON.stringify(reportData, null, 2)); + } catch (error) { + console.error('Error generating report file:', error); + } +} + async function processSyncOut(message: string): Promise { await new Promise((resolve) => { process.stdout.write(message, () => { @@ -131,8 +141,7 @@ function showJSONMessage(problems: ProblemInfo[][]): void { Logger.info(`{"linter messages":${JSON.stringify(jsonMessage)}}`); } -function runIDEMode(cmdOptions: CommandLineOptions): void { - cmdOptions.linterOptions.ideMode = true; +function runIdeModeDeprecated(cmdOptions: CommandLineOptions): void { const tmpFileName = getTempFileName(); // read data from stdin const writeStream = fs.createWriteStream(tmpFileName, { flags: 'w' }); @@ -153,7 +162,7 @@ function runIDEMode(cmdOptions: CommandLineOptions): void { cmdOptions.parsedConfigFile.fileNames.push(tmpFileName); } const compileOptions = compileLintOptions(cmdOptions); - const result = lint(compileOptions, getEtsLoaderPath(compileOptions)); + const result = lint(compileOptions); const problems = Array.from(result.problemsInfos.values()); if (problems.length === 1) { showJSONMessage(problems); @@ -163,8 +172,3 @@ function runIDEMode(cmdOptions: CommandLineOptions): void { fs.unlinkSync(tmpFileName); }); } - -export function getEtsLoaderPath(linterConfig: LinterConfig): string | undefined { - const tsProgram = linterConfig.tscCompiledProgram.getProgram(); - return tsProgram.getCompilerOptions().etsLoaderPath; -} diff --git a/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts b/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..82bf349ba604f6c291540d90ddbdf5d52cd3fea3 --- /dev/null +++ b/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type * as ts from 'typescript'; +import type { LinterOptions } from './LinterOptions'; +import type { ProblemInfo } from './ProblemInfo'; +import type { Autofix } from './autofixes/Autofixer'; +import { FileStatistics } from './statistics/FileStatistics'; +import { TsUtils } from './utils/TsUtils'; +import { cookBookRefToFixTitle } from './autofixes/AutofixTitles'; +import { faultDesc } from './FaultDesc'; +import { TypeScriptLinterConfig } from './TypeScriptLinterConfig'; +import { faultsAttrs } from './FaultAttrs'; +import { cookBookTag } from './CookBookMsg'; +import { FaultID } from './Problems'; +import { ProblemSeverity } from './ProblemSeverity'; + +export abstract class BaseTypeScriptLinter { + problemsInfos: ProblemInfo[] = []; + fileStats: FileStatistics; + tsUtils: TsUtils; + + constructor( + protected readonly tsTypeChecker: ts.TypeChecker, + readonly options: LinterOptions, + protected sourceFile: ts.SourceFile + ) { + this.tsUtils = new TsUtils(this.tsTypeChecker, options); + this.fileStats = new FileStatistics(sourceFile, this.problemsInfos); + } + + protected getLineAndCharacterOfNode(node: ts.Node | ts.CommentRange): ts.LineAndCharacter { + const startPos = TsUtils.getStartPos(node); + const { line, character } = this.sourceFile.getLineAndCharacterOfPosition(startPos); + // TSC counts lines and columns from zero + return { line: line + 1, character: character + 1 }; + } + + abstract lint(): void; + + protected updateFileStats(faultId: number, line: number): void { + this.fileStats.nodeCounters[faultId]++; + this.fileStats.lineCounters[faultId].add(line); + } + + protected static addLineColumnInfoInAutofix( + autofix: Autofix[], + startPos: ts.LineAndCharacter, + endPos: ts.LineAndCharacter + ): Autofix[] { + return autofix?.map((autofixElem) => { + autofixElem.line = startPos.line + 1; + autofixElem.column = startPos.character + 1; + autofixElem.endLine = endPos.line + 1; + autofixElem.endColumn = endPos.character + 1; + return autofixElem; + }); + } + + protected incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { + const [startOffset, endOffset] = TsUtils.getHighlightRange(node, faultId); + const startPos = this.sourceFile.getLineAndCharacterOfPosition(startOffset); + const endPos = this.sourceFile.getLineAndCharacterOfPosition(endOffset); + + const faultDescr = faultDesc[faultId]; + const faultType = TypeScriptLinterConfig.tsSyntaxKindNames[node.kind]; + + const cookBookMsgNum = faultsAttrs[faultId] ? faultsAttrs[faultId].cookBookRef : 0; + const cookBookTg = cookBookTag[cookBookMsgNum]; + const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; + const isMsgNumValid = cookBookMsgNum > 0; + autofix = autofix ? BaseTypeScriptLinter.addLineColumnInfoInAutofix(autofix, startPos, endPos) : autofix; + const badNodeInfo: ProblemInfo = { + line: startPos.line + 1, + column: startPos.character + 1, + endLine: endPos.line + 1, + endColumn: endPos.character + 1, + start: startOffset, + end: endOffset, + type: faultType, + severity: severity, + faultId: faultId, + problem: FaultID[faultId], + suggest: '', + // eslint-disable-next-line no-nested-ternary + rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, + ruleTag: cookBookMsgNum, + autofixable: !!autofix, + autofix: autofix, + autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined + }; + this.problemsInfos.push(badNodeInfo); + this.updateFileStats(faultId, badNodeInfo.line); + + // problems with autofixes might be collected separately + if (this.options.reportAutofixCb && badNodeInfo.autofix) { + this.options.reportAutofixCb(badNodeInfo); + } + } +} diff --git a/ets2panda/linter/src/lib/CommandLineOptions.ts b/ets2panda/linter/src/lib/CommandLineOptions.ts index 6468a283271a1e84d147e89826f94a6a05c9d24d..2e959dff1a4ead96afe8fe18c8546e7c3d976296 100644 --- a/ets2panda/linter/src/lib/CommandLineOptions.ts +++ b/ets2panda/linter/src/lib/CommandLineOptions.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -26,4 +26,7 @@ export interface CommandLineOptions { sdkExternalApiPath?: string[]; arktsWholeProjectPath?: string; homecheck?: boolean; + followSdkSettings?: boolean; + devecoPluginModeDeprecated?: boolean; + disableStrictDiagnostics?: boolean; } diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index 2426d7321f208aa6b3eeb939885da9188a664e31..cd0f7e6fc99b9292cb3fac84fab3903415d3a8d2 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -16,10 +16,6 @@ export const cookBookMsg: string[] = []; export const cookBookTag: string[] = []; -for (let i = 0; i <= 344; i++) { - cookBookMsg[i] = ''; -} - cookBookTag[1] = 'Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)'; cookBookTag[2] = '"Symbol()" API is not supported (arkts-no-symbol)'; @@ -233,24 +229,30 @@ cookBookTag[187] = 'function "Math.pow()" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)'; cookBookTag[189] = 'Numeric semantics is different for integer values (arkts-numeric-semantic)'; cookBookTag[190] = 'Stricter assignments into variables of function type (arkts-incompatible-function-types)'; +cookBookTag[191] = 'ASON is not supported. (arkts-no-need-stdlib-ason)'; cookBookTag[192] = 'Type "void" has no instances.(arkts-limited-void-type)'; cookBookTag[193] = '"void" operator is not supported (arkts-no-void-operator)'; cookBookTag[198] = 'Class TS overloading is not supported(arkts-no-ts-overload)'; +cookBookTag[199] = 'Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)'; cookBookTag[202] = 'Literal types are restricted(arkts-limited-literal-types)'; cookBookTag[203] = 'exponent opartions "**" and "**=" are disabled (arkts-no-exponent-op)'; cookBookTag[206] = '"debugger" is not supported (arkts-no-debugger-stmt)'; cookBookTag[207] = 'Special arguments object inside functions are not supported (arkts-no-arguments-obj)'; cookBookTag[208] = 'Tagged templates are not supported (arkts-no-tagged-templates)'; cookBookTag[209] = 'The index expression must be of a numeric type (arkts-array-index-expr-type)'; -cookBookTag[210] = 'The switch expression type must be of type number,string or enum (arkts-switch-expr)'; +cookBookTag[210] = + 'The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)'; cookBookTag[211] = 'No two case constant expressions have identical values.(arkts-case-expr)'; cookBookTag[212] = 'The index expression must be zero or positive value.(arkts-array-index-negative)'; +cookBookTag[213] = 'Class cannot have static codeblocks. (arkts-class-lazy-import)'; +cookBookTag[214] = 'The Class object does not have a constructor. (arkts-no-arkts-constructor)'; +cookBookTag[215] = 'Array bound not checked. (arkts-runtime-array-check)'; cookBookTag[222] = 'Import for side-effect only is prohibited.(arkts-no-side-effect-import)'; cookBookTag[232] = 'Lazy import is not supported(arkts-no-lazy-import)'; cookBookTag[233] = 'Dynamic import is not supported(arkts-no-dynamic-import)'; cookBookTag[234] = 'Decorators are not supported(arkts-no-ts-decorators)'; cookBookTag[235] = 'Avoid using union types (arkts-common-union-member-access)'; -cookBookTag[236] = 'Method cant\'t override filed in interface implemented (arkts-no-method-overriding-field)'; +cookBookTag[236] = 'Method can\'t override filed in interface implemented (arkts-no-method-overriding-field)'; 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)'; @@ -265,19 +267,36 @@ cookBookTag[257] = cookBookTag[258] = 'Data observation needs to add "@Observed" (arkui-data-observation)'; cookBookTag[259] = 'ArkUI interface should be imported before using (arkui-modular-interface)'; cookBookTag[260] = 'The "@Entry" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)'; +cookBookTag[261] = + 'The "Prop", "StorageProp", and "LocalStorageProp" decorators, as well as the "prop" and "setAndProp" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)'; +cookBookTag[262] = 'The makeObserved function is not supported (arkui-no-makeobserved-function)'; cookBookTag[263] = 'The "@Provide" annotation does not support dynamic parameters (arkui-provide-annotation-parameters)'; -cookBookTag[300] = 'The function type should be explicit (arkts-no-ts-like-function)'; +cookBookTag[264] = 'Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)'; +cookBookTag[265] = 'Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)'; +cookBookTag[266] = 'Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)'; +cookBookTag[267] = 'Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)'; +cookBookTag[268] = 'Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)'; +cookBookTag[269] = + 'Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)'; +cookBookTag[270] = 'Trying to catch JS errors is not permitted (arkts-interop-js2s-js-exception)'; +cookBookTag[271] = 'No support for static dynamic import (arkts-interop-d2s-dynamic-import)'; +cookBookTag[272] = 'No support for static dynamic import (arkts-interop-ts2s-dynamic-import-ts)'; +cookBookTag[273] = 'No support for static dynamic import (arkts-interop-js2s-dynamic-import-js)'; +cookBookTag[274] = + 'The subclass constructor must call the parent class\'s parametered constructor (arkts-subclass-must-call-super-constructor-with-args)'; +cookBookTag[275] = + 'Custom components with custom layout capability need to add the "@Layoutable" decorator (arkui-custom-layout-need-add-decorator)'; +cookBookTag[300] = 'The function type should be explicit (arkts-no-ts-like-function-call)'; cookBookTag[301] = 'Importing from "oh module" requires specifying full path (arkts-ohmurl-full-path)'; cookBookTag[302] = - 'Class type is not compatible with "Object" parameter in interop call (arkts-interop-call-object-param)'; + 'Class type is not compatible with "Object" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)'; cookBookTag[303] = - 'Reflect API usage is not allowed in interop calls when an "Object" parameter receives a class instance (arkts-interop-call-reflect)'; + 'Reflect API usage is not allowed in interop calls when an "Object" parameter receives a class instance (arkts-interop-d2s-static-reflect-on-dynamic-instance)'; cookBookTag[304] = 'Duplicate function name in namespace are not allowed (arkts-no-duplicate-function-name)'; -cookBookTag[305] = 'Typescript class decorators are not allowed (arkts-interop-no-decorators)'; -cookBookTag[306] = 'Cannot access typescript types directly (arkts-interop-access-ts-types)'; -cookBookTag[307] = 'Cannot invoke functions implemented in TypeScript (arkts-interop-ts-function)'; -cookBookTag[308] = 'Type "void" has no instances.(arkts-sdk-limited-void-type)'; +cookBookTag[306] = 'Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)'; +cookBookTag[307] = 'Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)'; +cookBookTag[308] = 'Type "void" has no instances.(sdk-limited-void-type)'; cookBookTag[309] = 'API no longer supports optional methods (sdk-optional-methods)'; cookBookTag[310] = 'Properties in "Sendable" classes and interfaces must have a Sendable data type (sdk-no-sendable-prop-types)'; @@ -286,25 +305,69 @@ cookBookTag[312] = 'Indexed access is not supported for fields (sdk-no-props-by- cookBookTag[313] = 'Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)'; cookBookTag[314] = 'Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)'; -cookBookTag[315] = - 'API path have changed - please update your imports accordingly (arkts-sdk-no-decl-with-duplicate-name)'; -cookBookTag[316] = 'Using typeof as a type is not allowed in this API (arkts-sdk-Type-Query)'; -cookBookTag[319] = 'Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)'; +cookBookTag[315] = 'API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)'; +cookBookTag[316] = 'Using typeof as a type is not allowed in this API (sdk-type-query)'; +cookBookTag[317] = '"use shared" is not supported (arkts-limited-stdlib-no-use-shared)'; +cookBookTag[318] = '"use concurrent" is not supported (arkts-limited-stdlib-no-use-concurrent)'; +cookBookTag[319] = + 'Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)'; cookBookTag[321] = 'Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)'; -cookBookTag[330] = 'Importing directly from "JS" module is not supported (arkts-no-js-import)'; -cookBookTag[331] = 'ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)'; -cookBookTag[332] = 'Properties of interop objects can\'t be accessed directly (arkts-no-js-obj-property)'; -cookBookTag[333] = 'Casting interop JS objects to "number" type is not allowed (arkts-no-js-number-import)'; -cookBookTag[334] = 'The "typeof" expression can\'t be used with interop JS objects (arkts-interop-import-typeof-js)'; -cookBookTag[335] = 'Interop object does not have property num (arkts-interop-does-not-have-num)'; -cookBookTag[336] = 'Binary operations on js objects (arkts-no-js-obj-binary-operation)'; +cookBookTag[322] = 'isConcurrent is not supported (arkts-limited-stdlib-no-support-isConcurrent)'; +cookBookTag[323] = 'Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)'; +cookBookTag[324] = 'Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)'; +cookBookTag[325] = + 'Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)'; +cookBookTag[326] = 'It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)'; +cookBookTag[327] = + 'Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)'; +cookBookTag[328] = + 'Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)'; +cookBookTag[329] = 'Enum cannot get member name by member value (arkts-unsupport-prop-name-from-value)'; +cookBookTag[330] = 'Importing directly from "JS" module is not supported (arkts-interop-js2s-import-js)'; +cookBookTag[331] = 'ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)'; +cookBookTag[332] = 'Properties of interop objects can\'t be accessed directly (arkts-interop-js2s-access-js-prop)'; +cookBookTag[333] = 'Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)'; +cookBookTag[334] = 'The "typeof" expression can\'t be used with interop JS objects (arkts-interop-js2s-typeof-js-type)'; +cookBookTag[335] = 'Interop object does not have property num (arkts-interop-js2s-unary-op)'; +cookBookTag[336] = 'Binary operations on js objects (arkts-interop-js2s-binary-op)'; cookBookTag[337] = - 'Importing data directly from the "JS" module for comparison is not supported (arkts-js-data-compare)'; + 'Importing data directly from the "JS" module for comparison is not supported (arkts-interop-js2s-compare-js-data)'; cookBookTag[338] = - '"JS" objects can\'t be used directly as operands of the equality operators (arkts-js-equality-judgment)'; -cookBookTag[339] = 'Interop objects can\'t be indexed directly (arkts-no-js-index-import)'; -cookBookTag[340] = '"Await" operator can\'t be used with interop objects (arkts-no-import-await)'; -cookBookTag[341] = 'ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)'; -cookBookTag[342] = 'Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)'; -cookBookTag[343] = 'Usage of "instanceof" operator is not allowed with interop objects (arkts-no-import-obj-type)'; -cookBookTag[344] = 'Interop objects can\'t be incremented or decremented (arkts-no-js-obj-increases-decreases)'; + '"JS" objects can\'t be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)'; +cookBookTag[339] = 'Interop objects can\'t be indexed directly (arkts-interop-js2s-access-js-index)'; +cookBookTag[340] = '"Await" operator can\'t be used with interop objects (arkts-interop-js2s-await-js-promise)'; +cookBookTag[341] = 'ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)'; +cookBookTag[342] = + 'Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)'; +cookBookTag[343] = + 'Usage of "instanceof" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)'; +cookBookTag[344] = 'Interop objects can\'t be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)'; +cookBookTag[345] = 'Using thisArgs as a type is not allowed in this API (arkts-builtin-thisArgs)'; +cookBookTag[346] = 'Using "Symbol.iterator" is not allowed in this API (arkts-builtin-symbol-iterator)'; +cookBookTag[347] = 'Not support propertydescriptor (arkts-builtin-no-property-descriptor)'; +cookBookTag[348] = 'API is not support ctor signature and func (arkts-builtin-cotr)'; +cookBookTag[349] = 'SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)'; +cookBookTag[350] = + 'The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)'; +cookBookTag[351] = + 'The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)'; +cookBookTag[355] = 'Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)'; +cookBookTag[356] = 'Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)'; +cookBookTag[357] = 'Worker are not supported(arkts-no-need-stdlib-worker)'; +cookBookTag[358] = + 'Using "Object.getOwnPropertyNames" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))'; +cookBookTag[359] = '"@LocalBuilder" Decorator is not supported (arkui-no-localbuilder-decorator)'; +cookBookTag[370] = 'Sparse array are not supported (arkts-no-sparse-array)'; +cookBookTag[371] = 'Enum prop as type are not supported (arkts-no-enum-prop-as-type)'; +cookBookTag[372] = 'Smart type differences (arkts-no-ts-like-smart-type)'; +cookBookTag[373] = 'Array types follow the principle of invariance (arkts-array-type-immutable)'; +cookBookTag[374] = 'ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)'; +cookBookTag[375] = 'TS catch type are not supported (arkts-no-ts-like-catch-type)'; +cookBookTag[376] = 'Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)'; +cookBookTag[377] = + 'Non-decimal BigInt literals (0x/0o/0b) are not supported. Use decimal format instead (arkts-only-support-decimal-bigint-literal)'; +cookBookTag[378] = 'Operator is not support (arkts-unsupport-operator)'; + +for (let i = 0; i <= cookBookTag.length; i++) { + cookBookMsg[i] = ''; +} diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index 42628f67a13b81a9cbce9a51366ba24296b1f762..cc8cb7c2181545288c1c5ee733640c852ebf5c09 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -148,9 +148,11 @@ faultsAttrs[FaultID.DynamicCtorCall] = new FaultAttributes(186); faultsAttrs[FaultID.MathPow] = new FaultAttributes(187); faultsAttrs[FaultID.NumericSemantics] = new FaultAttributes(189); faultsAttrs[FaultID.IncompationbleFunctionType] = new FaultAttributes(190); +faultsAttrs[FaultID.LimitedStdLibNoASON] = new FaultAttributes(191); faultsAttrs[FaultID.LimitedVoidType] = new FaultAttributes(192); faultsAttrs[FaultID.VoidOperator] = new FaultAttributes(193); faultsAttrs[FaultID.TsOverload] = new FaultAttributes(198); +faultsAttrs[FaultID.NoNeedStdLibSendableContainer] = new FaultAttributes(199); faultsAttrs[FaultID.LimitedLiteralType] = new FaultAttributes(202); faultsAttrs[FaultID.ExponentOp] = new FaultAttributes(203); faultsAttrs[FaultID.DebuggerStatement] = new FaultAttributes(206); @@ -160,6 +162,9 @@ faultsAttrs[FaultID.ArrayIndexExprType] = new FaultAttributes(209); faultsAttrs[FaultID.SwitchExpression] = new FaultAttributes(210); faultsAttrs[FaultID.CaseExpression] = new FaultAttributes(211); faultsAttrs[FaultID.IndexNegative] = new FaultAttributes(212); +faultsAttrs[FaultID.NoStaticOnClass] = new FaultAttributes(213); +faultsAttrs[FaultID.NoConstructorOnClass] = new FaultAttributes(214); +faultsAttrs[FaultID.RuntimeArrayCheck] = new FaultAttributes(215); faultsAttrs[FaultID.NoSideEffectImport] = new FaultAttributes(222); faultsAttrs[FaultID.ImportLazyIdentifier] = new FaultAttributes(232); faultsAttrs[FaultID.DynamicImport] = new FaultAttributes(233); @@ -179,13 +184,26 @@ faultsAttrs[FaultID.AnimatableExtendDecoratorTransform] = new FaultAttributes(25 faultsAttrs[FaultID.DataObservation] = new FaultAttributes(258); faultsAttrs[FaultID.UIInterfaceImport] = new FaultAttributes(259); faultsAttrs[FaultID.EntryAnnotation] = new FaultAttributes(260); +faultsAttrs[FaultID.PropDecoratorsAndInterfacesAreNotSupported] = new FaultAttributes(261); +faultsAttrs[FaultID.MakeObservedIsNotSupported] = new FaultAttributes(262); faultsAttrs[FaultID.ProvideAnnotation] = new FaultAttributes(263); +faultsAttrs[FaultID.InteropJsObjectUsage] = new FaultAttributes(264); +faultsAttrs[FaultID.InteropJsObjectInheritance] = new FaultAttributes(265); +faultsAttrs[FaultID.InteropJsObjectTraverseJsInstance] = new FaultAttributes(266); +faultsAttrs[FaultID.InteropJsObjectCallStaticFunc] = new FaultAttributes(267); +faultsAttrs[FaultID.InteropJsObjectConditionJudgment] = new FaultAttributes(268); +faultsAttrs[FaultID.InteropJsObjectExpandStaticInstance] = new FaultAttributes(269); +faultsAttrs[FaultID.InteropJSFunctionInvoke] = new FaultAttributes(270); +faultsAttrs[FaultID.InteropDynamicImport] = new FaultAttributes(271); +faultsAttrs[FaultID.InteropDynamicImportTs] = new FaultAttributes(272); +faultsAttrs[FaultID.InteropDynamicImportJs] = new FaultAttributes(273); +faultsAttrs[FaultID.MissingSuperCall] = new FaultAttributes(274); +faultsAttrs[FaultID.CustomLayoutNeedAddDecorator] = new FaultAttributes(275); faultsAttrs[FaultID.ExplicitFunctionType] = new FaultAttributes(300); faultsAttrs[FaultID.OhmUrlFullPath] = new FaultAttributes(301); faultsAttrs[FaultID.InteropCallObjectParam] = new FaultAttributes(302); faultsAttrs[FaultID.InteropCallReflect] = new FaultAttributes(303); faultsAttrs[FaultID.NoDuplicateFunctionName] = new FaultAttributes(304); -faultsAttrs[FaultID.InteropNoDecorators] = new FaultAttributes(305); faultsAttrs[FaultID.InteropDirectAccessToTSTypes] = new FaultAttributes(306); faultsAttrs[FaultID.InteropTSFunctionInvoke] = new FaultAttributes(307); faultsAttrs[FaultID.LimitedVoidTypeFromSdk] = new FaultAttributes(308); @@ -195,10 +213,20 @@ faultsAttrs[FaultID.ConstructorIfaceFromSdk] = new FaultAttributes(311); faultsAttrs[FaultID.PropertyAccessByIndexFromSdk] = new FaultAttributes(312); faultsAttrs[FaultID.ConstructorTypesDeprecated] = new FaultAttributes(313); faultsAttrs[FaultID.QuotedHyphenPropsDeprecated] = new FaultAttributes(314); -faultsAttrs[FaultID.ApiPathChanged] = new FaultAttributes(315); +faultsAttrs[FaultID.DuplicateDeclNameFromSdk] = new FaultAttributes(315); faultsAttrs[FaultID.SdkTypeQuery] = new FaultAttributes(316); -faultsAttrs[FaultID.InteropJsObjectUsage] = new FaultAttributes(319); +faultsAttrs[FaultID.UseSharedDeprecated] = new FaultAttributes(317); +faultsAttrs[FaultID.UseConcurrentDeprecated] = new FaultAttributes(318); +faultsAttrs[FaultID.MethodInheritRule] = new FaultAttributes(319); faultsAttrs[FaultID.LimitedStdLibNoImportConcurrency] = new FaultAttributes(321); +faultsAttrs[FaultID.IsConcurrentDeprecated] = new FaultAttributes(322); +faultsAttrs[FaultID.InteropJsObjectExport] = new FaultAttributes(323); +faultsAttrs[FaultID.InteropArkTs1ObjectExport] = new FaultAttributes(324); +faultsAttrs[FaultID.DefaultArgsBehindRequiredArgs] = new FaultAttributes(325); +faultsAttrs[FaultID.InteropStaticObjectLiterals] = new FaultAttributes(326); +faultsAttrs[FaultID.InteropObjectLiteralAmbiguity] = new FaultAttributes(327); +faultsAttrs[FaultID.InteropObjectLiteralClass] = new FaultAttributes(328); +faultsAttrs[FaultID.UnsupportPropNameFromValue] = new FaultAttributes(329); faultsAttrs[FaultID.InterOpImportJs] = new FaultAttributes(330); faultsAttrs[FaultID.CallJSFunction] = new FaultAttributes(331); faultsAttrs[FaultID.InteropObjectProperty] = new FaultAttributes(332); @@ -209,8 +237,29 @@ faultsAttrs[FaultID.BinaryOperations] = new FaultAttributes(336); faultsAttrs[FaultID.InterOpImportJsDataCompare] = new FaultAttributes(337); faultsAttrs[FaultID.InteropEqualityJudgment] = new FaultAttributes(338); faultsAttrs[FaultID.InterOpImportJsIndex] = new FaultAttributes(339); -faultsAttrs[FaultID.NoJsImportAwait] = new FaultAttributes(340); +faultsAttrs[FaultID.NoAwaitJsPromise] = new FaultAttributes(340); faultsAttrs[FaultID.InstantiatedJsOjbect] = new FaultAttributes(341); faultsAttrs[FaultID.InteropCallObjectMethods] = new FaultAttributes(342); faultsAttrs[FaultID.InteropJsInstanceof] = new FaultAttributes(343); faultsAttrs[FaultID.InteropIncrementDecrement] = new FaultAttributes(344); +faultsAttrs[FaultID.BuiltinThisArgs] = new FaultAttributes(345); +faultsAttrs[FaultID.BuiltinSymbolIterator] = new FaultAttributes(346); +faultsAttrs[FaultID.NoPropertyDescriptor] = new FaultAttributes(347); +faultsAttrs[FaultID.BuiltinNoCtorFunc] = new FaultAttributes(348); +faultsAttrs[FaultID.SharedArrayBufferDeprecated] = new FaultAttributes(349); +faultsAttrs[FaultID.SetCloneListDeprecated] = new FaultAttributes(350); +faultsAttrs[FaultID.SetTransferListDeprecated] = new FaultAttributes(351); +faultsAttrs[FaultID.LimitedStdLibNoSendableDecorator] = new FaultAttributes(355); +faultsAttrs[FaultID.LimitedStdLibNoDoncurrentDecorator] = new FaultAttributes(356); +faultsAttrs[FaultID.NoNeedStdlibWorker] = new FaultAttributes(357); +faultsAttrs[FaultID.BuiltinGetOwnPropertyNames] = new FaultAttributes(358); +faultsAttrs[FaultID.LocalBuilderDecoratorNotSupported] = new FaultAttributes(359); +faultsAttrs[FaultID.NosparseArray] = new FaultAttributes(370); +faultsAttrs[FaultID.NoEnumPropAsType] = new FaultAttributes(371); +faultsAttrs[FaultID.NoTsLikeSmartType] = new FaultAttributes(372); +faultsAttrs[FaultID.ArrayTypeImmutable] = new FaultAttributes(373); +faultsAttrs[FaultID.CreatingPrimitiveTypes] = new FaultAttributes(374); +faultsAttrs[FaultID.TsLikeCatchType] = new FaultAttributes(375); +faultsAttrs[FaultID.NumericBigintCompare] = new FaultAttributes(376); +faultsAttrs[FaultID.NondecimalBigint] = new FaultAttributes(377); +faultsAttrs[FaultID.UnsupportOperator] = new FaultAttributes(378); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index 9257b6277277e4a986a4020d646dee977c50edd5..820afd8a222f4ad4e5bcace6d3b68e9815899ce7 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -65,6 +65,9 @@ faultDesc[FaultID.NonDeclarationInNamespace] = 'Non-declaration statements in na faultDesc[FaultID.GeneratorFunction] = 'Generator functions'; faultDesc[FaultID.FunctionContainsThis] = 'Functions containing "this"'; faultDesc[FaultID.PropertyAccessByIndex] = 'property access by index'; +faultDesc[FaultID.NoStaticOnClass] = 'No static blocks on classes'; +faultDesc[FaultID.NoConstructorOnClass] = 'No constructor field on object'; +faultDesc[FaultID.RuntimeArrayCheck] = 'Array bound not checked'; faultDesc[FaultID.JsxElement] = 'JSX Elements'; faultDesc[FaultID.EnumMemberNonConstInit] = 'Enum members with non-constant initializer'; faultDesc[FaultID.ImplementsClass] = 'Class type mentioned in "implements" clause'; @@ -93,6 +96,8 @@ faultDesc[FaultID.ConstAssertion] = '"as const" assertion'; faultDesc[FaultID.ImportAssertion] = 'Import assertion'; faultDesc[FaultID.SpreadOperator] = 'Spread operation'; faultDesc[FaultID.LimitedStdLibApi] = 'Limited standard library API'; +faultDesc[FaultID.LimitedStdLibNoASON] = 'Cannot find symbol ASON.'; +faultDesc[FaultID.NoNeedStdLibSendableContainer] = 'Sendable Containers not supported'; faultDesc[FaultID.ErrorSuppression] = 'Error suppression annotation'; faultDesc[FaultID.StrictDiagnostic] = 'Strict diagnostic'; faultDesc[FaultID.ImportAfterStatement] = 'Import declaration after other declaration or statement'; @@ -156,6 +161,9 @@ faultDesc[FaultID.DoubleDollarBindingNotSupported] = 'Incorrect bidirectional da faultDesc[FaultID.DollarBindingNotSupported] = 'Link decorator passing'; faultDesc[FaultID.ExtendDecoratorNotSupported] = '"@Extend" decorator'; faultDesc[FaultID.MethodOverridingField] = '"Method overriding field" to keep style consistent'; +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.ExplicitFunctionType] = 'Not explicit function type'; faultDesc[FaultID.ClassstaticInitialization] = 'The static properties of a class need to have initial values'; faultDesc[FaultID.AvoidUnionTypes] = 'Union types'; @@ -164,7 +172,9 @@ faultDesc[FaultID.InvalidIdentifier] = 'Invalid identifiers'; faultDesc[FaultID.ExtendsExpression] = 'Extends Expression'; faultDesc[FaultID.NumericSemantics] = 'Numeric semantics'; faultDesc[FaultID.AnimatableExtendDecoratorTransform] = '"@AnimatableExtend" decorator'; -faultDesc[FaultID.InteropJsObjectUsage] = 'Interop JS object usage'; +faultDesc[FaultID.InteropJsObjectExport] = 'Interop JS object export'; +faultDesc[FaultID.InteropArkTs1ObjectExport] = 'Interop ArkTS1.0 object export'; +faultDesc[FaultID.DefaultArgsBehindRequiredArgs] = 'Default parameters before mandatory'; faultDesc[FaultID.NoDuplicateFunctionName] = 'No duplicate function name'; faultDesc[FaultID.OhmUrlFullPath] = 'Require full path file name'; faultDesc[FaultID.UIInterfaceImport] = 'UI interface'; @@ -172,33 +182,72 @@ faultDesc[FaultID.StylesDecoratorNotSupported] = '"@Styles" decorator'; faultDesc[FaultID.DataObservation] = 'Data observation'; faultDesc[FaultID.InteropCallReflect] = 'Interop call with Reflect API'; faultDesc[FaultID.InteropCallObjectParam] = 'Interop call with "Object" parameter'; -faultDesc[FaultID.InteropNoDecorators] = 'Interop decorators not supported'; faultDesc[FaultID.InteropDirectAccessToTSTypes] = 'TS Types Access'; faultDesc[FaultID.InteropTSFunctionInvoke] = 'TS Function Invoke'; faultDesc[FaultID.LimitedVoidTypeFromSdk] = 'Limited void type from sdk'; +faultDesc[FaultID.UseSharedDeprecated] = '"use shared" is not supported'; +faultDesc[FaultID.UseConcurrentDeprecated] = '"use concurrent" is not supported'; +faultDesc[FaultID.MethodInheritRule] = 'Method parameters/returns violate inheritance principles'; faultDesc[FaultID.EntryAnnotation] = '"@Entry" decorator parameter'; faultDesc[FaultID.ProvideAnnotation] = '"@Provide" decorator parameter'; +faultDesc[FaultID.InteropJsObjectUsage] = 'Interop JS object usage'; +faultDesc[FaultID.InteropJsObjectInheritance] = 'Interop JS class inheritance'; +faultDesc[FaultID.InteropJsObjectTraverseJsInstance] = 'Interop JS object traverse usage'; +faultDesc[FaultID.InteropJsObjectCallStaticFunc] = 'Interop JS function usage'; faultDesc[FaultID.OptionalMethodFromSdk] = 'Optional method from sdk'; faultDesc[FaultID.SendablePropTypeFromSdk] = 'ISendable is no longer supported'; faultDesc[FaultID.ConstructorIfaceFromSdk] = 'Construct signatures are not supported in interfaces from sdk'; faultDesc[FaultID.PropertyAccessByIndexFromSdk] = 'property access by index from sdk'; faultDesc[FaultID.ConstructorTypesDeprecated] = 'Constructor funcs'; faultDesc[FaultID.QuotedHyphenPropsDeprecated] = 'Quoted hyphen props deprecated'; -faultDesc[FaultID.ApiPathChanged] = 'API path have changed'; -faultDesc[FaultID.SdkTypeQuery] = 'NO typeof as a type in API'; +faultDesc[FaultID.DuplicateDeclNameFromSdk] = 'The API path has been changed due to the duplicate names in sdk.'; +faultDesc[FaultID.SdkTypeQuery] = 'No typeof as a type in API'; +faultDesc[FaultID.IsConcurrentDeprecated] = 'isConcurrent is not supported'; +faultDesc[FaultID.InteropStaticObjectLiterals] = 'Interop call object literals'; faultDesc[FaultID.LimitedStdLibNoImportConcurrency] = 'Import Concurrency Deprecated'; +faultDesc[FaultID.InteropDynamicImport] = 'Interop import await is not allowed'; +faultDesc[FaultID.InteropDynamicImportTs] = 'Interop import await is not allowed'; +faultDesc[FaultID.InteropDynamicImportJs] = 'Interop import await is not allowed'; +faultDesc[FaultID.MissingSuperCall] = 'Missing super call with args'; faultDesc[FaultID.InterOpImportJs] = 'No JS import'; +faultDesc[FaultID.InteropObjectLiteralAmbiguity] = 'Interop Object Literal ambiguity'; +faultDesc[FaultID.InteropObjectLiteralClass] = 'Interop Object Literal incompatible with class'; +faultDesc[FaultID.UnsupportPropNameFromValue] = 'Enum cannot get member name by value'; faultDesc[FaultID.CallJSFunction] = 'Call JS Function'; faultDesc[FaultID.InteropObjectProperty] = 'Interop property access'; -faultDesc[FaultID.InterOpConvertImport] = 'No import number from js file'; +faultDesc[FaultID.InterOpConvertImport] = 'No import primitive types from js file'; faultDesc[FaultID.InterOpImportJsForTypeOf] = 'TypeOf import from JS'; faultDesc[FaultID.InteropNoHaveNum] = 'Interop obj with "num" property'; faultDesc[FaultID.BinaryOperations] = 'Binary operations on js objects'; faultDesc[FaultID.InterOpImportJsDataCompare] = 'NO js import data compare'; faultDesc[FaultID.InteropEqualityJudgment] = 'Equality operator with JS objects'; faultDesc[FaultID.InterOpImportJsIndex] = 'No js index import'; -faultDesc[FaultID.NoJsImportAwait] = 'No js import await'; faultDesc[FaultID.InstantiatedJsOjbect] = 'Instantiated js ojbect'; faultDesc[FaultID.InteropCallObjectMethods] = 'Interop call methods in object'; faultDesc[FaultID.InteropJsInstanceof] = 'Instanceof operator with interop'; faultDesc[FaultID.InteropIncrementDecrement] = 'Interop increment or decrement'; +faultDesc[FaultID.BuiltinThisArgs] = 'No thisArgs as a type in API'; +faultDesc[FaultID.BuiltinSymbolIterator] = 'No "Symbol.iterator" in API'; +faultDesc[FaultID.NoPropertyDescriptor] = 'Not support property descriptor'; +faultDesc[FaultID.BuiltinNoCtorFunc] = 'Api is not support ctor-signature and call-signature'; +faultDesc[FaultID.SharedArrayBufferDeprecated] = 'SharedArrayBuffer is not supported'; +faultDesc[FaultID.SetCloneListDeprecated] = 'setCloneList is not supported'; +faultDesc[FaultID.SetTransferListDeprecated] = 'setTransferList is not supported'; +faultDesc[FaultID.LimitedStdLibNoSendableDecorator] = 'Limited stdlib no sendable decorator'; +faultDesc[FaultID.LimitedStdLibNoDoncurrentDecorator] = 'Limited stdlib no concurrent decorator'; +faultDesc[FaultID.NoNeedStdlibWorker] = 'No need stdlib worker'; +faultDesc[FaultID.BuiltinGetOwnPropertyNames] = 'No "Object.getOwnPropertyNames" in API'; +faultDesc[FaultID.LocalBuilderDecoratorNotSupported] = '"@LocalBuilder" decorator'; +faultDesc[FaultID.MakeObservedIsNotSupported] = 'MakeObserved is not supported'; +faultDesc[FaultID.PropDecoratorsAndInterfacesAreNotSupported] = 'Prop decorators and interfaces are not supported'; +faultDesc[FaultID.NoEnumPropAsType] = 'No enum prop as type'; +faultDesc[FaultID.NoAwaitJsPromise] = 'No await js promise'; +faultDesc[FaultID.NosparseArray] = 'No sparse array'; +faultDesc[FaultID.NoTsLikeSmartType] = 'No ts like smart type'; +faultDesc[FaultID.ArrayTypeImmutable] = 'Array type immutable'; +faultDesc[FaultID.CreatingPrimitiveTypes] = 'Creating primitive types'; +faultDesc[FaultID.TsLikeCatchType] = 'TS like catch type'; +faultDesc[FaultID.NumericBigintCompare] = 'No Comparison number between bigint'; +faultDesc[FaultID.NondecimalBigint] = 'No non decimal'; +faultDesc[FaultID.UnsupportOperator] = 'Unsupport operator'; +faultDesc[FaultID.CustomLayoutNeedAddDecorator] = 'Custom layout need add decorator'; diff --git a/ets2panda/linter/src/lib/HomeCheck.ts b/ets2panda/linter/src/lib/HomeCheck.ts index 1ebb9fbd7cc625aff65f63e8a3c4500512a0a717..cbbdd29885ad42db46dea51b57d199f5cd37ed22 100644 --- a/ets2panda/linter/src/lib/HomeCheck.ts +++ b/ets2panda/linter/src/lib/HomeCheck.ts @@ -12,7 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +import * as path from 'node:path'; +import type { FileIssues, RuleFix } from 'homecheck'; import type { CommandLineOptions } from './CommandLineOptions'; +import type { ProblemInfo } from './ProblemInfo'; +import { FaultID } from './Problems'; interface RuleConfigInfo { ruleSet: string[]; @@ -36,11 +41,9 @@ export function getHomeCheckConfigInfo(cmdOptions: CommandLineOptions): { } { const languageTags = new Map(); const inputFiles = cmdOptions.inputFiles; - inputFiles.forEach((file) => { - languageTags.set(file, 2); - }); const ruleConfigInfo = { - ruleSet: ['plugin:@migration/all'] + ruleSet: ['plugin:@migration/all'], + files: ['**/*.ets', '**/*.ts', '**/*.js'] }; const projectConfigInfo = { projectName: cmdOptions.arktsWholeProjectPath, @@ -55,3 +58,41 @@ export function getHomeCheckConfigInfo(cmdOptions: CommandLineOptions): { }; return { ruleConfigInfo, projectConfigInfo }; } + +export function transferIssues2ProblemInfo(fileIssuesArray: FileIssues[]): Map { + const result = new Map(); + fileIssuesArray.forEach((fileIssues) => { + fileIssues.issues.forEach((issueReport) => { + const defect = issueReport.defect; + const problemInfo: ProblemInfo = { + line: defect.reportLine, + column: defect.reportColumn, + endLine: defect.reportLine, + endColumn: defect.reportColumn, + start: 0, + end: 0, + type: '', + severity: defect.severity, + faultId: FaultID.LAST_ID, + problem: defect.problem, + suggest: '', + rule: defect.description, + ruleTag: -1, + autofixable: defect.fixable + }; + if (problemInfo.autofixable) { + const fix = issueReport.fix as RuleFix; + const replacementText = fix.text; + const start = fix.range[0]; + const end = fix.range[1]; + problemInfo.autofix = [{ replacementText, start, end }]; + problemInfo.autofixTitle = defect.ruleId; + } + const filePath = path.normalize(defect.mergeKey.split('%')[0]); + const problems = result.get(filePath) || []; + problems.push(problemInfo); + result.set(filePath, problems); + }); + }); + return result; +} diff --git a/ets2panda/linter/src/lib/InteropTypescriptLinter.ts b/ets2panda/linter/src/lib/InteropTypescriptLinter.ts index f171370910a3d2b4ec998ffe4a252624626fc70a..c9247e36eacfe93600fb13fdb7309dabe3cc197b 100644 --- a/ets2panda/linter/src/lib/InteropTypescriptLinter.ts +++ b/ets2panda/linter/src/lib/InteropTypescriptLinter.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -15,21 +15,14 @@ import * as fs from 'fs'; import * as path from 'node:path'; import * as ts from 'typescript'; -import { cookBookTag } from './CookBookMsg'; -import { faultsAttrs } from './FaultAttrs'; -import { faultDesc } from './FaultDesc'; -import { Logger } from './Logger'; -import type { ProblemInfo } from './ProblemInfo'; -import { ProblemSeverity } from './ProblemSeverity'; import { FaultID } from './Problems'; -import { LinterConfig } from './TypeScriptLinterConfig'; -import { cookBookRefToFixTitle } from './autofixes/AutofixTitles'; -import type { Autofix } from './autofixes/Autofixer'; +import { TypeScriptLinterConfig } from './TypeScriptLinterConfig'; import { TsUtils } from './utils/TsUtils'; import { ARKTS_COLLECTIONS_D_ETS, ARKTS_LANG_D_ETS } from './utils/consts/SupportedDetsIndexableTypes'; import { D_ETS, D_TS, ETS, KIT } from './utils/consts/TsSuffix'; import { forEachNodeInSubtree } from './utils/functions/ForEachNodeInSubtree'; import type { LinterOptions } from './LinterOptions'; +import { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; export interface KitSymbol { source: string; @@ -42,24 +35,7 @@ export interface KitInfo { symbols?: KitSymbols; } -export class InteropTypescriptLinter { - totalVisitedNodes: number = 0; - nodeCounters: number[] = []; - lineCounters: number[] = []; - - totalErrorLines: number = 0; - errorLineNumbersString: string = ''; - totalWarningLines: number = 0; - warningLineNumbersString: string = ''; - - problemsInfos: ProblemInfo[] = []; - - tsUtils: TsUtils; - - currentErrorLine: number; - currentWarningLine: number; - - private sourceFile?: ts.SourceFile; +export class InteropTypescriptLinter extends BaseTypeScriptLinter { private isInSdk?: boolean; static kitInfos = new Map(); private static etsLoaderPath?: string; @@ -69,25 +45,15 @@ export class InteropTypescriptLinter { InteropTypescriptLinter.kitInfos = new Map(); } - private initCounters(): void { - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } - } - constructor( - private readonly tsTypeChecker: ts.TypeChecker, - private readonly compileOptions: ts.CompilerOptions, - readonly options: LinterOptions, - etsLoaderPath: string | undefined + tsTypeChecker: ts.TypeChecker, + readonly compileOptions: ts.CompilerOptions, + options: LinterOptions, + sourceFile: ts.SourceFile ) { - this.tsUtils = new TsUtils(this.tsTypeChecker, options); - this.currentErrorLine = 0; - this.currentWarningLine = 0; - InteropTypescriptLinter.etsLoaderPath = etsLoaderPath; - InteropTypescriptLinter.sdkPath = etsLoaderPath ? path.resolve(etsLoaderPath, '../..') : undefined; - this.initCounters(); + super(tsTypeChecker, options, sourceFile); + InteropTypescriptLinter.etsLoaderPath = options.etsLoaderPath; + InteropTypescriptLinter.sdkPath = options.etsLoaderPath ? path.resolve(options.etsLoaderPath, '../..') : undefined; } readonly handlersMap = new Map([ @@ -102,84 +68,9 @@ export class InteropTypescriptLinter { [ts.SyntaxKind.ExportAssignment, this.handleExportAssignment] ]); - private getLineAndCharacterOfNode(node: ts.Node | ts.CommentRange): ts.LineAndCharacter { - const startPos = TsUtils.getStartPos(node); - const { line, character } = this.sourceFile!.getLineAndCharacterOfPosition(startPos); - // TSC counts lines and columns from zero - return { line: line + 1, character: character + 1 }; - } - - incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { - this.nodeCounters[faultId]++; - const { line, character } = this.getLineAndCharacterOfNode(node); - if (this.options.ideMode) { - this.incrementCountersIdeMode(node, faultId, autofix); - } else { - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - Logger.info( - `Warning: ${this.sourceFile!.fileName} (${line}, ${character}): ${faultDescr ? faultDescr : faultType}` - ); - } - this.lineCounters[faultId]++; - switch (faultsAttrs[faultId].severity) { - case ProblemSeverity.ERROR: { - this.currentErrorLine = line; - ++this.totalErrorLines; - this.errorLineNumbersString += line + ', '; - break; - } - case ProblemSeverity.WARNING: { - if (line === this.currentWarningLine) { - break; - } - this.currentWarningLine = line; - ++this.totalWarningLines; - this.warningLineNumbersString += line + ', '; - break; - } - default: - } - } - - private incrementCountersIdeMode(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { - if (!this.options.ideMode) { - return; - } - const [startOffset, endOffset] = TsUtils.getHighlightRange(node, faultId); - const startPos = this.sourceFile!.getLineAndCharacterOfPosition(startOffset); - const endPos = this.sourceFile!.getLineAndCharacterOfPosition(endOffset); - - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - - const cookBookMsgNum = faultsAttrs[faultId] ? faultsAttrs[faultId].cookBookRef : 0; - const cookBookTg = cookBookTag[cookBookMsgNum]; - const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; - const isMsgNumValid = cookBookMsgNum > 0; - const badNodeInfo: ProblemInfo = { - line: startPos.line + 1, - column: startPos.character + 1, - endLine: endPos.line + 1, - endColumn: endPos.character + 1, - start: startOffset, - end: endOffset, - type: faultType, - severity: severity, - problem: FaultID[faultId], - suggest: '', - // eslint-disable-next-line no-nested-ternary - rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, - ruleTag: cookBookMsgNum, - autofix: autofix, - autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined - }; - this.problemsInfos.push(badNodeInfo); - } - private visitSourceFile(sf: ts.SourceFile): void { const callback = (node: ts.Node): void => { - this.totalVisitedNodes++; + this.fileStats.visitedNodes++; const handler = this.handlersMap.get(node.kind); if (handler !== undefined) { @@ -194,7 +85,7 @@ export class InteropTypescriptLinter { if (!node) { return true; } - if (LinterConfig.terminalTokens.has(node.kind)) { + if (TypeScriptLinterConfig.terminalTokens.has(node.kind)) { return true; } return false; @@ -545,8 +436,7 @@ export class InteropTypescriptLinter { kitInfo.symbols[element.name.text].source; } - lint(sourceFile: ts.SourceFile): void { - this.sourceFile = sourceFile; + lint(): void { this.isInSdk = InteropTypescriptLinter.sdkPath ? path.normalize(this.sourceFile.fileName).indexOf(InteropTypescriptLinter.sdkPath) === 0 : false; diff --git a/ets2panda/linter/src/lib/LintRunResult.ts b/ets2panda/linter/src/lib/LintRunResult.ts index d3d6ff56fc1f4674fe07a8d6234c0eeffb883919..3397a3941a433ce685b7daca2e52ca52e2b2d678 100644 --- a/ets2panda/linter/src/lib/LintRunResult.ts +++ b/ets2panda/linter/src/lib/LintRunResult.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -14,8 +14,10 @@ */ import type { ProblemInfo } from './ProblemInfo'; +import type { ProjectStatistics } from './statistics/ProjectStatistics'; export interface LintRunResult { - errorNodes: number; + hasErrors: boolean; problemsInfos: Map; + projectStats: ProjectStatistics; } diff --git a/ets2panda/linter/src/lib/LinterOptions.ts b/ets2panda/linter/src/lib/LinterOptions.ts index d8cc2cdc4655e15d9d96e68a356d95af4a5e7432..f6124ac4ab079343ddac9223baed63f1b58d53ca 100644 --- a/ets2panda/linter/src/lib/LinterOptions.ts +++ b/ets2panda/linter/src/lib/LinterOptions.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -22,7 +22,6 @@ import type { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; // Common options interface, additional fields may be used by plugins export interface LinterOptions { checkTsAsSource?: boolean; - ideMode?: boolean; ideInteractive?: boolean; migratorMode?: boolean; warningsAsErrors?: boolean; @@ -39,4 +38,11 @@ export interface LinterOptions { interopCheckMode?: boolean; compatibleSdkVersion?: number; compatibleSdkVersionStage?: string; + etsLoaderPath?: string; + migrationMaxPass?: number; + migrationFilePathMap?: Map; + noMigrationBackupFile?: boolean; + migrationReport?: boolean; + wholeProjectPath?: string; + checkTsAndJs?: boolean; } diff --git a/ets2panda/linter/src/lib/LinterRunner.ts b/ets2panda/linter/src/lib/LinterRunner.ts index d7950d10d9d2b9283ea0fe28ca7af7867836f52b..532cea2ccadd4e48799cd479f582637d1040d9f5 100644 --- a/ets2panda/linter/src/lib/LinterRunner.ts +++ b/ets2panda/linter/src/lib/LinterRunner.ts @@ -13,19 +13,16 @@ * limitations under the License. */ +import * as fs from 'node:fs'; import * as path from 'node:path'; -import type * as ts from 'typescript'; +import * as ts from 'typescript'; import type { CommandLineOptions } from './CommandLineOptions'; -import { faultsAttrs } from './FaultAttrs'; -import { faultDesc } from './FaultDesc'; import { InteropTypescriptLinter } from './InteropTypescriptLinter'; import type { LinterConfig } from './LinterConfig'; import type { LinterOptions } from './LinterOptions'; import type { LintRunResult } from './LintRunResult'; import { Logger } from './Logger'; import type { ProblemInfo } from './ProblemInfo'; -import { ProblemSeverity } from './ProblemSeverity'; -import { FaultID } from './Problems'; import { TypeScriptLinter } from './TypeScriptLinter'; import { getTscDiagnostics } from './ts-diagnostics/GetTscDiagnostics'; import { transformTscDiagnostics } from './ts-diagnostics/TransformTscDiagnostics'; @@ -34,22 +31,15 @@ import { ARKTS_IGNORE_DIRS_OH_MODULES, ARKTS_IGNORE_FILES } from './utils/consts/ArktsIgnorePaths'; +import { EXTNAME_TS, EXTNAME_JS } from './utils/consts/ExtensionName'; import { mergeArrayMaps } from './utils/functions/MergeArrayMaps'; import { clearPathHelperCache, pathContainsDirectory } from './utils/functions/PathHelper'; import { LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; -import { compileLintOptions } from '../cli/Compiler'; +import type { createProgramCallback } from './ts-compiler/Compiler'; +import { compileLintOptions } from './ts-compiler/Compiler'; import * as qEd from './autofixes/QuasiEditor'; - -export function consoleLog(linterOptions: LinterOptions, ...args: unknown[]): void { - if (linterOptions.ideMode || linterOptions.ideInteractive) { - return; - } - let outLine = ''; - for (let k = 0; k < args.length; k++) { - outLine += `${args[k]} `; - } - Logger.info(outLine); -} +import { ProjectStatistics } from './statistics/ProjectStatistics'; +import type { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { let inputFiles = cmdOptions.inputFiles; @@ -81,28 +71,19 @@ function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { return inputFiles; } -function countProblems(linter: TypeScriptLinter | InteropTypescriptLinter): [number, number] { - let errorNodesTotal = 0; - let warningNodes = 0; - for (let i = 0; i < FaultID.LAST_ID; i++) { - switch (faultsAttrs[i].severity) { - case ProblemSeverity.ERROR: - errorNodesTotal += linter.nodeCounters[i]; - break; - case ProblemSeverity.WARNING: - warningNodes += linter.nodeCounters[i]; - break; - default: - } +export function lint( + config: LinterConfig, + etsLoaderPath?: string, + hcResults?: Map +): LintRunResult { + if (etsLoaderPath) { + config.cmdOptions.linterOptions.etsLoaderPath = etsLoaderPath; } - - return [errorNodesTotal, warningNodes]; + const lintResult = lintImpl(config); + return config.cmdOptions.linterOptions.migratorMode ? migrate(config, lintResult, hcResults) : lintResult; } -let linterConfig: LinterConfig; - -export function lint(config: LinterConfig, etsLoaderPath: string | undefined): LintRunResult { - linterConfig = config; +function lintImpl(config: LinterConfig): LintRunResult { const { cmdOptions, tscCompiledProgram } = config; const tsProgram = tscCompiledProgram.getProgram(); const options = cmdOptions.linterOptions; @@ -122,178 +103,144 @@ export function lint(config: LinterConfig, etsLoaderPath: string | undefined): L const tscStrictDiagnostics = getTscDiagnostics(tscCompiledProgram, srcFiles); LibraryTypeCallDiagnosticChecker.instance.rebuildTscDiagnostics(tscStrictDiagnostics); - const linter = !options.interopCheckMode ? - new TypeScriptLinter(tsProgram.getTypeChecker(), options, tscStrictDiagnostics) : - new InteropTypescriptLinter(tsProgram.getTypeChecker(), tsProgram.getCompilerOptions(), options, etsLoaderPath); - const { errorNodes, problemsInfos } = lintFiles(srcFiles, linter); + const lintResult = lintFiles(tsProgram, srcFiles, options, tscStrictDiagnostics); LibraryTypeCallDiagnosticChecker.instance.clear(); - consoleLog(options, '\n\n\nFiles scanned: ', srcFiles.length); - consoleLog(options, '\nFiles with problems: ', errorNodes); - const [errorNodesTotal, warningNodes] = countProblems(linter); - logTotalProblemsInfo(errorNodesTotal, warningNodes, linter); - logProblemsPercentageByFeatures(linter); + if (!options.ideInteractive) { + lintResult.problemsInfos = mergeArrayMaps(lintResult.problemsInfos, transformTscDiagnostics(tscStrictDiagnostics)); + } freeMemory(); - let problemsInfosValues = problemsInfos; - if (!options.ideInteractive) { - problemsInfosValues = mergeArrayMaps(problemsInfos, transformTscDiagnostics(tscStrictDiagnostics)); + return lintResult; +} + +function lintFiles( + tsProgram: ts.Program, + srcFiles: ts.SourceFile[], + options: LinterOptions, + tscStrictDiagnostics: Map +): LintRunResult { + const projectStats: ProjectStatistics = new ProjectStatistics(); + const problemsInfos: Map = new Map(); + + TypeScriptLinter.initGlobals(); + InteropTypescriptLinter.initGlobals(); + + for (const srcFile of srcFiles) { + const linter: BaseTypeScriptLinter = !options.interopCheckMode ? + new TypeScriptLinter(tsProgram.getTypeChecker(), options, srcFile, tscStrictDiagnostics) : + new InteropTypescriptLinter(tsProgram.getTypeChecker(), tsProgram.getCompilerOptions(), options, srcFile); + linter.lint(); + const problems = linter.problemsInfos; + problemsInfos.set(path.normalize(srcFile.fileName), [...problems]); + projectStats.fileStats.push(linter.fileStats); } return { - errorNodes: errorNodesTotal, - problemsInfos: problemsInfosValues + hasErrors: projectStats.hasError(), + problemsInfos, + projectStats }; } -function applyFixes(srcFile: ts.SourceFile, linter: TypeScriptLinter | InteropTypescriptLinter): void { - for (let pass = 0; pass < qEd.MAX_AUTOFIX_PASSES; pass++) { - const qe: qEd.QuasiEditor = new qEd.QuasiEditor(srcFile); - if (pass === 0) { - qe.backupSrcFile(); - } - qe.fix(linter.problemsInfos); - if (qe.wasError) { - Logger.error(`Error: fix-all converged for (${srcFile.fileName}) on pass #${pass}`); - break; - } - const tmpLinterConfig = compileLintOptions(linterConfig.cmdOptions); - const recompiledFile = tmpLinterConfig.tscCompiledProgram.getProgram().getSourceFile(srcFile.fileName); +function migrate( + initialConfig: LinterConfig, + initialLintResult: LintRunResult, + hcResults?: Map +): LintRunResult { + let linterConfig = initialConfig; + const { cmdOptions } = initialConfig; + const updatedSourceTexts: Map = new Map(); + let lintResult: LintRunResult = initialLintResult; + const problemsInfosBeforeMigrate = lintResult.problemsInfos; + + for (let pass = 0; pass < (cmdOptions.linterOptions.migrationMaxPass ?? qEd.DEFAULT_MAX_AUTOFIX_PASSES); pass++) { + const appliedFix = fix(linterConfig, lintResult, updatedSourceTexts, hcResults); + hcResults = undefined; - if (!recompiledFile) { - Logger.error(`Error: recompilation failed for (${srcFile.fileName}) on pass #${pass}`); + if (!appliedFix) { + // No fixes were applied, migration is finished. break; } - linter.problemsInfos = []; - linter.lint(recompiledFile); - } -} -function lintFiles(srcFiles: ts.SourceFile[], linter: TypeScriptLinter | InteropTypescriptLinter): LintRunResult { - let problemFiles = 0; - const problemsInfos: Map = new Map(); + // Re-compile and re-lint project after applying the fixes. + linterConfig = compileLintOptions(cmdOptions, getMigrationCreateProgramCallback(updatedSourceTexts)); + lintResult = lintImpl(linterConfig); + } - for (const srcFile of srcFiles) { - if (linter instanceof TypeScriptLinter) { - linter.initSdkInfo(); - } - const prevVisitedNodes = linter.totalVisitedNodes; - const prevErrorLines = linter.totalErrorLines; - const prevWarningLines = linter.totalWarningLines; - linter.errorLineNumbersString = ''; - linter.warningLineNumbersString = ''; - const nodeCounters: number[] = []; - - for (let i = 0; i < FaultID.LAST_ID; i++) { - nodeCounters[i] = linter.nodeCounters[i]; + // Write new text for updated source files. + updatedSourceTexts.forEach((newText, fileName) => { + if (!cmdOptions.linterOptions.noMigrationBackupFile) { + qEd.QuasiEditor.backupSrcFile(fileName); } - linter.lint(srcFile); - const problemsInfosBeforeMigrate = linter.problemsInfos; - if (linter.options.migratorMode) { - applyFixes(srcFile, linter); - } - if (linter.options.ideInteractive) { - problemsInfos.set(path.normalize(srcFile.fileName), [...problemsInfosBeforeMigrate]); - } else { - problemsInfos.set(path.normalize(srcFile.fileName), [...linter.problemsInfos]); - } - linter.problemsInfos.length = 0; - problemFiles = countProblemFiles( - nodeCounters, - problemFiles, - srcFile, - linter.totalVisitedNodes - prevVisitedNodes, - linter.totalErrorLines - prevErrorLines, - linter.totalWarningLines - prevWarningLines, - linter - ); + const filePathMap = cmdOptions.linterOptions.migrationFilePathMap; + const writeFileName = filePathMap?.get(fileName) ?? fileName; + fs.writeFileSync(writeFileName, newText); + }); + + if (cmdOptions.linterOptions.ideInteractive) { + lintResult.problemsInfos = problemsInfosBeforeMigrate; } - return { - errorNodes: problemFiles, - problemsInfos: problemsInfos - }; + + return lintResult; } -// eslint-disable-next-line max-lines-per-function, max-params -function countProblemFiles( - nodeCounters: number[], - filesNumber: number, - tsSrcFile: ts.SourceFile, - fileNodes: number, - fileErrorLines: number, - fileWarningLines: number, - linter: TypeScriptLinter | InteropTypescriptLinter -): number { - let errorNodes = 0; - let warningNodes = 0; - for (let i = 0; i < FaultID.LAST_ID; i++) { - const nodeCounterDiff = linter.nodeCounters[i] - nodeCounters[i]; - switch (faultsAttrs[i].severity) { - case ProblemSeverity.ERROR: - errorNodes += nodeCounterDiff; - break; - case ProblemSeverity.WARNING: - warningNodes += nodeCounterDiff; - break; - default: +function fix( + linterConfig: LinterConfig, + lintResult: LintRunResult, + updatedSourceTexts: Map, + hcResults?: Map +): boolean { + const program = linterConfig.tscCompiledProgram.getProgram(); + let appliedFix = false; + const mergedProblems = lintResult.problemsInfos; + if (hcResults !== undefined) { + for (const [filePath, problems] of hcResults) { + if (mergedProblems.has(filePath)) { + mergedProblems.get(filePath)!.push(...problems); + } else { + mergedProblems.set(filePath, problems); + } } } - if (errorNodes > 0) { - // eslint-disable-next-line no-param-reassign - filesNumber++; - const errorRate = (errorNodes / fileNodes * 100).toFixed(2); - const warningRate = (warningNodes / fileNodes * 100).toFixed(2); - consoleLog(linter.options, tsSrcFile.fileName, ': ', '\n\tError lines: ', linter.errorLineNumbersString); - consoleLog(linter.options, tsSrcFile.fileName, ': ', '\n\tWarning lines: ', linter.warningLineNumbersString); - consoleLog( - linter.options, - '\n\tError constructs (%): ', - errorRate, - '\t[ of ', - fileNodes, - ' constructs ], \t', - fileErrorLines, - ' lines' - ); - consoleLog( - linter.options, - '\n\tWarning constructs (%): ', - warningRate, - '\t[ of ', - fileNodes, - ' constructs ], \t', - fileWarningLines, - ' lines' - ); - } - return filesNumber; -} + mergedProblems.forEach((problemInfos, fileName) => { + // If nothing to fix, skip file + if (!qEd.QuasiEditor.hasAnyAutofixes(problemInfos)) { + return; + } -function logTotalProblemsInfo( - errorNodes: number, - warningNodes: number, - linter: TypeScriptLinter | InteropTypescriptLinter -): void { - const errorRate = (errorNodes / linter.totalVisitedNodes * 100).toFixed(2); - const warningRate = (warningNodes / linter.totalVisitedNodes * 100).toFixed(2); - consoleLog(linter.options, '\nTotal error constructs (%): ', errorRate); - consoleLog(linter.options, '\nTotal warning constructs (%): ', warningRate); - consoleLog(linter.options, '\nTotal error lines:', linter.totalErrorLines, ' lines\n'); - consoleLog(linter.options, '\nTotal warning lines:', linter.totalWarningLines, ' lines\n'); -} + const srcFile = program.getSourceFile(fileName); + if (!srcFile) { + Logger.error(`Failed to retrieve source file: ${fileName}`); + return; + } -function logProblemsPercentageByFeatures(linter: TypeScriptLinter | InteropTypescriptLinter): void { - consoleLog(linter.options, '\nPercent by features: '); - for (let i = 0; i < FaultID.LAST_ID; i++) { - const nodes = linter.nodeCounters[i]; - const lines = linter.lineCounters[i]; - const pecentage = (nodes / linter.totalVisitedNodes * 100).toFixed(2).padEnd(7, ' '); + const qe: qEd.QuasiEditor = new qEd.QuasiEditor(fileName, srcFile.text, linterConfig.cmdOptions.linterOptions); + updatedSourceTexts.set(fileName, qe.fix(problemInfos)); + appliedFix = true; + }); - consoleLog(linter.options, faultDesc[i].padEnd(55, ' '), pecentage, '[', nodes, ' constructs / ', lines, ' lines]'); - } + return appliedFix; +} + +function getMigrationCreateProgramCallback(updatedSourceTexts: Map): createProgramCallback { + return (createProgramOptions: ts.CreateProgramOptions): ts.Program => { + const compilerHost = createProgramOptions.host || ts.createCompilerHost(createProgramOptions.options, true); + const originalReadFile = compilerHost.readFile; + compilerHost.readFile = (fileName: string): string | undefined => { + const newText = updatedSourceTexts.get(path.normalize(fileName)); + return newText || originalReadFile(fileName); + }; + createProgramOptions.host = compilerHost; + return ts.createProgram(createProgramOptions); + }; } function shouldProcessFile(options: LinterOptions, fileFsPath: string): boolean { + if (!options.checkTsAndJs && (path.extname(fileFsPath) === EXTNAME_TS || path.extname(fileFsPath) === EXTNAME_JS)) { + return false; + } + if ( ARKTS_IGNORE_FILES.some((ignore) => { return path.basename(fileFsPath) === ignore; diff --git a/ets2panda/linter/src/lib/ProblemInfo.ts b/ets2panda/linter/src/lib/ProblemInfo.ts index f146ac4d2878da6efdde5aa397a06edc30a54c7e..955579e4bef45d9a73f890b43d408f12bba5482e 100644 --- a/ets2panda/linter/src/lib/ProblemInfo.ts +++ b/ets2panda/linter/src/lib/ProblemInfo.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -14,6 +14,7 @@ */ import type { Autofix } from './autofixes/Autofixer'; +import type { FaultID } from './Problems'; export interface ProblemInfo { line: number; @@ -24,6 +25,7 @@ export interface ProblemInfo { end: number; type: string; severity: number; + faultId: FaultID; problem: string; suggest: string; rule: string; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index 9b149207d44ad5aa3247e087afc1ecaca362c7bd..2608582dc6de9c9b01b0c1c7a030fced3b0f0bdf 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -66,6 +66,9 @@ export enum FaultID { JsxElement, EnumMemberNonConstInit, ImplementsClass, + NoStaticOnClass, + NoConstructorOnClass, + RuntimeArrayCheck, MethodReassignment, MultipleStaticBlocks, ThisType, @@ -94,6 +97,8 @@ export enum FaultID { ImportAssertion, SpreadOperator, LimitedStdLibApi, + LimitedStdLibNoASON, + NoNeedStdLibSendableContainer, ErrorSuppression, StrictDiagnostic, ImportAfterStatement, @@ -157,6 +162,8 @@ export enum FaultID { DollarBindingNotSupported, ExtendDecoratorNotSupported, MethodOverridingField, + InteropJsObjectConditionJudgment, + InteropJsObjectExpandStaticInstance, ExplicitFunctionType, ClassstaticInitialization, TaggedTemplates, @@ -172,22 +179,40 @@ export enum FaultID { DataObservation, InteropCallReflect, InteropCallObjectParam, - InteropNoDecorators, InteropDirectAccessToTSTypes, InteropTSFunctionInvoke, + InteropJSFunctionInvoke, LimitedVoidTypeFromSdk, EntryAnnotation, ProvideAnnotation, + UseSharedDeprecated, + UseConcurrentDeprecated, + MethodInheritRule, OptionalMethodFromSdk, SendablePropTypeFromSdk, ConstructorIfaceFromSdk, PropertyAccessByIndexFromSdk, ConstructorTypesDeprecated, QuotedHyphenPropsDeprecated, - ApiPathChanged, + DuplicateDeclNameFromSdk, SdkTypeQuery, + IsConcurrentDeprecated, + InteropStaticObjectLiterals, InteropJsObjectUsage, + InteropJsObjectInheritance, + InteropJsObjectTraverseJsInstance, + InteropJsObjectCallStaticFunc, + InteropJsObjectExport, + InteropArkTs1ObjectExport, + DefaultArgsBehindRequiredArgs, LimitedStdLibNoImportConcurrency, + InteropDynamicImport, + InteropDynamicImportTs, + InteropDynamicImportJs, + MissingSuperCall, + InteropObjectLiteralAmbiguity, + InteropObjectLiteralClass, + UnsupportPropNameFromValue, InterOpImportJs, CallJSFunction, InteropObjectProperty, @@ -198,11 +223,35 @@ export enum FaultID { InterOpImportJsDataCompare, InteropEqualityJudgment, InterOpImportJsIndex, - NoJsImportAwait, InstantiatedJsOjbect, InteropCallObjectMethods, InteropJsInstanceof, InteropIncrementDecrement, + BuiltinThisArgs, + BuiltinSymbolIterator, + NoPropertyDescriptor, + BuiltinNoCtorFunc, + SharedArrayBufferDeprecated, + SetCloneListDeprecated, + SetTransferListDeprecated, + LimitedStdLibNoSendableDecorator, + LimitedStdLibNoDoncurrentDecorator, + NoNeedStdlibWorker, + BuiltinGetOwnPropertyNames, + LocalBuilderDecoratorNotSupported, + MakeObservedIsNotSupported, + PropDecoratorsAndInterfacesAreNotSupported, + NoEnumPropAsType, + NoAwaitJsPromise, + NosparseArray, + NoTsLikeSmartType, + ArrayTypeImmutable, + CreatingPrimitiveTypes, + TsLikeCatchType, + NumericBigintCompare, + NondecimalBigint, + UnsupportOperator, + CustomLayoutNeedAddDecorator, // this should always be last enum LAST_ID } diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index d1b09c53672abfea43130e28aa8f15a11c1b6157..907593e7268ab653cdbed9b5854717721a90c5ee 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -15,29 +15,27 @@ import * as path from 'node:path'; import * as ts from 'typescript'; -import { cookBookTag } from './CookBookMsg'; -import { faultsAttrs } from './FaultAttrs'; -import { faultDesc } from './FaultDesc'; -import { Logger } from './Logger'; -import type { ProblemInfo } from './ProblemInfo'; -import { ProblemSeverity } from './ProblemSeverity'; import { FaultID } from './Problems'; -import { LinterConfig } from './TypeScriptLinterConfig'; -import { cookBookRefToFixTitle } from './autofixes/AutofixTitles'; +import { TypeScriptLinterConfig } from './TypeScriptLinterConfig'; import type { Autofix } from './autofixes/Autofixer'; import { Autofixer } from './autofixes/Autofixer'; import { SYMBOL, SYMBOL_CONSTRUCTOR, TsUtils } from './utils/TsUtils'; import { FUNCTION_HAS_NO_RETURN_ERROR_CODE } from './utils/consts/FunctionHasNoReturnErrorCode'; import { LIMITED_STANDARD_UTILITY_TYPES } from './utils/consts/LimitedStandardUtilityTypes'; import { LIKE_FUNCTION } from './utils/consts/LikeFunction'; +import { METHOD_DECLARATION } from './utils/consts/MethodDeclaration'; +import { METHOD_SIGNATURE } from './utils/consts/MethodSignature'; +import { OPTIONAL_METHOD } from './utils/consts/OptionalMethod'; import { STRINGLITERAL_NUMBER, STRINGLITERAL_STRING, STRINGLITERAL_INT, - STRINGLITERAL_ANY, STRINGLITERAL_BYTE, STRINGLITERAL_SHORT, - STRINGLITERAL_LONG + STRINGLITERAL_CHAR, + STRINGLITERAL_LONG, + STRINGLITERAL_FROM, + STRINGLITERAL_ARRAY } from './utils/consts/StringLiteral'; import { NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS, @@ -48,6 +46,8 @@ import { NON_RETURN_FUNCTION_DECORATORS } from './utils/consts/NonReturnFunction import { PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE } from './utils/consts/PropertyHasNoInitializerErrorCode'; import { CONCURRENT_DECORATOR, + ISCONCURRENT, + TASKPOOL, SENDABLE_DECORATOR, SENDABLE_DECORATOR_NODES, SENDABLE_FUNCTION_UNSUPPORTED_STAGES_IN_API12, @@ -80,6 +80,8 @@ import { BUILTIN_GENERIC_CONSTRUCTORS } from './utils/consts/BuiltinGenericConst import { DEFAULT_DECORATOR_WHITE_LIST } from './utils/consts/DefaultDecoratorWhitelist'; import { INVALID_IDENTIFIER_KEYWORDS } from './utils/consts/InValidIndentifierKeywords'; import { WORKER_MODULES, WORKER_TEXT } from './utils/consts/WorkerAPI'; +import { COLLECTIONS_TEXT, COLLECTIONS_MODULES } from './utils/consts/CollectionsAPI'; +import { ASON_TEXT, ASON_MODULES, JSON_TEXT } from './utils/consts/ArkTSUtilsAPI'; import { ETS_PART, PATH_SEPARATOR } from './utils/consts/OhmUrl'; import { DOUBLE_DOLLAR_IDENTIFIER, @@ -90,16 +92,46 @@ import { skipImportDecoratorName, ENTRY_DECORATOR_NAME, PROVIDE_DECORATOR_NAME, - PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME + PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME, + ARKUI_PACKAGE_NAME, + MAKE_OBSERVED, + ARKUI_STATE_MANAGEMENT, + deepCopyDecoratorName, + deepCopyFunctionName, + StorageTypeName, + customLayoutFunctionName } from './utils/consts/ArkuiConstants'; import { arkuiImportList } from './utils/consts/ArkuiImportList'; -import { REFLECT_PROPERTIES, USE_STATIC } from './utils/consts/InteropAPI'; +import { InteropType, REFLECT_PROPERTIES, USE_STATIC } from './utils/consts/InteropAPI'; import { EXTNAME_TS, EXTNAME_D_TS, EXTNAME_JS } from './utils/consts/ExtensionName'; import { ARKTS_IGNORE_DIRS_OH_MODULES } from './utils/consts/ArktsIgnorePaths'; import type { ApiInfo, ApiListItem } from './utils/consts/SdkWhitelist'; -import { ApiList } from './utils/consts/SdkWhitelist'; +import { ApiList, SdkProblem, SdkNameInfo } from './utils/consts/SdkWhitelist'; import * as apiWhiteList from './data/SdkWhitelist.json'; -import { SdkProblem, ARKTS_WHITE_API_PATH_TEXTSTYLE } from './utils/consts/WhiteListProblemType'; +import * as builtinWhiteList from './data/BuiltinList.json'; +import { + BuiltinProblem, + SYMBOL_ITERATOR, + BUILTIN_DISABLE_CALLSIGNATURE, + GET_OWN_PROPERTY_NAMES_TEXT +} from './utils/consts/BuiltinWhiteList'; +import { + USE_SHARED, + USE_CONCURRENT, + ESLIB_SHAREDMEMORY_FILENAME, + ESLIB_SHAREDARRAYBUFFER, + TASKPOOL_MODULES +} from './utils/consts/ConcurrentAPI'; +import { + DEPRECATED_TASKPOOL_METHOD_SETCLONELIST, + DEPRECATED_TASKPOOL_METHOD_SETTRANSFERLIST, + STDLIB_TASK_CLASS_NAME, + STDLIB_TASKPOOL_OBJECT_NAME +} from './utils/consts/TaskpoolAPI'; +import { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; +import type { ArrayAccess, UncheckedIdentifier, CheckedIdentifier } from './utils/consts/RuntimeCheckAPI'; +import { CheckResult } from './utils/consts/RuntimeCheckAPI'; +import { NUMBER_LITERAL } from './utils/consts/RuntimeCheckAPI'; interface InterfaceSymbolTypeResult { propNames: string[]; @@ -110,28 +142,13 @@ interface InterfaceSymbolTypePropertyNames { propertyNames: string[]; typeNames: string[]; } -export class TypeScriptLinter { - totalVisitedNodes: number = 0; - nodeCounters: number[] = []; - lineCounters: number[] = []; - - totalErrorLines: number = 0; - errorLineNumbersString: string = ''; - totalWarningLines: number = 0; - warningLineNumbersString: string = ''; - problemsInfos: ProblemInfo[] = []; - - tsUtils: TsUtils; - - currentErrorLine: number; - currentWarningLine: number; +export class TypeScriptLinter extends BaseTypeScriptLinter { supportedStdCallApiChecker: SupportedStdCallApiChecker; autofixer: Autofixer | undefined; private fileExportDeclCaches: Set | undefined; - private sourceFile?: ts.SourceFile; private useStatic?: boolean; private readonly compatibleSdkVersion: number; @@ -139,22 +156,66 @@ export class TypeScriptLinter { private static sharedModulesCache: Map; static nameSpaceFunctionCache: Map>; private readonly constVariableInitCache: Map = new Map(); - private funcMap: Map> = new Map>(); + static funcMap: Map>> = new Map>>(); private interfaceMap: Map> = new Map>(); static pathMap: Map>; static indexedTypeSet: Set; + static globalApiInfo: Map>; + static symbotIterSet: Set; + static missingAttributeSet: Set; + static literalAsPropertyNameTypeSet: Set; + private localApiListItem: ApiListItem | undefined = undefined; static initGlobals(): void { TypeScriptLinter.sharedModulesCache = new Map(); TypeScriptLinter.nameSpaceFunctionCache = new Map>(); TypeScriptLinter.pathMap = new Map>(); + TypeScriptLinter.globalApiInfo = new Map>(); + TypeScriptLinter.funcMap = new Map>>(); + TypeScriptLinter.symbotIterSet = new Set(); + TypeScriptLinter.missingAttributeSet = new Set(); + TypeScriptLinter.initSdkWhitelist(); + TypeScriptLinter.initSdkBuiltinInfo(); + TypeScriptLinter.initBuiltinlist(); } initSdkInfo(): void { - this.funcMap = new Map>(); this.interfaceMap = new Map>(); } + static initSdkBuiltinInfo(): void { + const list: ApiList = new ApiList(builtinWhiteList); + if (list?.api_list?.length > 0) { + for (const item of list.api_list) { + switch (item.api_info.problem) { + case BuiltinProblem.MissingAttributes: + TypeScriptLinter.missingAttributeSet.add(item.file_path); + break; + case BuiltinProblem.SymbolIterator: + TypeScriptLinter.symbotIterSet.add(item.file_path); + break; + case BuiltinProblem.LimitedThisArg: + TypeScriptLinter.initSdkBuiltinThisArgsWhitelist(item); + break; + default: + } + } + } + } + + static initSdkBuiltinThisArgsWhitelist(item: ApiListItem): void { + if (item.file_path === '' || !item.api_info.api_name) { + return; + } + + let funcApiInfos: Map> | undefined = TypeScriptLinter.funcMap.get(item.api_info.api_name); + if (!funcApiInfos) { + funcApiInfos = new Map>(); + TypeScriptLinter.funcMap.set(item.api_info.api_name, funcApiInfos); + } + TypeScriptLinter.addOrUpdateData(funcApiInfos, item.file_path, item.api_info); + } + private initEtsHandlers(): void { /* @@ -167,31 +228,54 @@ export class TypeScriptLinter { } } - private initCounters(): void { - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } - } - private static addSdkIndexedTypeSetData(item: ApiListItem): void { if (item.api_info.problem === SdkProblem.IndexedAccessType) { TypeScriptLinter.indexedTypeSet.add(item); } } + private static addSdkliteralAsPropertyNameTypeSetData(item: ApiListItem): void { + if (item.api_info.problem === SdkProblem.LiteralAsPropertyName) { + TypeScriptLinter.literalAsPropertyNameTypeSet.add(item); + } + } + + private static addGlobalApiInfosCollocetionData(item: ApiListItem): void { + const problemType = item.api_info.problem; + const isGlobal = item.is_global; + if (isGlobal) { + if (!TypeScriptLinter.globalApiInfo.has(problemType)) { + TypeScriptLinter.globalApiInfo.set(problemType, new Set()); + } + const setApiListItem = TypeScriptLinter.globalApiInfo.get(problemType); + setApiListItem?.add(item); + } + } + private static initSdkWhitelist(): void { TypeScriptLinter.indexedTypeSet = new Set(); + TypeScriptLinter.literalAsPropertyNameTypeSet = new Set(); const list: ApiList = new ApiList(apiWhiteList); if (list?.api_list?.length > 0) { for (const item of list.api_list) { - item.file_path.forEach((path) => { - TypeScriptLinter.addOrUpdateData(TypeScriptLinter.pathMap, `'${path}'`, item.api_info); - }); + if (item.file_path !== '') { + TypeScriptLinter.addOrUpdateData(TypeScriptLinter.pathMap, `'${item.file_path}'`, item.api_info); + } item.import_path.forEach((path) => { TypeScriptLinter.addOrUpdateData(TypeScriptLinter.pathMap, `'${path}'`, item.api_info); }); TypeScriptLinter.addSdkIndexedTypeSetData(item); + TypeScriptLinter.addSdkliteralAsPropertyNameTypeSetData(item); + TypeScriptLinter.addGlobalApiInfosCollocetionData(item); + } + } + } + + private static initBuiltinlist(): void { + const list: ApiList = new ApiList(builtinWhiteList); + if (list?.api_list?.length > 0) { + for (const item of list.api_list) { + TypeScriptLinter.addGlobalApiInfosCollocetionData(item); } } } @@ -206,19 +290,17 @@ export class TypeScriptLinter { } constructor( - private readonly tsTypeChecker: ts.TypeChecker, - readonly options: LinterOptions, - private readonly tscStrictDiagnostics?: Map + tsTypeChecker: ts.TypeChecker, + options: LinterOptions, + sourceFile: ts.SourceFile, + readonly tscStrictDiagnostics?: Map ) { - this.tsUtils = new TsUtils(this.tsTypeChecker, options); - this.currentErrorLine = 0; - this.currentWarningLine = 0; + super(tsTypeChecker, options, sourceFile); this.supportedStdCallApiChecker = new SupportedStdCallApiChecker(this.tsUtils, this.tsTypeChecker); this.compatibleSdkVersion = options.compatibleSdkVersion || DEFAULT_COMPATIBLE_SDK_VERSION; this.compatibleSdkVersionStage = options.compatibleSdkVersionStage || DEFAULT_COMPATIBLE_SDK_VERSION_STAGE; this.initEtsHandlers(); - this.initCounters(); - TypeScriptLinter.initSdkWhitelist(); + this.initSdkInfo(); } readonly handlersMap = new Map([ @@ -227,11 +309,13 @@ export class TypeScriptLinter { [ts.SyntaxKind.Parameter, this.handleParameter], [ts.SyntaxKind.EnumDeclaration, this.handleEnumDeclaration], [ts.SyntaxKind.InterfaceDeclaration, this.handleInterfaceDeclaration], + [ts.SyntaxKind.TryStatement, this.handleTryStatement], [ts.SyntaxKind.ThrowStatement, this.handleThrowStatement], [ts.SyntaxKind.ImportClause, this.handleImportClause], [ts.SyntaxKind.ForStatement, this.handleForStatement], [ts.SyntaxKind.ForInStatement, this.handleForInStatement], [ts.SyntaxKind.ForOfStatement, this.handleForOfStatement], + [ts.SyntaxKind.IfStatement, this.handleIfStatement], [ts.SyntaxKind.ImportDeclaration, this.handleImportDeclaration], [ts.SyntaxKind.PropertyAccessExpression, this.handlePropertyAccessExpression], [ts.SyntaxKind.PropertyDeclaration, this.handlePropertyDeclaration], @@ -268,6 +352,7 @@ export class TypeScriptLinter { [ts.SyntaxKind.SpreadAssignment, this.handleSpreadOp], [ts.SyntaxKind.GetAccessor, this.handleGetAccessor], [ts.SyntaxKind.SetAccessor, this.handleSetAccessor], + [ts.SyntaxKind.StringLiteral, this.handleStringLiteral], [ts.SyntaxKind.ConstructSignature, this.handleConstructSignature], [ts.SyntaxKind.ExpressionWithTypeArguments, this.handleExpressionWithTypeArguments], [ts.SyntaxKind.ComputedPropertyName, this.handleComputedPropertyName], @@ -295,142 +380,31 @@ export class TypeScriptLinter { [ts.SyntaxKind.StructDeclaration, this.handleStructDeclaration], [ts.SyntaxKind.TypeOfExpression, this.handleInterOpImportJsOnTypeOfNode], [ts.SyntaxKind.AwaitExpression, this.handleAwaitExpression], - [ts.SyntaxKind.PostfixUnaryExpression, this.handlePostfixUnaryExpression] + [ts.SyntaxKind.PostfixUnaryExpression, this.handlePostfixUnaryExpression], + [ts.SyntaxKind.BigIntLiteral, this.handleBigIntLiteral] ]); - private getLineAndCharacterOfNode(node: ts.Node | ts.CommentRange): ts.LineAndCharacter { - const startPos = TsUtils.getStartPos(node); - const { line, character } = this.sourceFile!.getLineAndCharacterOfPosition(startPos); - // TSC counts lines and columns from zero - return { line: line + 1, character: character + 1 }; - } - - incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { - this.nodeCounters[faultId]++; - const { line, character } = this.getLineAndCharacterOfNode(node); - if ((this.options.ideMode || this.options.migratorMode) && !this.options.ideInteractive) { - this.incrementCountersIdeMode(node, faultId, autofix); - } else if (this.options.ideInteractive) { - this.incrementCountersIdeInteractiveMode(node, faultId, autofix); - } else { - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - Logger.info( - `Warning: ${this.sourceFile!.fileName} (${line}, ${character}): ${faultDescr ? faultDescr : faultType}` - ); - } - this.lineCounters[faultId]++; - switch (faultsAttrs[faultId].severity) { - case ProblemSeverity.ERROR: { - this.currentErrorLine = line; - ++this.totalErrorLines; - this.errorLineNumbersString += line + ', '; - break; - } - case ProblemSeverity.WARNING: { - if (line === this.currentWarningLine) { - break; - } - this.currentWarningLine = line; - ++this.totalWarningLines; - this.warningLineNumbersString += line + ', '; - break; - } - default: - } - } - - private incrementCountersIdeMode(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { - if (!this.options.ideMode && !this.options.migratorMode) { - return; - } - const [startOffset, endOffset] = TsUtils.getHighlightRange(node, faultId); - const startPos = this.sourceFile!.getLineAndCharacterOfPosition(startOffset); - const endPos = this.sourceFile!.getLineAndCharacterOfPosition(endOffset); - - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - - const cookBookMsgNum = faultsAttrs[faultId] ? faultsAttrs[faultId].cookBookRef : 0; - const cookBookTg = cookBookTag[cookBookMsgNum]; - const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; - const isMsgNumValid = cookBookMsgNum > 0; - const badNodeInfo: ProblemInfo = { - line: startPos.line + 1, - column: startPos.character + 1, - endLine: endPos.line + 1, - endColumn: endPos.character + 1, - start: startOffset, - end: endOffset, - type: faultType, - severity: severity, - problem: FaultID[faultId], - suggest: '', - // eslint-disable-next-line no-nested-ternary - rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, - ruleTag: cookBookMsgNum, - autofix: autofix, - autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined - }; - this.problemsInfos.push(badNodeInfo); - // problems with autofixes might be collected separately - if (this.options.reportAutofixCb && badNodeInfo.autofix) { - this.options.reportAutofixCb(badNodeInfo); + lint(): void { + if (this.options.enableAutofix || this.options.migratorMode) { + this.autofixer = new Autofixer(this.tsTypeChecker, this.tsUtils, this.sourceFile, this.options.cancellationToken); } - } - private incrementCountersIdeInteractiveMode( - node: ts.Node | ts.CommentRange, - faultId: number, - autofix?: Autofix[] - ): void { - if (!this.options.ideInteractive) { - return; - } - const [startOffset, endOffset] = TsUtils.getHighlightRange(node, faultId); - const startPos = this.sourceFile!.getLineAndCharacterOfPosition(startOffset); - const endPos = this.sourceFile!.getLineAndCharacterOfPosition(endOffset); - - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - - const cookBookMsgNum = faultsAttrs[faultId] ? faultsAttrs[faultId].cookBookRef : 0; - const cookBookTg = cookBookTag[cookBookMsgNum]; - const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; - const isMsgNumValid = cookBookMsgNum > 0; - const badNodeInfo: ProblemInfo = { - line: startPos.line + 1, - column: startPos.character + 1, - endLine: endPos.line + 1, - endColumn: endPos.character + 1, - start: startOffset, - end: endOffset, - type: faultType, - severity: severity, - problem: FaultID[faultId], - suggest: '', - // eslint-disable-next-line no-nested-ternary - rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, - ruleTag: cookBookMsgNum, - autofixable: !!autofix, - autofix: autofix, - autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined - }; - this.problemsInfos.push(badNodeInfo); - // problems with autofixes might be collected separately - if (this.options.reportAutofixCb && badNodeInfo.autofix) { - this.options.reportAutofixCb(badNodeInfo); - } + this.useStatic = TsUtils.isArkts12File(this.sourceFile); + this.fileExportDeclCaches = undefined; + this.extractImportedNames(this.sourceFile); + this.visitSourceFile(this.sourceFile); + this.handleCommentDirectives(this.sourceFile); + this.processInterfacesToImport(this.sourceFile); } private visitSourceFile(sf: ts.SourceFile): void { const callback = (node: ts.Node): void => { - this.totalVisitedNodes++; + this.fileStats.visitedNodes++; if (isStructDeclaration(node)) { // early exit via exception if cancellation was requested this.options.cancellationToken?.throwIfCancellationRequested(); } - const incrementedType = LinterConfig.incrementOnlyTokens.get(node.kind); + const incrementedType = TypeScriptLinterConfig.incrementOnlyTokens.get(node.kind); if (incrementedType !== undefined) { this.incrementCounters(node, incrementedType); } else { @@ -456,7 +430,7 @@ export class TypeScriptLinter { if (node.parent && isStructDeclaration(node.parent) && ts.isConstructorDeclaration(node)) { return true; } - if (LinterConfig.terminalTokens.has(node.kind)) { + if (TypeScriptLinterConfig.terminalTokens.has(node.kind)) { return true; } return false; @@ -612,15 +586,24 @@ export class TypeScriptLinter { objectLiteralType: ts.Type | undefined, objectLiteralExpr: ts.ObjectLiteralExpression ): void { - const isRecordObject = objectLiteralType && this.tsUtils.isStdRecordType(objectLiteralType); - for (const prop of objectLiteralExpr.properties) { - if ( - isRecordObject && !(prop.name && this.tsUtils.isValidRecordObjectLiteralKey(prop.name)) || - !isRecordObject && !(ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) - ) { - const faultNode = ts.isPropertyAssignment(prop) ? prop.name : prop; - this.incrementCounters(faultNode, FaultID.ObjectLiteralProperty); - } + let objLiteralAutofix: Autofix[] | undefined; + const invalidProps = objectLiteralExpr.properties.filter((prop) => { + return !ts.isPropertyAssignment(prop); + }); + + if ( + invalidProps.some((prop) => { + return ts.isMethodDeclaration(prop) || ts.isAccessor(prop); + }) + ) { + objLiteralAutofix = this.autofixer?.fixTypedObjectLiteral(objectLiteralExpr, objectLiteralType); + } + + for (const prop of invalidProps) { + const autofix = ts.isShorthandPropertyAssignment(prop) ? + this.autofixer?.fixShorthandPropertyAssignment(prop) : + objLiteralAutofix; + this.incrementCounters(prop, FaultID.ObjectLiteralProperty, autofix); } } @@ -661,6 +644,9 @@ export class TypeScriptLinter { if (elementContextType) { this.checkAssignmentMatching(element, elementContextType, element, true); } + if (this.options.arkts2 && ts.isOmittedExpression(element)) { + this.incrementCounters(element, FaultID.NosparseArray); + } } if (emptyContextTypeForArrayLiteral) { this.incrementCounters(node, FaultID.ArrayLiteralNoContextType); @@ -671,6 +657,7 @@ export class TypeScriptLinter { if (!this.options.arkts2) { return; } + this.handleStructDeclarationForLayout(node); this.handleInvalidIdentifier(node); } @@ -682,10 +669,12 @@ export class TypeScriptLinter { this.handleDeclarationDestructuring(tsParam); this.handleDeclarationInferredType(tsParam); this.handleInvalidIdentifier(tsParam); + this.handleSdkDuplicateDeclName(tsParam); const typeNode = tsParam.type; if (this.options.arkts2 && typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { this.incrementCounters(typeNode, FaultID.LimitedVoidType); } + this.handlePropertyDescriptorInScenarios(tsParam); } private handleEnumDeclaration(node: ts.Node): void { @@ -763,6 +752,81 @@ export class TypeScriptLinter { this.countDeclarationsWithDuplicateName(interfaceNode.name, interfaceNode); } + private handleTryStatement(node: ts.TryStatement): void { + if (!this.options.arkts2) { + return; + } + + for (const stmt of node.tryBlock.statements) { + if (!ts.isExpressionStatement(stmt)) { + continue; + } + const callExpr = stmt.expression; + if (!ts.isCallExpression(callExpr)) { + continue; + } + const ident = callExpr.expression; + if (!ts.isIdentifier(ident)) { + continue; + } + + this.handleTsInterop(ident, () => { + this.tsFunctionInteropHandler(callExpr); + }); + + this.handleJsInterop(ident, () => { + this.jsFunctionInteropHandler(callExpr); + }); + } + } + + private tsFunctionInteropHandler(callExpr: ts.CallExpression): void { + this.checkInteropFunctionThrows(callExpr, FaultID.InteropTSFunctionInvoke); + } + + private jsFunctionInteropHandler(callExpr: ts.CallExpression): void { + this.checkInteropFunctionThrows(callExpr, FaultID.InteropJSFunctionInvoke); + } + + private checkInteropFunctionThrows(callExpr: ts.CallExpression, faultId: FaultID): void { + const signature = this.tsTypeChecker.getResolvedSignature(callExpr); + if (!signature) { + return; + } + + if (!signature.declaration) { + return; + } + + const functionSymbol = this.getFunctionSymbol(signature.declaration); + const functionDeclaration = functionSymbol?.valueDeclaration; + if (!functionDeclaration) { + return; + } + + if (!TypeScriptLinter.isFunctionLike(functionDeclaration)) { + return; + } + if (this.containsThrowNonError(functionDeclaration)) { + this.incrementCounters(callExpr, faultId); + } + } + + private containsThrowNonError(node: ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression): boolean { + if (!node.body) { + return false; + } + + const statements = node.body.statements; + for (const stmt of statements) { + if (!ts.isThrowStatement(stmt)) { + continue; + } + return this.tsUtils.checkStatementForErrorClass(stmt); + } + return false; + } + private handleThrowStatement(node: ts.Node): void { const throwStmt = node as ts.ThrowStatement; const throwExprType = this.tsTypeChecker.getTypeAtLocation(throwStmt.expression); @@ -789,174 +853,452 @@ export class TypeScriptLinter { } } - private handleForStatement(node: ts.Node): void { - const tsForStmt = node as ts.ForStatement; - const tsForInit = tsForStmt.initializer; - if (tsForInit) { - this.checkForLoopDestructuring(tsForInit); + /* + * this should report the point of access to the array + * and also should report the identifier type + */ + private checkElementAccessOfArray(statement: ts.Node): ArrayAccess | false { + if (ts.isElementAccessExpression(statement)) { + return this.isElementAccessOfArray(statement); } - } - - private handleForInStatement(node: ts.Node): void { - const tsForInStmt = node as ts.ForInStatement; - const tsForInInit = tsForInStmt.initializer; - this.checkForLoopDestructuring(tsForInInit); - this.incrementCounters(node, FaultID.ForInStatement); - } - - private handleForOfStatement(node: ts.Node): void { - const tsForOfStmt = node as ts.ForOfStatement; - const tsForOfInit = tsForOfStmt.initializer; - this.checkForLoopDestructuring(tsForOfInit); - } - private updateDataSdkJsonInfo(importDeclNode: ts.ImportDeclaration, importClause: ts.ImportClause): void { - const sdkInfo = TypeScriptLinter.pathMap.get(importDeclNode.moduleSpecifier.getText()); - if (sdkInfo && importClause.namedBindings) { - const namedImports = importClause.namedBindings as ts.NamedImports; - namedImports.elements.forEach((element) => { - const elementName = element.name.getText(); - sdkInfo.forEach((info) => { - TypeScriptLinter.addOrUpdateData(this.interfaceMap, elementName, info); - }); - }); + for (const children of statement.getChildren()) { + return this.checkElementAccessOfArray(children); } + return false; } - private handleImportDeclaration(node: ts.Node): void { - // early exit via exception if cancellation was requested - this.options.cancellationToken?.throwIfCancellationRequested(); - const importDeclNode = node as ts.ImportDeclaration; - this.handleImportModule(importDeclNode); - if (this.options.arkts2) { - const importClause = importDeclNode.importClause; - if (!importClause || !importClause.name && !importClause.namedBindings) { - this.incrementCounters(node, FaultID.NoSideEffectImport); - } else { - this.updateDataSdkJsonInfo(importDeclNode, importClause); - } + private isElementAccessOfArray(expr: ts.ElementAccessExpression): false | ArrayAccess { + if (!ts.isIdentifier(expr.expression)) { + return false; } - for (const stmt of importDeclNode.parent.statements) { - if (stmt === importDeclNode) { - break; - } - if (!ts.isImportDeclaration(stmt)) { - this.incrementCounters(node, FaultID.ImportAfterStatement); - break; - } + const type = this.tsTypeChecker.getTypeAtLocation(expr.expression); + if (!this.tsUtils.isArray(type)) { + return false; + } + const accessArgument = expr.argumentExpression; + if (ts.isNumericLiteral(accessArgument)) { + return { + pos: expr.getEnd(), + accessingIdentifier: NUMBER_LITERAL, + arrayIdent: expr.expression + }; } - const expr = importDeclNode.moduleSpecifier; - if (expr.kind === ts.SyntaxKind.StringLiteral) { - if (importDeclNode.assertClause) { - this.incrementCounters(importDeclNode.assertClause, FaultID.ImportAssertion); - } - const stringLiteral = expr as ts.StringLiteral; - this.handleSdkSendable(stringLiteral); + if (ts.isIdentifier(accessArgument)) { + return { + pos: expr.getEnd(), + accessingIdentifier: accessArgument, + arrayIdent: expr.expression + }; } + return false; + } - // handle no side effect import in sendable module - this.handleSharedModuleNoSideEffectImport(importDeclNode); - this.handleInvalidIdentifier(importDeclNode); - this.checkWorkerImport(importDeclNode); - this.checkStdLibConcurrencyImport(importDeclNode); - this.handleInterOpImportJs(importDeclNode); + private handleForStatement(node: ts.Node): void { + const tsForStmt = node as ts.ForStatement; + const tsForInit = tsForStmt.initializer; + if (tsForInit) { + this.checkStaticArrayControl(tsForStmt); + this.checkForLoopDestructuring(tsForInit); + } } - private handleSdkSendable(tsStringLiteral: ts.StringLiteral): void { - if (!this.options.arkts2) { + private checkStaticArrayControl(tsForStmt: ts.ForStatement): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - const moduleSpecifierValue = tsStringLiteral.getText(); - const sdkInfos = TypeScriptLinter.pathMap.get(moduleSpecifierValue); + if (!ts.isBlock(tsForStmt.statement)) { + return; + } - if (!sdkInfos || sdkInfos.size === 0) { + const loopBody = tsForStmt.statement; + const arrayAccessInfo = this.checkBodyHasArrayAccess(loopBody); + const loopCondition = tsForStmt.condition; + + if (!arrayAccessInfo) { return; } - if (moduleSpecifierValue.includes('sendable')) { - this.incrementCounters(tsStringLiteral, FaultID.SendablePropTypeFromSdk); + if (!loopCondition) { + this.incrementCounters(arrayAccessInfo.arrayIdent.parent, FaultID.RuntimeArrayCheck); + return; } - } - - private handleImportModule(importDeclNode: ts.ImportDeclaration): void { - if (!this.options.arkts2) { + const arraySymbol = this.tsUtils.trueSymbolAtLocation(arrayAccessInfo.arrayIdent); + if (!arraySymbol) { return; } - if (!importDeclNode.importClause) { + const arrayCheckedAgainst = this.checkConditionForArrayAccess(loopCondition, arraySymbol); + if (!arrayCheckedAgainst) { + this.incrementCounters(arrayAccessInfo.arrayIdent.parent, FaultID.RuntimeArrayCheck); return; } - const modulePath = importDeclNode.moduleSpecifier.getText().slice(1, -1); - if (modulePath.startsWith('./') || modulePath.startsWith('../')) { + this.checkIfAccessAndCheckVariablesMatch(arrayAccessInfo, arrayCheckedAgainst); + } - /* - * Reason for this method to check the oh module imports, - * We do not use relative paths when importing from OhModules, - * So we do not check the relative paths - */ + private checkIfAccessAndCheckVariablesMatch(accessInfo: ArrayAccess, checkedAgainst: CheckedIdentifier): void { + const { arrayIdent, accessingIdentifier } = accessInfo; + + if (accessingIdentifier === NUMBER_LITERAL) { + if (checkedAgainst === NUMBER_LITERAL) { + return; + } + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); return; } - if (this.checkFileExists(importDeclNode.importClause)) { + if (checkedAgainst === NUMBER_LITERAL) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); return; } - if (TsUtils.isValidOhModulePath(modulePath) || !TsUtils.isOhModule(modulePath)) { - // Valid or paths that we do not check because they are not ohModules + const checkedAgainstSym = this.tsUtils.trueSymbolAtLocation(checkedAgainst); + if (!checkedAgainstSym) { return; } - const pathParts = modulePath.split(PATH_SEPARATOR); - const etsIdx = pathParts.indexOf(ETS_PART); + const accessingIdentSym = this.tsUtils.trueSymbolAtLocation(accessingIdentifier); - if (etsIdx === 0) { - const autofix = Autofixer.addDefaultModuleToPath(pathParts, importDeclNode); - this.incrementCounters(importDeclNode, FaultID.OhmUrlFullPath, autofix); + if (checkedAgainstSym !== accessingIdentSym) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); return; } - const autofix = Autofixer.fixImportPath(pathParts, etsIdx, importDeclNode); - this.incrementCounters(importDeclNode, FaultID.OhmUrlFullPath, autofix); + if (this.isChangedAfterCheck(arrayIdent.getSourceFile(), checkedAgainstSym)) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); + } } - private checkFileExists(importClause: ts.ImportClause): boolean { + private checkConditionForArrayAccess(condition: ts.Expression, arraySymbol: ts.Symbol): UncheckedIdentifier { + if (!ts.isBinaryExpression(condition)) { + return undefined; + } + const { left, right } = condition; + + if (ts.isBinaryExpression(left)) { + return this.checkConditionForArrayAccess(left, arraySymbol); + } + if (ts.isBinaryExpression(right)) { + return this.checkConditionForArrayAccess(right, arraySymbol); + } - /* - * TODO: what would have a symbol on this context - * would the moduleSpecifier? I don't think so - * I think it would be the identifier - * Which would be the expression - * - * We get the symbol from import clause - * get a identifier inside the import clause and check if that file exists or not - */ - for (const child of importClause.getChildren()) { - if (child.kind !== ts.SyntaxKind.Identifier) { - continue; + if (this.isArrayLengthAccess(left, arraySymbol)) { + if (ts.isNumericLiteral(right)) { + return NUMBER_LITERAL; } - const declNode = this.tsUtils.getDeclarationNode(child); - if (declNode) { - // this is a valid path that and the file should not be checked - return true; + if (!ts.isIdentifier(right)) { + return undefined; } + return right; } - return false; - } - private handleSharedModuleNoSideEffectImport(node: ts.ImportDeclaration): void { - // check 'use shared' - if (TypeScriptLinter.inSharedModule(node) && !node.importClause) { - this.incrementCounters(node, FaultID.SharedNoSideEffectImport); + if (this.isArrayLengthAccess(right, arraySymbol)) { + if (ts.isNumericLiteral(left)) { + return NUMBER_LITERAL; + } + if (!ts.isIdentifier(left)) { + return undefined; + } + return left; } + + return undefined; } - private static inSharedModule(node: ts.Node): boolean { - const sourceFile: ts.SourceFile = node.getSourceFile(); - const modulePath = path.normalize(sourceFile.fileName); - if (TypeScriptLinter.sharedModulesCache.has(modulePath)) { - return TypeScriptLinter.sharedModulesCache.get(modulePath)!; + private isArrayLengthAccess(expr: ts.Expression, arraySymbol: ts.Symbol): boolean { + if (!ts.isPropertyAccessExpression(expr)) { + return false; + } + if (this.tsUtils.trueSymbolAtLocation(expr.expression) !== arraySymbol) { + return false; + } + if (expr.name.text !== 'length') { + return false; + } + + return true; + } + + private checkBodyHasArrayAccess(loopBody: ts.Block): ArrayAccess | undefined { + let arrayAccessResult: undefined | ArrayAccess; + // check if this element access expression is of an array. + for (const child of loopBody.statements) { + const result = this.checkElementAccessOfArray(child); + if (!result) { + continue; + } + arrayAccessResult = result; + } + return arrayAccessResult; + } + + private checkArrayUsageWithoutBound(accessExpr: ts.ElementAccessExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + const arrayAccessInfo = this.isElementAccessOfArray(accessExpr); + if (!arrayAccessInfo) { + return; + } + + const { arrayIdent } = arrayAccessInfo; + const arraySym = this.tsUtils.trueSymbolAtLocation(arrayIdent); + if (!arraySym) { + return; + } + const sourceFile = arrayIdent.getSourceFile(); + + for (const statement of sourceFile.statements) { + if (this.checkStatementForArrayAccess(statement, arrayAccessInfo, arraySym) === CheckResult.SKIP) { + continue; + } + } + } + + private checkStatementForArrayAccess( + statement: ts.Statement, + accessInfo: ArrayAccess, + arraySym: ts.Symbol + ): CheckResult { + if (!ts.isIfStatement(statement)) { + return CheckResult.SKIP; + } + + if (this.checkBodyHasArrayAccess(statement.thenStatement as ts.Block) !== undefined) { + return CheckResult.SKIP; + } + + const checkedAgainst = this.checkConditionForArrayAccess(statement.expression, arraySym); + if (!checkedAgainst) { + return CheckResult.SKIP; + } + + this.checkIfAccessAndCheckVariablesMatch(accessInfo, checkedAgainst); + return CheckResult.CHECKED; + } + + private isChangedAfterCheck(sourceFile: ts.SourceFile, sym: ts.Symbol): boolean { + for (const statement of sourceFile.statements) { + if (!ts.isExpressionStatement(statement)) { + continue; + } + if (!ts.isBinaryExpression(statement.expression)) { + continue; + } + if (!ts.isIdentifier(statement.expression.left)) { + continue; + } + if (statement.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + continue; + } + + const leftSym = this.tsUtils.trueSymbolAtLocation(statement.expression.left); + if (!leftSym) { + continue; + } + + if (leftSym === sym) { + return true; + } + continue; + } + + return false; + } + + private handleForInStatement(node: ts.Node): void { + const tsForInStmt = node as ts.ForInStatement; + const tsForInInit = tsForInStmt.initializer; + this.checkForLoopDestructuring(tsForInInit); + this.incrementCounters(node, FaultID.ForInStatement); + } + + private handleForOfStatement(node: ts.Node): void { + const tsForOfStmt = node as ts.ForOfStatement; + const tsForOfInit = tsForOfStmt.initializer; + this.checkForLoopDestructuring(tsForOfInit); + } + + private handleIfStatement(ifStatement: ts.IfStatement): void { + if (this.options.arkts2 && this.useStatic) { + this.checkIfStatementForArrayUsage(ifStatement); + } + } + + private checkIfStatementForArrayUsage(ifStatement: ts.IfStatement): void { + if (!ts.isBlock(ifStatement.thenStatement)) { + return; + } + + const accessInfo = this.checkBodyHasArrayAccess(ifStatement.thenStatement); + if (!accessInfo) { + return; + } + const { arrayIdent } = accessInfo; + + const arraySymbol = this.tsUtils.trueSymbolAtLocation(arrayIdent); + if (!arraySymbol) { + return; + } + + const checkedAgainst = this.checkConditionForArrayAccess(ifStatement.expression, arraySymbol); + if (!checkedAgainst) { + return; + } + + this.checkIfAccessAndCheckVariablesMatch(accessInfo, checkedAgainst); + } + + private updateDataSdkJsonInfo(importDeclNode: ts.ImportDeclaration, importClause: ts.ImportClause): void { + const sdkInfo = TypeScriptLinter.pathMap.get(importDeclNode.moduleSpecifier.getText()); + if (sdkInfo && importClause.namedBindings) { + const namedImports = importClause.namedBindings as ts.NamedImports; + if (!namedImports.elements) { + return; + } + namedImports.elements.forEach((element) => { + const elementName = element.name.getText(); + sdkInfo.forEach((info) => { + TypeScriptLinter.addOrUpdateData(this.interfaceMap, elementName, info); + }); + }); + } + } + + private handleImportDeclaration(node: ts.Node): void { + // early exit via exception if cancellation was requested + this.options.cancellationToken?.throwIfCancellationRequested(); + const importDeclNode = node as ts.ImportDeclaration; + this.handleImportModule(importDeclNode); + if (this.options.arkts2) { + const importClause = importDeclNode.importClause; + if (!importClause || !importClause.name && !importClause.namedBindings) { + this.incrementCounters(node, FaultID.NoSideEffectImport); + } else { + this.updateDataSdkJsonInfo(importDeclNode, importClause); + } + } + if (importDeclNode.parent.statements) { + for (const stmt of importDeclNode.parent.statements) { + if (stmt === importDeclNode) { + break; + } + if (!ts.isImportDeclaration(stmt)) { + this.incrementCounters(node, FaultID.ImportAfterStatement); + break; + } + } + } + + const expr = importDeclNode.moduleSpecifier; + if (expr.kind === ts.SyntaxKind.StringLiteral) { + if (importDeclNode.assertClause) { + this.incrementCounters(importDeclNode.assertClause, FaultID.ImportAssertion); + } + const stringLiteral = expr as ts.StringLiteral; + this.handleSdkSendable(stringLiteral); + } + + // handle no side effect import in sendable module + this.handleSharedModuleNoSideEffectImport(importDeclNode); + this.handleInvalidIdentifier(importDeclNode); + this.checkStdLibConcurrencyImport(importDeclNode); + this.handleInterOpImportJs(importDeclNode); + this.checkForDeprecatedModules(node); + } + + private checkForDeprecatedModules(node: ts.Node): void { + if (!ts.isImportDeclaration(node)) { + return; + } + + const deprecatedModules = ['@ohos.file.sendablePhotoAccessHelper']; + + const importDecl = node; + const moduleSpecifier = importDecl.moduleSpecifier; + + if (ts.isStringLiteral(moduleSpecifier)) { + const moduleName = moduleSpecifier.text; + if (deprecatedModules.includes(moduleName)) { + this.incrementCounters(moduleSpecifier, FaultID.SdkTypeQuery); + } + } + } + + private handleSdkSendable(tsStringLiteral: ts.StringLiteral): void { + if (!this.options.arkts2) { + return; + } + + const moduleSpecifierValue = tsStringLiteral.getText(); + const sdkInfos = TypeScriptLinter.pathMap.get(moduleSpecifierValue); + + if (!sdkInfos || sdkInfos.size === 0) { + return; + } + if (moduleSpecifierValue.includes('sendable')) { + this.incrementCounters(tsStringLiteral, FaultID.SendablePropTypeFromSdk); + } + } + + private handleImportModule(importDeclNode: ts.ImportDeclaration): void { + if (!this.options.arkts2) { + return; + } + + 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, + * So we do not check the relative paths + */ + return; + } + if (!importDeclNode.importClause) { + return; + } + + const pathParts = modulePath.split(PATH_SEPARATOR); + const etsIdx = pathParts.indexOf(ETS_PART); + + if (this.options.wholeProjectPath) { + if (TsUtils.checkFileExists(etsIdx !== 0, importDeclNode, modulePath, this.options.wholeProjectPath)) { + return; + } + } + + if (TsUtils.isValidOhModulePath(modulePath) || !TsUtils.isOhModule(modulePath)) { + // Valid or paths that we do not check because they are not ohModules + return; + } + + if (etsIdx === 0) { + const autofix = this.autofixer?.addDefaultModuleToPath(pathParts, importDeclNode); + this.incrementCounters(importDeclNode, FaultID.OhmUrlFullPath, autofix); + return; + } + + const autofix = this.autofixer?.fixImportPath(pathParts, etsIdx, importDeclNode); + this.incrementCounters(importDeclNode, FaultID.OhmUrlFullPath, autofix); + } + + private handleSharedModuleNoSideEffectImport(node: ts.ImportDeclaration): void { + // check 'use shared' + if (TypeScriptLinter.inSharedModule(node) && !node.importClause) { + this.incrementCounters(node, FaultID.SharedNoSideEffectImport); + } + } + + private static inSharedModule(node: ts.Node): boolean { + const sourceFile: ts.SourceFile = node.getSourceFile(); + const modulePath = path.normalize(sourceFile.fileName); + if (TypeScriptLinter.sharedModulesCache.has(modulePath)) { + return TypeScriptLinter.sharedModulesCache.get(modulePath)!; } const isSharedModule: boolean = TsUtils.isSharedModule(sourceFile); TypeScriptLinter.sharedModulesCache.set(modulePath, isSharedModule); @@ -964,9 +1306,16 @@ export class TypeScriptLinter { } private handlePropertyAccessExpression(node: ts.Node): void { + this.handleMakeObserved(node as ts.PropertyAccessExpression); + this.handleStateStyles(node as ts.PropertyAccessExpression); this.handleDoubleDollar(node); + this.handleQuotedHyphenPropsDeprecated(node as ts.PropertyAccessExpression); this.handleSdkTypeQuery(node as ts.PropertyAccessExpression); this.checkUnionTypes(node as ts.PropertyAccessExpression); + this.handleLimitedVoidTypeFromSdkOnPropertyAccessExpression(node as ts.PropertyAccessExpression); + this.checkDepricatedIsConcurrent(node as ts.PropertyAccessExpression); + this.propertyAccessExpressionForBuiltin(node as ts.PropertyAccessExpression); + if (ts.isCallExpression(node.parent) && node === node.parent.expression) { return; } @@ -982,7 +1331,6 @@ export class TypeScriptLinter { if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { this.incrementCounters(propertyAccessNode.name, FaultID.Prototype); } - if ( !this.options.arkts2 && !!exprSym && @@ -992,7 +1340,6 @@ export class TypeScriptLinter { this.incrementCounters(propertyAccessNode, FaultID.SymbolType); } if (this.options.advancedClassChecks && this.tsUtils.isClassObjectExpression(propertyAccessNode.expression)) { - // missing exact rule this.incrementCounters(propertyAccessNode.expression, FaultID.ClassAsObject); } @@ -1009,6 +1356,13 @@ export class TypeScriptLinter { this.handleArkTSPropertyAccess(propertyAccessNode); } + propertyAccessExpressionForBuiltin(decl: ts.PropertyAccessExpression): void { + if (this.options.arkts2) { + this.handleSymbolIterator(decl); + this.handleGetOwnPropertyNames(decl); + } + } + propertyAccessExpressionForInterop( exprSym: ts.Symbol | undefined, propertyAccessNode: ts.PropertyAccessExpression @@ -1030,6 +1384,45 @@ export class TypeScriptLinter { } } + private checkDepricatedIsConcurrent(node: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; + } + if (!ts.isCallExpression(node.parent)) { + return; + } + + const methodName = node.name.getText(); + + if (methodName !== ISCONCURRENT) { + return; + } + + const symbol = this.tsUtils.trueSymbolAtLocation(node.expression); + if (!symbol) { + return; + } + + if (symbol.name === TASKPOOL) { + const decl = TsUtils.getDeclaration(symbol); + + if (!decl) { + return; + } + + const sourceFile = decl.getSourceFile(); + const fileName = path.basename(sourceFile.fileName); + + if ( + TASKPOOL_MODULES.some((moduleName) => { + return fileName.startsWith(moduleName); + }) + ) { + this.incrementCounters(node.name, FaultID.IsConcurrentDeprecated); + } + } + } + checkFunctionProperty( node: ts.PropertyAccessExpression, baseExprSym: ts.Symbol | undefined, @@ -1068,7 +1461,7 @@ export class TypeScriptLinter { const rhs = binaryExpr.right; const lhs = binaryExpr.left as ts.PropertyAccessExpression; - const autofix = Autofixer.fixInteropTsType(binaryExpr, lhs, rhs); + const autofix = this.autofixer?.fixInteropTsType(binaryExpr, lhs, rhs); this.incrementCounters(pan, FaultID.InteropDirectAccessToTSTypes, autofix); } @@ -1129,7 +1522,6 @@ export class TypeScriptLinter { } private handlePropertyDeclaration(node: ts.PropertyDeclaration): void { - this.handleDataObservation(node); const propName = node.name; this.handleLiteralAsPropertyName(node); const decorators = ts.getDecorators(node); @@ -1161,7 +1553,8 @@ export class TypeScriptLinter { this.checkAssignmentNumericSemanticslyPro(node); this.handleInvalidIdentifier(node); this.handleStructPropertyDecl(node); - this.handleApipathChanged(node); + this.handlePropertyDeclarationForProp(node); + this.handleSdkDuplicateDeclName(node); } private handleSendableClassProperty(node: ts.PropertyDeclaration): void { @@ -1186,8 +1579,9 @@ export class TypeScriptLinter { private handlePropertyAssignment(node: ts.PropertyAssignment): void { this.handleDollarBind(node); + this.handleQuotedHyphenPropsDeprecated(node); const propName = node.name; - if (!(!!propName && ts.isNumericLiteral(propName))) { + if (!propName || !(ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { return; } @@ -1241,6 +1635,10 @@ export class TypeScriptLinter { this.handleLiteralAsPropertyName(node); this.handleSendableInterfaceProperty(node); this.handleInvalidIdentifier(node); + const typeNode = node.type; + if (this.options.arkts2 && typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { + this.incrementCounters(typeNode, FaultID.LimitedVoidType); + } } private handleInterfaceProperty(node: ts.PropertySignature): void { @@ -1248,8 +1646,8 @@ export class TypeScriptLinter { if (node.type && ts.isFunctionTypeNode(node.type)) { const interfaceName = node.parent.name.getText(); const propertyName = node.name.getText(); - const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile!); - const allInterfaces = TypeScriptLinter.getAllInterfaceFromSourceFile(this.sourceFile!); + const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile); + const allInterfaces = TypeScriptLinter.getAllInterfaceFromSourceFile(this.sourceFile); this.visitClassMembers(allClasses, interfaceName, propertyName); this.visitInterfaceMembers(allInterfaces, interfaceName, propertyName); } @@ -1266,7 +1664,7 @@ export class TypeScriptLinter { const implementsClause = this.getExtendsClause(interfaceDecl); if ( implementsClause?.types.some((type) => { - return type.getText() === interfaceName; + return type.expression.getText() === interfaceName; }) ) { this.checkInterfaceForProperty(interfaceDecl, propertyName); @@ -1310,7 +1708,7 @@ export class TypeScriptLinter { const implementsClause = this.getImplementsClause(classDecl); if ( implementsClause?.types.some((type) => { - return type.getText() === interfaceName; + return type.expression.getText() === interfaceName; }) ) { this.checkClassForProperty(classDecl, propertyName); @@ -1422,6 +1820,7 @@ export class TypeScriptLinter { this.handleMissingReturnType(arrowFunc); } } + this.checkDefaultParamBeforeRequired(arrowFunc); } private handleFunctionDeclaration(node: ts.Node): void { @@ -1466,6 +1865,7 @@ export class TypeScriptLinter { this.handleTSOverload(tsFunctionDeclaration); this.checkAssignmentNumericSemanticsFuntion(tsFunctionDeclaration); this.handleInvalidIdentifier(tsFunctionDeclaration); + this.checkDefaultParamBeforeRequired(tsFunctionDeclaration); } private handleMissingReturnType( @@ -1577,12 +1977,20 @@ export class TypeScriptLinter { } private handleInteropOperand(tsUnaryArithm: ts.PrefixUnaryExpression): void { - if (ts.isPropertyAccessExpression(tsUnaryArithm.operand)) { - const exprSym = this.tsUtils.trueSymbolAtLocation(tsUnaryArithm.operand); - const declaration = exprSym?.declarations?.[0]; - this.checkAndProcessDeclaration(declaration, tsUnaryArithm); - } - } + const processPropertyAccess = (expr: ts.PropertyAccessExpression | ts.ParenthesizedExpression): void => { + const propertyAccess = ts.isParenthesizedExpression(expr) ? expr.expression : expr; + + if (ts.isPropertyAccessExpression(propertyAccess)) { + const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccess); + const declaration = exprSym?.declarations?.[0]; + this.checkAndProcessDeclaration(declaration, tsUnaryArithm); + } + }; + + if (ts.isPropertyAccessExpression(tsUnaryArithm.operand) || ts.isParenthesizedExpression(tsUnaryArithm.operand)) { + processPropertyAccess(tsUnaryArithm.operand); + } + } private checkAndProcessDeclaration( declaration: ts.Declaration | undefined, @@ -1667,12 +2075,21 @@ export class TypeScriptLinter { this.checkAssignmentMatching(tsBinaryExpr, leftOperandType, tsRhsExpr); this.checkFunctionTypeCompatible(typeNode, tsRhsExpr); this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); + this.handleSdkDuplicateDeclName(tsBinaryExpr); + this.checkArrayTypeImmutable(tsBinaryExpr); + break; + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: + case ts.SyntaxKind.QuestionQuestionEqualsToken: + case ts.SyntaxKind.BarBarEqualsToken: + if (this.options.arkts2) { + this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.UnsupportOperator); + } break; default: } - this.checkNumericSemantics(tsBinaryExpr); this.checkInterOpImportJsDataCompare(tsBinaryExpr); this.checkInteropEqualityJudgment(tsBinaryExpr); + this.handleNumericBigintCompare(tsBinaryExpr); } private checkInterOpImportJsDataCompare(expr: ts.BinaryExpression): void { @@ -1694,7 +2111,6 @@ export class TypeScriptLinter { if (!initializer) { return false; } - return isJsFileExpression(initializer); }; @@ -1708,7 +2124,7 @@ export class TypeScriptLinter { const processExpression = (expr: ts.Expression): void => { const symbol = this.tsUtils.trueSymbolAtLocation(expr); - if (isJsFileSymbol(symbol)) { + if (isJsFileSymbol(symbol) || isJsFileExpression(expr)) { this.incrementCounters(expr, FaultID.InterOpImportJsDataCompare); } }; @@ -1722,8 +2138,7 @@ export class TypeScriptLinter { ts.SyntaxKind.GreaterThanToken, ts.SyntaxKind.LessThanToken, ts.SyntaxKind.GreaterThanEqualsToken, - ts.SyntaxKind.LessThanEqualsToken, - ts.SyntaxKind.EqualsToken + ts.SyntaxKind.LessThanEqualsToken ].includes(kind); } @@ -1745,7 +2160,7 @@ export class TypeScriptLinter { } private handleTsInterop(nodeToCheck: ts.Node, handler: { (): void }): void { - if (!this.options.arkts2) { + if (!this.options.arkts2 || !this.useStatic) { return; } @@ -1769,6 +2184,31 @@ export class TypeScriptLinter { handler(); } + private handleJsInterop(nodeToCheck: ts.Node, handler: { (): void }): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + const declarationNode = this.tsUtils.getDeclarationNode(nodeToCheck); + if (!declarationNode) { + return; + } + + const fileName = declarationNode.getSourceFile().fileName; + if (fileName.includes(ARKTS_IGNORE_DIRS_OH_MODULES)) { + return; + } + if (!fileName.endsWith(EXTNAME_JS)) { + return; + } + + if (fileName.endsWith(EXTNAME_D_TS)) { + return; + } + + handler(); + } + private processBinaryAssignment( binaryExpr: ts.BinaryExpression, tsLhsExpr: ts.Expression, @@ -1793,30 +2233,6 @@ export class TypeScriptLinter { } } - private checkNumericSemantics(binaryExpr: ts.BinaryExpression): void { - if (!this.options.arkts2) { - return; - } - if (isAssignmentOperator(binaryExpr.operatorToken)) { - this.checkAssignmentNumericSemantics(binaryExpr); - } else if (binaryExpr.operatorToken.kind === ts.SyntaxKind.SlashToken) { - this.checkDivisionNumericSemantics(binaryExpr); - } - } - - private checkAssignmentNumericSemantics(binaryExpr: ts.BinaryExpression): void { - const sym = this.tsTypeChecker.getSymbolAtLocation(binaryExpr.left); - if (this.tsUtils.isIntegerVariable(sym) && !this.tsUtils.isIntegerValue(binaryExpr.right)) { - this.incrementCounters(binaryExpr, FaultID.NumericSemantics); - } - } - - private checkDivisionNumericSemantics(binaryExpr: ts.BinaryExpression): void { - if (this.tsUtils.isIntegerValue(binaryExpr.left) && this.tsUtils.isIntegerValue(binaryExpr.right)) { - this.incrementCounters(binaryExpr, FaultID.NumericSemantics); - } - } - private checkAssignmentNumericSemanticsly(node: ts.VariableDeclaration): void { if (!this.options.arkts2) { return; @@ -1832,6 +2248,14 @@ export class TypeScriptLinter { return; } + if ( + ts.isBinaryExpression(initializer) && + ts.isCallExpression(initializer.left) && + TsUtils.isAppStorageAccess(initializer.left) + ) { + return; + } + const sym = this.tsTypeChecker.getSymbolAtLocation(name); if (!sym) { return; @@ -2066,6 +2490,7 @@ export class TypeScriptLinter { private handleVariableDeclaration(node: ts.Node): void { const tsVarDecl = node as ts.VariableDeclaration; + this.handleVariableDeclarationForProp(tsVarDecl); if ( !this.options.useRtLogic || ts.isVariableDeclarationList(tsVarDecl.parent) && ts.isVariableStatement(tsVarDecl.parent.parent) @@ -2092,6 +2517,49 @@ export class TypeScriptLinter { this.checkAssignmentNumericSemanticsly(tsVarDecl); this.checkTypeFromSdk(tsVarDecl.type); this.handleNoStructuralTyping(tsVarDecl); + this.handleObjectLiteralforUnionTypeInterop(tsVarDecl); + this.handleObjectLiteralAssignmentToClass(tsVarDecl); + this.handleObjectLiteralAssignment(tsVarDecl); + this.handlePropertyDescriptorInScenarios(tsVarDecl); + this.handleSdkDuplicateDeclName(tsVarDecl); + this.checkArrayTypeImmutable(tsVarDecl); + } + + private checkArrayTypeImmutable(node: ts.VariableDeclaration | ts.BinaryExpression): void { + if (!this.options.arkts2) { + return; + } + if (ts.isVariableDeclaration(node)) { + if (!node.initializer || ts.isArrayLiteralExpression(node.initializer)) { + return; + } + if (node.type && ts.isArrayTypeNode(node.type)) { + const varDeclType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(node.name)); + const initializerType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(node.initializer)); + if (varDeclType !== initializerType) { + this.incrementCounters(node, FaultID.ArrayTypeImmutable); + } + } + } else { + this.checkArrayTypeImmutableForBinaryExpression(node); + } + } + + private checkArrayTypeImmutableForBinaryExpression(node: ts.BinaryExpression): void { + const sym = this.tsTypeChecker.getSymbolAtLocation(node.left); + const declaration = sym?.declarations?.[0]; + if ( + declaration && + (ts.isVariableDeclaration(declaration) || ts.isParameter(declaration) || ts.isPropertyDeclaration(declaration)) + ) { + if (declaration.type && ts.isArrayTypeNode(declaration.type) && !ts.isArrayLiteralExpression(node.right)) { + const leftType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(node.left)); + const rightType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(node.right)); + if (leftType !== rightType) { + this.incrementCounters(node, FaultID.ArrayTypeImmutable); + } + } + } } private checkTypeFromSdk(type: ts.TypeNode | undefined): void { @@ -2107,7 +2575,7 @@ export class TypeScriptLinter { } for (const sdkInfo of sdkInfos) { - if (nameArr.includes(sdkInfo.api_name)) { + if (sdkInfo.api_name && nameArr.includes(sdkInfo.api_name)) { this.incrementCounters(type, FaultID.LimitedVoidTypeFromSdk); return; } @@ -2393,13 +2861,21 @@ export class TypeScriptLinter { const autofix = this.autofixer?.dropTypeOnVarDecl(tsCatch.variableDeclaration); this.incrementCounters(node, FaultID.CatchWithUnsupportedType, autofix); } + + if ( + this.options.arkts2 && + tsCatch.variableDeclaration && + TsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(tsCatch.variableDeclaration)) + ) { + this.incrementCounters(node, FaultID.TsLikeCatchType); + } } private handleClassExtends(tsClassDecl: ts.ClassDeclaration): void { if (!this.options.arkts2) { return; } - const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile!); + const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile); const classMap = new Map(); allClasses.forEach((classDecl) => { if (classDecl.name && !classDecl.heritageClauses) { @@ -2477,35 +2953,53 @@ export class TypeScriptLinter { this.processClassStaticBlocks(tsClassDecl); this.handleInvalidIdentifier(tsClassDecl); this.handleSdkMethod(tsClassDecl); + this.handleNotsLikeSmartType(tsClassDecl); } private static findFinalExpression(typeNode: ts.TypeNode): ts.Node { let currentNode = typeNode; - /* CC-OFFNXT(no_explicit_any) std lib */ - // Handle comment directive '@ts-nocheck' + + /* + * CC-OFFNXT(no_explicit_any) std lib + * Handle comment directive '@ts-nocheck' + */ while ((currentNode as any).expression) { - /* CC-OFFNXT(no_explicit_any) std lib */ - // Handle comment directive '@ts-nocheck' + + /* + * CC-OFFNXT(no_explicit_any) std lib + * Handle comment directive '@ts-nocheck' + */ currentNode = (currentNode as any).expression; } return currentNode; } - private processSdkMethodClauseTypes(tsClassDecl: ts.ClassDeclaration, heritageClause: ts.HeritageClause): void { - for (const type of heritageClause.types) { + private processSdkMethodClauseTypes( + tsClassDecl: ts.ClassDeclaration, + heritageClause: ts.HeritageClause, + methodName?: string + ): boolean { + return heritageClause.types.some((type) => { const fullTypeName = TypeScriptLinter.findFinalExpression(type).getText(); const sdkInfos = this.interfaceMap.get(fullTypeName); if (!sdkInfos || sdkInfos.size === 0) { - continue; + return false; } - for (const sdkInfo of sdkInfos) { - if (sdkInfo.api_type !== 'MethodSignature') { - continue; + return Array.from(sdkInfos).some((sdkInfo) => { + if (sdkInfo.api_type !== METHOD_SIGNATURE && sdkInfo.api_type !== METHOD_DECLARATION) { + return false; } - this.processSdkInfoWithMembers(sdkInfo, tsClassDecl.members); - } - } + + if (!methodName) { + this.processSdkInfoWithMembers(sdkInfo, tsClassDecl.members,tsClassDecl); + return false; + } + + const symbol = this.tsTypeChecker.getSymbolAtLocation(type.expression); + return TypeScriptLinter.isHeritageClauseisThirdPartyBySymbol(symbol) && sdkInfo.api_name === methodName; + }); + }); } private handleSdkMethod(tsClassDecl: ts.ClassDeclaration): void { @@ -2527,7 +3021,7 @@ export class TypeScriptLinter { } } - private processSdkInfoWithMembers(sdkInfo: ApiInfo, members: ts.NodeArray): void { + private processSdkInfoWithMembers(sdkInfo: ApiInfo, members: ts.NodeArray,tsClassDecl:ts.ClassDeclaration): void { for (const member of members) { if (!ts.isMethodDeclaration(member)) { continue; @@ -2535,12 +3029,14 @@ export class TypeScriptLinter { const memberName = member.name?.getText(); if (sdkInfo.api_name === memberName) { - if (TypeScriptLinter.areParametersEqual(sdkInfo.api_func_args, member.parameters)) { - this.incrementCounters( - member, - sdkInfo.problem === 'OptionalMethod' ? FaultID.OptionalMethodFromSdk : FaultID.LimitedVoidTypeFromSdk - ); + if (!TypeScriptLinter.areParametersEqual(sdkInfo.api_func_args ?? [], member.parameters) && + !TypeScriptLinter.areGenericsParametersEqual(sdkInfo.api_func_args ?? [], tsClassDecl)) { + return; } + this.incrementCounters( + member, + sdkInfo.problem === OPTIONAL_METHOD ? FaultID.OptionalMethodFromSdk : FaultID.LimitedVoidTypeFromSdk + ); } } } @@ -2564,6 +3060,85 @@ export class TypeScriptLinter { return true; } + private processLimitedVoidTypeFromSdkOnClassDeclaration( + tsClassDecl: ts.ClassDeclaration, + methodName?: string + ): boolean { + if ( + !this.options.arkts2 || + !tsClassDecl.heritageClauses || + tsClassDecl.heritageClauses.length === 0 || + !tsClassDecl.members || + tsClassDecl.members.length === 0 + ) { + return false; + } + let res: boolean = false; + for (const heritageClause of tsClassDecl.heritageClauses) { + if (heritageClause.types?.length) { + res = this.processSdkMethodClauseTypes(tsClassDecl, heritageClause, methodName); + break; + } + } + return res; + } + + private static isHeritageClauseisThirdPartyBySymbol(symbol: ts.Symbol | undefined): boolean { + if (!symbol) { + return false; + } + const declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + const firstDeclaration = declarations[0]; + if (ts.isImportSpecifier(firstDeclaration)) { + return true; + } + } + return false; + } + + private handleLimitedVoidTypeFromSdkOnPropertyAccessExpression(node: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; + } + const sym = this.getOriginalSymbol(node.name); + if (!sym) { + return; + } + const methodName = node.name.getText(); + const declaration = sym.declarations?.[0]; + if (declaration && ts.isClassDeclaration(declaration.parent)) { + if (this.processLimitedVoidTypeFromSdkOnClassDeclaration(declaration.parent, methodName)) { + this.incrementCounters(node, FaultID.LimitedVoidTypeFromSdk); + } + } + } + private static areGenericsParametersEqual( + sdkFuncArgs: { name: string; type: string }[], + node: ts.ClassDeclaration + ): boolean { + if (!ts.isClassDeclaration(node)) { + return false; + } + const apiParamCout = sdkFuncArgs.length; + const typeParameters = node.typeParameters; + if (!typeParameters) { + return false; + } + typeParameters.forEach(typeParam => { + if (!typeParam.constraint) { + return false; + } + for (let i = 0; i < apiParamCout; i++) { + if (!typeParam.constraint.getText().match(sdkFuncArgs[i].type)) { + return false; + } + } + return true; + }); + return true; + } + private handleNotSupportCustomDecorators(decorator: ts.Decorator): void { if (!this.options.arkts2) { return; @@ -2633,6 +3208,9 @@ export class TypeScriptLinter { const staticBlockNodes: ts.Node[] = []; for (const element of classDecl.members) { if (ts.isClassStaticBlockDeclaration(element)) { + if (this.options.arkts2 && this.useStatic) { + this.incrementCounters(element, FaultID.NoStaticOnClass); + } staticBlockNodes[staticBlocksCntr] = element; staticBlocksCntr++; } @@ -2790,7 +3368,8 @@ export class TypeScriptLinter { private handleImportClause(node: ts.Node): void { const tsImportClause = node as ts.ImportClause; if (this.options.arkts2 && tsImportClause.isLazy) { - this.incrementCounters(node, FaultID.ImportLazyIdentifier); + const autofix = this.autofixer?.fixImportClause(tsImportClause); + this.incrementCounters(node, FaultID.ImportLazyIdentifier, autofix); } if (tsImportClause.name) { this.countDeclarationsWithDuplicateName(tsImportClause.name, tsImportClause); @@ -2853,6 +3432,147 @@ export class TypeScriptLinter { if (!this.tsUtils.isAbstractMethodInAbstractClass(node)) { this.handleTSOverload(tsMethodDecl); } + this.checkDefaultParamBeforeRequired(tsMethodDecl); + this.handleMethodInherit(tsMethodDecl); + } + + private checkDefaultParamBeforeRequired(node: ts.FunctionLikeDeclarationBase): void { + if (!this.options.arkts2) { + return; + } + + const params = node.parameters; + let seenRequired = false; + + for (let i = params.length - 1; i >= 0; i--) { + const param = params[i]; + + const isOptional = !!param.initializer || !!param.questionToken; + + if (!isOptional) { + seenRequired = true; + continue; + } + + if (seenRequired && param.initializer) { + this.incrementCounters(param.name, FaultID.DefaultArgsBehindRequiredArgs); + } + } + } + + private handleMethodInherit(node: ts.MethodDeclaration): void { + if (!this.options.arkts2 || !node.name || !ts.isIdentifier(node.name)) { + return; + } + + const classDecl = node.parent; + if (!ts.isClassDeclaration(classDecl)) { + return; + } + + const classType = this.tsTypeChecker.getTypeAtLocation(classDecl); + const baseTypes = classType.getBaseTypes(); + if (!baseTypes || baseTypes.length === 0) { + return; + } + + const methodName = node.name.text; + + for (const baseType of baseTypes) { + const baseMethod = baseType.getProperty(methodName); + if (!baseMethod) { + continue; + } + + const baseMethodDecl = baseMethod.declarations?.find(ts.isMethodDeclaration); + if (!baseMethodDecl) { + continue; + } + + // Check parameter compatibility + this.checkMethodParameters(node, baseMethodDecl); + + // Check return type compatibility + this.checkMethodReturnType(node, baseMethodDecl); + + break; + } + } + + /** + * Checks if child parameters accept at least as many types as parent parameters. + * (Child parameter type should be same or wider than parent.) + */ + private checkMethodParameters(derivedMethod: ts.MethodDeclaration, baseMethod: ts.MethodDeclaration): void { + const derivedParams = derivedMethod.parameters; + const baseParams = baseMethod.parameters; + + const paramCount = Math.min(derivedParams.length, baseParams.length); + + for (let i = 0; i < paramCount; i++) { + const baseParamType = this.tsTypeChecker.getTypeAtLocation(baseParams[i]); + const derivedParamType = this.tsTypeChecker.getTypeAtLocation(derivedParams[i]); + + if (!this.isTypeSameOrWider(baseParamType, derivedParamType)) { + this.incrementCounters(derivedParams[i], FaultID.MethodInheritRule); + } + } + } + + /** + * Checks return type covariance between base and derived methods. + * (Derived return type must be assignable to base return type.) + */ + private checkMethodReturnType(derivedMethod: ts.MethodDeclaration, baseMethod: ts.MethodDeclaration): void { + if (!baseMethod.type || !derivedMethod.type) { + return; + } + + const baseReturnType = this.tsTypeChecker.getTypeAtLocation(baseMethod.type); + const derivedReturnType = this.tsTypeChecker.getTypeAtLocation(derivedMethod.type); + + if (!this.isTypeAssignable(derivedReturnType, baseReturnType)) { + this.incrementCounters(derivedMethod.type, FaultID.MethodInheritRule); + } + } + + /** + * Child type should include all types of parent type (be same or wider). + * Returns true if every type in baseType is also included in derivedType. + */ + private isTypeSameOrWider(baseType: ts.Type, derivedType: ts.Type): boolean { + const baseTypeSet = new Set(this.flattenUnionTypes(baseType)); + const derivedTypeSet = new Set(this.flattenUnionTypes(derivedType)); + + // Check if every type in baseType is also present in derivedType + for (const typeStr of baseTypeSet) { + if (!derivedTypeSet.has(typeStr)) { + return false; + } + } + + return true; + } + + // Checks structural assignability between two types. + private isTypeAssignable(fromType: ts.Type, toType: ts.Type): boolean { + const fromTypes = this.flattenUnionTypes(fromType); + const toTypes = new Set(this.flattenUnionTypes(toType)); + + // All types in `fromTypes` should exist in `toTypes` for assignability. + return fromTypes.every((typeStr) => { + return toTypes.has(typeStr); + }); + } + + // Converts union types into an array of type strings for easy comparison. + private flattenUnionTypes(type: ts.Type): string[] { + if (type.isUnion()) { + return type.types.map((t) => { + return this.tsTypeChecker.typeToString(t); + }); + } + return [this.tsTypeChecker.typeToString(type)]; } private checkClassImplementsMethod(classDecl: ts.ClassDeclaration, methodName: string): boolean { @@ -2871,8 +3591,8 @@ export class TypeScriptLinter { if (this.options.arkts2 && ts.isInterfaceDeclaration(node.parent)) { const methodName = node.name.getText(); const interfaceName = node.parent.name.getText(); - const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile!); - const allInterfaces = TypeScriptLinter.getAllInterfaceFromSourceFile(this.sourceFile!); + const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile); + const allInterfaces = TypeScriptLinter.getAllInterfaceFromSourceFile(this.sourceFile); allClasses.forEach((classDecl) => { if (this.classImplementsInterface(classDecl, interfaceName)) { this.checkClassImplementsMethod(classDecl, methodName); @@ -2973,41 +3693,116 @@ export class TypeScriptLinter { if (isArkTs2 && this.tsTypeChecker.isArgumentsSymbol(tsIdentSym)) { this.incrementCounters(node, FaultID.ArgumentsObject); } - if (isArkTs2 && tsIdentifier.text === LIKE_FUNCTION && isStdLibrarySymbol(tsIdentSym)) { - this.incrementCounters(node, FaultID.ExplicitFunctionType); + + if (isArkTs2) { + this.checkWorkerSymbol(tsIdentSym, node); + this.checkCollectionsSymbol(tsIdentSym, node); + this.checkAsonSymbol(tsIdentSym, node); } } - private handleGlobalThisCase(node: ts.Identifier, isArkTs2: boolean | undefined): void { - let faultId = FaultID.GlobalThis; - let autofix: Autofix[] | undefined; - let targetNode: ts.Node = node; + private handlePropertyDescriptorInScenarios(node: ts.Node): void { + if (ts.isVariableDeclaration(node)) { + const name = node.name; + this.handlePropertyDescriptor(name); - if (!isArkTs2) { - this.incrementCounters(targetNode, faultId); - return; + const type = node.type; + if (!type || !ts.isTypeReferenceNode(type)) { + return; + } + const typeName = type.typeName; + this.handlePropertyDescriptor(typeName); } - faultId = FaultID.GlobalThisError; - if (ts.isPropertyAccessExpression(node.parent)) { - const parentExpression = node.parent.parent; - if ( - parentExpression && - ts.isBinaryExpression(parentExpression) && - parentExpression.operatorToken.kind === ts.SyntaxKind.EqualsToken - ) { - targetNode = parentExpression; - autofix = this.autofixer?.fixGlobalThisSet(targetNode as ts.BinaryExpression); - } else { - targetNode = node.parent; - autofix = this.autofixer?.fixGlobalThisGet(targetNode as ts.PropertyAccessExpression); + if (ts.isParameter(node)) { + const name = node.name; + this.handlePropertyDescriptor(name); + + const type = node.type; + if (!type || !ts.isTypeReferenceNode(type)) { + return; } + const typeName = type.typeName; + this.handlePropertyDescriptor(typeName); } - this.incrementCounters(targetNode, faultId, autofix); + if (ts.isPropertyAccessExpression(node)) { + const name = node.name; + this.handlePropertyDescriptor(name); + + const expression = node.expression; + this.handlePropertyDescriptor(expression); + } } - // hard-coded alternative to TypeScriptLinter.advancedClassChecks + private handlePropertyDescriptor(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + + const symbol = this.tsUtils.trueSymbolAtLocation(node); + if (!symbol || !ts.isIdentifier(node)) { + return; + } + const tsIdentifier = node; + const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, tsIdentifier); + + const typeSymbol = type.getSymbol(); + const typeName = typeSymbol ? typeSymbol.getName() : symbol.getName(); + + const noPropertyDescriptorSet = TypeScriptLinter.globalApiInfo.get(BuiltinProblem.BuiltinNoPropertyDescriptor); + if (!noPropertyDescriptorSet) { + return; + } + + const matchedApi = [...noPropertyDescriptorSet].some((apiInfoItem) => { + if (apiInfoItem.api_info.parent_api?.length <= 0) { + return false; + } + const apiInfoParentName = apiInfoItem.api_info.parent_api[0].api_name; + const apiTypeName = apiInfoItem.api_info.method_return_type; + const isSameApi = apiInfoParentName === typeName || apiTypeName === typeName; + const decl = TsUtils.getDeclaration(typeSymbol ? typeSymbol : symbol); + const sourceFileName = path.normalize(decl?.getSourceFile().fileName || ''); + const isSameFile = sourceFileName.endsWith(path.normalize(apiInfoItem.file_path)); + return isSameFile && isSameApi; + }); + + if (matchedApi) { + this.incrementCounters(tsIdentifier, FaultID.NoPropertyDescriptor); + } + } + + private handleGlobalThisCase(node: ts.Identifier, isArkTs2: boolean | undefined): void { + let faultId = FaultID.GlobalThis; + let autofix: Autofix[] | undefined; + let targetNode: ts.Node = node; + + if (!isArkTs2) { + this.incrementCounters(targetNode, faultId); + return; + } + faultId = FaultID.GlobalThisError; + + if (ts.isPropertyAccessExpression(node.parent)) { + const parentExpression = node.parent.parent; + if ( + parentExpression && + ts.isBinaryExpression(parentExpression) && + parentExpression.operatorToken.kind === ts.SyntaxKind.EqualsToken + ) { + targetNode = parentExpression; + autofix = this.autofixer?.fixGlobalThisSet(targetNode as ts.BinaryExpression); + } else { + targetNode = node.parent; + autofix = this.autofixer?.fixGlobalThisGet(targetNode as ts.PropertyAccessExpression); + } + } + + this.incrementCounters(targetNode, faultId, autofix); + } + + // hard-coded alternative to TypeScriptLinter.advancedClassChecks private isAllowedClassValueContext(tsIdentifier: ts.Identifier): boolean { let ctx: ts.Node = tsIdentifier; while (ts.isPropertyAccessExpression(ctx.parent) || ts.isQualifiedName(ctx.parent)) { @@ -3175,9 +3970,11 @@ export class TypeScriptLinter { if (this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isIndexableArray)) { this.handleIndexNegative(node); } + this.checkArrayUsageWithoutBound(tsElementAccessExpr); this.checkArrayIndexType(tsElemAccessBaseExprType, tsElemAccessArgType, tsElementAccessExpr); this.fixJsImportElementAccessExpression(tsElementAccessExpr); this.checkInterOpImportJsIndex(tsElementAccessExpr); + this.checkEnumGetMemberValue(tsElementAccessExpr); } private checkInterOpImportJsIndex(expr: ts.ElementAccessExpression): void { @@ -3225,12 +4022,17 @@ export class TypeScriptLinter { } const argExpr = TypeScriptLinter.getUnwrappedArgumentExpression(expr.argumentExpression); - - const validStringLiteralTypes = [STRINGLITERAL_INT, STRINGLITERAL_BYTE, STRINGLITERAL_SHORT, STRINGLITERAL_LONG]; + const validStringLiteralTypes = [ + STRINGLITERAL_INT, + STRINGLITERAL_BYTE, + STRINGLITERAL_SHORT, + STRINGLITERAL_LONG, + STRINGLITERAL_CHAR + ]; const argTypeString = this.tsTypeChecker.typeToString(argType); if (this.tsUtils.isNumberLikeType(argType)) { - this.handleNumericArgument(argExpr); + this.handleNumericArgument(argExpr, expr.argumentExpression, argType); } else if (!validStringLiteralTypes.includes(argTypeString)) { this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); } @@ -3240,15 +4042,33 @@ export class TypeScriptLinter { return argExpr.kind === ts.SyntaxKind.AsExpression ? (argExpr as ts.AsExpression).expression : argExpr; } - private handleNumericArgument(argExpr: ts.Expression): void { - if ( - ts.isNumericLiteral(argExpr) && !Number.isInteger(Number(argExpr.text)) || - argExpr.kind === ts.SyntaxKind.CallExpression - ) { - this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + private handleNumericArgument(argExpr: ts.Expression, asExpr: ts.Expression, argType: ts.Type): void { + const isNumericLiteral = ts.isNumericLiteral(argExpr); + const isAsExpression = asExpr.kind === ts.SyntaxKind.AsExpression; + const argText = argExpr.getText(); + const argValue = Number(argText); + + if (isNumericLiteral) { + const isInteger = Number.isInteger(argValue); + const containsDot = argText.includes('.'); + + if (!isInteger || containsDot) { + const autofix = this.autofixer?.fixArrayIndexExprType(isAsExpression ? asExpr : argExpr); + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); + } + } else if (this.tsTypeChecker.typeToString(argType) === 'number') { + if (this.isArrayIndexValidNumber(argExpr)) { + return; + } + const autofix = this.autofixer?.fixArrayIndexExprType(argExpr); + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); + } else { + this.checkNumericArgumentDeclaration(argExpr); } - this.checkNumericArgumentDeclaration(argExpr); + if (ts.isConditionalExpression(argExpr)) { + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + } } private checkNumericArgumentDeclaration(argExpr: ts.Expression): void { @@ -3269,15 +4089,77 @@ export class TypeScriptLinter { const isNumericInitializer = initializer && ts.isNumericLiteral(initializer); const initializerNumber = isNumericInitializer ? Number(initializerText) : NaN; const isUnsafeNumber = isNumericInitializer && !Number.isInteger(initializerNumber); - const isConstDeclaration = firstDeclaration.parent.flags === ts.NodeFlags.Let; - const isUndefinedButNotMaxSafeInteger = initializerText === 'undefined'; - if ( - isUnsafeNumber || - firstDeclaration.parent.flags === ts.NodeFlags.Const && isUnsafeNumber || - isConstDeclaration || - isUndefinedButNotMaxSafeInteger - ) { + if (isUnsafeNumber) { + const autofix = this.autofixer?.fixArrayIndexExprType(argExpr); + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); + } + + if (initializerText === 'undefined') { + this.handleUndefinedInitializer(argExpr, firstDeclaration); + } + } + + private evaluateValueFromDeclaration(argExpr: ts.Expression): number | null { + const declaration = this.tsUtils.getDeclarationNode(argExpr); + if (!declaration) { + return null; + } + + if (!ts.isVariableDeclaration(declaration)) { + return null; + } + + const initializer = declaration.initializer; + if (!initializer) { + return null; + } + + if (!ts.isNumericLiteral(initializer)) { + return null; + } + + const numericValue = Number(initializer.text); + if (!Number.isInteger(numericValue)) { + return null; + } + + return numericValue; + } + + private isArrayIndexValidNumber(argExpr: ts.Expression): boolean { + let evaluatedValue: number | null = null; + if (ts.isParenthesizedExpression(argExpr)) { + return this.isArrayIndexValidNumber(argExpr.expression); + } + + if (ts.isBinaryExpression(argExpr)) { + evaluatedValue = this.evaluateNumericValueFromBinaryExpression(argExpr); + } else { + evaluatedValue = this.evaluateValueFromDeclaration(argExpr); + } + const valueString = String(evaluatedValue); + + if (evaluatedValue === null) { + return false; + } + + if (!Number.isInteger(evaluatedValue)) { + return false; + } + // floating points that can be converted to int should be fine, so as long as no floating point is here, we should be fine. + if (valueString.includes('.') && !valueString.endsWith('.0')) { + return false; + } + + return evaluatedValue >= 0 && !valueString.includes('.'); + } + + private handleUndefinedInitializer(argExpr: ts.Expression, declaration: ts.VariableDeclaration): void { + if (ts.isParameter(declaration)) { + const autofix = this.autofixer?.fixArrayIndexExprType(argExpr); + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); + } else { this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); } } @@ -3377,9 +4259,13 @@ export class TypeScriptLinter { } private processCalleeSym(calleeSym: ts.Symbol, tsCallExpr: ts.CallExpression): void { + const name = calleeSym.getName(); + const parName = this.tsUtils.getParentSymbolName(calleeSym); if (!this.options.arkts2) { - this.handleStdlibAPICall(tsCallExpr, calleeSym); + this.handleStdlibAPICall(tsCallExpr, calleeSym, name, parName); this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); + } else { + this.handleBuiltinThisArgs(tsCallExpr, calleeSym, name, parName); } if (TsUtils.symbolHasEsObjectType(calleeSym)) { const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; @@ -3421,8 +4307,7 @@ export class TypeScriptLinter { return false; } const declFileFromJson = path.normalize(interfaceDecl.getSourceFile().fileName); - const declFileFromSdk = - indexedTypeSdkInfo.file_path.length > 0 ? path.normalize(indexedTypeSdkInfo.file_path[0]) : ''; + const declFileFromSdk = path.normalize(indexedTypeSdkInfo.file_path); const isSameSdkFilePath = declFileFromJson.endsWith(declFileFromSdk); const interfaceNameData = indexedTypeSdkInfo.api_info.parent_api[0].api_name; const isSameInterfaceName = interfaceDecl.name.getText() === interfaceNameData; @@ -3434,18 +4319,50 @@ export class TypeScriptLinter { } } + private handleBuiltinCtorCallSignature(tsCallExpr: ts.CallExpression | ts.TypeReferenceNode): void { + if (!this.options.arkts2) { + return; + } + const node = ts.isCallExpression(tsCallExpr) ? tsCallExpr.expression : tsCallExpr.typeName; + const constructorType = this.tsTypeChecker.getTypeAtLocation(node); + const callSignatures = constructorType.getCallSignatures(); + if (callSignatures.length === 0 || BUILTIN_DISABLE_CALLSIGNATURE.includes(node.getText())) { + return; + } + const isSameApi = callSignatures.some((callSignature) => { + const callSignatureDecl = callSignature.getDeclaration(); + if (!ts.isCallSignatureDeclaration(callSignatureDecl)) { + return false; + } + const parentDecl = callSignatureDecl.parent; + const parentName = ts.isInterfaceDeclaration(parentDecl) ? parentDecl.name.getText() : ''; + const BultinNoCtorFuncApiInfoSet = TypeScriptLinter.globalApiInfo.get(BuiltinProblem.BuiltinNoCtorFunc); + if (!BultinNoCtorFuncApiInfoSet) { + return false; + } + const isSameApi = [...BultinNoCtorFuncApiInfoSet].some((apiInfoItem) => { + if (apiInfoItem.api_info.parent_api?.length <= 0) { + return false; + } + const apiInfoParentName = apiInfoItem.api_info.parent_api[0].api_name; + return apiInfoParentName === parentName; + }); + return isSameApi; + }); + if (isSameApi) { + this.incrementCounters(node, FaultID.BuiltinNoCtorFunc); + } + } + private handleCallExpression(node: ts.Node): void { const tsCallExpr = node as ts.CallExpression; this.handleStateStyles(tsCallExpr); + this.handleBuiltinCtorCallSignature(tsCallExpr); + this.handleInteropAwaitImport(tsCallExpr); if (this.options.arkts2 && tsCallExpr.typeArguments !== undefined) { this.handleSdkPropertyAccessByIndex(tsCallExpr); } - - this.handleTsInterop(tsCallExpr.expression, () => { - this.checkInteropFunctionCall(tsCallExpr); - }); - const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); this.handleImportCall(tsCallExpr); @@ -3453,13 +4370,16 @@ export class TypeScriptLinter { if (calleeSym !== undefined) { this.processCalleeSym(calleeSym, tsCallExpr); } - if (callSignature !== undefined && !this.tsUtils.isLibrarySymbol(calleeSym)) { - this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); - this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); + if (callSignature !== undefined) { + if (!this.tsUtils.isLibrarySymbol(calleeSym)) { + this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); + this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); + } else if (this.options.arkts2) { + this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); + } } this.handleInteropForCallExpression(tsCallExpr); this.handleLibraryTypeCall(tsCallExpr); - if ( ts.isPropertyAccessExpression(tsCallExpr.expression) && this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression) @@ -3470,46 +4390,68 @@ export class TypeScriptLinter { if ( !ts.isExpressionStatement(tsCallExpr.parent) && !ts.isVoidExpression(tsCallExpr.parent) && - !ts.isArrowFunction(tsCallExpr.parent) + !ts.isArrowFunction(tsCallExpr.parent) && + !(ts.isConditionalExpression(tsCallExpr.parent) && ts.isExpressionStatement(tsCallExpr.parent.parent)) ) { this.handleLimitedVoidWithCall(tsCallExpr); } - this.checkArkTSObjectInterop(tsCallExpr); this.handleAppStorageCallExpression(tsCallExpr); this.fixJsImportCallExpression(tsCallExpr); - this.handleCallJSFunction(tsCallExpr, calleeSym, callSignature); - this.handleInteropForCallObjectMethods(tsCallExpr, calleeSym, callSignature); + this.handleInteropForCallJSExpression(tsCallExpr, calleeSym, callSignature); + this.handleNoTsLikeFunctionCall(tsCallExpr); + this.handleObjectLiteralInFunctionArgs(tsCallExpr); + this.handleTaskPoolDeprecatedUsages(tsCallExpr); + this.handleSdkDuplicateDeclName(tsCallExpr); } - private handleAppStorageCallExpression(tsCallExpr: ts.CallExpression): void { - if (!this.options.arkts2 || !tsCallExpr) { + handleNoTsLikeFunctionCall(callExpr: ts.CallExpression): void { + if (!this.options.arkts2) { return; } - if ( - !ts.isBinaryExpression(tsCallExpr.parent) || - tsCallExpr.parent.operatorToken.kind !== ts.SyntaxKind.QuestionQuestionToken - ) { + + const expression = callExpr.expression; + const type = this.tsTypeChecker.getTypeAtLocation(expression); + const typeText = this.tsTypeChecker.typeToString(type); + if (typeText === LIKE_FUNCTION) { + const autofix = this.autofixer?.fixNoTsLikeFunctionCall(expression); + this.incrementCounters(expression, FaultID.ExplicitFunctionType, autofix); + } + } + + private handleAppStorageCallExpression(tsCallExpr: ts.CallExpression): void { + if (!this.options.arkts2 || !tsCallExpr) { return; } - const varDecl = tsCallExpr.parent.parent; - if (!ts.isVariableDeclaration(varDecl)) { + if (!TsUtils.isAppStorageAccess(tsCallExpr)) { return; } - if (varDecl.type && ts.isTypeReferenceNode(varDecl.type)) { - if (varDecl.type.typeName.getText() === STRINGLITERAL_ANY) { - return; + let varDecl: ts.VariableDeclaration | undefined; + let parent = tsCallExpr.parent; + + while (parent) { + if (ts.isVariableDeclaration(parent)) { + varDecl = parent; + break; } + parent = parent.parent; } + if (!varDecl || varDecl.type) { + return; + } const callReturnType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr); const isNumberReturnType = callReturnType.flags & ts.TypeFlags.Number; const isNumberGeneric = ((): boolean => { if (tsCallExpr.typeArguments?.length !== 1) { return false; } + const callText = tsCallExpr.getText(); + if (callText.startsWith('Array<') || callText.startsWith('Set<') || callText.startsWith('Map<')) { + return false; + } const typeArg = tsCallExpr.typeArguments[0]; if (typeArg.kind === ts.SyntaxKind.NumberKeyword) { return true; @@ -3527,7 +4469,7 @@ export class TypeScriptLinter { } } - handleCallJSFunction( + handleInteropForCallJSExpression( tsCallExpr: ts.CallExpression, sym: ts.Symbol | undefined, callSignature: ts.Signature | undefined @@ -3535,20 +4477,29 @@ export class TypeScriptLinter { if (!callSignature) { return; } - if (TypeScriptLinter.isDeclaredInArkTs2(callSignature) && this.options.arkts2) { + if (!TypeScriptLinter.isDeclaredInArkTs2(callSignature) && this.options.arkts2) { if (sym?.declarations?.[0]?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { - this.incrementCounters(tsCallExpr, FaultID.CallJSFunction); + this.incrementCounters( + tsCallExpr, + ts.isPropertyAccessExpression(tsCallExpr.expression) ? + FaultID.InteropCallObjectMethods : + FaultID.CallJSFunction + ); } } } private handleInteropForCallExpression(tsCallExpr: ts.CallExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); if (!callSignature) { return; } - if (TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { + if (!TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { return; } @@ -3556,19 +4507,43 @@ export class TypeScriptLinter { this.checkForReflectAPIUse(callSignature, tsCallExpr); } - private handleInteropForCallObjectMethods( - tsCallExpr: ts.CallExpression, - sym: ts.Symbol | undefined, - callSignature: ts.Signature | undefined - ): void { - if (!callSignature) { - return; + private isExportedEntityDeclaredInJs(exportDecl: ts.ExportDeclaration): boolean { + if (!this.options.arkts2 || !this.useStatic) { + return false; } - if (TypeScriptLinter.isDeclaredInArkTs2(callSignature) && this.options.arkts2) { - if (sym?.declarations?.[0]?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { - this.incrementCounters(tsCallExpr, FaultID.InteropCallObjectMethods); + + if (!exportDecl.exportClause || !ts.isNamedExports(exportDecl.exportClause)) { + return false; + } + + for (const exportSpecifier of exportDecl.exportClause.elements) { + const identifier = exportSpecifier.name; + if (this.tsUtils.isImportedFromJS(identifier)) { + return true; + } + } + + return false; + } + + private isExportedEntityDeclaredInArkTs1(exportDecl: ts.ExportDeclaration): boolean | undefined { + if (!this.options.arkts2 || !this.useStatic) { + return false; + } + + if (!exportDecl.exportClause || !ts.isNamedExports(exportDecl.exportClause)) { + return false; + } + + for (const exportSpecifier of exportDecl.exportClause.elements) { + const identifier = exportSpecifier.name; + + if (this.tsUtils.isExportImportedFromArkTs1(identifier, exportDecl)) { + return true; } } + + return false; } private static isDeclaredInArkTs2(callSignature: ts.Signature): boolean | undefined { @@ -3580,7 +4555,7 @@ export class TypeScriptLinter { return undefined; } // check for 'use static' at the start of the file this function declared at - if (declarationSourceFile.statements[0].getText() !== USE_STATIC) { + if (declarationSourceFile.statements[0].getText() === USE_STATIC) { return true; } return false; @@ -3600,7 +4575,6 @@ export class TypeScriptLinter { } if (this.tsTypeChecker.getTypeAtLocation(argument).isClass()) { - // return error this.incrementCounters(tsCallExpr, FaultID.InteropCallObjectParam); return; } @@ -3681,7 +4655,8 @@ export class TypeScriptLinter { * for a detailed analysis. */ if (this.options.arkts2 && TypeScriptLinter.isInvalidBuiltinGenericConstructorCall(callLikeExpr)) { - this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs); + const autofix = this.autofixer?.fixGenericCallNoTypeArgs(callLikeExpr as ts.NewExpression); + this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs, autofix); return; } this.checkTypeArgumentsForGenericCallWithNoTypeArgs(callLikeExpr, callSignature); @@ -3700,6 +4675,9 @@ export class TypeScriptLinter { callLikeExpr: ts.CallExpression | ts.NewExpression, callSignature: ts.Signature ): void { + if (ts.isNewExpression(callLikeExpr) && this.isNonGenericClass(callLikeExpr)) { + return; + } const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? ts.SyntaxKind.Constructor : ts.SyntaxKind.FunctionDeclaration; @@ -3717,7 +4695,8 @@ export class TypeScriptLinter { const startTypeArg = callLikeExpr.typeArguments?.length ?? 0; if (this.options.arkts2 && callLikeExpr.kind === ts.SyntaxKind.NewExpression) { if (startTypeArg !== resolvedTypeArgs.length) { - this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs); + const autofix = this.autofixer?.fixGenericCallNoTypeArgs(callLikeExpr); + this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs, autofix); } } else { for (let i = startTypeArg; i < resolvedTypeArgs.length; ++i) { @@ -3738,10 +4717,19 @@ export class TypeScriptLinter { } } + private isNonGenericClass(expression: ts.NewExpression): boolean { + const declaration = this.tsUtils.getDeclarationNode(expression.expression); + return !!declaration && ts.isClassDeclaration(declaration) && !declaration.typeParameters; + } + checkTypeArgumentsForGenericCallWithNoTypeArgsNumber( callLikeExpr: ts.CallExpression | ts.NewExpression, callSignature: ts.Signature ): void { + if (TypeScriptLinter.isArrayFromCall(callLikeExpr)) { + return; + } + const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? ts.SyntaxKind.Constructor : ts.SyntaxKind.FunctionDeclaration; @@ -3781,6 +4769,16 @@ export class TypeScriptLinter { } } + static isArrayFromCall(callLikeExpr: ts.CallExpression | ts.NewExpression): boolean { + return ( + ts.isCallExpression(callLikeExpr) && + ts.isPropertyAccessExpression(callLikeExpr.expression) && + callLikeExpr.expression.name.text === STRINGLITERAL_FROM && + ts.isIdentifier(callLikeExpr.expression.expression) && + callLikeExpr.expression.expression.text === STRINGLITERAL_ARRAY + ); + } + private static readonly listFunctionApplyCallApis = [ 'Function.apply', 'Function.call', @@ -3843,9 +4841,12 @@ export class TypeScriptLinter { [SYMBOL_CONSTRUCTOR, { arr: null, fault: FaultID.SymbolType }] ]); - private handleStdlibAPICall(callExpr: ts.CallExpression, calleeSym: ts.Symbol): void { - const name = calleeSym.getName(); - const parName = this.tsUtils.getParentSymbolName(calleeSym); + private handleStdlibAPICall( + callExpr: ts.CallExpression, + calleeSym: ts.Symbol, + name: string, + parName: string | undefined + ): void { if (parName === undefined) { if (LIMITED_STD_GLOBAL_API.includes(name)) { this.incrementCounters(callExpr, FaultID.LimitedStdLibApi); @@ -3867,6 +4868,43 @@ export class TypeScriptLinter { } } + private handleBuiltinThisArgs( + callExpr: ts.CallExpression, + calleeSym: ts.Symbol, + name: string, + parName: string | undefined + ): void { + if (parName === undefined) { + return; + } + + const builtinThisArgsInfos = TypeScriptLinter.funcMap.get(name); + if (!builtinThisArgsInfos) { + return; + } + + const sourceFile = calleeSym?.declarations?.[0]?.getSourceFile(); + if (!sourceFile) { + return; + } + + const fileName = path.basename(sourceFile.fileName); + const builtinInfos = builtinThisArgsInfos.get(fileName); + if (!(builtinInfos && builtinInfos.size > 0)) { + return; + } + for (const info of builtinInfos) { + const needReport = + info.parent_api.length > 0 && + info.parent_api[0].api_name === parName && + info?.api_func_args?.length === callExpr.arguments.length; + if (needReport) { + this.incrementCounters(callExpr, FaultID.BuiltinThisArgs); + return; + } + } + } + private checkLimitedStdlibApi(node: ts.Identifier, symbol: ts.Symbol): void { const parName = this.tsUtils.getParentSymbolName(symbol); const entries = LIMITED_STD_API.get(parName); @@ -3928,9 +4966,49 @@ export class TypeScriptLinter { ); } + private checkConstrutorAccess(newExpr: ts.NewExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + if (!ts.isPropertyAccessExpression(newExpr.parent)) { + return; + } + + if (newExpr.parent.name.text === 'constructor') { + this.incrementCounters(newExpr.parent, FaultID.NoConstructorOnClass); + } + } + + private checkForInterfaceInitialization(newExpression: ts.NewExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + if (!ts.isReturnStatement(newExpression.parent)) { + return; + } + + const calleeExpr = newExpression.expression; + if (!ts.isIdentifier(calleeExpr)) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(calleeExpr); + if (type.isClassOrInterface()) { + this.incrementCounters(calleeExpr, FaultID.ConstructorIface); + } + } + private handleNewExpression(node: ts.Node): void { const tsNewExpr = node as ts.NewExpression; + this.checkForInterfaceInitialization(tsNewExpr); + this.handleSharedArrayBuffer(tsNewExpr); + this.handleSdkDuplicateDeclName(tsNewExpr); + this.checkConstrutorAccess(tsNewExpr); + this.checkCreatingPrimitiveTypes(tsNewExpr); + if (this.options.advancedClassChecks || this.options.arkts2) { const calleeExpr = tsNewExpr.expression; const calleeType = this.tsTypeChecker.getTypeAtLocation(calleeExpr); @@ -3947,14 +5025,29 @@ export class TypeScriptLinter { } const sym = this.tsUtils.trueSymbolAtLocation(tsNewExpr.expression); const callSignature = this.tsTypeChecker.getResolvedSignature(tsNewExpr); - if (callSignature !== undefined && !this.tsUtils.isLibrarySymbol(sym)) { - this.handleStructIdentAndUndefinedInArgs(tsNewExpr, callSignature); - this.handleGenericCallWithNoTypeArgs(tsNewExpr, callSignature); + if (callSignature !== undefined) { + if (!this.tsUtils.isLibrarySymbol(sym)) { + this.handleStructIdentAndUndefinedInArgs(tsNewExpr, callSignature); + this.handleGenericCallWithNoTypeArgs(tsNewExpr, callSignature); + } else if (this.options.arkts2) { + this.handleGenericCallWithNoTypeArgs(tsNewExpr, callSignature); + } } this.handleSendableGenericTypes(tsNewExpr); this.handleInstantiatedJsObject(tsNewExpr, sym); } + private checkCreatingPrimitiveTypes(tsNewExpr: ts.NewExpression): void { + if (!this.options.arkts2) { + return; + } + const typeStr = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(tsNewExpr)); + const primitiveTypes = ['Number', 'String', 'Boolean']; + if (primitiveTypes.includes(typeStr)) { + this.incrementCounters(tsNewExpr, FaultID.CreatingPrimitiveTypes); + } + } + handleInstantiatedJsObject(tsNewExpr: ts.NewExpression, sym: ts.Symbol | undefined): void { if (this.useStatic && this.options.arkts2) { if (sym?.declarations?.[0]?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { @@ -4016,18 +5109,19 @@ export class TypeScriptLinter { this.incrementCounters(node, FaultID.StructuralIdentity); } } - this.handleAsExpressionNumber(tsAsExpr); + this.handleAsExpressionImport(tsAsExpr); + this.handleNoTuplesArrays(node, targetType, exprType); } - private handleAsExpressionNumber(tsAsExpr): void { + private handleAsExpressionImport(tsAsExpr: ts.AsExpression): void { const type = tsAsExpr.type; - - if ( - this.useStatic && - this.options.arkts2 && - ts.isAsExpression(tsAsExpr) && - type.kind === ts.SyntaxKind.NumberKeyword - ) { + const restrictedTypes = [ + ts.SyntaxKind.NumberKeyword, + ts.SyntaxKind.BooleanKeyword, + ts.SyntaxKind.StringKeyword, + ts.SyntaxKind.BigIntKeyword + ]; + if (this.useStatic && this.options.arkts2 && restrictedTypes.includes(type.kind)) { const expr = ts.isPropertyAccessExpression(tsAsExpr.expression) ? tsAsExpr.expression.expression : tsAsExpr.expression; @@ -4065,9 +5159,40 @@ export class TypeScriptLinter { } } - private handleTypeReference(node: ts.Node): void { - const typeRef = node as ts.TypeReferenceNode; - + private handleSharedArrayBuffer(node: ts.TypeReferenceNode | ts.NewExpression): void { + if (!this.options.arkts2) { + return; + } + + const typeNameIdentifier = ts.isTypeReferenceNode(node) ? node.typeName : node.expression; + if (!ts.isIdentifier(typeNameIdentifier) || typeNameIdentifier.getText() !== ESLIB_SHAREDARRAYBUFFER) { + return; + } + + const decls = this.tsUtils.trueSymbolAtLocation(typeNameIdentifier)?.getDeclarations(); + const isSharedMemoryEsLib = decls?.some((decl) => { + const srcFileName = decl.getSourceFile().fileName; + return srcFileName.endsWith(ESLIB_SHAREDMEMORY_FILENAME); + }); + if (!isSharedMemoryEsLib) { + return; + } + if (ts.isNewExpression(node)) { + const autofix = this.autofixer?.fixSharedArrayBufferConstructor(node); + this.incrementCounters(node.expression, FaultID.SharedArrayBufferDeprecated, autofix); + } else { + const autofix = this.autofixer?.fixSharedArrayBufferTypeReference(node); + this.incrementCounters(node, FaultID.SharedArrayBufferDeprecated, autofix); + } + } + + private handleTypeReference(node: ts.Node): void { + const typeRef = node as ts.TypeReferenceNode; + + this.handleBuiltinCtorCallSignature(typeRef); + this.handleSharedArrayBuffer(typeRef); + this.handleSdkDuplicateDeclName(typeRef); + this.handleSdkConstructorIface(typeRef); const isESObject = TsUtils.isEsObjectType(typeRef); @@ -4094,7 +5219,30 @@ export class TypeScriptLinter { if (this.tsUtils.isSendableClassOrInterface(typeNameType)) { this.checkSendableTypeArguments(typeRef); } - this.handleQuotedHyphenPropsDeprecated(typeRef); + + this.checkNoEnumProp(typeRef); + } + + private checkNoEnumProp(typeRef: ts.TypeReferenceNode): void { + if (!this.options.arkts2) { + return; + } + if (ts.isQualifiedName(typeRef.typeName)) { + const symbol = this.tsTypeChecker.getSymbolAtLocation(typeRef.typeName.right); + + if (!symbol) { + return; + } + + const declarations = symbol.getDeclarations(); + if (!declarations || declarations.length === 0) { + return; + } + + if (ts.isEnumMember(declarations[0])) { + this.incrementCounters(typeRef, FaultID.NoEnumPropAsType); + } + } } private checkPartialType(node: ts.Node): void { @@ -4176,6 +5324,7 @@ export class TypeScriptLinter { const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; this.incrementCounters(tsTypeExpr, faultId); } + this.handleSdkDuplicateDeclName(tsTypeExpr); } private handleComputedPropertyName(node: ts.Node): void { @@ -4608,20 +5757,6 @@ export class TypeScriptLinter { return this.fileExportDeclCaches.has(decl); } - lint(sourceFile: ts.SourceFile): void { - if (this.options.enableAutofix) { - this.autofixer = new Autofixer(this.tsTypeChecker, this.tsUtils, sourceFile, this.options.cancellationToken); - } - - this.sourceFile = sourceFile; - this.useStatic = TsUtils.isArkts12File(sourceFile); - this.fileExportDeclCaches = undefined; - this.extractImportedNames(this.sourceFile); - this.visitSourceFile(this.sourceFile); - this.handleCommentDirectives(this.sourceFile); - this.processInterfacesToImport(this.sourceFile); - } - private handleExportKeyword(node: ts.Node): void { const parentNode = node.parent; if (!TypeScriptLinter.inSharedModule(node) || ts.isModuleBlock(parentNode.parent)) { @@ -4655,11 +5790,22 @@ export class TypeScriptLinter { } private handleExportDeclaration(node: ts.Node): void { + const exportDecl = node as ts.ExportDeclaration; + + if (this.isExportedEntityDeclaredInJs(exportDecl)) { + this.incrementCounters(node, FaultID.InteropJsObjectExport); + return; + } + + if (this.isExportedEntityDeclaredInArkTs1(exportDecl)) { + this.incrementCounters(node, FaultID.InteropArkTs1ObjectExport); + return; + } + if (!TypeScriptLinter.inSharedModule(node) || ts.isModuleBlock(node.parent)) { return; } - const exportDecl = node as ts.ExportDeclaration; if (exportDecl.exportClause === undefined) { this.incrementCounters(exportDecl, FaultID.SharedModuleNoWildcardExport); return; @@ -4691,6 +5837,7 @@ export class TypeScriptLinter { return; } this.checkAssignmentMatching(node, lhsType, expr, true); + this.handleObjectLiteralInReturn(returnStat); } /** @@ -4724,11 +5871,11 @@ export class TypeScriptLinter { this.handleExtendDecorator(node); this.handleEntryDecorator(node); this.handleProvideDecorator(node); + this.handleLocalBuilderDecorator(node); const decorator: ts.Decorator = node as ts.Decorator; this.checkSendableAndConcurrentDecorator(decorator); this.handleStylesDecorator(decorator); - this.handleTypescriptDecorators(decorator); if (TsUtils.getDecoratorName(decorator) === SENDABLE_DECORATOR) { const parent: ts.Node = decorator.parent; if (!parent || !SENDABLE_DECORATOR_NODES.includes(parent.kind)) { @@ -4914,9 +6061,9 @@ export class TypeScriptLinter { return; } const switchStatement = node as ts.SwitchStatement; - if (!this.isValidSwitchExpr(switchStatement)) { - this.incrementCounters(switchStatement.expression, FaultID.SwitchExpression); - } + + this.validateSwitchExpression(switchStatement); + const duplicateCases = this.findDuplicateCases(switchStatement); if (duplicateCases.length > 0) { for (const duplicateCase of duplicateCases) { @@ -4925,6 +6072,71 @@ export class TypeScriptLinter { } } + private validateSwitchExpression(switchStatement: ts.SwitchStatement): void { + const nodeType = this.tsTypeChecker.getTypeAtLocation(switchStatement.expression); + const typeName = this.tsTypeChecker.typeToString(nodeType); + const isUnionType = (nodeType.flags & ts.TypeFlags.Union) !== 0; + + const { isLiteralInitialized, isFloatLiteral, hasExplicitTypeAnnotation } = this.getDeclarationInfo( + switchStatement.expression + ); + + const isAllowed = + !isUnionType && + (nodeType.flags & ts.TypeFlags.StringLike || + typeName === 'String' || + nodeType.flags & ts.TypeFlags.NumberLike && (/^\d+$/).test(typeName) || + isLiteralInitialized && !hasExplicitTypeAnnotation && !isFloatLiteral || + nodeType.flags & ts.TypeFlags.EnumLike); + + if (!isAllowed) { + this.incrementCounters(switchStatement.expression, FaultID.SwitchExpression); + } + } + + private getDeclarationInfo(expression: ts.Expression): { + isLiteralInitialized: boolean; + isFloatLiteral: boolean; + hasExplicitTypeAnnotation: boolean; + } { + const symbol = this.tsTypeChecker.getSymbolAtLocation(expression); + const declaration = symbol?.valueDeclaration; + + if (!declaration || !ts.isVariableDeclaration(declaration)) { + return { isLiteralInitialized: false, isFloatLiteral: false, hasExplicitTypeAnnotation: false }; + } + + const hasExplicitTypeAnnotation = !!declaration.type; + const initializerInfo = TypeScriptLinter.getInitializerInfo(declaration.initializer); + + return { + isLiteralInitialized: initializerInfo.isLiteralInitialized, + isFloatLiteral: initializerInfo.isFloatLiteral, + hasExplicitTypeAnnotation + }; + } + + private static getInitializerInfo(initializer?: ts.Expression): { + isLiteralInitialized: boolean; + isFloatLiteral: boolean; + } { + if (!initializer) { + return { isLiteralInitialized: false, isFloatLiteral: false }; + } + + const isLiteralInitialized = ts.isNumericLiteral(initializer) || ts.isStringLiteral(initializer); + + let isFloatLiteral = false; + if (ts.isNumericLiteral(initializer)) { + const literalText = initializer.getText(); + if (!(/^0[xX]/).test(literalText)) { + isFloatLiteral = (/\.|e[-+]|\dE[-+]/i).test(literalText); + } + } + + return { isLiteralInitialized, isFloatLiteral }; + } + private findDuplicateCases(switchStatement: ts.SwitchStatement): ts.CaseClause[] { const seenValues = new Map(); const duplicates: ts.CaseClause[] = []; @@ -4964,87 +6176,6 @@ export class TypeScriptLinter { } } - private isValidSwitchExpr(switchStatement: ts.SwitchStatement): boolean { - const expressionType = this.tsTypeChecker.getTypeAtLocation(switchStatement.expression); - if (!expressionType) { - return false; - } - if (this.isSwitchAllowedType(expressionType, switchStatement.expression)) { - return true; - } - if (expressionType.isUnion()) { - const unionTypes = expressionType.types; - return unionTypes.every((t) => { - return this.isSwitchAllowedType(t, switchStatement.expression); - }); - } - return false; - } - - private isSwitchAllowedType(type: ts.Type, node: ts.Node): boolean { - if (type.flags & (ts.TypeFlags.StringLike | ts.TypeFlags.EnumLike)) { - return true; - } - - if (type.flags & (ts.TypeFlags.Number | ts.TypeFlags.NumberLiteral)) { - if (type.isNumberLiteral()) { - const value = type.value; - return TypeScriptLinter.isValidNumber(value); - } - if (ts.isIdentifier(node)) { - const refValue = this.getNumberReferenceValue(node); - if (refValue !== null && !TypeScriptLinter.isValidNumber(refValue)) { - return false; - } - } - return true; - } - - const typeString = this.tsTypeChecker.typeToString(type); - return typeString === 'String' || typeString === 'int'; - } - - private static isValidNumber(value: number): boolean { - const forbiddenValues = [ - Number.NaN, - Number.POSITIVE_INFINITY, - Number.NEGATIVE_INFINITY, - Number.MAX_VALUE, - Number.MIN_VALUE - ]; - - return !forbiddenValues.includes(value) && Number.isInteger(value); - } - - private getNumberReferenceValue(node: ts.Identifier): number | null { - const symbol = this.tsTypeChecker.getSymbolAtLocation(node); - if (!symbol) { - return null; - } - - for (const decl of symbol.getDeclarations() || []) { - if (!ts.isVariableDeclaration(decl) || !decl.initializer) { - continue; - } - if (ts.isPropertyAccessExpression(decl.initializer)) { - const propName = decl.initializer.name.text; - const numberProps: Record = { - NaN: Number.NaN, - POSITIVE_INFINITY: Number.POSITIVE_INFINITY, - NEGATIVE_INFINITY: Number.NEGATIVE_INFINITY, - MAX_VALUE: Number.MAX_VALUE, - MIN_VALUE: Number.MIN_VALUE - }; - if (propName in numberProps) { - return numberProps[propName]; - } - } else if (ts.isNumericLiteral(decl.initializer)) { - return Number(decl.initializer.text); - } - } - return null; - } - private handleLimitedLiteralType(literalTypeNode: ts.LiteralTypeNode): void { if (!this.options.arkts2 || !literalTypeNode) { return; @@ -5219,7 +6350,9 @@ export class TypeScriptLinter { } if ( this.tsUtils.isOrDerivedFrom(lhsType, this.tsUtils.isArray) && - this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple) + this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple) || + this.tsUtils.isOrDerivedFrom(rhsType, this.tsUtils.isArray) && + this.tsUtils.isOrDerivedFrom(lhsType, TsUtils.isTuple) ) { this.incrementCounters(node, FaultID.NoTuplesArrays); } @@ -5317,14 +6450,17 @@ export class TypeScriptLinter { return; } - if (ts.isPropertyAssignment(node)) { - const text = node.initializer.getText(); - if (!(/^\$\w+$/).test(text)) { - return; - } - const autofix = this.autofixer?.fixDollarBind(node); - this.incrementCounters(node, FaultID.DollarBindingNotSupported, autofix); + if (!ts.isPropertyAssignment(node) || !ts.isIdentifier(node.initializer)) { + return; + } + + const text = node.initializer.getText(); + if (!(/^\$.+$/).test(text)) { + return; } + + const autofix = this.autofixer?.fixDollarBind(node); + this.incrementCounters(node, FaultID.DollarBindingNotSupported, autofix); } private handleExtendDecorator(node: ts.Node): void { @@ -5385,8 +6521,33 @@ export class TypeScriptLinter { } const isStatic = TsUtils.hasModifier(propDecl.modifiers, ts.SyntaxKind.StaticKeyword); const hasNoInitializer = !propDecl.initializer; - if (isStatic && hasNoInitializer) { - this.incrementCounters(propDecl, FaultID.ClassstaticInitialization); + const isOptional = !!propDecl.questionToken; + + const defaultSkipTypeCheck = (typeNode: ts.TypeNode | undefined): boolean => { + if (!typeNode) { + return false; + } + + const typeText = typeNode.getText(); + if (ts.isLiteralTypeNode(typeNode) || ['boolean', 'number', 'null', 'undefined'].includes(typeText)) { + return true; + } + + if (ts.isUnionTypeNode(typeNode)) { + return typeNode.types.some((t) => { + const tText = t.getText(); + return tText === 'undefined'; + }); + } + + return false; + }; + + const shouldSkipCheck = isOptional || defaultSkipTypeCheck(propDecl.type); + + if (isStatic && hasNoInitializer && !shouldSkipCheck) { + const autofix = this.autofixer?.fixStaticPropertyInitializer(propDecl); + this.incrementCounters(propDecl, FaultID.ClassstaticInitialization, autofix); } } @@ -5448,7 +6609,8 @@ export class TypeScriptLinter { } private handleHeritageClause(node: ts.HeritageClause): void { - if (!this.options.arkts2) { + this.checkEWTArgumentsForSdkDuplicateDeclName(node); + if (!this.options.arkts2 || !this.useStatic) { return; } if (node.token === ts.SyntaxKind.ExtendsKeyword || node.token === ts.SyntaxKind.ImplementsKeyword) { @@ -5468,6 +6630,8 @@ export class TypeScriptLinter { this.fixJsImportExtendsClass(node.parent, expr); } }); + + this.handleMissingSuperCallInExtendedClass(node); } } @@ -5477,61 +6641,87 @@ export class TypeScriptLinter { } private checkSendableAndConcurrentDecorator(decorator: ts.Decorator): void { - if (!this.options.arkts2) { + if (!this.options.arkts2 || !this.useStatic) { return; } const decoratorName = TsUtils.getDecoratorName(decorator); - if (decoratorName === SENDABLE_DECORATOR || decoratorName === CONCURRENT_DECORATOR) { - const autofix = this.autofixer?.removeNode(decorator); - this.incrementCounters(decorator, FaultID.LimitedStdLibApi, autofix); + const autofix = this.autofixer?.removeNode(decorator); + if (decoratorName === SENDABLE_DECORATOR) { + this.incrementCounters(decorator, FaultID.LimitedStdLibNoSendableDecorator, autofix); } - } - private handleTypescriptDecorators(decorator: ts.Decorator): void { - if (!this.options.arkts2) { - return; - } - if (!ts.isClassDeclaration(decorator.parent)) { - return; + if (decoratorName === CONCURRENT_DECORATOR) { + this.incrementCounters(decorator, FaultID.LimitedStdLibNoDoncurrentDecorator, autofix); } + } - const decoratorExpression = decorator.expression; - const symbol = this.tsUtils.trueSymbolAtLocation(decoratorExpression); - if (!symbol) { - return; - } + private checkAsonSymbol(symbol: ts.Symbol, node: ts.Node): void { + const cb = (): void => { + let autofix: Autofix[] | undefined; + const parent = node.parent; + autofix = this.autofixer?.replaceNode(parent ? parent : node, JSON_TEXT); - const decl = TsUtils.getDeclaration(symbol); - if (!decl) { - return; - } + if (ts.isImportSpecifier(parent) && ts.isIdentifier(node)) { + autofix = this.autofixer?.removeImport(node, parent); + } - const sourceFile = decl.getSourceFile(); - if (sourceFile.fileName.endsWith(EXTNAME_TS)) { - this.incrementCounters(decorator, FaultID.InteropNoDecorators); - } + this.incrementCounters(node, FaultID.LimitedStdLibNoASON, autofix); + }; + this.checkSymbolAndExecute(symbol, ASON_TEXT, ASON_MODULES, cb); } - private checkWorkerImport(node: ts.ImportDeclaration): void { - if (!this.options.arkts2) { - return; - } - const moduleSpecifier = (node.moduleSpecifier as ts.StringLiteral).text; - if (!WORKER_MODULES.includes(moduleSpecifier)) { - return; - } + private checkCollectionsSymbol(symbol: ts.Symbol, node: ts.Node): void { + const cb = (): void => { + const parent = node.parent; + if (!parent) { + return; + } + if (ts.isPropertyAccessExpression(parent)) { + const autofix = this.autofixer?.replaceNode(parent, parent.name.text); + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + } - const namedBindings = node.importClause?.namedBindings; - if (!namedBindings || namedBindings.kind !== ts.SyntaxKind.NamedImports) { - return; - } - const elements = namedBindings.elements; - for (const el of elements) { - const importedName = el.propertyName?.text ?? el.name.text; - if (importedName === WORKER_TEXT) { - this.incrementCounters(node, FaultID.LimitedStdLibApi); + if (ts.isQualifiedName(parent)) { + const autofix = this.autofixer?.replaceNode(parent, parent.right.text); + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + } + + if (ts.isImportSpecifier(parent) && ts.isIdentifier(node)) { + const autofix = this.autofixer?.removeImport(node, parent); + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + } + }; + + this.checkSymbolAndExecute(symbol, COLLECTIONS_TEXT, COLLECTIONS_MODULES, cb); + } + + private checkWorkerSymbol(symbol: ts.Symbol, node: ts.Node): void { + const cb = (): void => { + this.incrementCounters(node, FaultID.NoNeedStdlibWorker); + }; + + this.checkSymbolAndExecute(symbol, WORKER_TEXT, WORKER_MODULES, cb); + } + + private checkSymbolAndExecute(symbol: ts.Symbol, symbolName: string, modules: string[], cb: () => void): void { + void this; + if (symbol.name === symbolName) { + const decl = TsUtils.getDeclaration(symbol); + + if (!decl) { return; } + + const sourceFile = decl.getSourceFile(); + const fileName = path.basename(sourceFile.fileName); + + if ( + modules.some((moduleName) => { + return fileName.startsWith(moduleName); + }) + ) { + cb(); + } } } @@ -5648,34 +6838,50 @@ export class TypeScriptLinter { const decl = node.parent; const declName = decl.name?.getText(); if (ts.isFunctionDeclaration(decl)) { - const functionCalls = TypeScriptLinter.findDeclarationCalls(this.sourceFile as ts.SourceFile, declName as string); + const functionCalls = TypeScriptLinter.findDeclarationCalls(this.sourceFile, declName as string); const autofix = this.autofixer?.fixStylesDecoratorGlobal(decl, functionCalls, this.interfacesNeedToImport); this.incrementCounters(decl, FaultID.StylesDecoratorNotSupported, autofix); } if (ts.isMethodDeclaration(decl)) { - const methodCalls = TypeScriptLinter.findDeclarationCalls(this.sourceFile as ts.SourceFile, declName as string); + const methodCalls = TypeScriptLinter.findDeclarationCalls(this.sourceFile, declName as string); const autofix = this.autofixer?.fixStylesDecoratorStruct(decl, methodCalls, this.interfacesNeedToImport); this.incrementCounters(decl, FaultID.StylesDecoratorNotSupported, autofix); } } - private handleStateStyles(node: ts.CallExpression): void { + private handleStateStyles(node: ts.CallExpression | ts.PropertyAccessExpression): void { if (!this.options.arkts2) { return; } - if (node.expression.getText() !== STATE_STYLES) { - return; + let args: ts.Expression[] = []; + let startNode: ts.Node | undefined; + if (ts.isCallExpression(node)) { + if (node.expression.getText() !== STATE_STYLES) { + return; + } + startNode = node.expression; + args = Array.from(node.arguments); } - const args = node.arguments; - if (args.length === 0) { + if (ts.isPropertyAccessExpression(node)) { + if (node.name.getText() !== STATE_STYLES) { + return; + } + if (!ts.isCallExpression(node.parent)) { + return; + } + startNode = node.name; + args = Array.from(node.parent.arguments); + } + + if (args.length === 0 || !startNode) { return; } const object = args[0]; - if (!ts.isObjectLiteralExpression(object)) { + if (!object || !ts.isObjectLiteralExpression(object)) { return; } @@ -5683,28 +6889,81 @@ export class TypeScriptLinter { if (properties.length === 0) { return; } - const property = properties[0] as ts.PropertyAssignment; - if (!ts.isObjectLiteralExpression(property.initializer)) { + + if (!TypeScriptLinter.hasAnonBlock(properties)) { + return; + } + + const autofix = this.autofixer?.fixStateStyles(object, startNode, this.interfacesNeedToImport); + this.incrementCounters(object, FaultID.StylesDecoratorNotSupported, autofix); + } + + private static hasAnonBlock(properties: ts.NodeArray): boolean { + let anonBlockCount = 0; + + properties.forEach((property) => { + if (ts.isPropertyAssignment(property) && ts.isObjectLiteralExpression(property.initializer)) { + anonBlockCount++; + } + }); + + return anonBlockCount !== 0; + } + + private handleStringLiteral(node: ts.StringLiteral): void { + if (!this.options.arkts2) { + return; + } + + this.checkForConcurrentExpressions(node); + } + + private checkForConcurrentExpressions(stringLiteral: ts.StringLiteral): void { + if (!stringLiteral.parent) { + return; + } + + if (!ts.isExpressionStatement(stringLiteral.parent)) { return; } - const autofix = this.autofixer?.fixStateStyles(object, this.interfacesNeedToImport); - this.incrementCounters(node, FaultID.StylesDecoratorNotSupported, autofix); + const text = stringLiteral.text; + const autofix = this.autofixer?.removeNode(stringLiteral); + + if (text === USE_CONCURRENT) { + this.incrementCounters(stringLiteral, FaultID.UseConcurrentDeprecated, autofix); + } + + if (text === USE_SHARED) { + this.incrementCounters(stringLiteral, FaultID.UseSharedDeprecated, autofix); + } } - private static findDeclarationCalls(sourceFile: ts.SourceFile, declName: string): ts.CallExpression[] { - const functionCalls: ts.CallExpression[] = []; + private static findDeclarationCalls(sourceFile: ts.SourceFile, declName: string): ts.Identifier[] { + const functionCalls: ts.Identifier[] = []; function traverse(node: ts.Node): void { - if (ts.isCallExpression(node)) { - const callName = node.expression.getText(); - if (callName === declName) { - functionCalls.push(node); - } + const identifier = getIdentifierFromNode(node); + if (identifier && identifier.getText() === declName) { + functionCalls.push(identifier); } + ts.forEachChild(node, traverse); } + function getIdentifierFromNode(node: ts.Node): ts.Identifier | undefined { + if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) { + return node.expression; + } + if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name)) { + if (node.expression.getText() === THIS_IDENTIFIER) { + return undefined; + } + return node.name; + } + return undefined; + } + traverse(sourceFile); return functionCalls; } @@ -5865,7 +7124,7 @@ export class TypeScriptLinter { return; } - if (TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { + if (!TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { return; } @@ -5887,14 +7146,6 @@ export class TypeScriptLinter { } } - private checkInteropFunctionCall(node: ts.CallExpression): void { - if (!this.options.arkts2) { - return; - } - - this.incrementCounters(node, FaultID.InteropTSFunctionInvoke); - } - private hasObjectParameter(callSignature: ts.Signature, tsCallExpr: ts.CallExpression): boolean { for (const [index, param] of callSignature.parameters.entries()) { const paramType = this.tsTypeChecker.getTypeOfSymbolAtLocation(param, tsCallExpr); @@ -5978,108 +7229,330 @@ export class TypeScriptLinter { this.incrementCounters(node, FaultID.BinaryOperations); } } + this.handlePropertyDescriptorInScenarios(node); } - private handleQuotedHyphenPropsDeprecated(typeRef: ts.TypeReferenceNode): void { - if (!this.options.arkts2 || !ts.isQualifiedName(typeRef.typeName)) { - return; - } - const qualNode = typeRef.typeName; - const parent = typeRef.parent; - const sdkInfos = this.interfaceMap.get(qualNode.left.getText()); - if (!sdkInfos || sdkInfos.size === 0) { + private handleQuotedHyphenPropsDeprecated(node: ts.PropertyAccessExpression | ts.PropertyAssignment): void { + if (!this.options.arkts2 || !node) { return; } - - for (const sdkInfo of sdkInfos) { - this.processQuotedHyphenPropsDeprecated(parent, sdkInfo.api_name); - } - } - - private processQuotedHyphenPropsDeprecated(node: ts.Node, apiName: string): void { - if (ts.isVariableDeclaration(node)) { - this.handleQuotedHyphenPropsDeprecatedOnVarDecl(node, apiName); - } else if (ts.isFunctionDeclaration(node)) { - this.handleQuotedHyphenPropsDeprecatedOnFunDecl(node, apiName); - } + const literalAsPropertyNameInfos = Array.from(TypeScriptLinter.literalAsPropertyNameTypeSet); + literalAsPropertyNameInfos.some((literalAsPropertyNameInfo) => { + this.localApiListItem = literalAsPropertyNameInfo; + const api_name = literalAsPropertyNameInfo.api_info.api_name; + if (api_name !== (ts.isPropertyAccessExpression(node) ? node.name.text : node.name.getText())) { + return false; + } + const parentSym = this.getFinalSymOnQuotedHyphenPropsDeprecated( + ts.isPropertyAccessExpression(node) ? node.expression : node + ); + if (parentSym && this.shouldWarn(parentSym)) { + this.incrementCounters(node, FaultID.QuotedHyphenPropsDeprecated); + return true; + } + return false; + }); } - private handleQuotedHyphenPropsDeprecatedOnVarDecl(node: ts.VariableDeclaration, apiName: string): void { - const initializer = node.initializer; - if (!(initializer && ts.isObjectLiteralExpression(initializer))) { - return; + private shouldWarn(symbol: ts.Symbol): boolean { + const parentApiName = this.getLocalApiListItemByKey(SdkNameInfo.ParentApiName); + return symbol && this.isHeritageClauseisThirdPartyBySymbol(symbol) || symbol.name === parentApiName; + } + + private getFinalSymOnQuotedHyphenPropsDeprecated(node: ts.Node): ts.Symbol | undefined { + let currentNode = node; + while (currentNode) { + const symbol = this.checkNodeTypeOnQuotedHyphenPropsDeprecated(currentNode); + if (symbol) { + return symbol; + } + currentNode = currentNode.parent; } - initializer.properties.forEach((property) => { - if (!ts.isPropertyAssignment(property)) { - return; + return undefined; + } + + private checkNodeTypeOnQuotedHyphenPropsDeprecated(node: ts.Node): ts.Symbol | undefined { + if (ts.isVariableDeclaration(node)) { + return this.getTypeOfVariable(node); + } + + if (ts.isPropertySignature(node)) { + return this.tsTypeChecker.getTypeAtLocation(node.type!).getSymbol(); + } + + const nodesWithResolvableType = [ + ts.isFunctionDeclaration(node) && node.type, + ts.isMethodDeclaration(node) && node.type, + ts.isTypeReferenceNode(node) && node, + ts.isParameter(node) && node.type + ].filter(Boolean); + + for (const typeNode of nodesWithResolvableType) { + return typeNode ? this.resolveTypeNodeSymbol(typeNode) : undefined; + } + + if (ts.isIdentifier(node)) { + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + const declaration = symbol?.getDeclarations()?.[0]; + if (declaration) { + return this.getFinalSymOnQuotedHyphenPropsDeprecated(declaration); } - const propertyName = property.name.getText(); - if (propertyName === apiName) { - this.incrementCounters(property.name, FaultID.QuotedHyphenPropsDeprecated); + } + + return undefined; + } + + 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 variable.initializer ? this.tsTypeChecker.getTypeAtLocation(variable.initializer).getSymbol() : undefined; + } + + private resolveTypeNodeSymbol(typeNode: ts.TypeNode): ts.Symbol | undefined { + if (!ts.isTypeReferenceNode(typeNode)) { + return undefined; + } + const symbol = this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); + if (!symbol) { + return this.resolveTypeNoSymbol(typeNode); + } + const declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + const declaration = declarations[0]; + if (ts.isTypeAliasDeclaration(declaration)) { + return this.resolveTypeNodeSymbol(declaration.type); + } else if (ts.isInterfaceDeclaration(declaration)) { + const heritageSymbol = this.processQuotedHyphenPropsDeprecatedOnInterfaceDeclaration(declaration); + return heritageSymbol; } - }); + } + return this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); } - private handleQuotedHyphenPropsDeprecatedOnFunDecl(node: ts.FunctionDeclaration, apiName: string): void { - const body = node.body; - if (!body || !ts.isBlock(body)) { - return; + private resolveTypeNoSymbol(typeNode: ts.TypeReferenceNode): ts.Symbol | undefined { + if (!typeNode.typeName) { + return undefined; + } + if (ts.isQualifiedName(typeNode.typeName)) { + return this.tsTypeChecker.getSymbolAtLocation(typeNode.typeName.right); + } + const sym = this.tsUtils.trueSymbolAtLocation(typeNode.typeName); + if (sym) { + const globalDeclaration = sym.getDeclarations()?.[0]; + if (globalDeclaration && ts.isTypeAliasDeclaration(globalDeclaration)) { + return this.resolveTypeNodeSymbol(globalDeclaration.type); + } } - body.statements.forEach(this.processStatement.bind(this, apiName)); + return this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); } - private processStatement(apiName: string, statement: ts.Statement): void { - if (!ts.isReturnStatement(statement)) { - return; + private isHeritageClauseisThirdPartyBySymbol(symbol: ts.Symbol): boolean { + const declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + const firstDeclaration = declarations[0]; + if (ts.isImportSpecifier(firstDeclaration)) { + const importDecl = firstDeclaration.parent.parent.parent; + const importPath = importDecl.moduleSpecifier.getText(); + const import_path = this.getLocalApiListItemByKey(SdkNameInfo.ImportPath); + if (import_path && JSON.stringify(import_path).includes(importPath)) { + return true; + } + } + } + return false; + } + + private getLocalApiListItemByKey(key: string): string | string[] { + if (!this.localApiListItem) { + return ''; + } + if (SdkNameInfo.ParentApiName === key) { + return this.localApiListItem.api_info.parent_api[0].api_name; + } else if (SdkNameInfo.ImportPath === key) { + return this.localApiListItem.import_path; + } + return ''; + } + + private processQuotedHyphenPropsDeprecatedOnInterfaceDeclaration( + node: ts.InterfaceDeclaration + ): ts.Symbol | undefined { + const heritageSymbol = this.processHeritageClauses(node); + if (heritageSymbol) { + return heritageSymbol; } + return this.processMembers(node); + } + + private processHeritageClauses(node: ts.InterfaceDeclaration): ts.Symbol | undefined { + if (!node.heritageClauses) { + return undefined; + } + for (const heritageClause of node.heritageClauses) { + return this.processHeritageClause(heritageClause); + } + + return undefined; + } + + private processHeritageClause(heritageClause: ts.HeritageClause): ts.Symbol | undefined { + for (const type of heritageClause.types) { + if (!type.expression) { + return undefined; + } + if (ts.isPropertyAccessExpression(type.expression)) { + return this.processPropertyAccessExpression(type.expression); + } + } + return undefined; + } - const returnValue = statement.expression; - if (!returnValue || !ts.isObjectLiteralExpression(returnValue)) { + private processPropertyAccessExpression(expression: ts.PropertyAccessExpression): ts.Symbol | undefined { + const heritageSymbol = this.tsTypeChecker.getSymbolAtLocation(expression.expression); + if (heritageSymbol && expression.name.text === this.getLocalApiListItemByKey(SdkNameInfo.ParentApiName)) { + return heritageSymbol; + } + return undefined; + } + + private processMembers(node: ts.InterfaceDeclaration): ts.Symbol | undefined { + if (!node.members) { + return undefined; + } + for (const member of node.members) { + if (ts.isPropertySignature(member) && member.type) { + return this.resolveTypeNodeSymbol(member.type); + } + } + return undefined; + } + + private processApiNodeSdkDuplicateDeclName(apiName: string, errorNode: ts.Node): void { + const setApiListItem = TypeScriptLinter.globalApiInfo.get(SdkProblem.DeclWithDuplicateName); + if (!setApiListItem) { + return; + } + const apiNamesArr = [...setApiListItem]; + const hasSameApiName = apiNamesArr.some((apilistItem) => { + return apilistItem.api_info.api_name === errorNode.getText(); + }); + if (!hasSameApiName) { return; } - returnValue.properties.forEach(this.processProperty.bind(this, apiName)); + if (ts.isTypeReferenceNode(errorNode)) { + errorNode = errorNode.typeName; + } + + const matchedApi = apiNamesArr.some((sdkInfo) => { + const isSameName = sdkInfo.api_info.api_name === apiName; + const isGlobal = sdkInfo.is_global; + return isSameName && isGlobal; + }); + + if (matchedApi) { + this.incrementCounters(errorNode, FaultID.DuplicateDeclNameFromSdk); + } } - private processProperty(apiName: string, property: ts.ObjectLiteralElementLike): void { - if (!ts.isPropertyAssignment(property)) { + private handleSdkDuplicateDeclName( + node: + | ts.TypeReferenceNode + | ts.NewExpression + | ts.VariableDeclaration + | ts.PropertyDeclaration + | ts.ParameterDeclaration + | ts.CallExpression + | ts.BinaryExpression + | ts.ExpressionWithTypeArguments + | ts.Identifier + ): void { + if (!this.options.arkts2) { return; } + switch (node.kind) { + case ts.SyntaxKind.TypeReference: + this.checkTypeReferenceForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.NewExpression: + this.checkNewExpressionForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.Identifier: + this.checkHeritageClauseForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.Parameter: + this.checkDeclarationForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.CallExpression: + this.checkCallExpressionForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.BinaryExpression: + this.checkBinaryExpressionForSdkDuplicateDeclName(node); + break; + default: + } + } + + private checkTypeReferenceForSdkDuplicateDeclName(node: ts.TypeReferenceNode): void { + const typeName = node.typeName; + if (ts.isIdentifier(typeName)) { + this.processApiNodeSdkDuplicateDeclName(typeName.text, node); + } + } + + private checkNewExpressionForSdkDuplicateDeclName(node: ts.NewExpression): void { + const expression = node.expression; + if (ts.isIdentifier(expression)) { + this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + } + } + + private checkHeritageClauseForSdkDuplicateDeclName(node: ts.Identifier): void { + if (ts.isIdentifier(node)) { + this.processApiNodeSdkDuplicateDeclName(node.text, node); + } + } + + private checkDeclarationForSdkDuplicateDeclName( + node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration + ): void { + const expression = node.initializer; + if (expression && ts.isIdentifier(expression)) { + this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + } + } + + private checkCallExpressionForSdkDuplicateDeclName(node: ts.CallExpression): void { + if (ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { + const expression = node.expression.expression; + this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + } + } - const isMatch = property.name.getText() === apiName; - if (isMatch) { - this.incrementCounters(property.name, FaultID.QuotedHyphenPropsDeprecated); + private checkBinaryExpressionForSdkDuplicateDeclName(node: ts.BinaryExpression): void { + const expression = node.right; + if (ts.isIdentifier(expression)) { + this.processApiNodeSdkDuplicateDeclName(expression.text, expression); } } - private handleApipathChanged(node: ts.PropertyDeclaration): void { - if (!this.options.arkts2 || !ts.isPropertyDeclaration(node)) { + private checkEWTArgumentsForSdkDuplicateDeclName(node: ts.HeritageClause): void { + if (!this.options.arkts2) { return; } - const processApiNode = (apiName: string, errorNode: ts.Node): void => { - const sdkInfos = TypeScriptLinter.pathMap.get(`'${ARKTS_WHITE_API_PATH_TEXTSTYLE}'`); - if (!sdkInfos) { - return; - } - const matchedApi = [...sdkInfos].find((sdkInfo) => { - return sdkInfo.api_name === apiName; + if (node.token === ts.SyntaxKind.ExtendsKeyword || node.token === ts.SyntaxKind.ImplementsKeyword) { + node.types.forEach((type) => { + const expr = type.expression; + if (ts.isIdentifier(expr)) { + this.processApiNodeSdkDuplicateDeclName(expr.text, expr); + } }); - if (matchedApi) { - this.incrementCounters(errorNode, FaultID.ApiPathChanged); - } - }; - if (node.type && ts.isTypeReferenceNode(node.type)) { - const typeName = node.type.typeName; - if (ts.isIdentifier(typeName)) { - processApiNode(typeName.text, node.type); - } - } - if (node.initializer && ts.isNewExpression(node.initializer)) { - const expression = node.initializer.expression; - if (ts.isIdentifier(expression)) { - processApiNode(expression.text, expression); - } } } @@ -6156,24 +7629,95 @@ export class TypeScriptLinter { if (!this.options.arkts2 || !ts.isPropertyAccessExpression(decl)) { return; } - if (ts.isPropertyAccessExpression(decl.expression)) { - 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 matchedApi = [...sdkInfos].find((sdkInfo) => { - return sdkInfo.api_name === apiName; - }); - if (matchedApi) { + + if (this.handleSelfPropertyAccess(decl)) { + return; + } + + if (ts.isPropertyAccessExpression(decl)) { + const deprecatedProperties = [ + 'position', + 'subtype', + 'movingPhotoEffectMode', + 'dynamicRangeType', + 'thumbnailVisible' + ]; + + const propertyName = ts.isIdentifier(decl.name) ? decl.name.text : ''; + if (deprecatedProperties.includes(propertyName)) { this.incrementCounters(decl.name, FaultID.SdkTypeQuery); + return; } } + + this.handleImportApiPropertyAccess(decl); + } + + private handleSelfPropertyAccess(decl: ts.PropertyAccessExpression): boolean { + if (!ts.isPropertyAccessExpression(decl.expression)) { + return false; + } + + const propertyName = ts.isIdentifier(decl.expression.name) && decl.expression.name.text || ''; + if (propertyName !== 'self') { + return false; + } + + this.incrementCounters(decl.name, FaultID.SdkTypeQuery); + return true; + } + + private handleImportApiPropertyAccess(decl: ts.PropertyAccessExpression): void { + if (!ts.isPropertyAccessExpression(decl.expression)) { + return; + } + + 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 matchedApi = [...sdkInfos].find((sdkInfo) => { + return sdkInfo.api_name === apiName; + }); + + if (matchedApi) { + this.incrementCounters(decl.name, FaultID.SdkTypeQuery); + } + } + + private handleGetOwnPropertyNames(decl: ts.PropertyAccessExpression): void { + if (this.checkPropertyAccessExpression(decl, GET_OWN_PROPERTY_NAMES_TEXT, TypeScriptLinter.missingAttributeSet)) { + const autofix = this.autofixer?.fixMissingAttribute(decl); + this.incrementCounters(decl, FaultID.BuiltinGetOwnPropertyNames, autofix); + } + } + + private handleSymbolIterator(decl: ts.PropertyAccessExpression): void { + if (this.checkPropertyAccessExpression(decl, SYMBOL_ITERATOR, TypeScriptLinter.symbotIterSet)) { + this.incrementCounters(decl, FaultID.BuiltinSymbolIterator); + } + } + + private checkPropertyAccessExpression(decl: ts.PropertyAccessExpression, name: string, set: Set): boolean { + if (set.size === 0 || decl.getText() !== name) { + return false; + } + + const symbol = this.tsUtils.trueSymbolAtLocation(decl); + const sourceFile = symbol?.declarations?.[0]?.getSourceFile(); + if (!sourceFile) { + return false; + } + + const fileName = path.basename(sourceFile.fileName); + return set.has(fileName); } private fixJsImportCallExpression(callExpr: ts.CallExpression): void { - if (!this.options.arkts2) { + if (!this.options.arkts2 || !this.useStatic) { return; } @@ -6186,7 +7730,16 @@ export class TypeScriptLinter { return; } - this.incrementCounters(callExpr, FaultID.InteropJsObjectUsage); + // check if any argument is a `new` expression + const hasNewExpressionArg = callExpr.arguments.some((arg) => { + return ts.isNewExpression(arg); + }); + + const faultId = hasNewExpressionArg ? + FaultID.InteropJsObjectExpandStaticInstance : + FaultID.InteropJsObjectCallStaticFunc; + + this.incrementCounters(callExpr, faultId); } private fixJsImportExtendsClass( @@ -6205,11 +7758,11 @@ export class TypeScriptLinter { if (!className) { return; } - this.incrementCounters(node, FaultID.InteropJsObjectUsage); + this.incrementCounters(node, FaultID.InteropJsObjectInheritance); } private fixJsImportPropertyAccessExpression(node: ts.Node): void { - if (!this.options.arkts2) { + if (!this.options.arkts2 || !this.useStatic) { return; } @@ -6223,7 +7776,12 @@ export class TypeScriptLinter { const autofix = this.autofixer?.createReplacementForJsImportPropertyAccessExpression( node as ts.PropertyAccessExpression ); - this.incrementCounters(node, FaultID.InteropJsObjectUsage, autofix); + + this.incrementCounters( + node, + TsUtils.isInsideIfCondition(node) ? FaultID.InteropJsObjectConditionJudgment : FaultID.InteropJsObjectUsage, + autofix + ); return; } @@ -6238,7 +7796,7 @@ export class TypeScriptLinter { } private fixJsImportElementAccessExpression(elementAccessExpr: ts.ElementAccessExpression): void { - if (!this.options.arkts2) { + if (!this.options.arkts2 || !this.useStatic) { return; } @@ -6265,7 +7823,67 @@ export class TypeScriptLinter { elementAccessExpr.expression as ts.Identifier ); - this.incrementCounters(elementAccessExpr, FaultID.InteropJsObjectUsage, autofix); + this.incrementCounters(elementAccessExpr, FaultID.InteropJsObjectTraverseJsInstance, autofix); + } + + private handleTaskPoolDeprecatedUsages(node: ts.CallExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + if (!ts.isPropertyAccessExpression(node.expression)) { + return; + } + + const propertyAccess = node.expression; + const objectExpr = propertyAccess.expression; + + // Step 1: Must be either setCloneList or setTransferList + if (!TypeScriptLinter.isDeprecatedTaskPoolMethodCall(propertyAccess)) { + return; + } + + if (!ts.isIdentifier(objectExpr)) { + return; + } + + // Step 2: Resolve declaration of task + const variableDecl = this.tsUtils.findVariableDeclaration(objectExpr); + if (!variableDecl?.initializer || !ts.isNewExpression(variableDecl.initializer)) { + return; + } + + // Step 3: Check new taskpool.Task() + const taskpoolExpr = variableDecl.initializer.expression; + if (!TypeScriptLinter.isTaskPoolTaskCreation(taskpoolExpr)) { + return; + } + + const faultId = + propertyAccess.name.text === DEPRECATED_TASKPOOL_METHOD_SETCLONELIST ? + FaultID.SetCloneListDeprecated : + FaultID.SetTransferListDeprecated; + this.incrementCounters(node.parent, faultId); + } + + private static isDeprecatedTaskPoolMethodCall(propertyAccess: ts.PropertyAccessExpression): boolean { + if (!ts.isIdentifier(propertyAccess.expression)) { + return false; + } + const methodName = propertyAccess.name.text; + return ( + methodName === DEPRECATED_TASKPOOL_METHOD_SETCLONELIST || + methodName === DEPRECATED_TASKPOOL_METHOD_SETTRANSFERLIST + ); + } + + private static isTaskPoolTaskCreation(taskpoolExpr: ts.Expression): boolean { + return ( + ts.isPropertyAccessExpression(taskpoolExpr) && + ts.isIdentifier(taskpoolExpr.expression) && + taskpoolExpr.expression.text === STDLIB_TASKPOOL_OBJECT_NAME && + taskpoolExpr.name.text === STDLIB_TASK_CLASS_NAME + ); } private checkStdLibConcurrencyImport(importDeclaration: ts.ImportDeclaration): void { @@ -6284,32 +7902,156 @@ export class TypeScriptLinter { return; } + const defaultImport = importClause.name; const namedBindings = importClause.namedBindings; - const defaultImportName = importClause.name?.getText(); - if (defaultImportName && expectedImports.includes(defaultImportName)) { - this.incrementCounters(importDeclaration, FaultID.LimitedStdLibNoImportConcurrency); + const namedImports = namedBindings && ts.isNamedImports(namedBindings) ? namedBindings.elements : []; + + const defaultIsForbidden = defaultImport && expectedImports.includes(defaultImport.getText()); + const forbiddenNamed = namedImports.filter((spec) => { + const name = spec.propertyName ? spec.propertyName.getText() : spec.name.getText(); + return expectedImports.includes(name); + }); + + if ( + TypeScriptLinter.shouldRemoveWholeImport( + defaultIsForbidden, + forbiddenNamed.length, + namedImports.length, + defaultImport + ) + ) { + const autofix = this.autofixer?.removeNode(importDeclaration); + this.incrementCounters(importDeclaration, FaultID.LimitedStdLibNoImportConcurrency, autofix); + return; } - if (namedBindings && ts.isNamedImports(namedBindings)) { - for (const element of namedBindings.elements) { - const name = element.name.getText(); - if (expectedImports.includes(name)) { - this.incrementCounters(importDeclaration, FaultID.LimitedStdLibNoImportConcurrency); - } - } + if (defaultIsForbidden) { + const autofix = this.autofixer?.removeDefaultImport(importDeclaration, defaultImport); + this.incrementCounters(defaultImport, FaultID.LimitedStdLibNoImportConcurrency, autofix); + } + + for (const spec of forbiddenNamed) { + const autofix = this.autofixer?.removeImportSpecifier(spec, importDeclaration); + this.incrementCounters(spec, FaultID.LimitedStdLibNoImportConcurrency, autofix); } } - private handleInterOpImportJs(importDecl: ts.ImportDeclaration): void { - if (!this.options.arkts2 || !importDecl || !this.useStatic) { + private static shouldRemoveWholeImport( + defaultIsForbidden: boolean | undefined, + forbiddenNamedCount: number, + namedImportsCount: number, + defaultImport: ts.Identifier | undefined + ): boolean { + return ( + defaultIsForbidden && forbiddenNamedCount === namedImportsCount || + defaultIsForbidden && namedImportsCount === 0 || + !defaultImport && forbiddenNamedCount === namedImportsCount && namedImportsCount > 0 + ); + } + + /** + * Checks for missing super() call in child classes that extend a parent class + * with parameterized constructors. If parent class only has parameterized constructors + * and the child class does not call super() in its constructor, report a fault. + * + * This ensures safe and correct subclassing behavior. + * + * @param node The HeritageClause node (extends clause) to analyze. + */ + private handleMissingSuperCallInExtendedClass(node: ts.HeritageClause): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - const importClause = importDecl.importClause; - if (!importClause) { + + // We are only interested in 'extends' clauses + if (node.token !== ts.SyntaxKind.ExtendsKeyword) { return; } - const namedBindings = importClause.namedBindings; + + // Get the parent class declaration (what the child class extends) + const parentClass = this.getParentClassDeclaration(node); + if (!parentClass) { + return; + } + + // If parent class has a parameterless constructor (or no constructor at all), child is fine + if (TypeScriptLinter.parentHasParameterlessConstructor(parentClass)) { + return; + } + + // The child class node (the one extending) + const childClass = node.parent; + if (!ts.isClassDeclaration(childClass)) { + return; + } + + // Look for child class constructor + const childConstructor = childClass.members.find(ts.isConstructorDeclaration); + + /* + * If child has no constructor → error (super() cannot be called) + * If child constructor exists but does not contain super() → error + */ + if (!childConstructor?.body || !TypeScriptLinter.childHasSuperCall(childConstructor)) { + this.incrementCounters(node, FaultID.MissingSuperCall); + } + } + + /** + * Retrieves the parent class declaration node from an extends heritage clause. + */ + private getParentClassDeclaration(node: ts.HeritageClause): ts.ClassDeclaration | undefined { + const parentExpr = node.types[0]?.expression; + if (!parentExpr) { + return undefined; + } + const parentSymbol = this.tsUtils.trueSymbolAtLocation(parentExpr); + return parentSymbol?.declarations?.find(ts.isClassDeclaration); + } + + /** + * Determines if a parent class has a parameterless constructor. + * If it has no constructor at all, that counts as parameterless. + */ + private static parentHasParameterlessConstructor(parentClass: ts.ClassDeclaration): boolean { + const constructors = parentClass.members.filter(ts.isConstructorDeclaration); + return ( + constructors.length === 0 || + constructors.some((ctor) => { + return ctor.parameters.length === 0; + }) + ); + } + + private static childHasSuperCall(constructor: ts.ConstructorDeclaration): boolean { + let superCalled = false; + + if (!constructor.body) { + return false; + } + + ts.forEachChild(constructor.body, (stmt) => { + if ( + ts.isExpressionStatement(stmt) && + ts.isCallExpression(stmt.expression) && + stmt.expression.expression.kind === ts.SyntaxKind.SuperKeyword + ) { + superCalled = true; + } + }); + return superCalled; + } + + private handleInterOpImportJs(importDecl: ts.ImportDeclaration): void { + if (!this.options.arkts2 || !importDecl || !this.useStatic) { + return; + } + const importClause = importDecl.importClause; + if (!importClause) { + return; + } + const namedBindings = importClause.namedBindings; let symbol: ts.Symbol | undefined; let defaultSymbol: ts.Symbol | undefined; if (importClause.name) { @@ -6371,22 +8113,42 @@ export class TypeScriptLinter { return false; } - private handleAwaitExpression(node: ts.Node): void { + private handleInteropAwaitImport(callExpr: ts.CallExpression): void { if (!this.options.arkts2 || !this.useStatic) { return; } - const awaitExpr = node as ts.AwaitExpression; - const checkAndReportJsImportAwait = (targetNode: ts.Node): boolean => { - if (ts.isIdentifier(targetNode) && this.tsUtils.isJsImport(targetNode)) { - this.incrementCounters(node, FaultID.NoJsImportAwait); - return true; - } - return false; - }; - const expr = awaitExpr.expression; - checkAndReportJsImportAwait(expr); - if (ts.isCallExpression(expr)) { - checkAndReportJsImportAwait(expr.expression); + + if (callExpr.expression.kind !== ts.SyntaxKind.ImportKeyword) { + return; + } + + if (ts.isAwaitExpression(callExpr.parent) || ts.isPropertyAccessExpression(callExpr.parent)) { + this.checkInteropForDynamicImport(callExpr); + } + } + + private checkInteropForDynamicImport(callExpr: ts.CallExpression): void { + const interopType = TsUtils.resolveModuleAndCheckInterop( + this.options.wholeProjectPath ?? path.resolve(TsUtils.getCurrentModule(callExpr.getSourceFile().fileName)), + callExpr + ); + + if (!interopType) { + return; + } + + switch (interopType) { + case InteropType.JS: + this.incrementCounters(callExpr.parent, FaultID.InteropDynamicImportJs); + break; + case InteropType.TS: + this.incrementCounters(callExpr.parent, FaultID.InteropDynamicImportTs); + break; + case InteropType.LEGACY: + this.incrementCounters(callExpr.parent, FaultID.InteropDynamicImport); + break; + default: + break; } } @@ -6416,4 +8178,581 @@ export class TypeScriptLinter { } } } + + private handleObjectLiteralforUnionTypeInterop(node: ts.VariableDeclaration): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + if (!node.type || !ts.isUnionTypeNode(node.type)) { + return; + } + + if (!node.initializer || node.initializer.kind !== ts.SyntaxKind.ObjectLiteralExpression) { + return; + } + + const typeNodes = node.type.types; + + const isDefected = typeNodes.some((tNode) => { + if (!ts.isTypeReferenceNode(tNode)) { + return false; + } + const type = this.tsTypeChecker.getTypeAtLocation(tNode); + const symbol = type.getSymbol(); + if (!symbol) { + return false; + } + for (const declaration of symbol.declarations ?? []) { + if (!TsUtils.isArkts12File(declaration.getSourceFile())) { + return true; + } + } + return false; + }); + + if (isDefected) { + this.incrementCounters(node, FaultID.InteropObjectLiteralAmbiguity); + } + } + + private handleObjectLiteralAssignmentToClass(node: ts.VariableDeclaration): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + if (!node.initializer || node.initializer.kind !== ts.SyntaxKind.ObjectLiteralExpression) { + return; + } + if (!node.type) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(node.type); + const symbol = type.getSymbol(); + if (!symbol) { + return; + } + + const declarations = symbol.declarations ?? []; + + const isClass = declarations.some(ts.isClassDeclaration); + if (!isClass) { + return; + } + + const isFromArkTs2 = declarations.some((decl) => { + return TsUtils.isArkts12File(decl.getSourceFile()); + }); + + if (isFromArkTs2) { + return; + } + + const hasConstructor = declarations.some((decl) => { + return ts.isClassDeclaration(decl) && decl.members.some(ts.isConstructorDeclaration); + }); + + if (hasConstructor) { + this.incrementCounters(node, FaultID.InteropObjectLiteralClass); + } + } + + private isObjectLiteralAssignedToArkts12Type(node: ts.Expression, expectedTypeNode?: ts.TypeNode): boolean { + if (node.kind !== ts.SyntaxKind.ObjectLiteralExpression) { + return false; + } + + let type: ts.Type; + if (expectedTypeNode) { + type = this.tsTypeChecker.getTypeAtLocation(expectedTypeNode); + } else { + type = this.tsTypeChecker.getContextualType(node) ?? this.tsTypeChecker.getTypeAtLocation(node); + } + + if (!type) { + return false; + } + + return TypeScriptLinter.isTypeFromArkts12(type); + } + + private static isTypeFromArkts12(type: ts.Type): boolean { + const symbol = type?.getSymbol(); + if (!symbol) { + return false; + } + + const isFromArkts12 = (symbol.declarations ?? []).some((decl) => { + return TsUtils.isArkts12File(decl.getSourceFile()); + }); + + if (isFromArkts12) { + return true; + } + return false; + } + + private processNestedObjectLiterals(objLiteral: ts.Expression, parentType?: ts.Type): void { + if (!ts.isObjectLiteralExpression(objLiteral)) { + return; + } + + objLiteral.properties.forEach((prop) => { + if (!ts.isPropertyAssignment(prop) || !ts.isObjectLiteralExpression(prop.initializer)) { + return; + } + + if (this.isObjectLiteralAssignedToArkts12Type(prop.initializer)) { + this.incrementCounters(prop.initializer, FaultID.InteropStaticObjectLiterals); + return; + } + + this.checkPropertyTypeFromParent(prop, parentType); + this.processNestedObjectLiterals(prop.initializer); + }); + } + + private checkPropertyTypeFromParent(prop: ts.PropertyAssignment, parentType?: ts.Type): void { + if (!parentType) { + return; + } + if (!ts.isObjectLiteralExpression(prop.initializer)) { + return; + } + + const propName = prop.name.getText(); + const property = parentType.getProperty(propName); + + if (!property?.valueDeclaration) { + return; + } + + const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation(property, property.valueDeclaration); + + if (TypeScriptLinter.isTypeFromArkts12(propType)) { + this.incrementCounters(prop.initializer, FaultID.InteropStaticObjectLiterals); + } + } + + private handleObjectLiteralAssignment(node: ts.VariableDeclaration): void { + if (TsUtils.isArkts12File(node.getSourceFile())) { + return; + } + + if (!node.initializer) { + return; + } + + if ( + ts.isObjectLiteralExpression(node.initializer) && + this.isObjectLiteralAssignedToArkts12Type(node.initializer, node.type) + ) { + this.incrementCounters(node.initializer, FaultID.InteropStaticObjectLiterals); + return; + } + + const parentType = node.type ? + this.tsTypeChecker.getTypeAtLocation(node.type) : + this.tsTypeChecker.getTypeAtLocation(node.initializer); + + this.processNestedObjectLiterals(node.initializer, parentType); + } + + private handleObjectLiteralInFunctionArgs(node: ts.CallExpression): void { + if (TsUtils.isArkts12File(node.getSourceFile())) { + return; + } + const signature = this.tsTypeChecker.getResolvedSignature(node); + if (!signature) { + return; + } + + const params = signature.getParameters(); + + node.arguments.forEach((arg, index) => { + if (!ts.isObjectLiteralExpression(arg)) { + return; + } + + if (index < params.length) { + const param = params[index]; + if (!param.valueDeclaration) { + return; + } + + const paramType = this.tsTypeChecker.getTypeOfSymbolAtLocation(param, param.valueDeclaration); + + if (TypeScriptLinter.isTypeFromArkts12(paramType)) { + this.incrementCounters(arg, FaultID.InteropStaticObjectLiterals); + } + } else if (this.isObjectLiteralAssignedToArkts12Type(arg)) { + this.incrementCounters(arg, FaultID.InteropStaticObjectLiterals); + } + }); + } + + private handleObjectLiteralInReturn(node: ts.ReturnStatement): void { + if (TsUtils.isArkts12File(node.getSourceFile())) { + return; + } + + if (!node.expression || !ts.isObjectLiteralExpression(node.expression)) { + return; + } + + let current: ts.Node = node; + let functionNode: ts.FunctionLikeDeclaration | undefined; + + while (current && !functionNode) { + current = current.parent; + if ( + current && + (ts.isFunctionDeclaration(current) || + ts.isMethodDeclaration(current) || + ts.isFunctionExpression(current) || + ts.isArrowFunction(current)) + ) { + functionNode = current; + } + } + + if (functionNode?.type) { + const returnType = this.tsTypeChecker.getTypeAtLocation(functionNode.type); + if (TypeScriptLinter.isTypeFromArkts12(returnType)) { + this.incrementCounters(node.expression, FaultID.InteropStaticObjectLiterals); + } + } else if (this.isObjectLiteralAssignedToArkts12Type(node.expression)) { + this.incrementCounters(node.expression, FaultID.InteropStaticObjectLiterals); + } + } + + private handleLocalBuilderDecorator(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + if (!ts.isDecorator(node) || !ts.isIdentifier(node.expression)) { + return; + } + const decoratorName = node.expression.getText(); + if (decoratorName === CustomDecoratorName.LocalBuilder) { + const autofix = this.autofixer?.fixBuilderDecorators(node); + this.incrementCounters(node, FaultID.LocalBuilderDecoratorNotSupported, autofix); + } + } + + private checkEnumGetMemberValue(node: ts.ElementAccessExpression): void { + if (!this.options.arkts2) { + return; + } + + if (!ts.isIdentifier(node.expression) || !ts.isNumericLiteral(node.argumentExpression)) { + return; + } + + const symbol = this.tsUtils.trueSymbolAtLocation(node.expression); + if (!symbol?.declarations) { + return; + } + + for (const decl of symbol.declarations) { + if (ts.isEnumDeclaration(decl)) { + this.incrementCounters(node, FaultID.UnsupportPropNameFromValue); + return; + } + } + } + + private handleMakeObserved(node: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; + } + + const name = node.name; + if (name.getText() !== MAKE_OBSERVED) { + return; + } + + const expr = node.expression; + const symbol = this.tsTypeChecker.getSymbolAtLocation(expr); + const importSpecifier = TsUtils.getDeclaration(symbol); + if (!importSpecifier || !ts.isImportSpecifier(importSpecifier)) { + return; + } + + const importDecl = ts.findAncestor(importSpecifier, ts.isImportDeclaration); + if (!importDecl) { + return; + } + + const moduleSpecifier = importDecl.moduleSpecifier; + if (!ts.isStringLiteral(moduleSpecifier)) { + return; + } + if (moduleSpecifier.text !== ARKUI_PACKAGE_NAME && moduleSpecifier.text !== ARKUI_STATE_MANAGEMENT) { + return; + } + + this.incrementCounters(node, FaultID.MakeObservedIsNotSupported); + } + + private handlePropertyDeclarationForProp(node: ts.PropertyDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const decorators = ts.getDecorators(node); + if (!decorators || decorators.length === 0) { + return; + } + + let decoratorName: string | undefined; + if (ts.isIdentifier(decorators[0].expression)) { + decoratorName = decorators[0].expression.getText(); + } else if (ts.isCallExpression(decorators[0].expression) && ts.isIdentifier(decorators[0].expression.expression)) { + decoratorName = decorators[0].expression.expression.getText(); + } + + if (!decoratorName || !deepCopyDecoratorName.has(decoratorName)) { + return; + } + + this.incrementCounters(node, FaultID.PropDecoratorsAndInterfacesAreNotSupported); + } + + private handleVariableDeclarationForProp(node: ts.VariableDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const callExpr = node.initializer; + if (!callExpr || !ts.isCallExpression(callExpr)) { + return; + } + + const propertyAccessExpr = callExpr.expression; + if (!ts.isPropertyAccessExpression(propertyAccessExpr)) { + return; + } + + const storage = propertyAccessExpr.expression; + if ( + !ts.isIdentifier(storage) || + !this.isTargetStorageType(storage, [StorageTypeName.LocalStorage, StorageTypeName.AppStorage]) + ) { + return; + } + + const functionName = propertyAccessExpr.name; + if (!deepCopyFunctionName.has(functionName.getText())) { + return; + } + + this.incrementCounters(node, FaultID.PropDecoratorsAndInterfacesAreNotSupported); + } + + private isTargetStorageType(storage: ts.Identifier, targetTypes: string[]): boolean { + const decl = this.tsUtils.getDeclarationNode(storage); + if (!decl) { + if (targetTypes.includes(storage.getText())) { + return true; + } + return false; + } + + if (!ts.isVariableDeclaration(decl)) { + return false; + } + + let storageType: ts.Node | undefined; + if (decl.initializer) { + if (ts.isNewExpression(decl.initializer)) { + storageType = decl.initializer.expression; + } else if (ts.isCallExpression(decl.initializer) && ts.isPropertyAccessExpression(decl.initializer.expression)) { + storageType = decl.initializer.expression.expression; + } + } + + if (!storageType || !ts.isIdentifier(storageType)) { + return false; + } + + return targetTypes.includes(storageType.getText()); + } + + private handleAwaitExpression(node: ts.Node): void { + if (!this.options.arkts2 || !this.useStatic) { + return + } + const awaitExpr = node as ts.AwaitExpression; + const checkAndReportJsImportAwait = (targetNode: ts.Node): boolean => { + if (ts.isIdentifier(targetNode) && this.tsUtils.isJsImport(targetNode)) { + this.incrementCounters(node, FaultID.NoAwaitJsPromise); + return true; + } + return false; + }; + const expr = awaitExpr.expression; + checkAndReportJsImportAwait(expr); + if (ts.isCallExpression(expr)) { + checkAndReportJsImportAwait(expr.expression); + } + } + + private handleNotsLikeSmartType(classDecl: ts.ClassDeclaration): void { + if (!this.options.arkts2) { + return; + } + const className = classDecl.name?.getText(); + classDecl.members.forEach(member => { + if (ts.isMethodDeclaration(member)) { + this.checkMethod(member, className); + } + }) + } + + private checkMethod(methodNode: ts.MethodDeclaration, className: string | undefined): void { + const variableDeclarations = new Map(); + const returnStatements: ts.ReturnStatement[] = []; + if (methodNode.body) { + ts.forEachChild(methodNode.body, (node) => { + this.visitMethodBody(node, variableDeclarations, returnStatements); + }); + } + + const isStaticPropertyAccess=(node: ts.Expression, className: string): boolean => { + return ts.isPropertyAccessExpression(node) && + ts.isIdentifier(node.expression) && + node.expression.text === className; + } + + const isInstancePropertyAccess=(node: ts.Expression): boolean=> { + return ts.isPropertyAccessExpression(node) && + node.expression.kind === ts.SyntaxKind.ThisKeyword; + } + + this.checkReturnStatements(returnStatements, className, isStaticPropertyAccess, isInstancePropertyAccess); + } + + private visitMethodBody(node: ts.Node, variableDeclarations: Map, returnStatements: ts.ReturnStatement[]): void { + if (ts.isVariableStatement(node)) { + node.declarationList.declarations.forEach(decl => { + if (ts.isIdentifier(decl.name)) { + variableDeclarations.set(decl.name.text, decl.type); + } + }); + } + + if (ts.isReturnStatement(node)) { + returnStatements.push(node); + } + + ts.forEachChild(node, (child) => { + this.visitMethodBody(child, variableDeclarations, returnStatements); + }); + } + + private checkReturnStatements(returnStatements: ts.ReturnStatement[], className: string | undefined, + isStaticPropertyAccess: (node: ts.Expression, className: string) => boolean, + isInstancePropertyAccess: (node: ts.Expression) => boolean): void { + returnStatements.forEach(returnStmt => { + if (!returnStmt.expression) { + return; + } + + if (className && isStaticPropertyAccess(returnStmt.expression, className)) { + this.incrementCounters(returnStmt, FaultID.NoTsLikeSmartType); + } + + if (isInstancePropertyAccess(returnStmt.expression)) { + this.incrementCounters(returnStmt, FaultID.NoTsLikeSmartType); + } + }); + } + + private handleNumericBigintCompare(node: ts.BinaryExpression): void { + if (!this.options.arkts2) { + return; + } + switch(node.operatorToken.kind) { + case ts.SyntaxKind.LessThanEqualsToken: + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.GreaterThanEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.GreaterThanToken: + case ts.SyntaxKind.LessThanToken: + this.reportNumericBigintCompare(node); + break; + default: + } + } + + private reportNumericBigintCompare(node: ts.BinaryExpression): void { + const leftType = this.tsTypeChecker.getTypeAtLocation(node.left); + const rightType = this.tsTypeChecker.getTypeAtLocation(node.right); + + const isLeftNumber = (leftType.flags & ts.TypeFlags.Number) !== 0; + const isLeftBigInt = (leftType.flags & ts.TypeFlags.BigInt) !== 0; + + const isRightNumber = (rightType.flags & ts.TypeFlags.Number) !== 0; + const isRightBigInt = (rightType.flags & ts.TypeFlags.BigInt) !== 0; + + const valid = (isLeftNumber && isRightBigInt) || (isLeftBigInt && isRightNumber); + if (valid) { + this.incrementCounters(node, FaultID.NumericBigintCompare); + } + } + + private handleBigIntLiteral(node: ts.BigIntLiteral): void { + if (!this.options.arkts2) { + return; + } + const literalText = node.getText(); + + if ((/^0[box]/i).test(literalText)) { + this.incrementCounters(node, FaultID.NondecimalBigint); + } + } + + private handleStructDeclarationForLayout(node: ts.StructDeclaration): void { + if (!this.options.arkts2) { + return; + } + + if (!node.name) { + return; + } + + let hasTargetFunc = false; + + const members = node.members; + for (const member of members) { + if (!ts.isMethodDeclaration(member)) { + continue; + } + + if (customLayoutFunctionName.has(member.name.getText())) { + hasTargetFunc = true; + break; + } + } + + if (!hasTargetFunc) { + return; + } + + const decorators = ts.getDecorators(node); + if (decorators) { + for (const decorator of decorators) { + const decoratorName = TsUtils.getDecoratorName(decorator); + if (decoratorName && decoratorName === CustomDecoratorName.Layoutable) { + return; + } + } + } + + const autofix = this.autofixer?.fixCustomLayout(node); + this.incrementCounters(node.name, FaultID.CustomLayoutNeedAddDecorator, autofix); + } } diff --git a/ets2panda/linter/src/lib/TypeScriptLinterConfig.ts b/ets2panda/linter/src/lib/TypeScriptLinterConfig.ts index ade75c42e55c77eff5c5242c4984c76fd9fd5667..e43ee6219c936a521fe74aa59e2cf1c8fcba2843 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinterConfig.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinterConfig.ts @@ -16,7 +16,7 @@ import * as ts from 'typescript'; import { FaultID } from './Problems'; -export class LinterConfig { +export class TypeScriptLinterConfig { /* * The SyntaxKind enum defines additional elements at the end of the enum @@ -31,7 +31,7 @@ export class LinterConfig { static tsSyntaxKindNames: string[] = []; static { - LinterConfig.initTsSyntaxKindNames(); + TypeScriptLinterConfig.initTsSyntaxKindNames(); } private static initTsSyntaxKindNames(): void { @@ -41,8 +41,8 @@ export class LinterConfig { for (let i = 0; i < values.length; i++) { const val = values[i]; const kindNum = typeof val === 'string' ? parseInt(val) : val; - if (kindNum && !LinterConfig.tsSyntaxKindNames[kindNum]) { - LinterConfig.tsSyntaxKindNames[kindNum] = keys[i]; + if (kindNum && !TypeScriptLinterConfig.tsSyntaxKindNames[kindNum]) { + TypeScriptLinterConfig.tsSyntaxKindNames[kindNum] = keys[i]; } } } diff --git a/ets2panda/linter/src/lib/autofixes/AutofixReportHtmlHelper.ts b/ets2panda/linter/src/lib/autofixes/AutofixReportHtmlHelper.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b6908e29221eef3e7ccba8b4422a593ef0ca6aa --- /dev/null +++ b/ets2panda/linter/src/lib/autofixes/AutofixReportHtmlHelper.ts @@ -0,0 +1,47 @@ +/* + * 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. + */ + +export const AUTOFIX_HTML_TEMPLATE_TEXT = 'this is replace content'; +export const AutofixHtmlTemplate = ` + + + + AutoFixes + + + +
+ + + +`; diff --git a/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts b/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts index 8d4c45bfd1453e81ea233825cdb578891c6ac1df..6a0d3826c6e2e4bd59c518fa3ecd79d0ca177da1 100644 --- a/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts +++ b/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts @@ -21,6 +21,7 @@ export const cookBookRefToFixTitle: Map = new Map([ [16, 'Combine static block statements into one static block'], [25, 'Replace with field declaration'], [29, 'Replace with dot notation'], + [34, 'Add type annotation'], [37, 'Replace with \'new Regexp()\' stdlib API call'], [38, 'Add interface definition'], [40, 'Replace with interface'], @@ -39,6 +40,8 @@ export const cookBookRefToFixTitle: Map = new Map([ [189, 'Add type annotations to numerical variables'], [193, 'Replace with arrow function'], [206, 'Replace with a special library to call'], + [209, 'Transform "number" to "int"'], + [238, 'Replace with explicit static initializer'], [251, 'Transform "!!" to "$$()"'], [252, 'Transform "$$" to "$$()"'], [253, '"$value" transform to "this.value"'], @@ -49,11 +52,15 @@ export const cookBookRefToFixTitle: Map = new Map([ [259, 'Add UI Interface Import'], [260, '"@Entry" annotaion fixed'], [263, '"@Provide" annotation fixed'], + [275, 'Custom layout need add decorator'], + [300, 'Replace calling method of the TS-like `Function` type'], [330, 'Convert import named objects from JS to ESObject'], [332, 'Using the ESObject interface to access properties'], [334, 'Call typeOf function'], [335, 'Call toNumber function to convert'], [338, 'Replace with library function call'], [339, 'Using \'ESObject\' interface call'], - [341, 'Create JS objects using instantite'] + [341, 'Create JS objects using instantite'], + [358, 'Replace missing attribute'], + [359, '"@LocalBuilder" transform to "@Builder"'] ]); diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index c67f4ca381b61e223a22bc7bf7652489da5b1572..5a368e5400323eff607a49806cc4b87b838487b2 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -16,7 +16,6 @@ import * as ts from 'typescript'; import { TsUtils } from '../utils/TsUtils'; import { scopeContainsThis } from '../utils/functions/ContainsThis'; -import { forEachNodeInSubtree } from '../utils/functions/ForEachNodeInSubtree'; import { NameGenerator } from '../utils/functions/NameGenerator'; import { isAssignmentOperator } from '../utils/functions/isAssignmentOperator'; import { SymbolCache } from './SymbolCache'; @@ -55,12 +54,24 @@ import { INSTANTIATE, TO_NUMBER } from '../utils/consts/InteropAPI'; +import { ESLIB_SHAREDARRAYBUFFER } from '../utils/consts/ConcurrentAPI'; const UNDEFINED_NAME = 'undefined'; +const LINE_FEED = '\n'; +const CARRIAGE_RETURN_LINE_FEED = '\r\n'; + +const NEW_LINE_SEARCH_REGEX = /\r\n|\n|\r/; + const GENERATED_OBJECT_LITERAL_INTERFACE_NAME = 'GeneratedObjectLiteralInterface_'; const GENERATED_OBJECT_LITERAL_INTERFACE_TRESHOLD = 1000; +const GENERATED_OBJECT_LITERAL_CLASS_NAME = 'GeneratedObjectLiteralClass_'; +const GENERATED_OBJECT_LITERAL_CLASS_TRESHOLD = 1000; + +const GENERATED_OBJECT_LITERAL_INIT_INTERFACE_NAME = 'GeneratedObjectLiteralInitInterface_'; +const GENERATED_OBJECT_LITERAL_INIT_INTERFACE_TRESHOLD = 1000; + const GENERATED_TYPE_LITERAL_INTERFACE_NAME = 'GeneratedTypeLiteralInterface_'; const GENERATED_TYPE_LITERAL_INTERFACE_TRESHOLD = 1000; @@ -75,24 +86,32 @@ const GENERATED_IMPORT_VARIABLE_TRESHOLD = 1000; const SPECIAL_LIB_NAME = 'specialAutofixLib'; +const OBJECT_LITERAL_CLASS_CONSTRUCTOR_PARAM_NAME = 'init'; + +const METHOD_KEYS = 'keys'; + +interface CreateClassPropertyForObjectLiteralParams { + prop: ts.PropertyAssignment | ts.ShorthandPropertyAssignment; + enclosingStmt: ts.Node; + classFields: ts.PropertyDeclaration[]; + ctorBodyStmts: ts.Statement[]; + ctorInitProps: ts.PropertyAssignment[]; +} + export interface Autofix { replacementText: string; start: number; end: number; + line?: number; + column?: number; + endLine?: number; + endColumn?: number; } export class Autofixer { - private readonly printer: ts.Printer = ts.createPrinter({ - omitTrailingSemicolon: false, - removeComments: false, - newLine: ts.NewLineKind.LineFeed - }); - - private readonly nonCommentPrinter: ts.Printer = ts.createPrinter({ - omitTrailingSemicolon: false, - removeComments: true, - newLine: ts.NewLineKind.LineFeed - }); + private readonly printer: ts.Printer; + + private readonly nonCommentPrinter: ts.Printer; private readonly typeLiteralInterfaceNameGenerator = new NameGenerator( GENERATED_TYPE_LITERAL_INTERFACE_NAME, @@ -114,6 +133,16 @@ export class Autofixer { GENERATED_OBJECT_LITERAL_INTERFACE_TRESHOLD ); + private readonly objectLiteralClassNameGenerator = new NameGenerator( + GENERATED_OBJECT_LITERAL_CLASS_NAME, + GENERATED_OBJECT_LITERAL_CLASS_TRESHOLD + ); + + private readonly objectLiteralInitInterfaceNameGenerator = new NameGenerator( + GENERATED_OBJECT_LITERAL_INIT_INTERFACE_NAME, + GENERATED_OBJECT_LITERAL_INIT_INTERFACE_TRESHOLD + ); + private readonly importVarNameGenerator = new NameGenerator( GENERATED_IMPORT_VARIABLE_NAME, GENERATED_IMPORT_VARIABLE_TRESHOLD @@ -132,6 +161,8 @@ export class Autofixer { private readonly sendableDecoratorCache = new Map(); + private readonly newLine: string; + constructor( private readonly typeChecker: ts.TypeChecker, private readonly utils: TsUtils, @@ -139,6 +170,29 @@ export class Autofixer { readonly cancellationToken?: ts.CancellationToken ) { this.symbolCache = new SymbolCache(this.typeChecker, this.utils, sourceFile, cancellationToken); + this.newLine = Autofixer.getNewLineCharacterFromSrcFile(sourceFile); + + const tsNewLineKind = + this.newLine === CARRIAGE_RETURN_LINE_FEED ? ts.NewLineKind.CarriageReturnLineFeed : ts.NewLineKind.LineFeed; + this.printer = ts.createPrinter({ + omitTrailingSemicolon: false, + removeComments: false, + newLine: tsNewLineKind + }); + this.nonCommentPrinter = ts.createPrinter({ + omitTrailingSemicolon: false, + removeComments: true, + newLine: tsNewLineKind + }); + } + + private static getNewLineCharacterFromSrcFile(srcFile: ts.SourceFile): string { + const match = srcFile.text.match(NEW_LINE_SEARCH_REGEX); + return match ? match[0] : LINE_FEED; + } + + private getNewLine(srcFile?: ts.SourceFile): string { + return srcFile ? Autofixer.getNewLineCharacterFromSrcFile(srcFile) : this.newLine; } /** @@ -150,7 +204,7 @@ export class Autofixer { * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring text. */ - private static genDestructElementTextForObjDecls( + private genDestructElementTextForObjDecls( variableDeclarationMap: Map, newObjectName: string, declarationFlags: ts.NodeFlags, @@ -182,7 +236,7 @@ export class Autofixer { // Print the variable statement to text and append it const text = printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); - destructElementText += text; + destructElementText += text + this.getNewLine(); }); return destructElementText; @@ -195,7 +249,7 @@ export class Autofixer { * @param destructElementText - Generated text for destructuring elements. * @returns Array of autofix suggestions or undefined. */ - private static genAutofixForObjDecls( + private genAutofixForObjDecls( variableDeclaration: ts.VariableDeclaration, newObjectName: string | undefined, destructElementText: string, @@ -221,7 +275,7 @@ export class Autofixer { end: variableDeclaration.name.getEnd() }; destructElementReplaceText = { - replacementText: destructElementText, + replacementText: this.getNewLine() + destructElementText, start: variableDeclaration.parent.parent.getEnd(), end: variableDeclaration.parent.parent.getEnd() }; @@ -295,7 +349,7 @@ export class Autofixer { return undefined; } const declarationFlags = ts.getCombinedNodeFlags(variableDeclaration); - const destructElementText = Autofixer.genDestructElementTextForObjDecls( + const destructElementText = this.genDestructElementTextForObjDecls( variableDeclarationMap, newObjectName, declarationFlags, @@ -304,7 +358,7 @@ export class Autofixer { ); // Generate and return autofix suggestions for the object declarations - return Autofixer.genAutofixForObjDecls(variableDeclaration, newObjectName, destructElementText, isIdentifier); + return this.genAutofixForObjDecls(variableDeclaration, newObjectName, destructElementText, isIdentifier); } /** @@ -316,7 +370,7 @@ export class Autofixer { * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring text. */ - private static genDestructElementTextForArrayDecls( + private genDestructElementTextForArrayDecls( variableNames: string[], newArrayName: string, declarationFlags: ts.NodeFlags, @@ -352,7 +406,7 @@ export class Autofixer { // Print the variable statement to text and append it const text = printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); - destructElementText += text; + destructElementText += text + this.getNewLine(); } return destructElementText; @@ -365,7 +419,7 @@ export class Autofixer { * @param destructElementText - Generated text for destructuring elements. * @returns Array of autofix suggestions. */ - private static genAutofixForArrayDecls( + private genAutofixForArrayDecls( variableDeclaration: ts.VariableDeclaration, newArrayName: string | undefined, destructElementText: string, @@ -391,7 +445,7 @@ export class Autofixer { end: variableDeclaration.name.getEnd() }; destructElementReplaceText = { - replacementText: destructElementText, + replacementText: this.getNewLine() + destructElementText, start: variableDeclaration.parent.parent.getEnd(), end: variableDeclaration.parent.parent.getEnd() }; @@ -478,7 +532,7 @@ export class Autofixer { // Get the combined node flags for the variable declaration const declarationFlags = ts.getCombinedNodeFlags(variableDeclaration); // Generate the destructuring element text for the array declaration - const destructElementText = Autofixer.genDestructElementTextForArrayDecls( + const destructElementText = this.genDestructElementTextForArrayDecls( variableNames, newArrayName, declarationFlags, @@ -487,7 +541,7 @@ export class Autofixer { ); // Generate and return autofix suggestions for the array declarations - return Autofixer.genAutofixForArrayDecls( + return this.genAutofixForArrayDecls( variableDeclaration, newArrayName, destructElementText, @@ -503,7 +557,7 @@ export class Autofixer { * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring assignment text. */ - private static genDestructElementTextForArrayAssignment( + private genDestructElementTextForArrayAssignment( variableNames: string[], newArrayName: string | undefined, printer: ts.Printer, @@ -534,7 +588,7 @@ export class Autofixer { // Print the expression statement to text and append it const text = printer.printNode(ts.EmitHint.Unspecified, expressionStatement, sourceFile); - destructElementText += text; + destructElementText += text + this.getNewLine(); } return destructElementText; @@ -547,7 +601,7 @@ export class Autofixer { * @param destructElementText - Generated text for destructuring assignments. * @returns Array of autofix suggestions. */ - private static genAutofixForArrayAssignment( + private genAutofixForArrayAssignment( assignmentExpr: ts.BinaryExpression, newArrayName: string | undefined, destructElementText: string, @@ -574,7 +628,7 @@ export class Autofixer { end: assignmentExpr.left.getEnd() }; destructElementReplaceText = { - replacementText: destructElementText, + replacementText: this.getNewLine() + destructElementText, start: assignmentExpr.parent.getEnd(), end: assignmentExpr.parent.getEnd() }; @@ -658,14 +712,14 @@ export class Autofixer { } // Generate the text for destructuring assignments - const destructElementText = Autofixer.genDestructElementTextForArrayAssignment( + const destructElementText = this.genDestructElementTextForArrayAssignment( variableNames, newArrayName, this.printer, sourceFile ); - return Autofixer.genAutofixForArrayAssignment( + return this.genAutofixForArrayAssignment( assignmentExpr, newArrayName, destructElementText, @@ -711,7 +765,7 @@ export class Autofixer { * @param printer - TypeScript printer instance for printing nodes. * @returns The generated text for destructuring assignments. */ - private static genDestructElementTextForObjAssignment( + private genDestructElementTextForObjAssignment( tsVarDeclMap: Map, needParentheses: boolean[], newObjName: string, @@ -740,7 +794,8 @@ export class Autofixer { ts.factory.createExpressionStatement(assignmentExpr); // Append the generated text for the destructuring assignment - destructElementText += printer.printNode(ts.EmitHint.Unspecified, statement, binaryExpr.getSourceFile()); + destructElementText += + printer.printNode(ts.EmitHint.Unspecified, statement, binaryExpr.getSourceFile()) + this.getNewLine(); index++; }); @@ -782,7 +837,7 @@ export class Autofixer { * @param destructElementText - Generated text for destructuring assignments. * @returns Array of autofix suggestions or undefined if no fixes are needed. */ - private static createAutofixForObjAssignment( + private createAutofixForObjAssignment( binaryExpr: ts.BinaryExpression, declNameReplaceText: string, destructElementText: string, @@ -807,7 +862,7 @@ export class Autofixer { end: binaryExpr.parent.getEnd() }; destructElementReplaceTextAutofix = { - replacementText: destructElementText, + replacementText: this.getNewLine() + destructElementText, start: binaryExpr.parent.parent.getEnd(), end: binaryExpr.parent.parent.getEnd() }; @@ -867,7 +922,7 @@ export class Autofixer { return undefined; } // Create the text for destructuring elements - const destructElementText = Autofixer.genDestructElementTextForObjAssignment( + const destructElementText = this.genDestructElementTextForObjAssignment( tsVarDeclMap, needParentheses, newObjName, @@ -879,7 +934,7 @@ export class Autofixer { const declNameReplaceText = Autofixer.genDeclNameReplaceTextForObjAssignment(binaryExpr, newObjName, this.printer); // Generate autofix suggestions - return Autofixer.createAutofixForObjAssignment(binaryExpr, declNameReplaceText, destructElementText, isIdentifier); + return this.createAutofixForObjAssignment(binaryExpr, declNameReplaceText, destructElementText, isIdentifier); } fixLiteralAsPropertyNamePropertyAssignment(node: ts.PropertyAssignment): Autofix[] | undefined { @@ -963,7 +1018,8 @@ export class Autofixer { return result; } - static addDefaultModuleToPath(parts: string[], importDeclNode: ts.ImportDeclaration): Autofix[] | undefined { + addDefaultModuleToPath(parts: string[], importDeclNode: ts.ImportDeclaration): Autofix[] | undefined { + void this; const moduleSpecifier = importDeclNode.moduleSpecifier; /* @@ -979,7 +1035,8 @@ export class Autofixer { return [{ start: moduleSpecifier.getStart(), end: moduleSpecifier.getEnd(), replacementText: newPathString }]; } - static fixImportPath(parts: string[], index: number, importDeclNode: ts.ImportDeclaration): Autofix[] | undefined { + fixImportPath(parts: string[], index: number, importDeclNode: ts.ImportDeclaration): Autofix[] | undefined { + void this; const moduleSpecifier = importDeclNode.moduleSpecifier; const beforeEts = parts.slice(0, index); @@ -1345,11 +1402,11 @@ export class Autofixer { if (tsExprNode.left.kind === ts.SyntaxKind.BinaryExpression) { text += this.recursiveCommaOperator(tsExprNode.left as ts.BinaryExpression); - text += '\n' + tsExprNode.right.getFullText() + ';'; + text += this.getNewLine() + tsExprNode.right.getFullText() + ';'; } else { const leftText = tsExprNode.left.getFullText(); const rightText = tsExprNode.right.getFullText(); - text = leftText + ';\n' + rightText + ';'; + text = leftText + ';' + this.getNewLine() + rightText + ';'; } return text; @@ -1460,13 +1517,7 @@ export class Autofixer { const autofixes: Autofix[] = [{ start: newFieldPos, end: newFieldPos, replacementText: '' }]; for (let i = 0; i < ctorDecl.parameters.length; i++) { - this.fixCtorParameterPropertiesProcessParam( - ctorDecl.parameters[i], - paramTypes[i], - ctorDecl.getSourceFile(), - fieldInitStmts, - autofixes - ); + this.fixCtorParameterPropertiesProcessParam(ctorDecl.parameters[i], paramTypes[i], fieldInitStmts, autofixes); } // Note: Bodyless ctors can't have parameter properties. @@ -1524,7 +1575,6 @@ export class Autofixer { private fixCtorParameterPropertiesProcessParam( param: ts.ParameterDeclaration, paramType: ts.TypeNode, - sourceFile: ts.SourceFile, fieldInitStmts: ts.Statement[], autofixes: Autofix[] ): void { @@ -1547,7 +1597,8 @@ export class Autofixer { paramType, undefined ); - const newFieldText = this.printer.printNode(ts.EmitHint.Unspecified, newFieldNode, sourceFile) + '\n'; + const newFieldText = + this.printer.printNode(ts.EmitHint.Unspecified, newFieldNode, param.getSourceFile()) + this.getNewLine(); autofixes[0].replacementText += newFieldText; const newParamDecl = ts.factory.createParameterDeclaration( @@ -1558,7 +1609,7 @@ export class Autofixer { param.type, param.initializer ); - const newParamText = this.printer.printNode(ts.EmitHint.Unspecified, newParamDecl, sourceFile); + const newParamText = this.printer.printNode(ts.EmitHint.Unspecified, newParamDecl, param.getSourceFile()); autofixes.push({ start: param.getStart(), end: param.getEnd(), replacementText: newParamText }); fieldInitStmts.push( @@ -1794,7 +1845,11 @@ export class Autofixer { return this.fixRecordObjectLiteral(objectLiteralExpr); } - // Can't fix when object literal has a contextual type. + // Here, we only fix object literal that doesn't have a contextual type. + return undefined; + } + + if (Autofixer.hasUnfixableProperty(objectLiteralExpr)) { return undefined; } @@ -1803,6 +1858,28 @@ export class Autofixer { return undefined; } + if (Autofixer.hasMethodsOrAccessors(objectLiteralExpr)) { + return this.fixObjectLiteralAsClass(objectLiteralExpr, undefined, enclosingStmt); + } + return this.fixUntypedObjectLiteralAsInterface(objectLiteralExpr, enclosingStmt); + } + + private static hasUnfixableProperty(objectLiteralExpr: ts.ObjectLiteralExpression): boolean { + return objectLiteralExpr.properties.some((prop) => { + return ts.isSpreadAssignment(prop) || !ts.isIdentifier(prop.name); + }); + } + + private static hasMethodsOrAccessors(objectLiteralExpr: ts.ObjectLiteralExpression): boolean { + return objectLiteralExpr.properties.some((prop) => { + return ts.isMethodDeclaration(prop) || ts.isAccessor(prop); + }); + } + + private fixUntypedObjectLiteralAsInterface( + objectLiteralExpr: ts.ObjectLiteralExpression, + enclosingStmt: ts.Node + ): Autofix[] | undefined { const newInterfaceProps = this.getInterfacePropertiesFromObjectLiteral(objectLiteralExpr, enclosingStmt); if (!newInterfaceProps) { return undefined; @@ -1815,7 +1892,7 @@ export class Autofixer { } return [ - this.createNewInterface(srcFile, newInterfaceName, newInterfaceProps, enclosingStmt.getStart()), + this.createNewInterfaceForObjectLiteral(srcFile, newInterfaceName, newInterfaceProps, enclosingStmt.getStart()), this.fixObjectLiteralExpression(srcFile, newInterfaceName, objectLiteralExpr) ]; } @@ -1851,7 +1928,7 @@ export class Autofixer { return undefined; } - if (Autofixer.propertyTypeIsCapturedFromEnclosingLocalScope(propType, enclosingStmt)) { + if (TsUtils.typeIsCapturedFromEnclosingLocalScope(propType, enclosingStmt)) { return undefined; } @@ -1869,21 +1946,7 @@ export class Autofixer { return newProp; } - private static propertyTypeIsCapturedFromEnclosingLocalScope(type: ts.Type, enclosingStmt: ts.Node): boolean { - const sym = type.getSymbol(); - let symNode: ts.Node | undefined = TsUtils.getDeclaration(sym); - - while (symNode) { - if (symNode === enclosingStmt) { - return true; - } - symNode = symNode.parent; - } - - return false; - } - - private createNewInterface( + private createNewInterfaceForObjectLiteral( srcFile: ts.SourceFile, interfaceName: string, members: ts.TypeElement[], @@ -1896,7 +1959,7 @@ export class Autofixer { undefined, members ); - const text = this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile) + '\n'; + const text = this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile) + this.getNewLine(); return { start: pos, end: pos, replacementText: text }; } @@ -1945,6 +2008,286 @@ export class Autofixer { return (decl.exclamationToken || decl.name).getEnd(); } + private fixObjectLiteralAsClass( + objectLiteralExpr: ts.ObjectLiteralExpression, + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined, + enclosingStmt: ts.Node + ): Autofix[] | undefined { + if (this.utils.nodeCapturesValueFromEnclosingLocalScope(objectLiteralExpr, enclosingStmt)) { + return undefined; + } + + const srcFile = objectLiteralExpr.getSourceFile(); + const newClassName = TsUtils.generateUniqueName(this.objectLiteralClassNameGenerator, srcFile); + if (!newClassName) { + return undefined; + } + const newInitInterfaceName = TsUtils.generateUniqueName(this.objectLiteralInitInterfaceNameGenerator, srcFile); + if (!newInitInterfaceName) { + return undefined; + } + + const classDeclAndCtorInitProps = this.createClassDeclForObjectLiteral( + objectLiteralExpr, + enclosingStmt, + newClassName, + newInitInterfaceName, + typeDecl + ); + if (!classDeclAndCtorInitProps) { + return undefined; + } + const { classDecl, ctorInitProps } = classDeclAndCtorInitProps; + let classDeclText = + this.printer.printNode(ts.EmitHint.Unspecified, classDecl, srcFile) + this.getNewLine() + this.getNewLine(); + + const ctorArgs: ts.Expression[] = []; + if (ctorInitProps.length) { + classDeclText += this.createInitInterfaceForObjectLiteral(srcFile, newInitInterfaceName, classDecl); + classDeclText += this.getNewLine() + this.getNewLine(); + ctorArgs.push(ts.factory.createObjectLiteralExpression(ctorInitProps, ctorInitProps.length > 1)); + } + const newExpr = ts.factory.createNewExpression(ts.factory.createIdentifier(newClassName), undefined, ctorArgs); + const newExprText = this.printer.printNode(ts.EmitHint.Unspecified, newExpr, srcFile); + const ctorCallAutofix = { + start: objectLiteralExpr.getStart(), + end: objectLiteralExpr.getEnd(), + replacementText: newExprText + }; + const classDeclPos = enclosingStmt.getStart(); + return [{ start: classDeclPos, end: classDeclPos, replacementText: classDeclText }, ctorCallAutofix]; + } + + private createClassDeclForObjectLiteral( + objectLiteralExpr: ts.ObjectLiteralExpression, + enclosingStmt: ts.Node, + newClassName: string, + newInitInterfaceName: string, + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): { classDecl: ts.ClassDeclaration; ctorInitProps: ts.PropertyAssignment[] } | undefined { + const classFields: ts.PropertyDeclaration[] = []; + const classMethods: (ts.MethodDeclaration | ts.AccessorDeclaration)[] = []; + const ctorBodyStmts: ts.Statement[] = []; + const ctorInitProps: ts.PropertyAssignment[] = []; + + Autofixer.addSuperCallToObjectLiteralConstructor(typeDecl, ctorBodyStmts); + + for (const prop of objectLiteralExpr.properties) { + if (ts.isSpreadAssignment(prop) || !ts.isIdentifier(prop.name)) { + return undefined; + } + if (ts.isMethodDeclaration(prop) || ts.isAccessor(prop)) { + classMethods.push(prop); + continue; + } + const created = this.createClassPropertyForObjectLiteral({ + prop, + enclosingStmt, + classFields, + ctorBodyStmts, + ctorInitProps + }); + if (!created) { + return undefined; + } + } + + const classElements: ts.ClassElement[] = [...classFields]; + if (ctorInitProps.length) { + classElements.push(Autofixer.createClassConstructorForObjectLiteral(newInitInterfaceName, ctorBodyStmts)); + } + classElements.push(...classMethods); + + const heritageClauses = Autofixer.createHeritageClausesForObjectLiteralClass(typeDecl); + + return { + classDecl: ts.factory.createClassDeclaration(undefined, newClassName, undefined, heritageClauses, classElements), + ctorInitProps + }; + } + + private static addSuperCallToObjectLiteralConstructor( + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined, + ctorBodyStmts: ts.Statement[] + ): void { + if (typeDecl && ts.isClassDeclaration(typeDecl)) { + const superCall = ts.factory.createExpressionStatement( + ts.factory.createCallExpression(ts.factory.createSuper(), undefined, []) + ); + ctorBodyStmts.push(superCall); + } + } + + private createClassPropertyForObjectLiteral( + createClassPropParams: CreateClassPropertyForObjectLiteralParams + ): boolean { + const { prop, enclosingStmt, classFields, ctorBodyStmts, ctorInitProps } = createClassPropParams; + if (!ts.isIdentifier(prop.name)) { + return false; + } + const propType = this.typeChecker.getTypeAtLocation(prop); + + // Can't capture generic type parameters of enclosing declarations. + if (this.utils.hasGenericTypeParameter(propType)) { + return false; + } + + if (TsUtils.typeIsCapturedFromEnclosingLocalScope(propType, enclosingStmt)) { + return false; + } + + const propTypeNode = this.typeChecker.typeToTypeNode(propType, undefined, ts.NodeBuilderFlags.None); + if (!propTypeNode || !this.utils.isSupportedType(propTypeNode)) { + return false; + } + + const propName = ts.factory.createIdentifier(prop.name.text); + classFields.push(ts.factory.createPropertyDeclaration(undefined, propName, undefined, propTypeNode, undefined)); + ctorBodyStmts.push( + ts.factory.createExpressionStatement( + ts.factory.createBinaryExpression( + ts.factory.createPropertyAccessExpression(ts.factory.createThis(), propName), + ts.factory.createToken(ts.SyntaxKind.EqualsToken), + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(OBJECT_LITERAL_CLASS_CONSTRUCTOR_PARAM_NAME), + propName + ) + ) + ) + ); + ctorInitProps.push(ts.isPropertyAssignment(prop) ? prop : ts.factory.createPropertyAssignment(prop.name, propName)); + return true; + } + + private static createHeritageClausesForObjectLiteralClass( + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): ts.HeritageClause[] | undefined { + if (!typeDecl?.name) { + return undefined; + } + + return [ + ts.factory.createHeritageClause( + ts.isClassDeclaration(typeDecl) ? ts.SyntaxKind.ExtendsKeyword : ts.SyntaxKind.ImplementsKeyword, + [ts.factory.createExpressionWithTypeArguments(typeDecl.name, undefined)] + ) + ]; + } + + private static createClassConstructorForObjectLiteral( + newInitInterfaceName: string, + ctorBodyStmts: ts.Statement[] + ): ts.ConstructorDeclaration { + const ctorParams: ts.ParameterDeclaration[] = []; + ctorParams.push( + ts.factory.createParameterDeclaration( + undefined, + undefined, + OBJECT_LITERAL_CLASS_CONSTRUCTOR_PARAM_NAME, + undefined, + ts.factory.createTypeReferenceNode(newInitInterfaceName) + ) + ); + return ts.factory.createConstructorDeclaration(undefined, ctorParams, ts.factory.createBlock(ctorBodyStmts, true)); + } + + private createInitInterfaceForObjectLiteral( + srcFile: ts.SourceFile, + interfaceName: string, + newClassDecl: ts.ClassDeclaration + ): string { + const props: ts.PropertySignature[] = []; + newClassDecl.members.forEach((prop) => { + if (ts.isPropertyDeclaration(prop)) { + props.push(ts.factory.createPropertySignature(undefined, prop.name, undefined, prop.type)); + } + }); + const newInterfaceDecl = ts.factory.createInterfaceDeclaration( + undefined, + interfaceName, + undefined, + undefined, + props + ); + return this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile); + } + + fixTypedObjectLiteral( + objectLiteralExpr: ts.ObjectLiteralExpression, + objectLiteralType: ts.Type | undefined + ): Autofix[] | undefined { + // Here we only try to fix typed object literal. Other case is handled by 'fixUntypedObjectLiteral' method. + + if (!objectLiteralType || !this.utils.validateObjectLiteralType(objectLiteralType)) { + return undefined; + } + + const typeDecl = TsUtils.getDeclaration(objectLiteralType.getSymbol()); + if (!typeDecl || !ts.isClassDeclaration(typeDecl) && !ts.isInterfaceDeclaration(typeDecl) || !typeDecl.name) { + return undefined; + } + + if (Autofixer.hasUnfixableProperty(objectLiteralExpr)) { + return undefined; + } + + if (this.hasMethodOverridingProperty(objectLiteralExpr, objectLiteralType)) { + return undefined; + } + + const enclosingStmt = TsUtils.getEnclosingTopLevelStatement(objectLiteralExpr); + if (!enclosingStmt) { + return undefined; + } + + return this.fixObjectLiteralAsClass(objectLiteralExpr, typeDecl, enclosingStmt); + } + + private hasMethodOverridingProperty( + objectLiteralExpr: ts.ObjectLiteralExpression, + objectLiteralType: ts.Type + ): boolean { + const typeProps = this.typeChecker.getPropertiesOfType(objectLiteralType); + for (const objProp of objectLiteralExpr.properties) { + if ( + ts.isPropertyAssignment(objProp) && + typeProps.some((typeProp) => { + const typePropDecl = TsUtils.getDeclaration(typeProp); + return ( + !!typePropDecl && + (ts.isMethodSignature(typePropDecl) || ts.isMethodDeclaration(typePropDecl)) && + typePropDecl.name === objProp.name + ); + }) + ) { + return true; + } + + if ( + ts.isMethodDeclaration(objProp) && + typeProps.some((typeProp) => { + const typePropDecl = TsUtils.getDeclaration(typeProp); + return ( + !!typePropDecl && + (ts.isPropertyDeclaration(typePropDecl) || ts.isPropertySignature(typePropDecl)) && + typePropDecl.name.getText() === objProp.name.getText() + ); + }) + ) { + return true; + } + } + + return false; + } + + fixShorthandPropertyAssignment(prop: ts.ShorthandPropertyAssignment): Autofix[] { + const newName = ts.factory.createIdentifier(prop.name.text); + const newProp = ts.factory.createPropertyAssignment(newName, newName); + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, newProp, prop.getSourceFile()); + return [{ start: prop.getStart(), end: prop.getEnd(), replacementText }]; + } + /* * In case of type alias initialized with type literal, replace * entire type alias with identical interface declaration. @@ -1981,7 +2324,7 @@ export class Autofixer { return undefined; } - if (this.typeLiteralCapturesTypeFromEnclosingLocalScope(typeLiteral, enclosingStmt)) { + if (this.utils.nodeCapturesValueFromEnclosingLocalScope(typeLiteral, enclosingStmt)) { return undefined; } @@ -1997,7 +2340,8 @@ export class Autofixer { undefined, typeLiteral.members ); - const interfaceText = this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile) + '\n'; + const interfaceText = + this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile) + this.getNewLine(); return [ { start: newInterfacePos, end: newInterfacePos, replacementText: interfaceText }, @@ -2005,39 +2349,79 @@ export class Autofixer { ]; } - typeLiteralCapturesTypeFromEnclosingLocalScope(typeLiteral: ts.TypeLiteralNode, enclosingStmt: ts.Node): boolean { - let found = false; + removeNode(node: ts.Node): Autofix[] { + void this; + return [{ start: node.getStart(), end: node.getEnd(), replacementText: '' }]; + } - const callback = (node: ts.Node): void => { - if (!ts.isIdentifier(node)) { - return; - } - const sym = this.typeChecker.getSymbolAtLocation(node); - let symNode: ts.Node | undefined = TsUtils.getDeclaration(sym); - while (symNode) { - if (symNode === typeLiteral) { - return; - } - if (symNode === enclosingStmt) { - found = true; - return; - } - symNode = symNode.parent; + replaceNode(node: ts.Node, replacementText: string): Autofix[] { + void this; + return [{ start: node.getStart(), end: node.getEnd(), replacementText }]; + } + + removeImportSpecifier( + specToRemove: ts.ImportSpecifier, + importDeclaration: ts.ImportDeclaration + ): Autofix[] | undefined { + if (!importDeclaration) { + return undefined; + } + + const importClause = importDeclaration.importClause; + if (!importClause?.namedBindings || !ts.isNamedImports(importClause.namedBindings)) { + return undefined; + } + + const namedBindings = importClause.namedBindings; + const allSpecifiers = namedBindings.elements; + const remainingSpecifiers = allSpecifiers.filter((spec) => { + return spec !== specToRemove; + }); + + // If none are valid, remove all named imports. + if (remainingSpecifiers.length === 0) { + if (importClause.name) { + const start = importClause.name.end; + const end = namedBindings.end; + return [{ start, end, replacementText: '' }]; } - }; + return this.removeNode(importDeclaration); + } - const stopCondition = (node: ts.Node): boolean => { - void node; - return found; - }; + const specIndex = allSpecifiers.findIndex((spec) => { + return spec === specToRemove; + }); + const isLast = specIndex === allSpecifiers.length - 1; + const isFirst = specIndex === 0; + + let start = specToRemove.getStart(); + let end = specToRemove.getEnd(); - forEachNodeInSubtree(typeLiteral, callback, stopCondition); - return found; + if (!isLast) { + end = allSpecifiers[specIndex + 1].getStart(); + } else if (!isFirst) { + const prev = allSpecifiers[specIndex - 1]; + start = prev.getEnd(); + } + + return [{ start, end, replacementText: '' }]; } - removeNode(node: ts.Node): Autofix[] { - void this; - return [{ start: node.getStart(), end: node.getEnd(), replacementText: '' }]; + removeDefaultImport(importDecl: ts.ImportDeclaration, defaultImport: ts.Identifier): Autofix[] | undefined { + const importClause = importDecl.importClause; + if (!importClause || !defaultImport) { + return undefined; + } + + const namedBindings = importClause.namedBindings; + + if (!namedBindings) { + return this.removeNode(importDecl); + } + const start = defaultImport.getStart(); + const end = namedBindings.getStart(); + + return [{ start, end, replacementText: '' }]; } fixSendableExplicitFieldType(node: ts.PropertyDeclaration): Autofix[] | undefined { @@ -2052,19 +2436,9 @@ export class Autofixer { return undefined; } - const questionOrExclamationToken: ts.ExclamationToken | ts.QuestionToken | undefined = - node.questionToken ?? node.exclamationToken ?? undefined; - - const newPropDecl: ts.PropertyDeclaration = ts.factory.createPropertyDeclaration( - node.modifiers, - node.name, - questionOrExclamationToken, - propTypeNode, - initializer - ); - - const text = this.printer.printNode(ts.EmitHint.Unspecified, newPropDecl, node.getSourceFile()); - return [{ start: node.getFullStart(), end: node.getEnd(), replacementText: text }]; + const pos = (node.questionToken || node.exclamationToken || node.name).getEnd(); + const text = ': ' + this.printer.printNode(ts.EmitHint.Unspecified, propTypeNode, node.getSourceFile()); + return [{ start: pos, end: pos, replacementText: text }]; } addClassSendableDecorator( @@ -2085,7 +2459,7 @@ export class Autofixer { addSendableDecorator(node: ts.Node): Autofix[] { void this; - const text = '@' + SENDABLE_DECORATOR + '\n'; + const text = '@' + SENDABLE_DECORATOR + this.getNewLine(); const pos = node.getStart(); return [{ start: pos, end: pos, replacementText: text }]; } @@ -2153,12 +2527,13 @@ export class Autofixer { fixRegularExpressionLiteral(node: ts.RegularExpressionLiteral | ts.CallExpression): Autofix[] | undefined { const srcFile = node.getSourceFile(); - let pattern: string; + let patternNode: ts.Expression | undefined; let flag: string | undefined; + if (ts.isRegularExpressionLiteral(node)) { const literalText = node.getText(); const parts = Autofixer.extractRegexParts(literalText); - pattern = parts.pattern; + patternNode = ts.factory.createStringLiteral(parts.pattern); flag = parts.flag; } else if (ts.isCallExpression(node)) { const args = node.arguments; @@ -2166,10 +2541,11 @@ export class Autofixer { return undefined; } const patternArg = args[0]; - if (!ts.isStringLiteral(patternArg)) { + if (!this.isStaticStringExpression(patternArg)) { return undefined; } - pattern = patternArg.text; + patternNode = patternArg; + if (args.length > 1) { const flagArg = args[1]; if (ts.isStringLiteral(flagArg)) { @@ -2181,13 +2557,47 @@ export class Autofixer { } else { return undefined; } - const args = [ts.factory.createStringLiteral(pattern)]; - if (flag) { - args.push(ts.factory.createStringLiteral(flag)); + + const newArgs: ts.Expression[] = [patternNode]; + if (flag !== undefined) { + newArgs.push(ts.factory.createStringLiteral(flag)); } - const newExpression = ts.factory.createNewExpression(ts.factory.createIdentifier('RegExp'), undefined, args); + const newExpression = ts.factory.createNewExpression(ts.factory.createIdentifier('RegExp'), undefined, newArgs); + const text = this.printer.printNode(ts.EmitHint.Unspecified, newExpression, srcFile); - return [{ start: node.getStart(), end: node.getEnd(), replacementText: text }]; + return [ + { + start: node.getStart(), + end: node.getEnd(), + replacementText: text + } + ]; + } + + private isStaticStringExpression(node: ts.Node): boolean { + if (ts.isStringLiteral(node)) { + return true; + } + if (ts.isBinaryExpression(node)) { + return ( + node.operatorToken.kind === ts.SyntaxKind.PlusToken && + this.isStaticStringExpression(node.left) && + this.isStaticStringExpression(node.right) + ); + } + if (ts.isCallExpression(node)) { + const expression = node.expression; + if ( + ts.isPropertyAccessExpression(expression) && + expression.name.text === 'concat' && + this.isStaticStringExpression(expression.expression) + ) { + return node.arguments.every((arg) => { + return this.isStaticStringExpression(arg); + }); + } + } + return false; } private static extractRegexParts(literalText: string): { @@ -2209,7 +2619,7 @@ export class Autofixer { fixDebuggerStatement(debuggerStmt: ts.DebuggerStatement): Autofix[] { void this; - const text = SPECIAL_LIB_NAME + '.debugger()'; + const text = SPECIAL_LIB_NAME + '.debugger();'; return [{ start: debuggerStmt.getStart(), end: debuggerStmt.getEnd(), replacementText: text }]; } @@ -2327,7 +2737,7 @@ export class Autofixer { const newExpr = ts.factory.createObjectLiteralExpression([assignment1, assignment2], true); let text = this.printer.printNode(ts.EmitHint.Unspecified, newExpr, originalExpr.getSourceFile()); const startPos = this.sourceFile.getLineAndCharacterOfPosition(originalExpr.parent.getStart()).character; - text = Autofixer.adjustIndentation(text, startPos); + text = this.adjustIndentation(text, startPos); return [{ start: originalExpr.getStart(), end: originalExpr.getEnd(), replacementText: text }]; } @@ -2392,7 +2802,7 @@ export class Autofixer { const newFuncDecl = Autofixer.createFunctionDeclaration(funcDecl, undefined, parameDecl, returnType, newBlock); let text = this.printer.printNode(ts.EmitHint.Unspecified, newFuncDecl, funcDecl.getSourceFile()); if (preserveDecorator) { - text = '@' + CustomDecoratorName.AnimatableExtend + '\n' + text; + text = '@' + CustomDecoratorName.AnimatableExtend + this.getNewLine() + text; } return [{ start: funcDecl.getStart(), end: funcDecl.getEnd(), replacementText: text }]; } @@ -2425,7 +2835,7 @@ export class Autofixer { fixedEntryDecorator, parentNode.getSourceFile() ); - text = text + '\n' + fixedEntryDecoratorText; + text = text + this.getNewLine() + fixedEntryDecoratorText; return [{ start: entryDecorator.getStart(), end: entryDecorator.getEnd(), replacementText: text }]; } return undefined; @@ -2863,6 +3273,36 @@ export class Autofixer { }); } + removeImport(ident: ts.Identifier, importSpecifier: ts.ImportSpecifier): Autofix[] | undefined { + const namedImports = importSpecifier.parent; + const importClause = namedImports.parent; + const importDeclaration = importClause.parent; + if (!importDeclaration || !importClause) { + return undefined; + } + + if (namedImports.elements.length === 1 && !importClause.name) { + return this.removeNode(importDeclaration); + } + + if (namedImports.elements.length <= 0) { + return undefined; + } + + const specifiers = namedImports.elements.filter((specifier) => { + return specifier.name.text !== ident.text; + }); + + const newClause = ts.factory.createImportClause( + importClause.isTypeOnly, + importClause.name, + ts.factory.createNamedImports(specifiers) + ); + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, newClause, ident.getSourceFile()); + return [{ start: importClause.getStart(), end: importClause.getEnd(), replacementText }]; + } + fixInterfaceImport( interfacesNeedToImport: Set, interfacesAlreadyImported: Set, @@ -2893,19 +3333,19 @@ export class Autofixer { let text = this.printer.printNode(ts.EmitHint.Unspecified, importDeclaration, sourceFile); if (annotationEndPos !== 0) { - text = '\n\n' + text; + text = this.getNewLine() + this.getNewLine() + text; } const codeStartLine = sourceFile.getLineAndCharacterOfPosition(sourceFile.getStart()).line; for (let i = 2; i > codeStartLine - annotationEndLine; i--) { - text = text + '\n'; + text = text + this.getNewLine(); } return [{ start: annotationEndPos, end: annotationEndPos, replacementText: text }]; } fixStylesDecoratorGlobal( funcDecl: ts.FunctionDeclaration, - calls: ts.CallExpression[], + calls: ts.Identifier[], needImport: Set ): Autofix[] | undefined { const block = funcDecl.body; @@ -2933,7 +3373,7 @@ export class Autofixer { fixStylesDecoratorStruct( methodDecl: ts.MethodDeclaration, - calls: ts.CallExpression[], + calls: ts.Identifier[], needImport: Set ): Autofix[] | undefined { const block = methodDecl.body; @@ -2962,7 +3402,7 @@ export class Autofixer { needImport.add(COMMON_METHOD_IDENTIFIER); let text = this.printer.printNode(ts.EmitHint.Unspecified, expr, methodDecl.getSourceFile()); const startPos = this.sourceFile.getLineAndCharacterOfPosition(methodDecl.getStart()).character; - text = Autofixer.adjustIndentation(text, startPos); + text = this.adjustIndentation(text, startPos); const autofix = [{ start: methodDecl.getStart(), end: methodDecl.getEnd(), replacementText: text }]; const argument = ts.factory.createPropertyAccessExpression( ts.factory.createThis(), @@ -2972,8 +3412,8 @@ export class Autofixer { return autofix; } - private static adjustIndentation(text: string, startPos: number): string { - const lines = text.split('\n'); + private adjustIndentation(text: string, startPos: number): string { + const lines = text.split(this.getNewLine()); if (lines.length <= 1) { return text; } @@ -2991,34 +3431,50 @@ export class Autofixer { }); const lastLine = ' '.repeat(startPos) + lines[lines.length - 1]; - return [firstLine, ...middleLines, lastLine].join('\n'); + return [firstLine, ...middleLines, lastLine].join(this.getNewLine()); } - private addAutofixFromCalls(calls: ts.CallExpression[], autofix: Autofix[], argument: ts.Expression): void { + private addAutofixFromCalls(calls: ts.Identifier[], autofix: Autofix[], argument: ts.Expression): void { calls.forEach((call) => { const callExpr = ts.factory.createCallExpression( ts.factory.createIdentifier(APPLY_STYLES_IDENTIFIER), undefined, [argument] ); + + const start: number = call.getStart(); + let end: number = 0; + const expr = call.parent; + if (ts.isCallExpression(expr)) { + end = expr.getEnd(); + } + if (ts.isPropertyAccessExpression(expr) && ts.isCallExpression(expr.parent)) { + end = expr.parent.getEnd(); + } + if (end === 0) { + return; + } const text = this.printer.printNode(ts.EmitHint.Unspecified, callExpr, call.getSourceFile()); - autofix.push({ start: call.getStart(), end: call.getEnd(), replacementText: text }); + autofix.push({ start: start, end: end, replacementText: text }); }); } - fixStateStyles(object: ts.ObjectLiteralExpression, needImport: Set): Autofix[] | undefined { + fixStateStyles( + object: ts.ObjectLiteralExpression, + startNode: ts.Node, + needImport: Set + ): Autofix[] | undefined { const properties = object.properties; - const stateStyles: ts.Identifier[] = []; - const stateParams: ts.MemberName[][] = []; - const stateValues: ts.Expression[][][] = []; + const assignments: ts.PropertyAssignment[] = []; for (let i = 0; i < properties.length; i++) { const property = properties[i]; const stateStyle = property.name; - if (stateStyle && ts.isIdentifier(stateStyle)) { - stateStyles.push(stateStyle); + if (!stateStyle || !ts.isIdentifier(stateStyle) || !ts.isPropertyAssignment(property)) { + return undefined; } - if (!ts.isPropertyAssignment(property) || !ts.isObjectLiteralExpression(property.initializer)) { - return []; + if (!ts.isObjectLiteralExpression(property.initializer)) { + assignments.push(property); + continue; } const propAssignments = property.initializer.properties; const parameters: ts.MemberName[] = []; @@ -3042,33 +3498,23 @@ export class Autofixer { values.push(tempVals[k]); } } - stateParams.push(parameters); - stateValues.push(values); + const assignment = Autofixer.createPropertyAssignment(parameters, values, stateStyle); + assignments.push(assignment); } needImport.add(COMMON_METHOD_IDENTIFIER); - const newExpr = ts.factory.createObjectLiteralExpression( - Autofixer.createPropertyAssignments(stateParams, stateValues, stateStyles), - true - ); + const newExpr = ts.factory.createObjectLiteralExpression(assignments, true); let text = this.printer.printNode(ts.EmitHint.Unspecified, newExpr, object.getSourceFile()); - const startPos = this.sourceFile.getLineAndCharacterOfPosition(object.parent.getStart()).character - 1; - text = Autofixer.adjustIndentation(text, startPos); + const startPos = this.sourceFile.getLineAndCharacterOfPosition(startNode.getStart()).character - 1; + text = this.adjustIndentation(text, startPos); return [{ start: object.getStart(), end: object.getEnd(), replacementText: text }]; } - private static createPropertyAssignments( - stateParams: ts.MemberName[][], - sateValues: ts.Expression[][][], - stateStyles: ts.Identifier[] - ): ts.PropertyAssignment[] { - const blocks: ts.Block[] = []; - for (let i = 0; i < stateParams.length; i++) { - const parameters = stateParams[i]; - const values = sateValues[i]; - const block = Autofixer.createBlock(parameters, values, ts.factory.createIdentifier(INSTANCE_IDENTIFIER)); - blocks.push(block); - } - + private static createPropertyAssignment( + stateParam: ts.MemberName[], + sateValue: ts.Expression[][], + stateStyle: ts.Identifier + ): ts.PropertyAssignment { + const block = Autofixer.createBlock(stateParam, sateValue, ts.factory.createIdentifier(INSTANCE_IDENTIFIER)); const parameterDecl = ts.factory.createParameterDeclaration( undefined, undefined, @@ -3079,15 +3525,11 @@ export class Autofixer { ); const voidToken = ts.factory.createToken(ts.SyntaxKind.VoidKeyword); const arrowToken = ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken); - const newProperties: ts.PropertyAssignment[] = []; - for (let i = 0; i < blocks.length; i++) { - const property = ts.factory.createPropertyAssignment( - stateStyles[i], - ts.factory.createArrowFunction(undefined, undefined, [parameterDecl], voidToken, arrowToken, blocks[i]) - ); - newProperties.push(property); - } - return newProperties; + const property = ts.factory.createPropertyAssignment( + stateStyle, + ts.factory.createArrowFunction(undefined, undefined, [parameterDecl], voidToken, arrowToken, block) + ); + return property; } fixDataObservation(classDecls: ts.ClassDeclaration[]): Autofix[] | undefined { @@ -3095,18 +3537,19 @@ export class Autofixer { classDecls.forEach((classDecl) => { const observedDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Observed)); const sourceFile = classDecl.getSourceFile(); - const text = this.printer.printNode(ts.EmitHint.Unspecified, observedDecorator, sourceFile) + '\n'; + const text = this.printer.printNode(ts.EmitHint.Unspecified, observedDecorator, sourceFile) + this.getNewLine(); const autofix = { start: classDecl.getStart(), end: classDecl.getStart(), replacementText: text }; autofixes.push(autofix); }); return autofixes.length !== 0 ? autofixes : undefined; } - static fixInteropTsType( + fixInteropTsType( binaryExpr: ts.BinaryExpression, lhs: ts.PropertyAccessExpression, rhs: ts.Expression ): Autofix[] | undefined { + void this; const base = lhs.expression.getText(); const prop = lhs.name.text; const replacementText = `${base}.setPropertyByName('${prop}',ESObject.wrap(${rhs.getText()}))`; @@ -3165,6 +3608,32 @@ export class Autofixer { return [{ replacementText, start, end }]; } + fixSharedArrayBufferConstructor(node: ts.NewExpression): Autofix[] | undefined { + void this; + + // Ensure it's a constructor call to SharedArrayBuffer + if (!ts.isIdentifier(node.expression) || node.expression.text !== ESLIB_SHAREDARRAYBUFFER) { + return undefined; + } + + // Construct replacement + const replacementText = 'ArrayBuffer'; + + return [{ replacementText, start: node.expression.getStart(), end: node.expression.getEnd() }]; + } + + fixSharedArrayBufferTypeReference(node: ts.TypeReferenceNode): Autofix[] | undefined { + void this; + + if (!ts.isIdentifier(node.typeName) || node.typeName.text !== ESLIB_SHAREDARRAYBUFFER) { + return undefined; + } + + const replacementText = 'ArrayBuffer'; + + return [{ replacementText, start: node.getStart(), end: node.getEnd() }]; + } + fixAppStorageCallExpression(callExpr: ts.CallExpression): Autofix[] | undefined { const varDecl = Autofixer.findParentVariableDeclaration(callExpr); if (!varDecl || varDecl.type) { @@ -3309,7 +3778,11 @@ export class Autofixer { } return [ { start: importDecl.getStart(), end: importDecl.getEnd(), replacementText: '' }, - { start: lastImportEnd, end: lastImportEnd, replacementText: statements.join('\n') } + { + start: lastImportEnd, + end: lastImportEnd, + replacementText: statements.join(this.getNewLine()) + this.getNewLine() + } ]; } @@ -3441,28 +3914,58 @@ export class Autofixer { } fixInteropInterfaceConvertNum(express: ts.PrefixUnaryExpression): Autofix[] | undefined { - let text = ''; - if (ts.isPropertyAccessExpression(express.operand)) { - const states = ts.factory.createCallExpression( + const createConversionExpression = (propertyAccess: ts.PropertyAccessExpression): ts.Expression => { + const getPropertyCall = ts.factory.createCallExpression( ts.factory.createPropertyAccessExpression( - ts.factory.createCallExpression( - ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier(express.operand.expression.getText()), - ts.factory.createIdentifier(GET_PROPERTY_BY_NAME) - ), - undefined, - [ts.factory.createStringLiteral(express.operand.name.getText())] - ), - ts.factory.createIdentifier(TO_NUMBER) + ts.factory.createIdentifier(propertyAccess.expression.getText()), + ts.factory.createIdentifier(GET_PROPERTY_BY_NAME) ), undefined, + [ts.factory.createStringLiteral(propertyAccess.name.getText())] + ); + + return ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(getPropertyCall, ts.factory.createIdentifier(TO_NUMBER)), + undefined, [] ); - text = this.printer.printNode(ts.EmitHint.Unspecified, states, express.getSourceFile()); + }; + + let replacementExpression: ts.Expression | undefined; + if (ts.isPropertyAccessExpression(express.operand)) { + replacementExpression = createConversionExpression(express.operand); + } else if ( + ts.isParenthesizedExpression(express.operand) && + ts.isPropertyAccessExpression(express.operand.expression) + ) { + replacementExpression = ts.factory.createParenthesizedExpression( + createConversionExpression(express.operand.expression) + ); + } + + if (!replacementExpression) { + return undefined; } + + const text = this.printer.printNode(ts.EmitHint.Unspecified, replacementExpression, express.getSourceFile()); + return [{ start: express.operand.getStart(), end: express.operand.getEnd(), replacementText: text }]; } + fixImportClause(tsImportClause: ts.ImportClause): Autofix[] { + const newImportClause = ts.factory.createImportClause( + tsImportClause.isTypeOnly, + tsImportClause.name, + tsImportClause.namedBindings + ); + const replacementText = this.printer.printNode( + ts.EmitHint.Unspecified, + newImportClause, + tsImportClause.getSourceFile() + ); + return [{ start: tsImportClause.getStart(), end: tsImportClause.getEnd(), replacementText }]; + } + fixInteropEqualityOperator( tsBinaryExpr: ts.BinaryExpression, binaryOperator: ts.BinaryOperator @@ -3518,4 +4021,308 @@ export class Autofixer { return undefined; } } + + fixArrayIndexExprType(argExpr: ts.Expression): Autofix[] | undefined { + void this; + if (ts.isAsExpression(argExpr)) { + const innerExpr = argExpr.expression; + return [ + { + start: argExpr.getStart(), + end: argExpr.getEnd(), + replacementText: `${innerExpr ? innerExpr.getText() : ''} as int` + } + ]; + } + + if (ts.isBinaryExpression(argExpr)) { + return [{ start: argExpr.getStart(), end: argExpr.getEnd(), replacementText: `(${argExpr.getText()}) as int` }]; + } + + return [{ start: argExpr.getStart(), end: argExpr.getEnd(), replacementText: `${argExpr.getText()} as int` }]; + } + + fixNoTsLikeFunctionCall(identifier: ts.Node): Autofix[] { + void this; + const funcName = identifier.getText(); + const replacementText = `${funcName}.unSafeCall`; + return [ + { + replacementText, + start: identifier.getStart(), + end: identifier.getEnd() + } + ]; + } + + fixStaticPropertyInitializer(propDecl: ts.PropertyDeclaration): Autofix[] | undefined { + const srcFile = propDecl.getSourceFile(); + const startPos = srcFile.getLineAndCharacterOfPosition(propDecl.getStart()).character; + + const newPropDecl = Autofixer.createUltimateFixedProperty(propDecl); + if (!newPropDecl) { + return undefined; + } + let text = this.printer.printNode(ts.EmitHint.Unspecified, newPropDecl, srcFile); + text = this.adjustIndentation(text, startPos); + + return [ + { + start: propDecl.getStart(), + end: propDecl.getEnd(), + replacementText: text + } + ]; + } + + private static createUltimateFixedProperty(propDecl: ts.PropertyDeclaration): ts.PropertyDeclaration | undefined { + const type = propDecl.type; + + if (!type) { + return undefined; + } + + switch (type.kind) { + case ts.SyntaxKind.TypeLiteral: + return Autofixer.handleTypeLiteralProperty(propDecl, type as ts.TypeLiteralNode); + case ts.SyntaxKind.TypeReference: + return Autofixer.handleTypeReferenceProperty(propDecl, type as ts.TypeReferenceNode); + case ts.SyntaxKind.ArrayType: + return Autofixer.handleArrayTypeProperty(propDecl, type as ts.ArrayTypeNode); + case ts.SyntaxKind.StringKeyword: + return Autofixer.handleStringProperty(propDecl, type); + default: + return undefined; + } + } + + private static handleTypeLiteralProperty( + propDecl: ts.PropertyDeclaration, + type: ts.TypeLiteralNode + ): ts.PropertyDeclaration { + return ts.factory.updatePropertyDeclaration( + propDecl, + propDecl.modifiers, + propDecl.name, + propDecl.questionToken, + type, + Autofixer.createExactObjectInitializer(type) + ); + } + + private static handleTypeReferenceProperty( + propDecl: ts.PropertyDeclaration, + type: ts.TypeReferenceNode + ): ts.PropertyDeclaration | undefined { + if (Autofixer.isUserDefinedClass(type)) { + return Autofixer.handleCustomClassProperty(propDecl, type); + } + const newInit = Autofixer.createBuiltInTypeInitializer(type); + if (!newInit) { + return undefined; + } + return ts.factory.updatePropertyDeclaration( + propDecl, + propDecl.modifiers, + propDecl.name, + propDecl.questionToken, + type, + newInit + ); + } + + private static handleCustomClassProperty( + propDecl: ts.PropertyDeclaration, + type: ts.TypeReferenceNode + ): ts.PropertyDeclaration | undefined { + const nullableType = ts.factory.createUnionTypeNode([ + type, + ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword) + ]); + + return ts.factory.updatePropertyDeclaration( + propDecl, + propDecl.modifiers, + propDecl.name, + undefined, + nullableType, + ts.factory.createIdentifier('undefined') + ); + } + + private static handleArrayTypeProperty( + propDecl: ts.PropertyDeclaration, + type: ts.ArrayTypeNode + ): ts.PropertyDeclaration { + return ts.factory.updatePropertyDeclaration( + propDecl, + propDecl.modifiers, + propDecl.name, + propDecl.questionToken, + type, + ts.factory.createArrayLiteralExpression([], false) + ); + } + + private static handleStringProperty(propDecl: ts.PropertyDeclaration, type: ts.TypeNode): ts.PropertyDeclaration { + return ts.factory.updatePropertyDeclaration( + propDecl, + propDecl.modifiers, + propDecl.name, + propDecl.questionToken, + type, + ts.factory.createStringLiteral('') + ); + } + + private static createBuiltInTypeInitializer(type: ts.TypeReferenceNode): ts.Expression | undefined { + const typeName = type.typeName.getText(); + + switch (typeName) { + case 'Date': + return ts.factory.createNewExpression(ts.factory.createIdentifier('Date'), undefined, []); + case 'Map': + case 'Set': + return ts.factory.createNewExpression(ts.factory.createIdentifier(typeName), type.typeArguments, []); + case 'Promise': + return ts.factory.createIdentifier('undefined'); + default: + return this.isNullableType(type) ? ts.factory.createIdentifier('undefined') : undefined; + } + } + + private static isNullableType(type: ts.TypeNode): boolean { + if (type.kind === ts.SyntaxKind.UndefinedKeyword) { + return true; + } + + if (ts.isUnionTypeNode(type)) { + return type.types.some((t) => { + return t.kind === ts.SyntaxKind.UndefinedKeyword; + }); + } + + return false; + } + + private static createExactObjectInitializer(type: ts.TypeLiteralNode): ts.ObjectLiteralExpression { + const properties = type.members. + filter((member): member is ts.PropertySignature => { + return ts.isPropertySignature(member); + }). + map((member) => { + const initializer = Autofixer.createInitializerForPropertySignature(member); + if (initializer) { + return ts.factory.createPropertyAssignment(member.name, initializer); + } + return null; + }). + filter((property): property is ts.PropertyAssignment => { + return property !== null; + }); + + return ts.factory.createObjectLiteralExpression(properties, true); + } + + private static createInitializerForPropertySignature(member: ts.PropertySignature): ts.Expression | undefined { + return member.type ? Autofixer.createTypeBasedInitializer(member.type) : undefined; + } + + private static createTypeBasedInitializer(type?: ts.TypeNode): ts.Expression | undefined { + if (!type) { + return undefined; + } + + switch (type.kind) { + case ts.SyntaxKind.StringKeyword: + return ts.factory.createStringLiteral(''); + case ts.SyntaxKind.TypeLiteral: + return Autofixer.createExactObjectInitializer(type as ts.TypeLiteralNode); + case ts.SyntaxKind.ArrayType: + return ts.factory.createArrayLiteralExpression([], false); + case ts.SyntaxKind.TypeReference: + return Autofixer.createBuiltInTypeInitializer(type as ts.TypeReferenceNode); + default: + return this.isNullableType(type) ? ts.factory.createIdentifier('undefined') : undefined; + } + } + + private static isUserDefinedClass(type: ts.TypeReferenceNode): boolean { + const builtInTypes = new Set(['Date', 'Array', 'Map', 'Set', 'Promise', 'RegExp', 'Function']); + return !builtInTypes.has(type.typeName.getText()); + } + + fixGenericCallNoTypeArgs(node: ts.NewExpression): Autofix[] | undefined { + const typeNode = this.getTypeNodeForNewExpression(node); + if (!typeNode || !ts.isTypeReferenceNode(typeNode) || typeNode.typeName.getText() !== node.expression.getText()) { + return undefined; + } + + const reference: ts.TypeReferenceNode[] = []; + typeNode.typeArguments?.forEach((arg) => { + return reference.push(ts.factory.createTypeReferenceNode(arg.getText())); + }); + const srcFile = node.getSourceFile(); + const identifier = node.expression; + const args = node.arguments; + const newExpression = ts.factory.createNewExpression(identifier, reference, args); + const text = this.printer.printNode(ts.EmitHint.Unspecified, newExpression, srcFile); + return [{ start: node.getStart(), end: node.getEnd(), replacementText: text }]; + } + + private getTypeNodeForNewExpression(node: ts.NewExpression): ts.TypeNode | undefined { + if (ts.isVariableDeclaration(node.parent) || ts.isPropertyDeclaration(node.parent)) { + return node.parent.type; + } else if (ts.isBinaryExpression(node.parent)) { + return this.utils.getDeclarationTypeNode(node.parent.left); + } else if (ts.isReturnStatement(node.parent) && ts.isBlock(node.parent.parent)) { + const funcNode = node.parent.parent.parent; + const isFunc = ts.isFunctionDeclaration(funcNode) || ts.isMethodDeclaration(funcNode); + if (!isFunc || !funcNode.type) { + return undefined; + } + + const isAsync = TsUtils.hasModifier(funcNode.modifiers, ts.SyntaxKind.AsyncKeyword); + if (isAsync) { + if (ts.isTypeReferenceNode(funcNode.type) && funcNode.type.typeName.getText() === 'Promise') { + return funcNode.type?.typeArguments?.[0]; + } + } + return funcNode.type; + } + return undefined; + } + + fixMissingAttribute(node: ts.PropertyAccessExpression): Autofix[] { + const exprName = node.expression.getText(); + const propertyAccessExpr = ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(exprName), + ts.factory.createIdentifier(METHOD_KEYS) + ); + const replacement = this.printer.printNode(ts.EmitHint.Unspecified, propertyAccessExpr, node.getSourceFile()); + return [{ start: node.getStart(), end: node.getEnd(), replacementText: replacement }]; + } + + fixBuilderDecorators(decorator: ts.Decorator): Autofix[] | undefined { + const newDecorator = ts.factory.createDecorator(ts.factory.createIdentifier('Builder')); + const text = this.printer.printNode(ts.EmitHint.Unspecified, newDecorator, decorator.getSourceFile()); + return [{ start: decorator.getStart(), end: decorator.getEnd(), replacementText: text }]; + } + + fixCustomLayout(node: ts.StructDeclaration): Autofix[] { + const startPos = Autofixer.getStartPositionWithoutDecorators(node); + const decorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Layoutable)); + + const text = this.getNewLine() + this.printer.printNode(ts.EmitHint.Unspecified, decorator, node.getSourceFile()); + return [{ start: startPos, end: startPos, replacementText: text }]; + } + + private static getStartPositionWithoutDecorators(node: ts.StructDeclaration): number { + const decorators = ts.getDecorators(node); + if (!decorators || decorators.length === 0) { + return node.getStart(); + } + + return decorators[decorators.length - 1].getEnd(); + } } diff --git a/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts b/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts index 3605f29a37696dfee033ceb54eea513aadb131cb..1d05ac4792952a0f3d2ff1007df0a4150e21c3bc 100644 --- a/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts +++ b/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts @@ -14,94 +14,109 @@ */ import * as fs from 'node:fs'; -import { Logger } from '../Logger'; import type * as ts from 'typescript'; +import { Logger } from '../Logger'; import type { ProblemInfo } from '../ProblemInfo'; import type { Autofix } from './Autofixer'; +import type { LinterOptions } from '../LinterOptions'; +import { AUTOFIX_HTML_TEMPLATE_TEXT, AutofixHtmlTemplate } from './AutofixReportHtmlHelper'; const BACKUP_AFFIX = '~'; -const EOL = '\n'; -export const MAX_AUTOFIX_PASSES = 10; +export const DEFAULT_MAX_AUTOFIX_PASSES = 10; export class QuasiEditor { - private textBuffer: string; - private readonly dataBuffer: Buffer; - private readonly srcFileName: string; - wasError: boolean = false; - constructor( - readonly sourceFile: ts.SourceFile, - readonly passNumber?: number, + readonly srcFileName: string, + readonly sourceText: string, + readonly linterOpts: LinterOptions, readonly cancellationToken?: ts.CancellationToken - ) { - this.srcFileName = this.sourceFile.fileName; + ) {} - /* - * need to backup only once "this.backupSrcFile();" - * load text into buffer - */ - this.dataBuffer = fs.readFileSync(this.srcFileName); - this.textBuffer = this.dataBuffer.toString(); - if (!passNumber) { - passNumber = 1; - } + private static getBackupFileName(filePath: string): string { + return filePath + BACKUP_AFFIX; } - backupSrcFile(): void { - fs.copyFileSync(this.srcFileName, this.srcFileName + BACKUP_AFFIX); + static backupSrcFile(filePath: string): void { + fs.copyFileSync(filePath, QuasiEditor.getBackupFileName(filePath)); } - backupSrcFileDebug(pass: number): void { - fs.copyFileSync(this.srcFileName, this.srcFileName + BACKUP_AFFIX + pass.toString()); + static hasAnyAutofixes(problemInfos: ProblemInfo[]): boolean { + return problemInfos.some((problemInfo) => { + return problemInfo.autofix !== undefined; + }); } - private saveText(): void { - fs.truncateSync(this.srcFileName); + private generateReport(acceptedPatches: Autofix[]): void { + const report = { + filePath: this.srcFileName, + fixCount: acceptedPatches.length, + fixes: acceptedPatches.map((fix) => { + return { + line: fix.line, + colum: fix.column, + endLine: fix.endLine, + endColum: fix.endColumn, + start: fix.start, + end: fix.end, + replacement: fix.replacementText, + original: this.sourceText.slice(fix.start, fix.end) + }; + }) + }; - const srcLines = this.textBuffer.split(EOL); - for (let i = 0; i < srcLines.length - 1; i++) { - fs.appendFileSync(this.srcFileName, srcLines[i] + EOL); - } - // check if last line is empty out of loop to optimize - if (srcLines[srcLines.length - 1] !== '') { - fs.appendFileSync(this.srcFileName, srcLines[srcLines.length - 1] + EOL); + const reportPath = './autofix-report.html'; + const getOldJsonArray = (reportPath: string): Set => { + try { + const RegexCaptureBraketFirst = 1; + const rawData = fs.readFileSync(reportPath, 'utf-8'); + const rawContent = rawData.match(/`([\s\S]*?)`/)?.[RegexCaptureBraketFirst] ?? ''; + return new Set(JSON.parse(rawContent) || []); + } catch { + return new Set(); + } + }; + + try { + const existingReports = getOldJsonArray(reportPath); + existingReports.add(report); + const str = JSON.stringify([...existingReports], null, 2); + const HtmlContent = AutofixHtmlTemplate.replace(AUTOFIX_HTML_TEMPLATE_TEXT, str); + fs.writeFileSync(reportPath, HtmlContent, { encoding: 'utf-8' }); + } catch (error) { + Logger.error(`Failed to update autofix report: ${(error as Error).message}`); } } - private static hasAnyAutofixes(problemInfos: ProblemInfo[]): boolean { - return problemInfos.some((problemInfo) => { - return problemInfo.autofix !== undefined; - }); - } + fix(problemInfos: ProblemInfo[]): string { + const acceptedPatches = QuasiEditor.sortAndRemoveIntersections(problemInfos); + const result = this.applyFixes(acceptedPatches); - fix(problemInfos: ProblemInfo[]): void { - if (!QuasiEditor.hasAnyAutofixes(problemInfos)) { - return; + if (this.linterOpts.migrationReport) { + this.generateReport(acceptedPatches); } - const acceptedPatches = QuasiEditor.sortAndRemoveIntersections(problemInfos); - this.textBuffer = this.applyFixes(acceptedPatches); - this.saveText(); + + return result; } private applyFixes(autofixes: Autofix[]): string { let output: string = ''; - let lastPos = Number.NEGATIVE_INFINITY; + let lastFixEnd = Number.NEGATIVE_INFINITY; const doFix = (fix: Autofix): void => { const { replacementText, start, end } = fix; - if (lastPos >= start || start > end) { + if (lastFixEnd > start || start > end) { Logger.error(`Failed to apply autofix in range [${start}, ${end}] at ${this.srcFileName}`); return; } - output += this.textBuffer.slice(Math.max(0, lastPos), Math.max(0, start)); + output += this.sourceText.slice(Math.max(0, lastFixEnd), Math.max(0, start)); output += replacementText; - lastPos = end; + lastFixEnd = end; }; autofixes.forEach(doFix); - output += this.textBuffer.slice(Math.max(0, lastPos)); + output += this.sourceText.slice(Math.max(0, lastFixEnd)); return output; } @@ -109,7 +124,7 @@ export class QuasiEditor { private static sortAndRemoveIntersections(problemInfos: ProblemInfo[]): Autofix[] { let acceptedPatches: Autofix[] = []; - problemInfos.forEach((problemInfo) => { + problemInfos.forEach((problemInfo): void => { if (!problemInfo.autofix) { return; } @@ -127,7 +142,7 @@ export class QuasiEditor { } private static sortAutofixes(autofixes: Autofix[]): Autofix[] { - return autofixes.sort((a, b) => { + return autofixes.sort((a, b): number => { return a.start - b.start; }); } diff --git a/ets2panda/linter/src/lib/autofixes/SymbolCache.ts b/ets2panda/linter/src/lib/autofixes/SymbolCache.ts index 9a16be4fd08fed29d4eea6c15aa2efbd4dff35b9..7724bce4481a64af3261e65ac7a1c65fc9b15d23 100644 --- a/ets2panda/linter/src/lib/autofixes/SymbolCache.ts +++ b/ets2panda/linter/src/lib/autofixes/SymbolCache.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -14,7 +14,7 @@ */ import * as ts from 'typescript'; -import { LinterConfig } from '../TypeScriptLinterConfig'; +import { TypeScriptLinterConfig } from '../TypeScriptLinterConfig'; import { forEachNodeInSubtree } from '../utils/functions/ForEachNodeInSubtree'; import { isStructDeclaration } from '../utils/functions/IsStruct'; import type { TsUtils } from '../utils/TsUtils'; @@ -39,7 +39,7 @@ export class SymbolCache { }; const stopCondition = (node: ts.Node): boolean => { - return !node || LinterConfig.terminalTokens.has(node.kind); + return !node || TypeScriptLinterConfig.terminalTokens.has(node.kind); }; forEachNodeInSubtree(sourceFile, callback, stopCondition); diff --git a/ets2panda/linter/src/lib/data/BuiltinList.json b/ets2panda/linter/src/lib/data/BuiltinList.json new file mode 100644 index 0000000000000000000000000000000000000000..3ba53f2cbb312d567c6bdc3b9c58df079844fb3e --- /dev/null +++ b/ets2panda/linter/src/lib/data/BuiltinList.json @@ -0,0 +1,4631 @@ +{ + "api_list": [ + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 107, + "problem": "BuiltinAll", + "api_name": "PropertyKey", + "api_type": "TypeAliasDeclaration", + "api_func_args": [], + "parent_api": [], + "code_kind": 268, + "api_property_type": "string | number | symbol" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 110, + "problem": "NoPropertyDescriptor", + "api_name": "configurable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 111, + "problem": "NoPropertyDescriptor", + "api_name": "enumerable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 112, + "problem": "NoPropertyDescriptor", + "api_name": "value", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 113, + "problem": "NoPropertyDescriptor", + "api_name": "writable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 114, + "problem": "NoPropertyDescriptor", + "api_name": "get", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "any", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 115, + "problem": "NoPropertyDescriptor", + "api_name": "set", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "v", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 133, + "problem": "BuiltinAll", + "api_name": "valueOf", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Object", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Object", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 174, + "problem": "MissingAttributes", + "api_name": "getOwnPropertyNames", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 156, + "problem": "BuiltinAll", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 157, + "problem": "BuiltinAll", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 392, + "problem": "BuiltinAll", + "api_name": "length", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "IArguments", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 393, + "problem": "BuiltinAll", + "api_name": "callee", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "IArguments", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "Function" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 522, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "StringConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 539, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "BooleanConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 576, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "NumberConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 608, + "problem": "BuiltinAll", + "api_name": "raw", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "TemplateStringsArray", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "readonly string[]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 916, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "DateConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1005, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "RegExpConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1006, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "RegExpConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1060, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1071, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "EvalErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1082, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "RangeErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1093, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ReferenceErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1104, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "SyntaxErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1115, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "TypeErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1126, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "URIErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinAll", + "api_name": "parse", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "text", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "reviver", + "type": "(this: any, key: string, value: any) => any", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "JSON", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "any", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1188, + "problem": "BuiltinAll", + "api_name": "concat", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "items", + "type": "(T | ConcatArray)[]", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1220, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => value is S", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1229, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1238, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1244, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, index: number, array: readonly T[]) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1250, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, index: number, array: readonly T[]) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "U[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1256, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => value is S", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "S[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1262, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1304, + "problem": "BuiltinAll", + "api_name": "length", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1334, + "problem": "BuiltinAll", + "api_name": "concat", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "items", + "type": "(T | ConcatArray)[]", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1411, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: T[]) => value is S", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1420, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1429, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1435, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, index: number, array: T[]) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1441, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, index: number, array: T[]) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "U[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1453, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1490, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1498, + "problem": "NoPropertyDescriptor", + "api_name": "enumerable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1499, + "problem": "NoPropertyDescriptor", + "api_name": "configurable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1500, + "problem": "NoPropertyDescriptor", + "api_name": "writable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1501, + "problem": "NoPropertyDescriptor", + "api_name": "value", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1502, + "problem": "NoPropertyDescriptor", + "api_name": "get", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "() => T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1503, + "problem": "NoPropertyDescriptor", + "api_name": "set", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "(value: T) => void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinAll", + "api_name": "ClassDecorator", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "TFunction", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "TFunction | void", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1507, + "problem": "BuiltinAll", + "api_name": "PropertyDecorator", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "Object", + "is_optional": false + }, + { + "name": "propertyKey", + "type": "string | symbol", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "void", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1508, + "problem": "NoPropertyDescriptor", + "api_name": "MethodDecorator", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "Object", + "is_optional": false + }, + { + "name": "propertyKey", + "type": "string | symbol", + "is_optional": false + }, + { + "name": "descriptor", + "type": "TypedPropertyDescriptor", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "TypedPropertyDescriptor | void", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1509, + "problem": "BuiltinAll", + "api_name": "ParameterDecorator", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "Object", + "is_optional": false + }, + { + "name": "propertyKey", + "type": "string | symbol", + "is_optional": false + }, + { + "name": "parameterIndex", + "type": "number", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "void", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1681, + "problem": "BuiltinAll", + "api_name": "ArrayBuffer", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ArrayBufferTypes", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ArrayBuffer" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1887, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int8Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1906, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int8Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1917, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int8Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1928, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int8Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1937, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int8Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1975, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int8Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2054, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int8Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2169, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2188, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2199, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint8Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2210, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint8Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2219, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint8Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2257, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint8Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2336, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2451, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8ClampedArray) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2470, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8ClampedArray) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8ClampedArray", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2481, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint8ClampedArray) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2492, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint8ClampedArray) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2501, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint8ClampedArray) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2539, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint8ClampedArray) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8ClampedArray", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2618, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8ClampedArray) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2732, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int16Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2751, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int16Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2762, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int16Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2773, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int16Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2782, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int16Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2819, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int16Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2898, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int16Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3014, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint16Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3033, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint16Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3044, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint16Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3055, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint16Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3064, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint16Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3102, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint16Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3181, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint16Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3296, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3315, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int32Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3326, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3337, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3346, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int32Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3384, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int32Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3463, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3578, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3597, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint32Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3608, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3619, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3628, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint32Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3665, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint32Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3744, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3859, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3878, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float32Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3889, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Float32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3900, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Float32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3909, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Float32Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3947, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Float32Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4026, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4142, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float64Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4161, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float64Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4172, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Float64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4183, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Float64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4192, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Float64Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4230, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Float64Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4309, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float64Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4439, + "problem": "BuiltinAll", + "api_name": "prototype", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "NumberFormat" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4483, + "problem": "BuiltinAll", + "api_name": "prototype", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "DateTimeFormat" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 46, + "problem": "BuiltinAll", + "api_name": "return", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "value", + "type": "TReturn", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Iterator", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IteratorResult", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 47, + "problem": "BuiltinAll", + "api_name": "throw", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "e", + "type": "any", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Iterator", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IteratorResult", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 51, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Iterable", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Iterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 55, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "IterableIterator", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 60, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 96, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 116, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "IArguments", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 121, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Map", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 141, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ReadonlyMap", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 172, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Set", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 190, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ReadonlySet", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 240, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "String", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 244, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 272, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 300, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 331, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 361, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 389, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 417, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 445, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 473, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "BigIntConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 186, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 205, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigInt64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 216, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "bigint | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 227, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 236, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: bigint, index: number, array: BigInt64Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 282, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: bigint, index: number, array: BigInt64Array) => bigint", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigInt64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 357, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 385, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 458, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 477, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigUint64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 488, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "bigint | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 499, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 508, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: bigint, index: number, array: BigUint64Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 554, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: bigint, index: number, array: BigUint64Array) => bigint", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigUint64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 629, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 657, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 31, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: V, key: K, map: Map) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Map", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 59, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: V, key: K, map: ReadonlyMap) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyMap", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 107, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, value2: T, set: Set) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Set", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 125, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, value2: T, set: ReadonlySet) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlySet", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/src/lib/data/SdkWhitelist.json b/ets2panda/linter/src/lib/data/SdkWhitelist.json index 8aee8281b85feddba8c1a6abea9395835d800259..b0c83d569625a4b150d31bd4a3f1b2fd4fbab1f0 100644 --- a/ets2panda/linter/src/lib/data/SdkWhitelist.json +++ b/ets2panda/linter/src/lib/data/SdkWhitelist.json @@ -1,41 +1,21 @@ { "api_list": [ { - "import_path": ["@ohos.arkui.Prefetcher", "@kit.ArkUI"], - "file_path": ["api/@ohos.arkui.Prefetcher.d.ts"], - "is_global": false, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "", - "api_name": "prefetch", + "line": 84, + "problem": "LimitedVoidType", + "api_name": "write", "api_type": "MethodSignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [{ "name": "index", "type": "number", "is_optional": false, "hasDefault": false }], - "parent_api": [ + "api_func_args": [ { - "api_name": "IDataSourcePrefetching", - "api_type": "InterfaceDeclaration" + "name": "buffer", + "type": "ArrayBuffer", + "is_optional": false, + "has_default": false } ], - "methd_return_type": "void | Promise", - "codeKind": 173 - } - }, - { - "import_path": ["@hms.collaboration.rcp", "@kit.RemoteCommunicationKit"], - "file_path": ["api/@hms.collaboration.rcp.d.ts"], - "is_global": false, - "api_info": { - "problem": "LimitiedVoidType", - "api_name": "write", - "api_type": "MethodSignature", - "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [{ "name": "buffer", "type": "ArrayBuffer", "is_optional": false, "hasDefault": false }], "parent_api": [ { "api_name": "WriteFile", @@ -46,250 +26,226 @@ "api_type": "ModuleDeclaration" } ], - "methd_return_type": "void | Promise", - "codeKind": 115 - } + "method_return_type": "Promise", + "code_kind": 173 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false }, { - "import_path": ["@hms.collaboration.rcp", "@kit.RemoteCommunicationKit"], - "file_path": ["api/@hms.collaboration.rcp.d.ts"], - "is_global": false, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "LimitiedVoidType", - "api_name": "IncomingDataCallback", - "api_type": "TypeAliasDeclaration", + "line": 116, + "problem": "LimitedVoidType", + "api_name": "write", + "api_type": "MethodSignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [{ "name": "incomingData", "type": "ArrayBuffer", "is_optional": false, "hasDefault": false }], - "parent_api": [ + "api_func_args": [ { - "api_name": "rcp", - "api_type": "ModuleDeclaration" + "name": "buffer", + "type": "ArrayBuffer", + "is_optional": false, + "has_default": false } ], - "methd_return_type": "void | Promise", - "codeKind": 115 - } - }, - { - "import_path": ["@ohos.web.webview", "@kit.ArkWeb"], - "file_path": ["api/@ohos.web.webview.d.ts"], - "is_global": false, - "api_info": { - "problem": "OptionalMethod", - "api_name": "resumePlayer", - "api_type": "MethodSignature", - "api_optional": true, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], "parent_api": [ { - "api_name": "NativeMediaPlayerBridge", + "api_name": "WriteStream", "api_type": "InterfaceDeclaration" }, { - "api_name": "webview", + "api_name": "rcp", "api_type": "ModuleDeclaration" } ], - "methd_return_type": "void", - "codeKind": 173 - } + "method_return_type": "Promise", + "code_kind": 173 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false }, { - "import_path": ["@ohos.web.webview", "@kit.ArkWeb"], - "file_path": ["api/@ohos.web.webview.d.ts"], - "is_global": false, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "OptionalMethod", - "api_name": "suspendPlayer", + "line": 132, + "problem": "LimitedVoidType", + "api_name": "writeSync", "api_type": "MethodSignature", - "api_optional": true, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", + "api_optional": false, "api_func_args": [ - { "name": "type", "type": "SuspendType", "is_optional": false, "hasDefault": false } + { + "name": "buffer", + "type": "ArrayBuffer", + "is_optional": false, + "has_default": false + } ], "parent_api": [ { - "api_name": "NativeMediaPlayerBridge", + "api_name": "SyncWriteStream", "api_type": "InterfaceDeclaration" }, { - "api_name": "webview", + "api_name": "rcp", "api_type": "ModuleDeclaration" } ], - "methd_return_type": "void", - "codeKind": 173 - } + "method_return_type": "number | void", + "code_kind": 173 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false }, { - "import_path": ["@ohos.file.sendablePhotoAccessHelper", "@kit.MediaLibraryKit"], - "file_path": ["api/@ohos.file.sendablePhotoAccessHelper.d.ets"], - "is_global": false, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "SendablePropType", - "api_name": "position", - "api_type": "PropertySignatrue", - "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], + "line": 229, + "problem": "LimitedVoidType", + "api_name": "IncomingDataCallback", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "incomingData", + "type": "ArrayBuffer", + "is_optional": false + } + ], "parent_api": [ - { - "api_name": "SharedPhotoAsset", - "api_type": "InterfaceDeclaration" - }, - { - "api_name": "sendablePhotoAccessHelper", - "api_type": "ModuleDeclaration" - } - ], - "methd_return_type": "", - "codeKind": 170 - } - }, - { - "import_path": [], - "file_path": ["component/progress.d.ts"], - "is_global": true, - "api_info": { - "problem": "ComputedPropertyName", - "api_name": "[ProgressType.Linear]", - "api_type": "PropertySignatrue", - "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], - "parent_api": [ - { - "api_name": "ProgressStyleMap", - "api_type": "InterfaceDeclaration" - } + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 268 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" ], - "methd_return_type": "", - "codeKind": 170 - } + "is_global": false }, { - "import_path": [], - "file_path": ["component/progress.d.ts"], - "is_global": true, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "ComputedPropertyName", - "api_name": "[ProgressType.Ring]", - "api_type": "PropertySignatrue", + "line": 351, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", "api_func_args": [], "parent_api": [ { - "api_name": "ProgressStyleMap", + "api_name": "NetworkOutputQueueConstructor", "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" } ], - "methd_return_type": "", - "codeKind": 170 - } + "method_return_type": "INetworkOutputQueue", + "code_kind": 180 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false }, { - "import_path": [], - "file_path": ["component/progress.d.ts"], - "is_global": true, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "ComputedPropertyName", - "api_name": "[ProgressType.Eclipse]", - "api_type": "PropertySignatrue", + "line": 359, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], - "parent_api": [ - { - "api_name": "ProgressStyleMap", - "api_type": "InterfaceDeclaration" - } + "api_func_args": [ + { + "name": "maxSize", + "type": "number", + "is_optional": false, + "has_default": false + } ], - "methd_return_type": "", - "codeKind": 170 - } - }, - { - "import_path": [], - "file_path": ["component/progress.d.ts"], - "is_global": true, - "api_info": { - "problem": "ComputedPropertyName", - "api_name": "[ProgressType.ScaleRing]", - "api_type": "PropertySignatrue", - "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], "parent_api": [ - { - "api_name": "ProgressStyleMap", - "api_type": "InterfaceDeclaration" - } + { + "api_name": "NetworkOutputQueueConstructor", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } ], - "methd_return_type": "", - "codeKind": 170 - } + "method_return_type": "INetworkOutputQueue", + "code_kind": 180 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false }, { - "import_path": [], - "file_path": ["component/progress.d.ts"], - "is_global": true, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "ComputedPropertyName", - "api_name": "[ProgressType.Capsule]", - "api_type": "PropertySignatrue", + "line": 368, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], + "api_func_args": [ + { + "name": "maxSize", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "pausePolicyOverride", + "type": "ReceivingPausePolicy", + "is_optional": false, + "has_default": false + } + ], "parent_api": [ - { - "api_name": "ProgressStyleMap", - "api_type": "InterfaceDeclaration" - } + { + "api_name": "NetworkOutputQueueConstructor", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } ], - "methd_return_type": "", - "codeKind": 170 - } - }, - { + "method_return_type": "INetworkOutputQueue", + "code_kind": 180 + }, "import_path": [ "@hms.collaboration.rcp", "@kit.RemoteCommunicationKit" ], - "file_path": ["api/@hms.collaboration.rcp.d.ts"], - "is_global": false, + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { + "line": 386, "problem": "ConstructorIface", - "api_name": "", "api_type": "ConstructSignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", "api_func_args": [], "parent_api": [ { - "api_name": "NetworkOutputQueueConstructor", + "api_name": "NetworkInputQueueConstructor", "api_type": "InterfaceDeclaration" }, { @@ -297,127 +253,97 @@ "api_type": "ModuleDeclaration" } ], - "methd_return_type": "INetworkOutputQueue", - "codeKind": 180 - } - }, - { + "method_return_type": "INetworkInputQueue", + "code_kind": 180 + }, "import_path": [ - "@ohos.application.AccessibilityExtensionAbility", - "@kit.AccessibilityKit" + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" ], - "file_path": ["api/application/AccessibilityExtensionContext.d.ts"], - "is_global": false, + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "IndexedAccessType", - "api_name": "attributeValue", - "api_type": "MethodSignature", + "line": 394, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", "api_func_args": [ { - "name": "attributeName", - "type": "T", + "name": "maxSize", + "type": "number", "is_optional": false, - "hasDefault": false + "has_default": false } ], "parent_api": [ { - "api_name": "AccessibilityElement", + "api_name": "NetworkInputQueueConstructor", "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" } ], - "methd_return_type": "Promise", - "codeKind": 173 - } - }, - { + "method_return_type": "INetworkInputQueue", + "code_kind": 180 + }, "import_path": [ - "@ohos.application.AccessibilityExtensionAbility", - "@kit.AccessibilityKit" + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" ], - "file_path": ["api/application/AccessibilityExtensionContext.d.ts"], - "is_global": false, + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "IndexedAccessType", - "api_name": "attributeValue", - "api_type": "MethodSignature", + "line": 404, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", "api_func_args": [ { - "name": "attributeName", - "type": "T", + "name": "maxSize", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "pausePolicyOverride", + "type": "SendingPausePolicy", "is_optional": false, - "hasDefault": false + "has_default": false } ], "parent_api": [ { - "api_name": "AccessibilityElement", + "api_name": "NetworkInputQueueConstructor", "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" } ], - "methd_return_type": "Promise", - "codeKind": 173 - } - }, - { + "method_return_type": "INetworkInputQueue", + "code_kind": 180 + }, "import_path": [ - "@hms.core.deviceCloudGateway.cloudDatabase", - "@kit.CloudFoundationKit" - ], - "file_path": [ - "api/@hms.core.deviceCloudGateway.cloudDatabase.d.ts" + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" ], - "is_global": false, - "api_info": { - "problem": "ConstructorFuncs", - "api_name": "DatabaseQuery", - "api_type": "ClassDeclaration", - "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [ - { - "name": "entityClass", - "type": "new () => T", - "is_optional": false, - "hasDefault": false - } - ], - "parent_api": [ - { - "api_name": "cloudDatabase", - "api_type": "ModuleDeclaration" - } - ], - "methd_return_type": "DatabaseQuery", - "codeKind": 264 - } + "is_global": false }, { - "import_path": [ - "@hms.collaboration.rcp.d.ts", - "@kit.RemoteCommunicationKit" - ], - "file_path": ["api/@hms.collaboration.rcp.d.ts"], - "is_global": false, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { + "line": 536, "problem": "LiteralAsPropertyName", "api_name": "'authorization'", "api_type": "PropertySignature", "api_optional": true, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], "parent_api": [ { "api_name": "RequestHeaders", @@ -428,26 +354,23 @@ "api_type": "ModuleDeclaration" } ], - "methd_return_type": "string", - "codeKind": 170 - } - }, - { + "code_kind": 170, + "api_property_type": "string" + }, "import_path": [ - "@hms.collaboration.rcp.d.ts", + "@hms.collaboration.rcp", "@kit.RemoteCommunicationKit" ], - "file_path": ["api/@hms.collaboration.rcp.d.ts"], - "is_global": false, + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { + "line": 536, "problem": "LiteralAsPropertyName", - "api_name": "'content-type'", + "api_name": "'authorization'", "api_type": "PropertySignature", "api_optional": true, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], "parent_api": [ { "api_name": "RequestHeaders", @@ -458,26 +381,23 @@ "api_type": "ModuleDeclaration" } ], - "methd_return_type": "string", - "codeKind": 170 - } - }, - { + "code_kind": 170, + "api_property_type": "string" + }, "import_path": [ - "@hms.collaboration.rcp.d.ts", + "@hms.collaboration.rcp", "@kit.RemoteCommunicationKit" ], - "file_path": ["api/@hms.collaboration.rcp.d.ts"], - "is_global": false, + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { + "line": 537, "problem": "LiteralAsPropertyName", "api_name": "'accept'", "api_type": "PropertySignature", "api_optional": true, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], "parent_api": [ { "api_name": "RequestHeaders", @@ -488,26 +408,23 @@ "api_type": "ModuleDeclaration" } ], - "methd_return_type": "ContentType | ContentType[]", - "codeKind": 170 - } - }, - { + "code_kind": 170, + "api_property_type": "ContentType | ContentType[]" + }, "import_path": [ - "@hms.collaboration.rcp.d.ts", + "@hms.collaboration.rcp", "@kit.RemoteCommunicationKit" ], - "file_path": ["api/@hms.collaboration.rcp.d.ts"], - "is_global": false, + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { + "line": 537, "problem": "LiteralAsPropertyName", - "api_name": "'cache-control'", + "api_name": "'accept'", "api_type": "PropertySignature", "api_optional": true, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], "parent_api": [ { "api_name": "RequestHeaders", @@ -518,26 +435,23 @@ "api_type": "ModuleDeclaration" } ], - "methd_return_type": "string | string[]", - "codeKind": 170 - } - }, - { + "code_kind": 170, + "api_property_type": "ContentType | ContentType[]" + }, "import_path": [ - "@hms.collaboration.rcp.d.ts", + "@hms.collaboration.rcp", "@kit.RemoteCommunicationKit" ], - "file_path": ["api/@hms.collaboration.rcp.d.ts"], - "is_global": false, + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { + "line": 538, "problem": "LiteralAsPropertyName", - "api_name": "'user-agent'", + "api_name": "'accept-charset'", "api_type": "PropertySignature", "api_optional": true, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [], "parent_api": [ { "api_name": "RequestHeaders", @@ -548,60 +462,8005 @@ "api_type": "ModuleDeclaration" } ], - "methd_return_type": "string", - "codeKind": 170 - } + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false }, { - "import_path": [], - "file_path": ["component/styled_string.d.ts"], - "is_global": true, + "file_path": "api/@hms.collaboration.rcp.d.ts", "api_info": { - "problem": "DeclWithDuplicateName", - "api_name": "TextStyle", - "api_type": "ClassDeclaration", - "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", - "api_func_args": [ + "line": 538, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-charset'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ { - "name": "value", - "type": "TextStyleInterface", - "is_optional": true, - "hasDefault": false + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" } ], - "parent_api": [], - "methd_return_type": "TextStyle", - "codeKind": 264 - } - }, - { + "code_kind": 170, + "api_property_type": "string | string[]" + }, "import_path": [ - "@ohos.worker.d.ts", - "@kit.ArkTS" + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 539, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-encoding'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentCoding | ContentCoding[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 539, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-encoding'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentCoding | ContentCoding[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 540, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-language'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 540, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-language'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 541, + "problem": "LiteralAsPropertyName", + "api_name": "'cache-control'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 541, + "problem": "LiteralAsPropertyName", + "api_name": "'cache-control'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 542, + "problem": "LiteralAsPropertyName", + "api_name": "'cookie'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 542, + "problem": "LiteralAsPropertyName", + "api_name": "'cookie'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 543, + "problem": "LiteralAsPropertyName", + "api_name": "'range'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 543, + "problem": "LiteralAsPropertyName", + "api_name": "'range'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 544, + "problem": "LiteralAsPropertyName", + "api_name": "'upgrade'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 544, + "problem": "LiteralAsPropertyName", + "api_name": "'upgrade'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" ], - "file_path": ["api/@ohos.worker.d.ts"], - "is_global": false, + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 545, + "problem": "LiteralAsPropertyName", + "api_name": "'user-agent'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 545, + "problem": "LiteralAsPropertyName", + "api_name": "'user-agent'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 546, + "problem": "LiteralAsPropertyName", + "api_name": "'content-type'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 546, + "problem": "LiteralAsPropertyName", + "api_name": "'content-type'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 556, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-ranges'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "'none' | 'bytes' | (string & NonNullable)" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 556, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-ranges'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "'none' | 'bytes' | (string & NonNullable)" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 557, + "problem": "LiteralAsPropertyName", + "api_name": "'allow'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "HttpMethod | HttpMethod[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 557, + "problem": "LiteralAsPropertyName", + "api_name": "'allow'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "HttpMethod | HttpMethod[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 558, + "problem": "LiteralAsPropertyName", + "api_name": "'cache-control'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 558, + "problem": "LiteralAsPropertyName", + "api_name": "'cache-control'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 559, + "problem": "LiteralAsPropertyName", + "api_name": "'content-encoding'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentCoding" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 559, + "problem": "LiteralAsPropertyName", + "api_name": "'content-encoding'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentCoding" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 560, + "problem": "LiteralAsPropertyName", + "api_name": "'content-range'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 560, + "problem": "LiteralAsPropertyName", + "api_name": "'content-range'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 561, + "problem": "LiteralAsPropertyName", + "api_name": "'content-type'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 561, + "problem": "LiteralAsPropertyName", + "api_name": "'content-type'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 562, + "problem": "LiteralAsPropertyName", + "api_name": "'date'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 562, + "problem": "LiteralAsPropertyName", + "api_name": "'date'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 563, + "problem": "LiteralAsPropertyName", + "api_name": "'etag'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 563, + "problem": "LiteralAsPropertyName", + "api_name": "'etag'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 564, + "problem": "LiteralAsPropertyName", + "api_name": "'expires'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 564, + "problem": "LiteralAsPropertyName", + "api_name": "'expires'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 565, + "problem": "LiteralAsPropertyName", + "api_name": "'location'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 565, + "problem": "LiteralAsPropertyName", + "api_name": "'location'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 566, + "problem": "LiteralAsPropertyName", + "api_name": "'retry-after'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 566, + "problem": "LiteralAsPropertyName", + "api_name": "'retry-after'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 567, + "problem": "LiteralAsPropertyName", + "api_name": "'set-cookie'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 567, + "problem": "LiteralAsPropertyName", + "api_name": "'set-cookie'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 568, + "problem": "LiteralAsPropertyName", + "api_name": "'server'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 568, + "problem": "LiteralAsPropertyName", + "api_name": "'server'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 569, + "problem": "LiteralAsPropertyName", + "api_name": "'www-authenticate'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 569, + "problem": "LiteralAsPropertyName", + "api_name": "'www-authenticate'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 1355, + "problem": "LimitedVoidType", + "api_name": "OnDataReceive", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "incomingData", + "type": "ArrayBuffer", + "is_optional": false + } + ], + "parent_api": [ + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number | void | Promise", + "code_kind": 268 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.core.deviceCloudGateway.cloudDatabase.d.ts", + "api_info": { + "line": 285, + "problem": "ConstructorFuncs", + "api_name": "DatabaseQuery", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "entityClass", + "type": "new () => T", + "is_optional": false + } + ], + "parent_api": [ + { + "api_name": "cloudDatabase", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "DatabaseQuery", + "code_kind": 264 + }, + "import_path": [ + "@hms.core.deviceCloudGateway.cloudDatabase", + "@kit.CloudFoundationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.core.map.mapCommon.d.ts", + "api_info": { + "line": 1877, + "problem": "OptionalMethod", + "api_name": "getCustomIcon", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "clusterItems", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ClusterOverlayParams", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "mapCommon", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 173 + }, + "import_path": [ + "@hms.core.map.mapCommon", + "@kit.MapKit" + ], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 54, + "problem": "OptionalMethod", + "api_name": "onCreate", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "FormBindingData", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 63, + "problem": "OptionalMethod", + "api_name": "onCastToNormal", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "formId", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 72, + "problem": "OptionalMethod", + "api_name": "onUpdate", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "formId", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 104, + "problem": "OptionalMethod", + "api_name": "onVisibilityChange", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "newStatus", + "type": "Record", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 117, + "problem": "OptionalMethod", + "api_name": "onEvent", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "formId", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "message", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 127, + "problem": "OptionalMethod", + "api_name": "onDestroy", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "formId", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 141, + "problem": "OptionalMethod", + "api_name": "onAcquireFormState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "FormState", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 159, + "problem": "OptionalMethod", + "api_name": "onShow", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 167, + "problem": "OptionalMethod", + "api_name": "onHide", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 175, + "problem": "OptionalMethod", + "api_name": "onDestroy", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 183, + "problem": "OptionalMethod", + "api_name": "onCreate", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 192, + "problem": "OptionalMethod", + "api_name": "onStartContinuation", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 204, + "problem": "OptionalMethod", + "api_name": "onSaveData", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "data", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 216, + "problem": "OptionalMethod", + "api_name": "onCompleteContinuation", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "result", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 227, + "problem": "OptionalMethod", + "api_name": "onRestoreData", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "data", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 236, + "problem": "OptionalMethod", + "api_name": "onRemoteTerminated", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 248, + "problem": "OptionalMethod", + "api_name": "onSaveAbilityState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "outState", + "type": "PacMap", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 260, + "problem": "OptionalMethod", + "api_name": "onRestoreAbilityState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "inState", + "type": "PacMap", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 269, + "problem": "OptionalMethod", + "api_name": "onInactive", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 277, + "problem": "OptionalMethod", + "api_name": "onActive", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 286, + "problem": "OptionalMethod", + "api_name": "onNewWant", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 296, + "problem": "OptionalMethod", + "api_name": "onMemoryLevel", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "level", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 315, + "problem": "OptionalMethod", + "api_name": "onStart", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 327, + "problem": "OptionalMethod", + "api_name": "onCommand", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + }, + { + "name": "startId", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 335, + "problem": "OptionalMethod", + "api_name": "onStop", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 345, + "problem": "OptionalMethod", + "api_name": "onConnect", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "RemoteObject", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 354, + "problem": "OptionalMethod", + "api_name": "onDisconnect", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 366, + "problem": "OptionalMethod", + "api_name": "onReconnect", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 390, + "problem": "OptionalMethod", + "api_name": "update", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "valueBucket", + "type": "rdb.ValuesBucket", + "is_optional": false, + "has_default": false + }, + { + "name": "predicates", + "type": "dataAbility.DataAbilityPredicates", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 405, + "problem": "OptionalMethod", + "api_name": "query", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "columns", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "predicates", + "type": "dataAbility.DataAbilityPredicates", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 418, + "problem": "OptionalMethod", + "api_name": "delete", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "predicates", + "type": "dataAbility.DataAbilityPredicates", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 431, + "problem": "OptionalMethod", + "api_name": "normalizeUri", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 443, + "problem": "OptionalMethod", + "api_name": "batchInsert", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "valueBuckets", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 455, + "problem": "OptionalMethod", + "api_name": "denormalizeUri", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 467, + "problem": "OptionalMethod", + "api_name": "insert", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "valueBucket", + "type": "rdb.ValuesBucket", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 483, + "problem": "OptionalMethod", + "api_name": "openFile", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 499, + "problem": "OptionalMethod", + "api_name": "getFileTypes", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "mimeTypeFilter", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback>", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 508, + "problem": "OptionalMethod", + "api_name": "onInitialized", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "info", + "type": "AbilityInfo", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 521, + "problem": "OptionalMethod", + "api_name": "getType", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 534, + "problem": "OptionalMethod", + "api_name": "executeBatch", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "ops", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback>", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 547, + "problem": "OptionalMethod", + "api_name": "call", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "method", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "arg", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "extras", + "type": "PacMap", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 83, + "problem": "OptionalMethod", + "api_name": "onAbilityWillCreate", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 125, + "problem": "OptionalMethod", + "api_name": "onWindowStageWillCreate", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + }, + { + "name": "windowStage", + "type": "window.WindowStage", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 135, + "problem": "OptionalMethod", + "api_name": "onWillNewWant", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 145, + "problem": "OptionalMethod", + "api_name": "onNewWant", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 227, + "problem": "OptionalMethod", + "api_name": "onWindowStageWillDestroy", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + }, + { + "name": "windowStage", + "type": "window.WindowStage", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 265, + "problem": "OptionalMethod", + "api_name": "onAbilityWillDestroy", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 303, + "problem": "OptionalMethod", + "api_name": "onAbilityWillForeground", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 341, + "problem": "OptionalMethod", + "api_name": "onAbilityWillBackground", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 369, + "problem": "OptionalMethod", + "api_name": "onAbilityWillContinue", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 380, + "problem": "OptionalMethod", + "api_name": "onWindowStageWillRestore", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + }, + { + "name": "windowStage", + "type": "window.WindowStage", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 391, + "problem": "OptionalMethod", + "api_name": "onWindowStageRestore", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + }, + { + "name": "windowStage", + "type": "window.WindowStage", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 401, + "problem": "OptionalMethod", + "api_name": "onAbilityWillSaveState", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 411, + "problem": "OptionalMethod", + "api_name": "onAbilitySaveState", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.DriverExtensionAbility.d.ts", + "api_info": { + "line": 78, + "problem": "LimitedVoidType", + "api_name": "onDisconnect", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DriverExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.DriverExtensionAbility", + "@kit.DriverDevelopmentKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.PhotoEditorExtensionAbility.d.ts", + "api_info": { + "line": 73, + "problem": "LimitedVoidType", + "api_name": "onDestroy", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "PhotoEditorExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.PhotoEditorExtensionAbility", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.UIAbility.d.ts", + "api_info": { + "line": 472, + "problem": "LimitedVoidType", + "api_name": "onDestroy", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "UIAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.UIAbility", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.UIExtensionAbility.d.ts", + "api_info": { + "line": 101, + "problem": "LimitedVoidType", + "api_name": "onDestroy", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "UIExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.UIExtensionAbility", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.appstartup.StartupConfigEntry.d.ts", + "api_info": { + "line": 36, + "problem": "OptionalMethod", + "api_name": "onConfig", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "StartupConfigEntry", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "StartupConfig", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.appstartup.StartupConfigEntry", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.appstartup.StartupListener.d.ts", + "api_info": { + "line": 36, + "problem": "OptionalMethod", + "api_name": "onCompleted", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "error", + "type": "BusinessError", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StartupListener", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.appstartup.StartupListener", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.appstartup.StartupTask.d.ets", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "onDependencyCompleted", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "dependency", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "result", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StartupTask", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.appstartup.StartupTask", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.appstartup.StartupTask.d.ets", + "api_info": { + "line": 49, + "problem": "LimitedVoidType", + "api_name": "init", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "context", + "type": "AbilityStageContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StartupTask", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.appstartup.StartupTask", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.form.FormExtensionAbility.d.ts", + "api_info": { + "line": 253, + "problem": "OptionalMethod", + "api_name": "onAcquireFormState", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "FormExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "FormState", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.form.FormExtensionAbility", + "@kit.FormKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.form.FormExtensionAbility.d.ts", + "api_info": { + "line": 262, + "problem": "OptionalMethod", + "api_name": "onStop", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "FormExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.form.FormExtensionAbility", + "@kit.FormKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.Prefetcher.d.ts", + "api_info": { + "line": 41, + "problem": "LimitedVoidType", + "api_name": "prefetch", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "IDataSourcePrefetching", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 173 + }, + "import_path": [ + "@ohos.arkui.Prefetcher", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.Prefetcher.d.ts", + "api_info": { + "line": 53, + "problem": "OptionalMethod", + "api_name": "cancel", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "IDataSourcePrefetching", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 173 + }, + "import_path": [ + "@ohos.arkui.Prefetcher", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.Prefetcher.d.ts", + "api_info": { + "line": 53, + "problem": "LimitedVoidType", + "api_name": "cancel", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "IDataSourcePrefetching", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 173 + }, + "import_path": [ + "@ohos.arkui.Prefetcher", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.StateManagement.d.ts", + "api_info": { + "line": 47, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "args", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TypeConstructorWithArgs", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 180 + }, + "import_path": [ + "@ohos.arkui.StateManagement", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.StateManagement.d.ts", + "api_info": { + "line": 156, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "TypeConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 180 + }, + "import_path": [ + "@ohos.arkui.StateManagement", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.multimedia.audio.d.ts", + "api_info": { + "line": 5120, + "problem": "LimitedVoidType", + "api_name": "AudioRendererWriteDataCallback", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "data", + "type": "ArrayBuffer", + "is_optional": false + } + ], + "parent_api": [ + { + "api_name": "audio", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "AudioDataCallbackResult | void", + "code_kind": 268 + }, + "import_path": [ + "@ohos.multimedia.audio", + "@kit.AudioKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.web.webview.d.ts", + "api_info": { + "line": 6490, + "problem": "OptionalMethod", + "api_name": "resumePlayer", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NativeMediaPlayerBridge", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "webview", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [ + "@ohos.web.webview", + "@kit.ArkWeb" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.web.webview.d.ts", + "api_info": { + "line": 6500, + "problem": "OptionalMethod", + "api_name": "suspendPlayer", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "type", + "type": "SuspendType", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NativeMediaPlayerBridge", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "webview", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [ + "@ohos.web.webview", + "@kit.ArkWeb" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 492, + "problem": "LimitedVoidType", + "api_name": "EventListener", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 561, + "problem": "LimitedVoidType", + "api_name": "WorkerEventListener", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 869, + "problem": "TypeQuery", + "api_name": "self", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DedicatedWorkerGlobalScope", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "WorkerGlobalScope", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "WorkerGlobalScope & typeof globalThis" + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 869, + "problem": "GlobalThisError", + "api_name": "self", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DedicatedWorkerGlobalScope", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "WorkerGlobalScope", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "WorkerGlobalScope & typeof globalThis" + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 970, + "problem": "TypeQuery", + "api_name": "self", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ThreadWorkerGlobalScope", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "GlobalScope", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "GlobalScope & typeof globalThis" + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 970, + "problem": "GlobalThisError", + "api_name": "self", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ThreadWorkerGlobalScope", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "GlobalScope", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "GlobalScope & typeof globalThis" + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/app/context.d.ts", + "api_info": { + "line": 39, + "problem": "InterfaceExtendsClass", + "api_name": "Context", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/application/AbilityStartCallback.d.ts", + "api_info": { + "line": 49, + "problem": "OptionalMethod", + "api_name": "onResult", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "parameter", + "type": "AbilityResult", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityStartCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.common" + ], + "is_global": false + }, + { + "file_path": "api/application/AccessibilityExtensionContext.d.ts", + "api_info": { + "line": 275, + "problem": "IndexedAccessType", + "api_name": "attributeValue", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "attributeName", + "type": "T", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AccessibilityElement", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [ + "@ohos.application.AccessibilityExtensionAbility", + "@kit.AccessibilityKit" + ], + "is_global": false + }, + { + "file_path": "api/application/AccessibilityExtensionContext.d.ts", + "api_info": { + "line": 290, + "problem": "IndexedAccessType", + "api_name": "attributeValue", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "attributeName", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AccessibilityElement", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 173 + }, + "import_path": [ + "@ohos.application.AccessibilityExtensionAbility", + "@kit.AccessibilityKit" + ], + "is_global": false + }, + { + "file_path": "api/application/ErrorObserver.d.ts", + "api_info": { + "line": 64, + "problem": "OptionalMethod", + "api_name": "onException", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "errObject", + "type": "Error", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ErrorObserver", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.errorManager" + ], + "is_global": false + }, + { + "file_path": "api/application/LoopObserver.d.ts", + "api_info": { + "line": 36, + "problem": "OptionalMethod", + "api_name": "onLoopTimeOut", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "timeout", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LoopObserver", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [ + "@ohos.app.ability.errorManager" + ], + "is_global": false + }, + { + "file_path": "api/arkui/AlphabetIndexerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "AlphabetIndexerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AlphabetIndexerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/AttributeUpdater.d.ts", + "api_info": { + "line": 49, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeUpdater", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/BlankModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "BlankAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BlankModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ButtonModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ButtonAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ButtonModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CalendarPickerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CalendarPickerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CalendarPickerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CheckboxGroupModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CheckboxGroupAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CheckboxGroupModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CheckboxModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CheckboxAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CheckboxModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ColumnModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ColumnAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ColumnModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ColumnSplitModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ColumnSplitAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ColumnSplitModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CommonModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CommonAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CommonModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ContainerSpanModifier.d.ts", + "api_info": { + "line": 39, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "containerSpanAttribute", + "type": "ContainerSpanAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ContainerSpanModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CounterModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CounterAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CounterModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/DataPanelModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "DataPanelAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DataPanelModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/DatePickerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "DatePickerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DatePickerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/DividerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "DividerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DividerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 545, + "problem": "OptionalMethod", + "api_name": "onDraw", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "context", + "type": "DrawContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "FrameNode", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 722, + "problem": "InterfaceExtendsClass", + "api_name": "TypedFrameNode", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1606, + "problem": "OptionalMethod", + "api_name": "onAttachToNode", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "target", + "type": "FrameNode", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1615, + "problem": "OptionalMethod", + "api_name": "onDetachFromNode", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1626, + "problem": "OptionalMethod", + "api_name": "onGetChildId", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1637, + "problem": "OptionalMethod", + "api_name": "onCreateChild", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "FrameNode", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1648, + "problem": "OptionalMethod", + "api_name": "onDisposeChild", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "id", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "node", + "type": "FrameNode", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1659, + "problem": "OptionalMethod", + "api_name": "onUpdateChild", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "id", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "node", + "type": "FrameNode", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GaugeModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GaugeAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GaugeModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GridColModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GridColAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridColModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GridItemModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GridItemAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridItemModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GridModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GridAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GridRowModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GridRowAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridRowModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/HyperlinkModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "HyperlinkAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "HyperlinkModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ImageAnimatorModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ImageAnimatorAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ImageAnimatorModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ImageModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ImageAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ImageModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ImageSpanModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ImageSpanAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ImageSpanModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/LineModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "LineAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LineModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ListItemGroupModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ListItemGroupAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ListItemGroupModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ListItemModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ListItemAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ListItemModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ListModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ListAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ListModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/LoadingProgressModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "LoadingProgressAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LoadingProgressModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/MarqueeModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "MarqueeAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "MarqueeModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/MenuItemModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "MenuItemAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "MenuItemModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/MenuModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "MenuAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "MenuModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NavDestinationModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "NavDestinationAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavDestinationModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NavigationModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "NavigationAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavigationModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NavigatorModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "NavigatorAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavigatorModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NavRouterModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "NavRouterAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavRouterModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NodeController.d.ts", + "api_info": { + "line": 81, + "problem": "OptionalMethod", + "api_name": "aboutToResize", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "size", + "type": "Size", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeController", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NodeController.d.ts", + "api_info": { + "line": 97, + "problem": "OptionalMethod", + "api_name": "aboutToAppear", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NodeController", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NodeController.d.ts", + "api_info": { + "line": 113, + "problem": "OptionalMethod", + "api_name": "aboutToDisappear", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NodeController", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NodeController.d.ts", + "api_info": { + "line": 147, + "problem": "OptionalMethod", + "api_name": "onTouchEvent", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "event", + "type": "TouchEvent", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeController", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PanelModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PanelAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PanelModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ParticleModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "particleAttribute", + "type": "ParticleAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ParticleModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PathModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PathAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PathModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PatternLockModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PatternLockAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PatternLockModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PolygonModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PolygonAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PolygonModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PolylineModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PolylineAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PolylineModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ProgressModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ProgressAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ProgressModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/QRCodeModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "QRCodeAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "QRCodeModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RadioModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RadioAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RadioModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RatingModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RatingAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RatingModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RectModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RectAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RectModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RefreshModifier.d.ts", + "api_info": { + "line": 39, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RefreshAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RefreshModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RichEditorModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RichEditorAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RichEditorModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RowModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RowAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RowModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RowSplitModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RowSplitAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RowSplitModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ScrollModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ScrollAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ScrollModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SearchModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SearchAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SearchModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SelectModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SelectAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SelectModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ShapeModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ShapeAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ShapeModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SideBarContainerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SideBarContainerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SideBarContainerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SliderModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SliderAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SliderModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SpanModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SpanAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SpanModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/StackModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "StackAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StackModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/StepperItemModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "StepperItemAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StepperItemModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SwiperModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SwiperAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SwiperModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SymbolGlyphModifier.d.ts", + "api_info": { + "line": 46, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SymbolGlyphAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SymbolGlyphModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SymbolSpanModifier.d.ts", + "api_info": { + "line": 46, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "attribute", + "type": "SymbolSpanAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SymbolSpanModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TabsModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TabsAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TabsModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextAreaModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextAreaAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextAreaModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextClockModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextClockAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextClockModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextInputModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextInputAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextInputModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextPickerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextPickerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextPickerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextTimerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextTimerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextTimerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TimePickerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TimePickerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TimePickerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ToggleModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ToggleAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ToggleModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/VideoModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "VideoAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "VideoModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/WaterFlowModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "WaterFlowAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "WaterFlowModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "declarations/alert_dialog.d.ts", + "api_info": { + "line": 502, + "problem": "DeclWithDuplicateName", + "api_name": "TextStyle", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/canvas.d.ts", + "api_info": { + "line": 529, + "problem": "DeclWithDuplicateName", + "api_name": "CanvasPath", + "api_type": "ClassDeclaration", + "api_func_args": [], + "parent_api": [], + "method_return_type": "CanvasPath", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/canvas.d.ts", + "api_info": { + "line": 1215, + "problem": "DeclWithDuplicateName", + "api_name": "CanvasPattern", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/canvas.d.ts", + "api_info": { + "line": 1286, + "problem": "DeclWithDuplicateName", + "api_name": "TextMetrics", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/circle.d.ts", + "api_info": { + "line": 198, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "CircleOptions", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CircleInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "CircleAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3882, + "problem": "OptionalMethod", + "api_name": "drawBehind", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "drawContext", + "type": "DrawContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DrawModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3893, + "problem": "OptionalMethod", + "api_name": "drawContent", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "drawContext", + "type": "DrawContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DrawModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3903, + "problem": "OptionalMethod", + "api_name": "drawFront", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "drawContext", + "type": "DrawContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DrawModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3931, + "problem": "IndexedAccessType", + "api_name": "TransitionEffect", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "type", + "type": "Type", + "is_optional": false + }, + { + "name": "effect", + "type": "Effect", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "TransitionEffect", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3931, + "problem": "IndexedAccessType", + "api_name": "TransitionEffect", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "type", + "type": "Type", + "is_optional": false + }, + { + "name": "effect", + "type": "Effect", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "TransitionEffect", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 5167, + "problem": "DeclWithDuplicateName", + "api_name": "EventTarget", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 7610, + "problem": "OptionalMethod", + "api_name": "getModifierKeyState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "keys", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BaseEvent", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 8211, + "problem": "DeclWithDuplicateName", + "api_name": "MouseEvent", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 8866, + "problem": "DeclWithDuplicateName", + "api_name": "TouchEvent", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 9942, + "problem": "DeclWithDuplicateName", + "api_name": "DragEvent", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 10303, + "problem": "OptionalMethod", + "api_name": "getModifierKeyState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "keys", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DragEvent", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 10640, + "problem": "OptionalMethod", + "api_name": "getModifierKeyState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "keys", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "KeyEvent", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14270, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14288, + "problem": "OptionalMethod", + "api_name": "applyPressedAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14306, + "problem": "OptionalMethod", + "api_name": "applyFocusedAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14324, + "problem": "OptionalMethod", + "api_name": "applyDisabledAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14342, + "problem": "OptionalMethod", + "api_name": "applySelectedAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 20453, + "problem": "LimitedVoidType", + "api_name": "CustomBuilder", + "api_type": "TypeAliasDeclaration", + "api_func_args": [], + "parent_api": [], + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 21123, + "problem": "DeclWithDuplicateName", + "api_name": "LinearGradient", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22047, + "problem": "OptionalMethod", + "api_name": "aboutToAppear", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22086, + "problem": "OptionalMethod", + "api_name": "aboutToDisappear", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22104, + "problem": "OptionalMethod", + "api_name": "aboutToReuse", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "params", + "type": "{\n [key: string]: unknown;\n }", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22122, + "problem": "OptionalMethod", + "api_name": "aboutToRecycle", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22132, + "problem": "OptionalMethod", + "api_name": "onWillApplyTheme", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "theme", + "type": "Theme", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22144, + "problem": "OptionalMethod", + "api_name": "onLayout", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22166, + "problem": "OptionalMethod", + "api_name": "onPlaceChildren", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "selfLayoutInfo", + "type": "GeometryInfo", + "is_optional": false, + "has_default": false + }, + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22178, + "problem": "OptionalMethod", + "api_name": "onMeasure", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22200, + "problem": "OptionalMethod", + "api_name": "onMeasureSize", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "selfLayoutInfo", + "type": "GeometryInfo", + "is_optional": false, + "has_default": false + }, + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "SizeResult", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22228, + "problem": "OptionalMethod", + "api_name": "onPageShow", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22256, + "problem": "OptionalMethod", + "api_name": "onPageHide", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22280, + "problem": "OptionalMethod", + "api_name": "onFormRecycle", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22300, + "problem": "OptionalMethod", + "api_name": "onFormRecover", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "statusData", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22335, + "problem": "OptionalMethod", + "api_name": "onBackPress", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean | void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22335, + "problem": "LimitedVoidType", + "api_name": "onBackPress", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean | void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22360, + "problem": "OptionalMethod", + "api_name": "pageTransition", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22437, + "problem": "OptionalMethod", + "api_name": "onDidBuild", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 23015, + "problem": "LimitedVoidType", + "api_name": "OnWillScrollCallback", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "scrollOffset", + "type": "number", + "is_optional": false + }, + { + "name": "scrollState", + "type": "ScrollState", + "is_optional": false + }, + { + "name": "scrollSource", + "type": "ScrollSource", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "void | ScrollResult", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/data_panel.d.ts", + "api_info": { + "line": 180, + "problem": "DeclWithDuplicateName", + "api_name": "LinearGradient", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "colorStops", + "type": "ColorStop[]", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "LinearGradient", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/ellipse.d.ts", + "api_info": { + "line": 92, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: string | number;\n height?: string | number;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "EllipseInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "EllipseAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/grid.d.ts", + "api_info": { + "line": 925, + "problem": "LimitedVoidType", + "api_name": "onItemDragStart", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(event: ItemDragInfo, itemIndex: number) => (() => any) | void", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridAttribute", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "GridAttribute", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/hyperlink.d.ts", + "api_info": { + "line": 34, + "problem": "DeclWithDuplicateName", + "api_name": "HyperlinkInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/hyperlink.d.ts", + "api_info": { + "line": 122, + "problem": "DeclWithDuplicateName", + "api_name": "HyperlinkInterface", + "api_type": "FirstStatement", + "parent_api": [], + "code_kind": 244, + "api_property_type": "HyperlinkAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/line.d.ts", + "api_info": { + "line": 100, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: string | number;\n height?: string | number;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LineInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "LineAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/list.d.ts", + "api_info": { + "line": 1643, + "problem": "LimitedVoidType", + "api_name": "onItemDragStart", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(event: ItemDragInfo, itemIndex: number) => ((() => any) | void)", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ListAttribute", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "ListAttribute", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/navigation.d.ts", + "api_info": { + "line": 2873, + "problem": "OptionalMethod", + "api_name": "cancelTransition", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NavigationTransitionProxy", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/navigation.d.ts", + "api_info": { + "line": 2883, + "problem": "OptionalMethod", + "api_name": "updateTransition", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "progress", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavigationTransitionProxy", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/page_transition.d.ts", + "api_info": { + "line": 554, + "problem": "InterfaceExtendsClass", + "api_name": "PageTransitionEnterInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/page_transition.d.ts", + "api_info": { + "line": 638, + "problem": "InterfaceExtendsClass", + "api_name": "PageTransitionExitInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/particle.d.ts", "api_info": { - "problem": "TypeQuery", - "api_name": "self", + "line": 438, + "problem": "IndexedAccessType", + "api_name": "config", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "EmitterOptions", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ParticleConfigs[PARTICLE]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/particle.d.ts", + "api_info": { + "line": 696, + "problem": "IndexedAccessType", + "api_name": "config", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ParticlePropertyOptions", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ParticlePropertyUpdaterConfigs[UPDATER]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/particle.d.ts", + "api_info": { + "line": 849, + "problem": "IndexedAccessType", + "api_name": "config", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ParticleColorPropertyOptions", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ParticleColorPropertyUpdaterConfigs[UPDATER]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/path.d.ts", + "api_info": { + "line": 92, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: number | string;\n height?: number | string;\n commands?: string;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PathInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "PathAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/polygon.d.ts", + "api_info": { + "line": 83, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: string | number;\n height?: string | number;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PolygonInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "PolygonAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/polyline.d.ts", + "api_info": { + "line": 84, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: string | number;\n height?: string | number;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PolylineInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "PolylineAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1176, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.Linear]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "LinearStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1191, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.Ring]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "RingStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1206, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.Eclipse]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "EclipseStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1221, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.ScaleRing]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ScaleRingStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1236, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.Capsule]", "api_type": "PropertySignature", "api_optional": false, - "api_auto_fix": false, - "api_auto_fix_context": "", - "target_type": "", + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "CapsuleStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1347, + "problem": "IndexedAccessType", + "api_name": "ProgressAttribute", + "api_type": "ClassDeclaration", + "api_func_args": [], + "parent_api": [], + "method_return_type": "ProgressAttribute", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1347, + "problem": "IndexedAccessType", + "api_name": "ProgressAttribute", + "api_type": "ClassDeclaration", "api_func_args": [], + "parent_api": [], + "method_return_type": "ProgressAttribute", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/rect.d.ts", + "api_info": { + "line": 92, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: number | string;\n height?: number | string;\n radius?: number | string | Array;\n } | {\n width?: number | string;\n height?: number | string;\n radiusWidth?: number | string;\n radiusHeight?: number | string;\n }", + "is_optional": true, + "has_default": false + } + ], "parent_api": [ { - "api_name": "DedicatedWorkerGlobalScope", + "api_name": "RectInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "RectAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/scroll.d.ts", + "api_info": { + "line": 1397, + "problem": "LimitedVoidType", + "api_name": "ScrollOnWillScrollCallback", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "xOffset", + "type": "number", + "is_optional": false + }, + { + "name": "yOffset", + "type": "number", + "is_optional": false + }, + { + "name": "scrollState", + "type": "ScrollState", + "is_optional": false + }, + { + "name": "scrollSource", + "type": "ScrollSource", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "void | OffsetResult", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/shape.d.ts", + "api_info": { + "line": 75, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "PixelMap", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ShapeInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "ShapeAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/styled_string.d.ts", + "api_info": { + "line": 244, + "problem": "DeclWithDuplicateName", + "api_name": "TextStyle", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "value", + "type": "TextStyleInterface", + "is_optional": true + } + ], + "parent_api": [], + "method_return_type": "TextStyle", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/text_common.d.ts", + "api_info": { + "line": 468, + "problem": "OptionalMethod", + "api_name": "getPreviewText", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "TextEditControllerEx", "api_type": "InterfaceDeclaration" } ], - "methd_return_type": "WorkerGlobalScope & typeof globalThis", - "codeKind": 170 - } + "method_return_type": "PreviewText", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/text_input.d.ts", + "api_info": { + "line": 623, + "problem": "DeclWithDuplicateName", + "api_name": "SubmitEvent", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true } ] } \ No newline at end of file diff --git a/ets2panda/linter/src/lib/statistics/FileProblemStatistics.ts b/ets2panda/linter/src/lib/statistics/FileProblemStatistics.ts new file mode 100644 index 0000000000000000000000000000000000000000..8b95c12d27f1db9bf83b744f66b803689097c888 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/FileProblemStatistics.ts @@ -0,0 +1,23 @@ +/* + * 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. + */ + +export interface FileProblemStatistics { + errors: number; + warnings: number; + errorLines: number; + warningLines: number; + errorLineNumbersString: string; + warningLineNumbersString: string; +} diff --git a/ets2panda/linter/src/lib/statistics/FileStatistics.ts b/ets2panda/linter/src/lib/statistics/FileStatistics.ts new file mode 100644 index 0000000000000000000000000000000000000000..f9395d9c0a88007e3caf77296848cbc15fcd4d34 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/FileStatistics.ts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type * as ts from 'typescript'; +import type { ProblemInfo } from '../ProblemInfo'; +import { FaultID } from '../Problems'; + +export class FileStatistics { + visitedNodes: number = 0; + nodeCounters: number[] = []; + lineCounters: Set[] = []; + srcFileName: string; + problems: ProblemInfo[]; + + constructor(srcFile: ts.SourceFile, problems: ProblemInfo[]) { + this.srcFileName = srcFile.fileName; + this.problems = problems; + + for (let i = 0; i < FaultID.LAST_ID; i++) { + this.nodeCounters[i] = 0; + this.lineCounters[i] = new Set(); + } + } +} diff --git a/ets2panda/linter/src/lib/statistics/ProjectStatistics.ts b/ets2panda/linter/src/lib/statistics/ProjectStatistics.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b2193729b3daa57ab97c9a60c778e2270a1886e --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/ProjectStatistics.ts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { faultsAttrs } from '../FaultAttrs'; +import type { ProblemInfo } from '../ProblemInfo'; +import { ProblemSeverity } from '../ProblemSeverity'; +import type { FileStatistics } from './FileStatistics'; + +export class ProjectStatistics { + fileStats: FileStatistics[] = []; + + hasError(): boolean { + return this.fileStats.some((fileStats) => { + return fileStats.problems.some((problemInfo: ProblemInfo) => { + return faultsAttrs[problemInfo.faultId].severity === ProblemSeverity.ERROR; + }); + }); + } +} diff --git a/ets2panda/linter/src/lib/statistics/StatisticsLogger.ts b/ets2panda/linter/src/lib/statistics/StatisticsLogger.ts new file mode 100644 index 0000000000000000000000000000000000000000..da586f7a9198959df6e3bde597a257f2fe446782 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/StatisticsLogger.ts @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { faultsAttrs } from '../FaultAttrs'; +import { Logger } from '../Logger'; +import { FaultID } from '../Problems'; +import { ProblemSeverity } from '../ProblemSeverity'; +import type { ProblemInfo } from '../ProblemInfo'; +import { faultDesc } from '../FaultDesc'; +import type { FileStatistics } from './FileStatistics'; +import type { FileProblemStatistics } from './FileProblemStatistics'; +import type { ProjectStatistics } from './ProjectStatistics'; + +export function log(...args: unknown[]): void { + let outLine = ''; + for (let k = 0; k < args.length; k++) { + outLine += `${args[k]} `; + } + Logger.info(outLine); +} + +function logReport(srcFileName: string, problemInfo: ProblemInfo): void { + const faultDescr = faultDesc[problemInfo.faultId]; + const faultType = problemInfo.type; + Logger.info( + `Warning: ${srcFileName} (${problemInfo.line}, ${problemInfo.column}): ${faultDescr ? faultDescr : faultType}` + ); +} + +function logFileProblems(fileStats: FileStatistics): void { + for (const problem of fileStats.problems) { + logReport(fileStats.srcFileName, problem); + } +} + +function countProblemStats(fileStats: FileStatistics): FileProblemStatistics { + let errors = 0; + let warnings = 0; + const errorLines = new Set(); + const warningLines = new Set(); + fileStats.problems.forEach((problemInfo: ProblemInfo) => { + const line = problemInfo.line; + switch (faultsAttrs[problemInfo.faultId].severity) { + case ProblemSeverity.ERROR: { + errors++; + errorLines.add(line); + break; + } + case ProblemSeverity.WARNING: { + warnings++; + warningLines.add(line); + break; + } + default: + } + }); + const sortFunc = (a, b): number => { + return a - b; + }; + let errorLineNumbersString = ''; + Array.from(errorLines). + sort(sortFunc). + forEach((line) => { + errorLineNumbersString += line + ', '; + }); + let warningLineNumbersString = ''; + Array.from(warningLines). + sort(sortFunc). + forEach((line) => { + warningLineNumbersString += line + ', '; + }); + return { + errors, + warnings, + errorLines: errorLines.size, + warningLines: warningLines.size, + errorLineNumbersString, + warningLineNumbersString + }; +} + +function logProblemFileInfo(fileStats: FileStatistics, problemStats: FileProblemStatistics): void { + if (problemStats.errors > 0) { + const errorRate = (problemStats.errors / fileStats.visitedNodes * 100).toFixed(2); + const warningRate = (problemStats.warnings / fileStats.visitedNodes * 100).toFixed(2); + log(fileStats.srcFileName, ': ', '\n\tError lines: ', problemStats.errorLineNumbersString); + log(fileStats.srcFileName, ': ', '\n\tWarning lines: ', problemStats.warningLineNumbersString); + log( + '\n\tError constructs (%): ', + errorRate, + '\t[ of ', + fileStats.visitedNodes, + ' constructs ], \t', + problemStats.errorLines, + ' lines' + ); + log( + '\n\tWarning constructs (%): ', + warningRate, + '\t[ of ', + fileStats.visitedNodes, + ' constructs ], \t', + problemStats.warningLines, + ' lines' + ); + } +} + +function logTotalProblemsInfo( + totalErrors: number, + totalWarnings: number, + totalErrorLines: number, + totalWarningLines: number, + totalVisitedNodes: number +): void { + const errorRate = (totalErrors / totalVisitedNodes * 100).toFixed(2); + const warningRate = (totalWarnings / totalVisitedNodes * 100).toFixed(2); + log('\nTotal error constructs (%): ', errorRate); + log('\nTotal warning constructs (%): ', warningRate); + log('\nTotal error lines:', totalErrorLines, ' lines\n'); + log('\nTotal warning lines:', totalWarningLines, ' lines\n'); +} + +function logProblemsPercentageByFeatures(projectStats: ProjectStatistics, totalVisitedNodes: number): void { + log('\nPercent by features: '); + for (let i = 0; i < FaultID.LAST_ID; i++) { + let nodes = 0; + let lines = 0; + for (const fileStats of projectStats.fileStats) { + nodes += fileStats.nodeCounters[i]; + lines += fileStats.lineCounters[i].size; + } + const pecentage = (nodes / totalVisitedNodes * 100).toFixed(2).padEnd(7, ' '); + log(faultDesc[i].padEnd(55, ' '), pecentage, '[', nodes, ' constructs / ', lines, ' lines]'); + } +} + +export function logStatistics(projectStats: ProjectStatistics): void { + let filesWithErrors = 0; + let totalErrors = 0; + let totalWarnings = 0; + let totalErrorLines = 0; + let totalWarningLines = 0; + let totalVisitedNodes = 0; + + for (const fileStats of projectStats.fileStats) { + logFileProblems(fileStats); + + const problemStats = countProblemStats(fileStats); + logProblemFileInfo(fileStats, problemStats); + + if (problemStats.errors > 0) { + filesWithErrors++; + } + + totalErrors += problemStats.errors; + totalWarnings += problemStats.warnings; + totalErrorLines += problemStats.errorLines; + totalWarningLines += problemStats.warningLines; + totalVisitedNodes += fileStats.visitedNodes; + } + + log('\n\n\nFiles scanned: ', projectStats.fileStats.length); + log('\nFiles with problems: ', filesWithErrors); + + logTotalProblemsInfo(totalErrors, totalWarnings, totalErrorLines, totalWarningLines, totalVisitedNodes); + logProblemsPercentageByFeatures(projectStats, totalVisitedNodes); +} diff --git a/ets2panda/linter/src/cli/Compiler.ts b/ets2panda/linter/src/lib/ts-compiler/Compiler.ts similarity index 44% rename from ets2panda/linter/src/cli/Compiler.ts rename to ets2panda/linter/src/lib/ts-compiler/Compiler.ts index b37a0996a48405ef12819b87993059cdb4a1e72d..7708b647daccfddd1f5b85bbb074b7964b8d6f83 100644 --- a/ets2panda/linter/src/cli/Compiler.ts +++ b/ets2panda/linter/src/lib/ts-compiler/Compiler.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -14,16 +14,22 @@ */ import * as ts from 'typescript'; -import type { CommandLineOptions } from '../lib/CommandLineOptions'; -import { formTscOptions } from './ts-compiler/FormTscOptions'; -import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; -import type { LinterConfig } from '../lib/LinterConfig'; -import { TSCCompiledProgramWithDiagnostics } from '../lib/ts-diagnostics/TSCCompiledProgram'; -import { Logger } from '../lib/Logger'; - -function compile(cmdOptions: CommandLineOptions, overrideCompilerOptions: ts.CompilerOptions): ts.Program { +import type { CommandLineOptions } from '../CommandLineOptions'; +import { formTscOptions } from './FormTscOptions'; +import { logTscDiagnostic } from '../utils/functions/LogTscDiagnostic'; +import type { LinterConfig } from '../LinterConfig'; +import { TSCCompiledProgramSimple, TSCCompiledProgramWithDiagnostics } from '../ts-diagnostics/TSCCompiledProgram'; +import { Logger } from '../Logger'; + +export type createProgramCallback = (createProgramOptions: ts.CreateProgramOptions) => ts.Program; + +function compile( + cmdOptions: CommandLineOptions, + overrideCompilerOptions: ts.CompilerOptions, + createProgramCb?: createProgramCallback +): ts.Program { const createProgramOptions = formTscOptions(cmdOptions, overrideCompilerOptions); - const program = ts.createProgram(createProgramOptions); + const program = createProgramCb ? createProgramCb(createProgramOptions) : ts.createProgram(createProgramOptions); // Log Tsc errors if needed if (cmdOptions.logTscErrors) { const diagnostics = ts.getPreEmitDiagnostics(program); @@ -32,9 +38,32 @@ function compile(cmdOptions: CommandLineOptions, overrideCompilerOptions: ts.Com return program; } -export function compileLintOptions(cmdOptions: CommandLineOptions): LinterConfig { - const strict = compile(cmdOptions, getOverrideCompilerOptions(true)); - const nonStrict = compile(cmdOptions, getOverrideCompilerOptions(false)); +export function compileLintOptions( + cmdOptions: CommandLineOptions, + createProgramCb?: createProgramCallback +): LinterConfig { + const linterConfig = cmdOptions.disableStrictDiagnostics ? + compileSimpleProgram(cmdOptions, createProgramCb) : + compileWithStrictDiagnostics(cmdOptions, createProgramCb); + + linterConfig.cmdOptions.linterOptions.etsLoaderPath = getEtsLoaderPath(linterConfig); + return linterConfig; +} + +function compileSimpleProgram(cmdOptions: CommandLineOptions, createProgramCb?: createProgramCallback): LinterConfig { + const program = compile(cmdOptions, getOverrideCompilerOptions(true), createProgramCb); + return { + cmdOptions: cmdOptions, + tscCompiledProgram: new TSCCompiledProgramSimple(program) + }; +} + +function compileWithStrictDiagnostics( + cmdOptions: CommandLineOptions, + createProgramCb?: createProgramCallback +): LinterConfig { + const strict = compile(cmdOptions, getOverrideCompilerOptions(true), createProgramCb); + const nonStrict = compile(cmdOptions, getOverrideCompilerOptions(false), createProgramCb); return { cmdOptions: cmdOptions, tscCompiledProgram: new TSCCompiledProgramWithDiagnostics(strict, nonStrict, cmdOptions.inputFiles) @@ -55,3 +84,8 @@ function getOverrideCompilerOptions(strict: boolean): ts.CompilerOptions { noImplicitReturns: strict }; } + +export function getEtsLoaderPath(linterConfig: LinterConfig): string | undefined { + const tsProgram = linterConfig.tscCompiledProgram.getProgram(); + return tsProgram.getCompilerOptions().etsLoaderPath; +} diff --git a/ets2panda/linter/src/cli/ts-compiler/FormTscOptions.ts b/ets2panda/linter/src/lib/ts-compiler/FormTscOptions.ts similarity index 66% rename from ets2panda/linter/src/cli/ts-compiler/FormTscOptions.ts rename to ets2panda/linter/src/lib/ts-compiler/FormTscOptions.ts index 1494a294fa8af16e79b56f81d81eec66cd3f505c..b29b42f3bb3b66554a2015fbc765ba4b6c238f45 100644 --- a/ets2panda/linter/src/cli/ts-compiler/FormTscOptions.ts +++ b/ets2panda/linter/src/lib/ts-compiler/FormTscOptions.ts @@ -14,8 +14,19 @@ */ import * as ts from 'typescript'; -import type { CommandLineOptions } from '../../lib/CommandLineOptions'; -import { createCompilerHost } from './ResolveSdks'; +import type { CommandLineOptions } from '../CommandLineOptions'; +import { createCompilerHost, readDeclareFiles } from './ResolveSdks'; + +function getTargetESVersionLib(optionsTarget: ts.ScriptTarget): string[] { + switch (optionsTarget) { + case ts.ScriptTarget.ES2017: + return ['lib.es2017.d.ts']; + case ts.ScriptTarget.ES2021: + return ['lib.es2021.d.ts']; + default: + return ['lib.es2021.d.ts']; + } +} export function formTscOptions( cmdOptions: CommandLineOptions, @@ -31,13 +42,18 @@ export function formTscOptions( options.options = Object.assign(options.options, overrideCompilerOptions); return options; } + const rootNames = cmdOptions.inputFiles.concat(readDeclareFiles(cmdOptions.sdkDefaultApiPath ?? '')); + const ESVersion = cmdOptions.followSdkSettings ? ts.ScriptTarget.ES2021 : ts.ScriptTarget.Latest; + const ESVersionLib = cmdOptions.followSdkSettings ? getTargetESVersionLib(ESVersion) : undefined; + const isCheckJs = !cmdOptions.followSdkSettings; const options: ts.CreateProgramOptions = { - rootNames: cmdOptions.inputFiles, + rootNames: rootNames, options: { - target: ts.ScriptTarget.Latest, + target: ESVersion, module: ts.ModuleKind.CommonJS, allowJs: true, - checkJs: true + checkJs: isCheckJs, + lib: ESVersionLib } }; if (cmdOptions.sdkDefaultApiPath && cmdOptions.arktsWholeProjectPath && cmdOptions.sdkExternalApiPath) { diff --git a/ets2panda/linter/src/cli/ts-compiler/ResolveSdks.ts b/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts similarity index 92% rename from ets2panda/linter/src/cli/ts-compiler/ResolveSdks.ts rename to ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts index f4a11b5fc7f7c79176a8731f88dbf3d0af8e34a2..290326c0fc66a1584faac14d1b9e8376931ab237 100644 --- a/ets2panda/linter/src/cli/ts-compiler/ResolveSdks.ts +++ b/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts @@ -15,7 +15,7 @@ import * as path from 'node:path'; import * as fs from 'fs'; import * as ts from 'typescript'; -import { EXTNAME_JS, EXTNAME_TS, EXTNAME_D_ETS, EXTNAME_D_TS, EXTNAME_ETS } from '../../lib/utils/consts/ExtensionName'; +import { EXTNAME_JS, EXTNAME_TS, EXTNAME_D_ETS, EXTNAME_D_TS, EXTNAME_ETS } from '../utils/consts/ExtensionName'; interface ResolutionContext { sdkContext: SdkContext; @@ -30,6 +30,23 @@ interface SdkContext { sdkDefaultApiPath: string; } +export function readDeclareFiles(SdkPath: string): string[] { + if (SdkPath === '') { + return []; + } + const declarationsFileNames: string[] = []; + const declarationsPath = path.resolve(SdkPath, './build-tools/ets-loader/declarations'); + if (!fs.existsSync(declarationsPath)) { + throw new Error('get wrong sdkDefaultApiPath, declarationsPath not found'); + } + fs.readdirSync(declarationsPath).forEach((fileName: string) => { + if ((/\.d\.ts$/).test(fileName)) { + declarationsFileNames.push(path.resolve(SdkPath, './build-tools/ets-loader/declarations', fileName)); + } + }); + return declarationsFileNames; +} + export function createCompilerHost( sdkDefaultApiPath: string, sdkExternalApiPath: string[], @@ -298,28 +315,16 @@ function createResolutionContext(sdkContext: SdkContext, projectPath: string): R return { sdkContext, projectPath, - compilerOptions: createCompilerOptions(projectPath) + compilerOptions: createCompilerOptions(sdkContext, projectPath) }; } -function createCompilerOptions(projectPath: string): ts.CompilerOptions { +function createCompilerOptions(sdkContext: SdkContext, projectPath: string): ts.CompilerOptions { const compilerOptions: ts.CompilerOptions = ((): ts.CompilerOptions => { - let configPath: string | null = null; - let currentDir: string = __dirname; - - while (currentDir) { - const filePath = path.resolve(currentDir, 'tsconfig.json'); - if (fs.existsSync(filePath)) { - configPath = filePath; - break; - } - currentDir = path.dirname(currentDir); + const configPath = path.resolve(sdkContext.sdkDefaultApiPath, './build-tools/ets-loader/tsconfig.json'); + if (!fs.existsSync(configPath)) { + throw new Error('get wrong sdkDefaultApiPath, tsconfig.json not found'); } - - if (!configPath) { - throw new Error('tsconfig.json not found'); - } - const configFile = ts.readConfigFile(configPath, ts.sys.readFile); return configFile.config.compilerOptions; })(); diff --git a/ets2panda/linter/src/lib/ts-diagnostics/TSCCompiledProgram.ts b/ets2panda/linter/src/lib/ts-diagnostics/TSCCompiledProgram.ts index c4b5a7a19be630e1368583172feb16d2198b8af8..c3719cc50aa46d4b54a4f9fc5b92ca6fcbbf6eb4 100644 --- a/ets2panda/linter/src/lib/ts-diagnostics/TSCCompiledProgram.ts +++ b/ets2panda/linter/src/lib/ts-diagnostics/TSCCompiledProgram.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -97,6 +97,7 @@ export function transformDiagnostic(diagnostic: ts.Diagnostic): ProblemInfo { end: endPos, type: 'StrictModeError', // expect strict options to always present + faultId: faultId, severity: diagnostic.category === ts.DiagnosticCategory.Warning ? ProblemSeverity.WARNING : ProblemSeverity.ERROR, problem: FaultID[faultId], suggest: messageText, diff --git a/ets2panda/linter/src/lib/utils/TsUtils.ts b/ets2panda/linter/src/lib/utils/TsUtils.ts index 386623e4752f28c0a0b6fe844393124158059274..6365fab13f26e8068d81b96e4bc91f9016f2576a 100644 --- a/ets2panda/linter/src/lib/utils/TsUtils.ts +++ b/ets2panda/linter/src/lib/utils/TsUtils.ts @@ -15,6 +15,7 @@ import * as path from 'node:path'; import * as ts from 'typescript'; +import * as fs from 'fs'; import type { IsEtsFileCallback } from '../IsEtsFileCallback'; import { FaultID } from '../Problems'; import { ARKTS_IGNORE_DIRS, ARKTS_IGNORE_DIRS_OH_MODULES, ARKTS_IGNORE_FILES } from './consts/ArktsIgnorePaths'; @@ -43,9 +44,10 @@ import { isIntrinsicObjectType } from './functions/isIntrinsicObjectType'; import type { LinterOptions } from '../LinterOptions'; import { ETS } from './consts/TsSuffix'; import { STRINGLITERAL_NUMBER, STRINGLITERAL_NUMBER_ARRAY } from './consts/StringLiteral'; -import { ETS_MODULE, VALID_OHM_COMPONENTS_MODULE_PATH } from './consts/OhmUrl'; -import { EXTNAME_JS } from './consts/ExtensionName'; -import { USE_STATIC } from './consts/InteropAPI'; +import { InteropType, USE_STATIC } from './consts/InteropAPI'; +import { ETS_MODULE, PATH_SEPARATOR, VALID_OHM_COMPONENTS_MODULE_PATH } from './consts/OhmUrl'; +import { EXTNAME_D_TS, EXTNAME_ETS, EXTNAME_JS, EXTNAME_TS } from './consts/ExtensionName'; +import { STRING_ERROR_LITERAL } from './consts/Literals'; export const SYMBOL = 'Symbol'; export const SYMBOL_CONSTRUCTOR = 'SymbolConstructor'; @@ -231,6 +233,54 @@ export class TsUtils { ); } + checkStatementForErrorClass(stmt: ts.ThrowStatement): boolean { + const newExpr = stmt.expression; + if (!ts.isNewExpression(newExpr)) { + return true; + } + const ident = newExpr.expression; + if (!ts.isIdentifier(ident)) { + return true; + } + + if (ident.text === STRING_ERROR_LITERAL) { + return false; + } + + const declaration = this.getDeclarationNode(ident); + if (!declaration) { + return true; + } + + if (!ts.isClassDeclaration(declaration)) { + return true; + } + + if (!declaration.heritageClauses) { + return true; + } + + return !this.includesErrorClass(declaration.heritageClauses); + } + + includesErrorClass(hClauses: ts.NodeArray): boolean { + void this; + let includesErrorClass = false; + + for (const hClause of hClauses) { + for (const type of hClause.types) { + if (!ts.isIdentifier(type.expression)) { + continue; + } + if (type.expression.text === 'Error') { + includesErrorClass = true; + } + } + } + + return includesErrorClass; + } + static isPrimitiveLiteralType(type: ts.Type): boolean { return !!( type.flags & @@ -624,6 +674,9 @@ export class TsUtils { if (this.processExtendedParentTypes(typeA, typeB)) { return true; } + if (this.isStdIterableType(typeB) && this.hasSymbolIteratorMethod(typeA)) { + return true; + } if (!typeADecl.heritageClauses) { return false; } @@ -636,6 +689,25 @@ export class TsUtils { return false; } + hasSymbolIteratorMethod(type: ts.Type): boolean { + const rhsTypeProps = this.tsTypeChecker.getPropertiesOfType(type); + return rhsTypeProps.some((prop) => { + const propDecl = TsUtils.getDeclaration(prop); + return ( + propDecl && + (ts.isMethodSignature(propDecl) || ts.isMethodDeclaration(propDecl)) && + ts.isComputedPropertyName(propDecl.name) && + this.isSymbolIteratorExpression(propDecl.name.expression) + ); + }); + } + + isStdIterableType(type: ts.Type): boolean { + void this; + const sym = type.getSymbol(); + return !!sym && sym.getName() === 'Iterable' && isStdLibrarySymbol(sym); + } + static reduceReference(t: ts.Type): ts.Type { return TsUtils.isTypeReference(t) && t.target !== t ? t.target : t; } @@ -922,10 +994,25 @@ export class TsUtils { return result; } - private static hasDefaultCtor(type: ts.Type): boolean { + private hasDefaultCtor(type: ts.Type): boolean { + const checkBaseTypes = (type: ts.Type): boolean => { + if (!this.options.arkts2) { + return true; + } + const baseTypes = type.getBaseTypes()?.filter((baseType) => { + return baseType.isClass(); + }); + if (!baseTypes || baseTypes.length === 0) { + return true; + } + return baseTypes.some((baseType: ts.Type) => { + return this.hasDefaultCtor(baseType); + }); + }; + // No members -> no explicit constructors -> there is default ctor if (type.symbol.members === undefined) { - return true; + return checkBaseTypes(type); } // has any constructor @@ -950,7 +1037,11 @@ export class TsUtils { }); // Has no any explicit constructor -> has implicit default constructor. - return !hasCtor || hasDefaultCtor; + if (!hasCtor) { + return checkBaseTypes(type); + } + + return hasDefaultCtor; } private static isAbstractClass(type: ts.Type): boolean { @@ -982,7 +1073,7 @@ export class TsUtils { return false; } - static validateObjectLiteralType(type: ts.Type | undefined): boolean { + validateObjectLiteralType(type: ts.Type | undefined): boolean { if (!type) { return false; } @@ -990,7 +1081,7 @@ export class TsUtils { type = TsUtils.reduceReference(type); return ( type.isClassOrInterface() && - TsUtils.hasDefaultCtor(type) && + this.hasDefaultCtor(type) && !TsUtils.hasReadonlyFields(type) && !TsUtils.isAbstractClass(type) ); @@ -1096,7 +1187,7 @@ export class TsUtils { return this.validateRecordObjectKeys(rhsExpr); } return ( - TsUtils.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr) + this.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr) ); } @@ -1798,6 +1889,22 @@ export class TsUtils { } getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { + const sym = this.trueSymbolAtLocation(node); + if (sym === undefined) { + return undefined; + } + return TsUtils.getVariableSymbolDeclarationTypeNode(sym); + } + + static getVariableSymbolDeclarationTypeNode(sym: ts.Symbol): ts.TypeNode | undefined { + const decl = TsUtils.getDeclaration(sym); + if (!!decl && ts.isVariableDeclaration(decl)) { + return decl.type; + } + return undefined; + } + + getDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { const sym = this.trueSymbolAtLocation(node); if (sym === undefined) { return undefined; @@ -1807,7 +1914,7 @@ export class TsUtils { static getSymbolDeclarationTypeNode(sym: ts.Symbol): ts.TypeNode | undefined { const decl = TsUtils.getDeclaration(sym); - if (!!decl && ts.isVariableDeclaration(decl)) { + if (!!decl && (ts.isVariableDeclaration(decl) || ts.isPropertyDeclaration(decl))) { return decl.type; } return undefined; @@ -1819,7 +1926,7 @@ export class TsUtils { } static symbolHasEsObjectType(sym: ts.Symbol): boolean { - const typeNode = TsUtils.getSymbolDeclarationTypeNode(sym); + const typeNode = TsUtils.getVariableSymbolDeclarationTypeNode(sym); return typeNode !== undefined && TsUtils.isEsObjectType(typeNode); } @@ -2065,7 +2172,9 @@ export class TsUtils { } } // We allow computed property names if expression is string literal or string Enum member - return ts.isStringLiteralLike(expr) || this.isEnumStringLiteral(computedProperty.expression); + return ( + !this.options.arkts2 && (ts.isStringLiteralLike(expr) || this.isEnumStringLiteral(computedProperty.expression)) + ); } skipPropertyInferredTypeCheck( @@ -3330,6 +3439,23 @@ export class TsUtils { ); } + static isAppStorageAccess(tsCallExpr: ts.CallExpression): boolean { + const propertyAccessExpr = tsCallExpr.expression; + if (!ts.isPropertyAccessExpression(propertyAccessExpr)) { + return false; + } + const accessedExpr = propertyAccessExpr.expression; + if (!ts.isIdentifier(accessedExpr)) { + return false; + } + + if (accessedExpr.text !== 'AppStorage') { + return false; + } + + return true; + } + static isArithmeticOperator(op: ts.BinaryOperatorToken): boolean { switch (op.kind) { case ts.SyntaxKind.PlusToken: @@ -3392,6 +3518,34 @@ export class TsUtils { return sanitizedDirectories[sanitizedDirectories.length - 1]; } + static checkFileExists( + importIncludesModule: boolean, + currentNode: ts.Node, + importFilePath: string, + projectPath: string, + extension: string = EXTNAME_ETS + ): boolean { + const currentModule = TsUtils.getModuleName(currentNode); + + /* + * some imports are like this + * ets/pages/test1 + * in this case, they are in the same module as the file we are trying to import to + * so we add the current module back in + */ + if (!importIncludesModule) { + if (!currentModule) { + return false; + } + + projectPath.concat(PATH_SEPARATOR + currentModule); + } + + const importedFile = path.resolve(projectPath, importFilePath + extension); + + return fs.existsSync(importedFile); + } + isImportedFromJS(identifier: ts.Identifier): boolean { const sym = this.trueSymbolAtLocation(identifier); const declaration = sym?.declarations?.[0]; @@ -3488,6 +3642,17 @@ export class TsUtils { return conversionMethod; } + static isInsideIfCondition(node: ts.Node): boolean { + let current: ts.Node | undefined = node; + while (current) { + if (ts.isIfStatement(current)) { + return true; + } + current = current.parent; + } + return false; + } + static isOhModule(path: string): boolean { return path.includes(ETS_MODULE); } @@ -3518,8 +3683,43 @@ export class TsUtils { return undefined; } + /** + * Checks whether an exported identifier is imported from an ArkTS1 file. + * @param exportIdentifier The exported identifier to check. + * @param node The node where the export occurs (used to get the current source file). + * @returns true if imported from ArkTS1, false if not, undefined if undetermined. + */ + isExportImportedFromArkTs1(exportIdentifier: ts.Identifier, node: ts.Node): boolean | undefined { + // Get the symbol associated with the identifier. + const symbol = this.tsTypeChecker.getSymbolAtLocation(exportIdentifier); + if (!symbol) { + return undefined; + } + + // If the symbol is an alias (imported), resolve the real symbol. + const realSymbol = + (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? this.tsTypeChecker.getAliasedSymbol(symbol) : undefined; + + const declarations = realSymbol?.getDeclarations(); + if (!declarations || declarations.length === 0) { + return undefined; + } + + // Get the source file where the declaration is located. + const importSourceFile = declarations[0].getSourceFile(); + + // Ensure import is from ArkTS1 file and usage is in ArkTS1.2 file + const currentSourceFile = node.getSourceFile(); + return ( + importSourceFile.fileName.endsWith(EXTNAME_ETS) && + currentSourceFile.fileName.endsWith(EXTNAME_ETS) && + !TsUtils.isArkts12File(importSourceFile) && + TsUtils.isArkts12File(currentSourceFile) + ); + } + static isArkts12File(sourceFile: ts.SourceFile): boolean { - if (!sourceFile || !sourceFile.statements.length) { + if (!sourceFile?.statements.length) { return false; } const statements = sourceFile.statements; @@ -3544,16 +3744,115 @@ export class TsUtils { return str; } + static getCurrentModule(currentFileName: string): string { + const parts = currentFileName.split(PATH_SEPARATOR); + parts.pop(); + const currentModule = parts.join(PATH_SEPARATOR); + return currentModule; + } + + static resolveModuleAndCheckInterop(wholeProjectPath: string, callExpr: ts.CallExpression): InteropType | undefined { + const moduleName = callExpr.arguments[0]; + if (!ts.isStringLiteral(moduleName)) { + return undefined; + } + + const importedModule = path.resolve(wholeProjectPath, moduleName.text); + + const importedFile = TsUtils.resolveImportModule(importedModule); + if (!importedFile) { + return undefined; + } + + const importSource = ts.sys.readFile(importedFile); + if (!importSource) { + return undefined; + } + + return TsUtils.checkFileForInterop(importedFile, importSource); + } + + static resolveImportModule(importedModule: string): string | undefined { + const extensions = ['.ts', '.js', '.ets']; + for (const ext of extensions) { + const tryPath = path.resolve(importedModule + ext); + if (fs.existsSync(tryPath)) { + return tryPath; + } + } + + return undefined; + } + + static checkFileForInterop(fileName: string, importSource: string): InteropType { + if (fileName.endsWith(EXTNAME_JS)) { + return InteropType.JS; + } + + if (fileName.endsWith(EXTNAME_TS) && !fileName.endsWith(EXTNAME_D_TS)) { + return InteropType.TS; + } + + if (fileName.endsWith(EXTNAME_ETS) && !importSource.includes('\'use static\'')) { + return InteropType.LEGACY; + } + + return InteropType.NONE; + } + isJsImport(node: ts.Node): boolean { const symbol = this.trueSymbolAtLocation(node); if (symbol) { const declaration = symbol.declarations?.[0]; if (declaration) { const sourceFile = declaration.getSourceFile(); - const isFromJs = sourceFile.fileName.endsWith(EXTNAME_JS); - return isFromJs; + return sourceFile.fileName.endsWith(EXTNAME_JS); + } + } + return false; + } + + static typeIsCapturedFromEnclosingLocalScope(type: ts.Type, enclosingStmt: ts.Node): boolean { + let symNode: ts.Node | undefined = TsUtils.getDeclaration(type.getSymbol()); + + while (symNode) { + if (symNode === enclosingStmt) { + return true; } + symNode = symNode.parent; } + return false; } + + nodeCapturesValueFromEnclosingLocalScope(targetNode: ts.Node, enclosingStmt: ts.Node): boolean { + let found = false; + + const callback = (node: ts.Node): void => { + if (!ts.isIdentifier(node)) { + return; + } + const sym = this.tsTypeChecker.getSymbolAtLocation(node); + let symNode: ts.Node | undefined = TsUtils.getDeclaration(sym); + while (symNode) { + if (symNode === targetNode) { + // Symbol originated from the target node. Skip and continue to search + return; + } + if (symNode === enclosingStmt) { + found = true; + return; + } + symNode = symNode.parent; + } + }; + + const stopCondition = (node: ts.Node): boolean => { + void node; + return found; + }; + + forEachNodeInSubtree(targetNode, callback, stopCondition); + return found; + } } diff --git a/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts b/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts index 14327f018d85b5094f4b17b84183ec68b0471230..f1a9c97b6bc0ac2e7ac082b7b38bb215ecd2b5b3 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts @@ -64,37 +64,5 @@ export const arkts2Rules: number[] = [ 263, 300, 301, - 302, - 303, 304, - 305, - 306, - 307, - 308, - 309, - 310, - 311, - 312, - 313, - 314, - 315, - 316, - 319, - 320, - 321, - 330, - 331, - 332, - 333, - 334, - 335, - 336, - 337, - 338, - 339, - 340, - 341, - 342, - 343, - 344 ]; diff --git a/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts b/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..dcddab08b580a515ee4cbb998d5b2bff7a1025a9 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export const ASON_TEXT = 'ASON'; +export const ASON_MODULES = ['@arkts.utils', '@kit.ArkTS']; +export const JSON_TEXT = 'JSON'; diff --git a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts index aab38266ad9023ededa22b636c06465579ecac90..ec5b3df5042e3b9698048a81018a3bd24e9f1025 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts @@ -23,13 +23,22 @@ export const STATE_STYLES = 'stateStyles'; export const ARKUI_PACKAGE_NAME = '@kit.ArkUI'; export const VALUE_IDENTIFIER = 'value'; export const INDENT_STEP = 2; +export const MAKE_OBSERVED = 'makeObserved'; +export const ARKUI_STATE_MANAGEMENT = '@ohos.arkui.StateManagement'; export enum CustomDecoratorName { Extend = 'Extend', + LocalBuilder = 'LocalBuilder', Styles = 'Styles', AnimatableExtend = 'AnimatableExtend', Memo = 'Memo', - Observed = 'Observed' + Observed = 'Observed', + Layoutable = 'Layoutable' +} + +export enum StorageTypeName { + LocalStorage = 'LocalStorage', + AppStorage = 'AppStorage' } export const observedDecoratorName: Set = new Set([ @@ -45,7 +54,19 @@ export const observedDecoratorName: Set = new Set([ 'Track' ]); -export const skipImportDecoratorName: Set = new Set(['Extend', 'Styles', 'Sendable', 'Concurrent']); +export const skipImportDecoratorName: Set = new Set([ + 'Extend', + 'Styles', + 'Sendable', + 'Concurrent', + 'LocalBuilder' +]); + +export const deepCopyDecoratorName: Set = new Set(['Prop', 'StorageProp', 'LocalStorageProp']); + +export const deepCopyFunctionName: Set = new Set(['prop', 'setAndProp']); + +export const customLayoutFunctionName: Set = new Set(['onMeasureSize', 'onPlaceChildren']); export const ENTRY_DECORATOR_NAME = 'Entry'; export const ENTRY_STORAGE_PROPERITY = 'storage'; diff --git a/ets2panda/linter/src/lib/utils/consts/BuiltinGenericConstructor.ts b/ets2panda/linter/src/lib/utils/consts/BuiltinGenericConstructor.ts index dbadef70d4c093c250dc45878b6b3a7e23b04e73..211a86e8860932ce1da776c9429bc3a475aa83fa 100755 --- a/ets2panda/linter/src/lib/utils/consts/BuiltinGenericConstructor.ts +++ b/ets2panda/linter/src/lib/utils/consts/BuiltinGenericConstructor.ts @@ -19,5 +19,14 @@ export const BUILTIN_GENERIC_CONSTRUCTORS = new Set([ 'ReadonlyArray', 'Promise', 'WeakMap', - 'WeakSet' + 'WeakSet', + 'Deque', + 'ArrayList', + 'HashMap', + 'HashSet', + 'LinkedList', + 'PlainArray', + 'TreeMap', + 'TreeSet', + 'Queue' ]); diff --git a/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts b/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts new file mode 100644 index 0000000000000000000000000000000000000000..d4e4898557e485d0cb4c9c83c21c143be6314e61 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts @@ -0,0 +1,47 @@ +/* + * 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. + */ + +export enum BuiltinProblem { + LimitedThisArg = 'ThisArg', + SymbolIterator = 'SymbolIterator', + BuiltinNoCtorFunc = 'BuiltinNoCtorFunc', + BuiltinNoPropertyDescriptor = 'NoPropertyDescriptor', + MissingAttributes = 'MissingAttributes' +} + +export const SYMBOL_ITERATOR: string = 'Symbol.iterator'; + +export const GET_OWN_PROPERTY_NAMES_TEXT: string = 'Object.getOwnPropertyNames'; + +export const BUILTIN_DISABLE_CALLSIGNATURE = [ + 'AggregateError', + 'Array', + 'Array', + 'BigInt', + 'Boolean', + 'Date', + 'Error', + 'EvalError', + 'Number', + 'RangeError', + 'ReferenceError', + 'RegExp', + 'RegExp', + 'RegExp', + 'String', + 'SyntaxError', + 'TypeError', + 'URIError' +]; diff --git a/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts b/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..a7c1698e3ba00a285e16df6ee6b1c418f3832d4b --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export const COLLECTIONS_TEXT = 'collections'; +export const COLLECTIONS_MODULES = ['@arkts.collections', '@kit.ArkTS']; diff --git a/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts b/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..5fc45d2e960b875ace2b3e42b94de233b7d33b66 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +export const USE_CONCURRENT = 'use concurrent'; +export const USE_SHARED = 'use shared'; +export const ESLIB_SHAREDARRAYBUFFER = 'SharedArrayBuffer'; +export const ESLIB_SHAREDMEMORY_FILENAME = 'lib.es2017.sharedmemory.d.ts'; +export const TASKPOOL_MODULES = ['@kit.ArkTS', '@ohos.taskpool']; diff --git a/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts b/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts index 5aa9c0be54964a153cd852a7e3358a4fcb5e21a4..1d7f1f674578282bdb1b625dc42c5df4cad00463 100644 --- a/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts @@ -40,3 +40,10 @@ export const SET_PROPERTY_BY_NAME = 'setPropertyByName'; export const GET_PROPERTY_BY_INDEX = 'getPropertyByIndex'; export const SET_PROPERTY_BY_INDEX = 'setPropertyByIndex'; export const TO_NUMBER = 'toNumber'; + +export enum InteropType { + TS = 'TS', + JS = 'JS', + LEGACY = '1.0', + NONE = 'none' +} diff --git a/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts b/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts index fb9fcb6e2c2b5aef70b5ea443124e5cb37499b59..ca9bdcd8431c31b723b45d592176955b315df23d 100644 --- a/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts @@ -153,6 +153,7 @@ export const LIMITED_STD_API = new Map = { - '@kit.ArkTS': ['taskpool', 'ArkTSUtils'], - '@ohos.process': ['process'] + '@kit.ArkTS': ['taskpool', 'ArkTSUtils', 'process'], + '@ohos.process': ['process'], + '@ohos.taskpool': ['taskpool'] }; diff --git a/ets2panda/linter/test/sdkwhite/GlobalThisError&TypeQuery.ets b/ets2panda/linter/src/lib/utils/consts/Literals.ts similarity index 93% rename from ets2panda/linter/test/sdkwhite/GlobalThisError&TypeQuery.ets rename to ets2panda/linter/src/lib/utils/consts/Literals.ts index 359249a5ec87579dfc3174c7de11190cf45365ab..3ca262e108fa4358f39d2498be4cc3a9e1d0d6a7 100644 --- a/ets2panda/linter/test/sdkwhite/GlobalThisError&TypeQuery.ets +++ b/ets2panda/linter/src/lib/utils/consts/Literals.ts @@ -13,4 +13,4 @@ * limitations under the License. */ -import { worker } from '@kit.ArkTS'; // Error \ No newline at end of file +export const STRING_ERROR_LITERAL = 'ERROR'; diff --git a/ets2panda/linter/test/sdkwhite/SendablePropType.ets b/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts similarity index 85% rename from ets2panda/linter/test/sdkwhite/SendablePropType.ets rename to ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts index 02860a5f306c5b65852b83d314ac3675774bdb01..7705ae690e06280b6bf50db10a3d4116267b6b1b 100644 --- a/ets2panda/linter/test/sdkwhite/SendablePropType.ets +++ b/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts @@ -13,4 +13,4 @@ * limitations under the License. */ -import sendablePhotoAccessHelper from "@ohos.file.sendablePhotoAccessHelper" // Error +export const METHOD_DECLARATION = 'MethodDeclaration'; diff --git a/ets2panda/linter/test/interop/oh_modules/ts_decorator.ts b/ets2panda/linter/src/lib/utils/consts/MethodSignature.ts similarity index 84% rename from ets2panda/linter/test/interop/oh_modules/ts_decorator.ts rename to ets2panda/linter/src/lib/utils/consts/MethodSignature.ts index 511202fa7900b891732d398dd9b5dc206ae8b029..d1a2ad228ec1dfe1eb64abb457565d7f1174a103 100644 --- a/ets2panda/linter/test/interop/oh_modules/ts_decorator.ts +++ b/ets2panda/linter/src/lib/utils/consts/MethodSignature.ts @@ -1,17 +1,16 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export function MyClassDecorator(klass: Object) { } -export function MyClassDecorator2(target: Function) { } \ No newline at end of file +/* + * 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. + */ + +export const METHOD_SIGNATURE = 'MethodSignature'; \ No newline at end of file diff --git a/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts b/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts new file mode 100644 index 0000000000000000000000000000000000000000..a262a88b17d85c6dd1b6c3de028a21f8d71efd3d --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const OPTIONAL_METHOD = 'OptionalMethod'; \ No newline at end of file diff --git a/ets2panda/linter/src/lib/utils/consts/RuntimeCheckAPI.ts b/ets2panda/linter/src/lib/utils/consts/RuntimeCheckAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..48678d03cca2429037046383f7094456b3b0262b --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/RuntimeCheckAPI.ts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type ts from 'typescript'; + +export type ArrayAccess = { + pos: number; + accessingIdentifier: 'number' | ts.Identifier; + arrayIdent: ts.Identifier; +}; + +export type UncheckedIdentifier = ts.Identifier | typeof NUMBER_LITERAL | undefined; +export type CheckedIdentifier = ts.Identifier | typeof NUMBER_LITERAL; + +export const NUMBER_LITERAL = 'number'; + +export enum LoopConditionChecked { + LEFT, + RIGHT, + NOT_CHECKED +} + +export enum CheckResult { + SKIP, + CHECKED +} diff --git a/ets2panda/linter/src/lib/utils/consts/SdkWhitelist.ts b/ets2panda/linter/src/lib/utils/consts/SdkWhitelist.ts index 3c8dd7b5cfb29286cefadc69dbe49456c00a6762..da2140601bdd69c2667b62a94f9a4259704bbcb4 100644 --- a/ets2panda/linter/src/lib/utils/consts/SdkWhitelist.ts +++ b/ets2panda/linter/src/lib/utils/consts/SdkWhitelist.ts @@ -13,18 +13,40 @@ * limitations under the License. */ +export enum SdkProblem { + LimitedVoidType = 'LimitedVoidType', + ConstructorIface = 'ConstructorIface', + LiteralAsPropertyName = 'LiteralAsPropertyName', + OptionalMethod = 'OptionalMethod', + ConstructorFuncs = 'ConstructorFuncs', + IndexedAccessType = 'IndexedAccessType', + SendablePropType = 'SendablePropType', + TypeQuery = 'TypeQuery', + GlobalThisError = 'GlobalThisError', + InterfaceExtendsClass = 'InterfaceExtendsClass', + DeclWithDuplicateName = 'DeclWithDuplicateName', + ComputedPropertyName = 'ComputedPropertyName' +} + +export enum SdkNameInfo { + ParentApiName = 'parent_api_name', + ImportPath = 'import_path' +} + +export const ARKTS_WHITE_API_PATH_TEXTSTYLE = 'component/styled_string.d.ts'; + // Define function argument class export class ApiFuncArg { name: string; type: string; is_optional: boolean; - hasDefault: boolean; + has_default?: boolean; constructor(data: Partial) { this.name = data.name || ''; this.type = data.type || ''; this.is_optional = data.is_optional || false; - this.hasDefault = data.hasDefault || false; + this.has_default = data.has_default || undefined; } } @@ -42,46 +64,49 @@ export class ParentApi { // Define the API information class export class ApiInfo { problem: string; - api_name: string; + api_name?: string; api_type: string; - api_optional: boolean; - api_auto_fix: boolean; - api_auto_fix_context: string; - target_type: string; - api_func_args: ApiFuncArg[]; + api_optional?: boolean; + api_auto_fix?: boolean; + api_auto_fix_context?: string; + api_func_args?: ApiFuncArg[]; parent_api: ParentApi[]; - methd_return_type: string; - codeKind: number; + method_return_type?: string; + api_property_type?: string; + code_kind: number; constructor(data: Partial) { this.problem = data.problem || ''; - this.api_name = data.api_name || ''; + this.api_name = data.api_name || undefined; this.api_type = data.api_type || ''; - this.api_optional = data.api_optional || false; - this.api_auto_fix = data.api_auto_fix || false; - this.api_auto_fix_context = data.api_auto_fix_context || ''; - this.target_type = data.target_type || ''; - this.api_func_args = (data.api_func_args || []).map((arg) => { - return new ApiFuncArg(arg); - }); + this.api_optional = data.api_optional || undefined; + this.api_auto_fix = data.api_auto_fix || undefined; + this.api_auto_fix_context = data.api_auto_fix_context || undefined; + this.api_func_args = + (data.api_func_args || []).map((arg) => { + return new ApiFuncArg(arg); + }) || undefined; this.parent_api = (data.parent_api || []).map((parent) => { return new ParentApi(parent); }); - this.methd_return_type = data.methd_return_type || ''; - this.codeKind = data.codeKind || 0; + this.method_return_type = data.method_return_type || undefined; + this.api_property_type = data.api_property_type || undefined; + this.code_kind = data.code_kind || 0; } } // Define the API list item class export class ApiListItem { import_path: string[]; - file_path: string[]; + file_path: string; api_info: ApiInfo; + is_global: boolean; constructor(data: Partial) { this.import_path = data.import_path || []; - this.file_path = data.file_path || []; + this.file_path = data.file_path || ''; this.api_info = new ApiInfo(data.api_info || {}); + this.is_global = data.is_global || false; } } diff --git a/ets2panda/linter/src/lib/utils/consts/SendableAPI.ts b/ets2panda/linter/src/lib/utils/consts/SendableAPI.ts index e6a6cdae377796c9b749a5c2ea0b5b12b682b1e7..2809e8afab971996abd65819ae3410ec964bb06f 100644 --- a/ets2panda/linter/src/lib/utils/consts/SendableAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/SendableAPI.ts @@ -17,6 +17,8 @@ import * as ts from 'typescript'; export const SENDABLE_DECORATOR = 'Sendable'; export const CONCURRENT_DECORATOR = 'Concurrent'; +export const TASKPOOL = 'taskpool'; +export const ISCONCURRENT = 'isConcurrent'; export const SENDABLE_DECORATOR_NODES = [ ts.SyntaxKind.ClassDeclaration, diff --git a/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts b/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts index 4b1653fb1f7ad4590a8d353992ac339de3bfbb54..a525f8d321ec233034d4c21c2f9e36d4defdac3f 100644 --- a/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts +++ b/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts @@ -20,4 +20,8 @@ export const STRINGLITERAL_INT = 'int'; export const STRINGLITERAL_BYTE = 'byte'; export const STRINGLITERAL_SHORT = 'short'; export const STRINGLITERAL_LONG = 'long'; +export const STRINGLITERAL_CHAR = 'char'; export const STRINGLITERAL_ANY = 'ANY'; +export const STRINGLITERAL_ENUM = 'enum'; +export const STRINGLITERAL_FROM = 'from'; +export const STRINGLITERAL_ARRAY = 'Array'; \ No newline at end of file diff --git a/ets2panda/linter/src/lib/utils/consts/TaskpoolAPI.ts b/ets2panda/linter/src/lib/utils/consts/TaskpoolAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..5414202732da6e0802fdf658b97ca4778b6c198f --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/TaskpoolAPI.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +export const STDLIB_TASKPOOL_OBJECT_NAME = 'taskpool'; +export const STDLIB_TASK_CLASS_NAME = 'Task'; + +export const DEPRECATED_TASKPOOL_METHOD_SETCLONELIST = 'setCloneList'; +export const DEPRECATED_TASKPOOL_METHOD_SETTRANSFERLIST = 'setTransferList'; diff --git a/ets2panda/linter/src/lib/utils/functions/ArrayUtils.ts b/ets2panda/linter/src/lib/utils/functions/ArrayUtils.ts index ffd5a98fa49a49043fce138b223806ea5df67d33..83a75ea2ce972715e81bb15fafd11c0307140639 100644 --- a/ets2panda/linter/src/lib/utils/functions/ArrayUtils.ts +++ b/ets2panda/linter/src/lib/utils/functions/ArrayUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/ets2panda/linter/src/lib/utils/functions/IsStruct.ts b/ets2panda/linter/src/lib/utils/functions/IsStruct.ts index b766931529cd9b5197d1ebe5fae4cc47f7ee37a1..7b450748c14b33b203e25612977ad833e0bdde85 100644 --- a/ets2panda/linter/src/lib/utils/functions/IsStruct.ts +++ b/ets2panda/linter/src/lib/utils/functions/IsStruct.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -14,7 +14,7 @@ */ import type * as ts from 'typescript'; -import { LinterConfig } from '../../TypeScriptLinterConfig'; +import { TypeScriptLinterConfig } from '../../TypeScriptLinterConfig'; export function isStruct(symbol: ts.Symbol): boolean { if (!symbol.declarations) { @@ -29,7 +29,7 @@ export function isStruct(symbol: ts.Symbol): boolean { } export function isStructDeclarationKind(kind: ts.SyntaxKind): boolean { - return LinterConfig.tsSyntaxKindNames[kind] === 'StructDeclaration'; + return TypeScriptLinterConfig.tsSyntaxKindNames[kind] === 'StructDeclaration'; } export function isStructDeclaration(node: ts.Node): boolean { diff --git a/ets2panda/linter/src/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts b/ets2panda/linter/src/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts index 9d38e6e6639d1dfeefa0f6c73778cd09ee3dbb94..453f5f7e9af4f25ad70f3648becbda7234c098c6 100644 --- a/ets2panda/linter/src/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts +++ b/ets2panda/linter/src/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2025 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/ets2panda/linter/src/sdk/linter_1_1/LintParameter.ts b/ets2panda/linter/src/sdk/linter_1_1/LintParameter.ts index ed31ce04a21708028f02fbeffbb622cc51413b8f..f3cdd6f08f870a2a9ce5a9d14d8c6eb9fc936fb6 100644 --- a/ets2panda/linter/src/sdk/linter_1_1/LintParameter.ts +++ b/ets2panda/linter/src/sdk/linter_1_1/LintParameter.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -14,16 +14,15 @@ */ import type * as ts from 'typescript'; -import type { InteropTypescriptLinter } from '../../lib/InteropTypescriptLinter'; -import type { TypeScriptLinter } from '../../lib/TypeScriptLinter'; import type { IncrementalLinterState } from './IncrementalLinter'; +import type { SdkOptions } from './SdkOptions'; export interface LintParameter { incrementalLinterState: IncrementalLinterState; - typeScriptLinter: TypeScriptLinter; - interopTypescriptLinter: InteropTypescriptLinter; tscStrictDiagnostics: Map; diagnostics: ts.Diagnostic[]; etsLoaderPath?: string; tsImportSendableEnable?: boolean; + program: ts.Program; + sdkOptions?: SdkOptions; } diff --git a/ets2panda/linter/src/sdk/linter_1_1/RunArkTSLinter.ts b/ets2panda/linter/src/sdk/linter_1_1/RunArkTSLinter.ts index 2f950ae644a6bedcaa0f9c670f5fe086551d89c2..cb6a206c377ca43f22eb69c24b713364d55d48a9 100644 --- a/ets2panda/linter/src/sdk/linter_1_1/RunArkTSLinter.ts +++ b/ets2panda/linter/src/sdk/linter_1_1/RunArkTSLinter.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -76,18 +76,17 @@ export function runArkTSLinter( timePrinterInstance.appendTime(TimePhase.GET_TSC_DIAGNOSTICS); const etsLoaderPath = program.getCompilerOptions().etsLoaderPath; const tsImportSendableEnable = program.getCompilerOptions().tsImportSendableEnable; - const typeScriptLinter = createTypeScriptLinter(program, tscStrictDiagnostics, sdkOptions); LibraryTypeCallDiagnosticChecker.instance.rebuildTscDiagnostics(tscStrictDiagnostics); - const interopTypescriptLinter = createInteropTypescriptLinter(program, !!sdkOptions?.isUseRtLogic); - processFiles(srcFiles, { + const lintParam: LintParameter = { incrementalLinterState, - typeScriptLinter, - interopTypescriptLinter, tscStrictDiagnostics, diagnostics, etsLoaderPath, - tsImportSendableEnable - }); + tsImportSendableEnable, + program, + sdkOptions + }; + processFiles(srcFiles, lintParam, tscStrictDiagnostics); timePrinterInstance.appendTime(TimePhase.LINT); if (buildInfoWriteFile) { IncrementalLinterState.emitBuildInfo(buildInfoWriteFile, tscDiagnosticsLinter.getBuilderProgram()); @@ -97,14 +96,18 @@ export function runArkTSLinter( return diagnostics; } -function processFiles(srcFiles: ts.SourceFile[], lintParameter: LintParameter): void { +function processFiles( + srcFiles: ts.SourceFile[], + lintParameter: LintParameter, + tscStrictDiagnostics: Map +): void { for (const fileToLint of srcFiles) { const scriptKind = getScriptKind(fileToLint); if (scriptKind !== ts.ScriptKind.ETS && scriptKind !== ts.ScriptKind.TS) { continue; } - const currentDiagnostics = getDiagnostic(fileToLint, scriptKind, lintParameter); + const currentDiagnostics = getDiagnostic(fileToLint, scriptKind, lintParameter, tscStrictDiagnostics); lintParameter.diagnostics.push(...currentDiagnostics); lintParameter.incrementalLinterState.updateDiagnostics(fileToLint, currentDiagnostics); } @@ -113,19 +116,20 @@ function processFiles(srcFiles: ts.SourceFile[], lintParameter: LintParameter): function getDiagnostic( fileToLint: ts.SourceFile, scriptKind: ts.ScriptKind, - lintParameter: LintParameter + lintParameter: LintParameter, + tscStrictDiagnostics: Map ): ts.Diagnostic[] { let currentDiagnostics: ts.Diagnostic[] = []; if (lintParameter.incrementalLinterState.isFileChanged(fileToLint)) { if (scriptKind === ts.ScriptKind.ETS) { - lintParameter.typeScriptLinter.lint(fileToLint); + const typeScriptLinter = createTypeScriptLinter(fileToLint, lintParameter, tscStrictDiagnostics); + typeScriptLinter.lint(); // Get list of bad nodes from the current run. currentDiagnostics = lintParameter.tscStrictDiagnostics.get(path.normalize(fileToLint.fileName)) ?? []; - lintParameter.typeScriptLinter.problemsInfos.forEach((x) => { + typeScriptLinter.problemsInfos.forEach((x) => { return currentDiagnostics.push(translateDiag(fileToLint, x)); }); - lintParameter.typeScriptLinter.problemsInfos.length = 0; } else { if ( path.basename(fileToLint.fileName).toLowerCase(). @@ -145,11 +149,11 @@ function getDiagnostic( return currentDiagnostics; } - lintParameter.interopTypescriptLinter.lint(fileToLint); - lintParameter.interopTypescriptLinter.problemsInfos.forEach((x) => { + const interopTypescriptLinter = createInteropTypescriptLinter(lintParameter.program, fileToLint, lintParameter); + interopTypescriptLinter.lint(); + interopTypescriptLinter.problemsInfos.forEach((x) => { return currentDiagnostics.push(translateDiag(fileToLint, x)); }); - lintParameter.interopTypescriptLinter.problemsInfos.length = 0; } } else { // Get diagnostics from old run. @@ -169,34 +173,38 @@ function getSrcFiles(program: ts.Program, srcFile?: ts.SourceFile): ts.SourceFil } function createTypeScriptLinter( - program: ts.Program, - tscStrictDiagnostics: Map, - sdkOptions?: SdkOptions + sourceFile: ts.SourceFile, + lintParameter: LintParameter, + tscStrictDiagnostics: Map ): TypeScriptLinter { TypeScriptLinter.initGlobals(); return new TypeScriptLinter( - program.getLinterTypeChecker(), + lintParameter.program.getLinterTypeChecker(), { - ideMode: true, - enableAutofix: sdkOptions?.needAutoFix, - useRtLogic: sdkOptions?.isUseRtLogic, - compatibleSdkVersion: program.getCompilerOptions().compatibleSdkVersion, - compatibleSdkVersionStage: program.getCompilerOptions().compatibleSdkVersionStage + enableAutofix: lintParameter.sdkOptions?.needAutoFix, + useRtLogic: lintParameter.sdkOptions?.isUseRtLogic, + compatibleSdkVersion: lintParameter.program.getCompilerOptions().compatibleSdkVersion, + compatibleSdkVersionStage: lintParameter.program.getCompilerOptions().compatibleSdkVersionStage }, + sourceFile, tscStrictDiagnostics ); } -function createInteropTypescriptLinter(program: ts.Program, useRtLogic: boolean): InteropTypescriptLinter { +function createInteropTypescriptLinter( + program: ts.Program, + sourceFile: ts.SourceFile, + lintParameter: LintParameter +): InteropTypescriptLinter { InteropTypescriptLinter.initGlobals(); return new InteropTypescriptLinter( program.getLinterTypeChecker(), program.getCompilerOptions(), { - ideMode: true, - useRtLogic: useRtLogic + etsLoaderPath: lintParameter.etsLoaderPath, + useRtLogic: lintParameter.sdkOptions?.isUseRtLogic }, - program.getCompilerOptions().etsLoaderPath + sourceFile ); } diff --git a/ets2panda/linter/src/testRunner/Consts.ts b/ets2panda/linter/src/testRunner/Consts.ts new file mode 100644 index 0000000000000000000000000000000000000000..cc5c33ea357d553c9eb2ba54a0a34d22602e851b --- /dev/null +++ b/ets2panda/linter/src/testRunner/Consts.ts @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022-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. + */ + +export const TAB = ' '; +export const RESULTS_DIR = 'results'; + +export const DIFF_EXT = '.diff'; +export const TEST_EXTENSION_ETS = '.ets'; +export const TEST_EXTENSION_D_ETS = '.d.ets'; + +export const MIGRATE_RESULT_SUFFIX = '.migrate'; diff --git a/ets2panda/linter/src/testRunner/FileUtil.ts b/ets2panda/linter/src/testRunner/FileUtil.ts new file mode 100644 index 0000000000000000000000000000000000000000..2d21d616d304b76bec728fff6df83151ac331c00 --- /dev/null +++ b/ets2panda/linter/src/testRunner/FileUtil.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as fs from 'node:fs'; + +export function readLines(filePath: string): string[] { + const text = fs.readFileSync(filePath).toString(); + return text.split(/\r\n|\n|\r/); +} diff --git a/ets2panda/linter/src/testRunner/LintTest.ts b/ets2panda/linter/src/testRunner/LintTest.ts new file mode 100644 index 0000000000000000000000000000000000000000..02db53dd4993067c10a6897c7fc08d5b0563dc62 --- /dev/null +++ b/ets2panda/linter/src/testRunner/LintTest.ts @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import type { LinterConfig } from '../lib/LinterConfig'; +import { lint } from '../lib/LinterRunner'; +import { Logger } from '../lib/Logger'; +import { compileLintOptions } from '../lib/ts-compiler/Compiler'; +import type { TestModeProperties } from './TestMode'; +import { TestMode } from './TestMode'; +import { transformProblemInfos } from './TestUtil'; +import type { TestProblemInfo, TestResult } from './TestResult'; +import { validateTestResult } from './TestResult'; +import type { LintRunResult } from '../lib/LintRunResult'; +import { DIFF_EXT, RESULTS_DIR, TAB } from './Consts'; +import type { Autofix } from '../lib/autofixes/Autofixer'; +import type { CreateLintTestOptions } from './TestFactory'; + +export class LintTest { + readonly testDir: string; + readonly testFile: string; + readonly testModeProps: TestModeProperties; + readonly cmdOptions: CommandLineOptions; + + constructor(createLintTestOpts: CreateLintTestOptions) { + this.testDir = createLintTestOpts.testDir; + this.testFile = createLintTestOpts.testFile; + this.testModeProps = createLintTestOpts.testModeProps; + this.cmdOptions = createLintTestOpts.cmdOptions; + } + + run(): boolean { + Logger.info(`Running test ${this.testFile} (${TestMode[this.testModeProps.mode]} mode)`); + + const linterConfig = this.compile(); + const linterResult = lint(linterConfig); + return this.validate(linterResult); + } + + compile(): LinterConfig { + return compileLintOptions(this.cmdOptions); + } + + validate(actualLinterResult: LintRunResult): boolean { + // Get actual test results. + const fileProblems = actualLinterResult.problemsInfos.get(path.normalize(this.cmdOptions.inputFiles[0])); + if (fileProblems === undefined) { + return true; + } + const actualResult = transformProblemInfos(fileProblems, this.testModeProps.mode); + + // Read file with expected test result. + const resultDiff = this.compareLintResult(actualResult); + + // Write file with actual test results. + this.writeLintResultFile(actualResult, resultDiff); + return !resultDiff; + } + + private static readLintResultFile(testDir: string, testResultFileName: string): TestProblemInfo[] { + const filePath = path.join(testDir, testResultFileName); + try { + const testResult = fs.readFileSync(filePath).toString(); + return validateTestResult(JSON.parse(testResult)).result; + } catch (error) { + throw new Error(`Failed to process ${filePath}: ${(error as Error).message}`); + } + } + + private compareLintResult(actual: TestProblemInfo[]): string { + // Read file with expected test result. + let diff: string = ''; + const testResultFileName = this.testFile + this.testModeProps.resultFileExt; + try { + let expected = LintTest.readLintResultFile(this.testDir, testResultFileName); + + /** + * The exclusive field is added to identify whether the use case is exclusive to the RT or SDK + * RT means the RT exclusive + * SDK means the SDK exclusive + * undefined means shared + */ + expected = expected.filter((x) => { + return !x?.exclusive || x.exclusive === (this.cmdOptions.linterOptions.useRtLogic ? 'RT' : 'SDK'); + }); + + if (!expected || expected.length !== actual.length) { + const expectedResultCount = expected ? expected.length : 0; + diff = `Expected count: ${expectedResultCount} vs actual count: ${actual.length}`; + } else { + diff = LintTest.expectedAndActualMatch(expected, actual); + } + + if (diff) { + Logger.info(`${TAB}Lint test failed. Expected and actual results differ:\n${diff}`); + } + } catch (error) { + // Write error message to diff, as non-empty diff indicates that test has failed. + diff = (error as Error).message; + Logger.info(`${TAB}Failed to compare expected and actual results. ` + diff); + } + + return diff; + } + + private static expectedAndActualMatch(expectedNodes: TestProblemInfo[], actualNodes: TestProblemInfo[]): string { + // Compare expected and actual results. + for (let i = 0; i < actualNodes.length; i++) { + const actual = actualNodes[i]; + const expected = expectedNodes[i]; + if (!LintTest.locationMatch(expected, actual) || actual.problem !== expected.problem) { + return LintTest.reportLintResultDiff(expected, actual); + } + if (!LintTest.autofixArraysMatch(expected.autofix, actual.autofix)) { + return LintTest.reportLintResultDiff(expected, actual); + } + if (expected.suggest && actual.suggest !== expected.suggest) { + return LintTest.reportLintResultDiff(expected, actual); + } + if (expected.rule && actual.rule !== expected.rule) { + return LintTest.reportLintResultDiff(expected, actual); + } + if (expected.severity && actual.severity !== expected.severity) { + return LintTest.reportLintResultDiff(expected, actual); + } + } + + return ''; + } + + private static locationMatch(expected: TestProblemInfo, actual: TestProblemInfo): boolean { + return ( + actual.line === expected.line && + actual.column === expected.column && + (!expected.endLine || actual.endLine === expected.endLine) && + (!expected.endColumn || actual.endColumn === expected.endColumn) + ); + } + + private static autofixArraysMatch(expected: Autofix[] | undefined, actual: Autofix[] | undefined): boolean { + if (!expected && !actual) { + return true; + } + if (!(expected && actual) || expected.length !== actual.length) { + return false; + } + for (let i = 0; i < actual.length; ++i) { + if ( + actual[i].start !== expected[i].start || + actual[i].end !== expected[i].end || + actual[i].replacementText !== expected[i].replacementText + ) { + return false; + } + } + return true; + } + + private writeLintResultFile(actual: TestProblemInfo[], diff: string): void { + const actualResultsDir = path.join(this.testDir, RESULTS_DIR); + if (!fs.existsSync(actualResultsDir)) { + fs.mkdirSync(actualResultsDir); + } + + const actualTestResult: TestResult = { result: actual }; + const actualResultJSON = JSON.stringify(actualTestResult, null, 4); + fs.writeFileSync(path.join(actualResultsDir, this.testFile + this.testModeProps.resultFileExt), actualResultJSON); + + if (diff) { + fs.writeFileSync(path.join(actualResultsDir, this.testFile + this.testModeProps.resultFileExt + DIFF_EXT), diff); + } + } + + private static reportLintResultDiff(expected: TestProblemInfo, actual: TestProblemInfo): string { + const expectedNode = JSON.stringify({ nodes: [expected] }, null, 4); + const actualNode = JSON.stringify({ nodes: [actual] }, null, 4); + + const diff = `Expected: +${expectedNode} +Actual: +${actualNode}`; + + return diff; + } +} diff --git a/ets2panda/linter/src/testRunner/MigrateTest.ts b/ets2panda/linter/src/testRunner/MigrateTest.ts new file mode 100644 index 0000000000000000000000000000000000000000..a849e1db74e1a4cf46b88025c37a45501c958119 --- /dev/null +++ b/ets2panda/linter/src/testRunner/MigrateTest.ts @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import type { LinterConfig } from '../lib/LinterConfig'; +import { Logger } from '../lib/Logger'; +import { compileLintOptions } from '../lib/ts-compiler/Compiler'; +import type { LintRunResult } from '../lib/LintRunResult'; +import { DIFF_EXT, MIGRATE_RESULT_SUFFIX, RESULTS_DIR, TAB } from './Consts'; +import { LintTest } from './LintTest'; +import type { CreateLintTestOptions } from './TestFactory'; +import { readLines } from './FileUtil'; + +export class MigrateTest extends LintTest { + constructor(createLintTestOpts: CreateLintTestOptions) { + super(createLintTestOpts); + } + + compile(): LinterConfig { + this.cmdOptions.linterOptions.migratorMode = true; + + // Set filepath mapping to write migration result at 'results' dir instead of modifying original test file + const filePathMap = new Map(); + filePathMap.set( + path.normalize(path.join(this.testDir, this.testFile)), + path.normalize(this.getActualMigrateResultsFilePath()) + ); + this.cmdOptions.linterOptions.migrationFilePathMap = filePathMap; + + return compileLintOptions(this.cmdOptions); + } + + validate(actualLinterResult: LintRunResult): boolean { + const validateBase = super.validate(actualLinterResult); + const validateMigrateResult = this.validateMigrateResult(); + return validateBase && validateMigrateResult; + } + + private validateMigrateResult(): boolean { + this.writeMigrationResultForUnchangedFiles(); + const resultDiff = this.compareMigrateResult(); + if (resultDiff) { + this.writeMigrateDiff(resultDiff); + } + return !resultDiff; + } + + private compareMigrateResult(): string { + let diff: string = ''; + try { + const expectedResult = readFileLines(this.getExpectedMigrateResultsFilePath()); + const actualResult = readFileLines(this.getActualMigrateResultsFilePath()); + + if (expectedResult.length !== actualResult.length) { + diff = `Expected lines: ${expectedResult.length} vs actual lines: ${actualResult.length}`; + } else { + diff = MigrateTest.compareTextLines(expectedResult, actualResult); + } + + if (diff) { + Logger.info(`${TAB}Migration test failed. Expected and actual results differ:\n${diff}`); + } + } catch (error) { + // Write error message to diff, as non-empty diff indicates that test has failed. + diff = (error as Error).message; + Logger.info(`${TAB}Failed to compare expected and actual results. ` + diff); + } + + return diff; + } + + private static compareTextLines(expected: string[], actual: string[]): string { + for (let i = 0; i < expected.length && i < actual.length; i++) { + if (expected[i] !== actual[i]) { + const diff = `Difference at line ${i + 1} +Expected: +${expected[i]} +Actual: +${actual[i]}`; + return diff; + } + } + return ''; + } + + writeMigrateDiff(diff: string): void { + fs.writeFileSync(this.getActualMigrateResultsFilePath() + DIFF_EXT, diff); + } + + writeMigrationResultForUnchangedFiles(): void { + + /* + * If test file doesn't produce any autofix, the migration result won't be created. + * In such case, use original text of the test file as migration result. + */ + const filePathMap = this.cmdOptions.linterOptions.migrationFilePathMap; + if (!filePathMap) { + return; + } + filePathMap.forEach((targetFile, srcFile) => { + if (fs.existsSync(targetFile)) { + return; + } + fs.copyFileSync(srcFile, targetFile); + }); + } + + private getMigrateResultFileName(): string { + return this.testFile + MIGRATE_RESULT_SUFFIX + path.extname(this.testFile); + } + + private getExpectedMigrateResultsFilePath(): string { + return path.join(this.testDir, this.getMigrateResultFileName()); + } + + private getActualMigrateResultsFilePath(): string { + return path.join(this.testDir, RESULTS_DIR, this.getMigrateResultFileName()); + } +} + +function readFileLines(filePath: string): string[] { + try { + return readLines(filePath); + } catch (error) { + throw new Error(`Failed to process ${filePath}: ${(error as Error).message}`); + } +} diff --git a/ets2panda/linter/src/testRunner/RunTestFileOptions.ts b/ets2panda/linter/src/testRunner/RunTestFileOptions.ts new file mode 100644 index 0000000000000000000000000000000000000000..0f894ccaf7446c48629640efbe15b2df01e08b29 --- /dev/null +++ b/ets2panda/linter/src/testRunner/RunTestFileOptions.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { TestRunnerOptions } from './TestRunnerOptions'; + +export interface RunTestFileOptions { + testDir: string; + testFile: string; + testRunnerOpts: TestRunnerOptions; +} diff --git a/ets2panda/linter/src/testRunner/TestArgs.ts b/ets2panda/linter/src/testRunner/TestArgs.ts index d18564e118183d9674aedf2e6ee92ed00a69f3a7..f29c782f7b0f40c848fe2633487ad1fdb432bd61 100644 --- a/ets2panda/linter/src/testRunner/TestArgs.ts +++ b/ets2panda/linter/src/testRunner/TestArgs.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -13,8 +13,11 @@ * limitations under the License. */ +import * as fs from 'node:fs'; +import * as path from 'node:path'; import * as yup from 'yup'; +const ARGS_CONFIG_EXT = '.args.json'; const TAB = ' '; /** @@ -60,6 +63,7 @@ export interface TestArguments { /** * Enables 'migrate' mode, runs test with '--migrate' option. + * Performs code migration and produces new test code. */ migrate?: string; }; @@ -90,3 +94,17 @@ export function validateTestArgs(value: object): TestArguments { throw error; } } + +export function readTestArgsFile(testDir: string, testFile: string): TestArguments | undefined { + const argsFileName = path.join(testDir, testFile + ARGS_CONFIG_EXT); + if (fs.existsSync(argsFileName)) { + try { + const data = fs.readFileSync(argsFileName).toString(); + const json = JSON.parse(data); + return validateTestArgs(json); + } catch (error) { + throw new Error(`Failed to process ${argsFileName}: ${(error as Error).message}`); + } + } + return undefined; +} diff --git a/ets2panda/linter/src/testRunner/TestFactory.ts b/ets2panda/linter/src/testRunner/TestFactory.ts new file mode 100644 index 0000000000000000000000000000000000000000..ef4a2906ab6cac5c4d8f173d897c30f90e1e67a0 --- /dev/null +++ b/ets2panda/linter/src/testRunner/TestFactory.ts @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as path from 'node:path'; +import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import type { LinterOptions } from '../lib/LinterOptions'; +import { LintTest } from './LintTest'; +import type { RunTestFileOptions } from './RunTestFileOptions'; +import { parseCommandLine } from '../cli/CommandLineParser'; +import { getCommandLineArguments } from './CommandLineUtil'; +import type { TestModeProperties } from './TestMode'; +import { DEFAULT_MODE_PROPERTIES, TestMode, testModePropsMap } from './TestMode'; +import type { TestArguments } from './TestArgs'; +import { readTestArgsFile } from './TestArgs'; +import { MigrateTest } from './MigrateTest'; + +interface CreateTestOptions { + runTestFileOpts: RunTestFileOptions; + testModeProps: TestModeProperties; + testModeArgs?: string; + testCommonOpts?: LinterOptions; +} + +export interface CreateLintTestOptions { + testDir: string; + testFile: string; + testModeProps: TestModeProperties; + cmdOptions: CommandLineOptions; +} + +export function createTests(runTestFileOpts: RunTestFileOptions): LintTest[] { + const testArgs = readTestArgsFile(runTestFileOpts.testDir, runTestFileOpts.testFile); + return testArgs ? + createTestsFromTestArgs(runTestFileOpts, testArgs) : + [createTest({ runTestFileOpts, testModeProps: DEFAULT_MODE_PROPERTIES })]; +} + +function createTestsFromTestArgs(runTestFileOpts: RunTestFileOptions, testArgs: TestArguments): LintTest[] { + const tests: LintTest[] = []; + const testCommonOpts = testArgs.commonArgs ? getLinterOptionsFromCommandLine(testArgs.commonArgs) : undefined; + + addDefaultModeIfNeeded(testArgs); + + if (testArgs.mode) { + for (const mode of Object.keys(testArgs.mode)) { + const testModeProps = testModePropsMap.get(mode); + if (!testModeProps) { + throw new Error(`Failed to create test. Unknown mode: '${mode}'`); + } + const testModeArgs: string | undefined = testArgs.mode[mode]; + tests.push(createTest({ runTestFileOpts, testModeProps, testCommonOpts, testModeArgs })); + } + } + + return tests; +} + +function addDefaultModeIfNeeded(testArgs: TestArguments): void { + if (testArgs.mode?.default === undefined) { + // For convenience, always add 'default' mode as first + testArgs.mode = Object.assign({ default: '' }, testArgs.mode); + } +} + +function createTest(createTestOpts: CreateTestOptions): LintTest { + const opts = createCreateLintTestOpts(createTestOpts); + if (createTestOpts.testModeProps.mode === TestMode.MIGRATE) { + return new MigrateTest(opts); + } + return new LintTest(opts); +} + +function createCreateLintTestOpts(createTestConfigOpts: CreateTestOptions): CreateLintTestOptions { + const { runTestFileOpts, testCommonOpts, testModeArgs, testModeProps } = createTestConfigOpts; + const { testDir, testFile, testRunnerOpts } = runTestFileOpts; + + /* + * Test options are formed in the following order (from lowest to highest priority): + * - default test options; + * - [test_args_file] --> 'commonArgs'; + * - [test_args_file] --> the arguments specified for a mode; + * - options specified by TestRunner command-line arguments; + * - options that enable specific mode. + */ + const linterOpts = getDefaultTestOptions(); + if (testCommonOpts) { + Object.assign(linterOpts, testCommonOpts); + } + if (testModeArgs) { + Object.assign(linterOpts, getLinterOptionsFromCommandLine(testModeArgs)); + } + Object.assign(linterOpts, testRunnerOpts.linterOptions); + Object.assign(linterOpts, testModeProps.modeOpts); + + const cmdOptions: CommandLineOptions = { + inputFiles: [path.join(testDir, testFile)], + linterOptions: linterOpts + }; + + return { + testDir, + testFile, + testModeProps, + cmdOptions + }; +} + +function getLinterOptionsFromCommandLine(cmdLine: string): LinterOptions { + return parseCommandLine(getCommandLineArguments(cmdLine), { exitOnFail: false, disableErrorOutput: true }). + linterOptions; +} + +function getDefaultTestOptions(): LinterOptions { + return { + useRtLogic: true, + checkTsAsSource: + true /* By default, treat any test file with '.ts' extension as a source file (as opposed to library) */, + compatibleSdkVersion: 12, + compatibleSdkVersionStage: 'beta3', + checkTsAndJs: true + }; +} diff --git a/ets2panda/linter/src/testRunner/TestMode.ts b/ets2panda/linter/src/testRunner/TestMode.ts new file mode 100644 index 0000000000000000000000000000000000000000..7bec4187e586487de43dcbb7d9cf21aee36e4d52 --- /dev/null +++ b/ets2panda/linter/src/testRunner/TestMode.ts @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { LinterOptions } from '../lib/LinterOptions'; + +export enum TestMode { + DEFAULT, + AUTOFIX, + ARKTS2, + MIGRATE +} + +export interface TestModeProperties { + resultFileExt: string; + mode: TestMode; + modeOpts: LinterOptions; +} + +export const DEFAULT_MODE_PROPERTIES: TestModeProperties = { + resultFileExt: '.json', + mode: TestMode.DEFAULT, + modeOpts: {} +}; +const AUTOFIX_MODE_PROPERTIES: TestModeProperties = { + resultFileExt: '.autofix.json', + mode: TestMode.AUTOFIX, + modeOpts: { + enableAutofix: true + } +}; +const ARKTS2_MODE_PROPERTIES: TestModeProperties = { + resultFileExt: '.arkts2.json', + mode: TestMode.ARKTS2, + modeOpts: { + arkts2: true + } +}; +const MIGRATE_MODE_PROPERTIES: TestModeProperties = { + resultFileExt: '.migrate.json', + mode: TestMode.MIGRATE, + modeOpts: { + migratorMode: true, + noMigrationBackupFile: true + } +}; + +export const testModePropsMap: Map = new Map([ + ['default', DEFAULT_MODE_PROPERTIES], + ['autofix', AUTOFIX_MODE_PROPERTIES], + ['arkts2', ARKTS2_MODE_PROPERTIES], + ['migrate', MIGRATE_MODE_PROPERTIES] +]); diff --git a/ets2panda/linter/src/testRunner/TestResult.ts b/ets2panda/linter/src/testRunner/TestResult.ts index 37e064e22d42cf6d2b091b3a0518b70fd2af6983..d1754cdebab468718d2b101428bbe29f3e767c9b 100644 --- a/ets2panda/linter/src/testRunner/TestResult.ts +++ b/ets2panda/linter/src/testRunner/TestResult.ts @@ -38,7 +38,11 @@ export interface TestProblemInfo { const autofixResultSchema: yup.ObjectSchema = yup.object({ replacementText: yup.string().defined(), start: yup.number().required(), - end: yup.number().required() + end: yup.number().required(), + line: yup.number().optional(), + column: yup.number().optional(), + endLine: yup.number().optional(), + endColumn: yup.number().optional() }); const testResultSchema: yup.ObjectSchema = yup.object({ diff --git a/ets2panda/linter/src/testRunner/TestRunner.ts b/ets2panda/linter/src/testRunner/TestRunner.ts index 62ce4f9d4415e4c642009a3235f3a7af6b25e985..4d3639fb3225a8fe9765d4f8207e96fd82ed8667 100755 --- a/ets2panda/linter/src/testRunner/TestRunner.ts +++ b/ets2panda/linter/src/testRunner/TestRunner.ts @@ -13,118 +13,29 @@ * limitations under the License. */ -import { Logger } from '../lib/Logger'; -import { LoggerImpl } from '../cli/LoggerImpl'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as ts from 'typescript'; -import type { CommandLineOptions } from '../lib/CommandLineOptions'; -import { lint } from '../lib/LinterRunner'; -import { TypeScriptLinter } from '../lib/TypeScriptLinter'; -import { InteropTypescriptLinter } from '../lib/InteropTypescriptLinter'; -import type { Autofix } from '../lib/autofixes/Autofixer'; -import { parseCommandLine as parseLinterCommandLine } from '../cli/CommandLineParser'; -import { compileLintOptions } from '../cli/Compiler'; -import { getEtsLoaderPath } from '../cli/LinterCLI'; -import { ProblemSeverity } from '../lib/ProblemSeverity'; -import type { ProblemInfo } from '../lib/ProblemInfo'; -import type { TestArguments } from './TestArgs'; -import { validateTestArgs } from './TestArgs'; -import type { LinterOptions } from '../lib/LinterOptions'; +import { Logger } from '../lib/Logger'; +import { LoggerImpl } from '../cli/LoggerImpl'; import { Command } from 'commander'; import { rimrafSync } from 'rimraf'; -import type { TestProblemInfo, TestResult } from './TestResult'; -import { validateTestResult } from './TestResult'; import { globSync } from 'glob'; import type { Path } from 'path-scurry'; import { PathScurry } from 'path-scurry'; -import { getCommandLineArguments } from './CommandLineUtil'; +import { createTests } from './TestFactory'; +import type { LintTest } from './LintTest'; +import type { TestRunnerOptions } from './TestRunnerOptions'; +import type { RunTestFileOptions } from './RunTestFileOptions'; +import { MIGRATE_RESULT_SUFFIX, RESULTS_DIR, TAB } from './Consts'; Logger.init(new LoggerImpl()); -const TAB = ' '; -const RESULTS_DIR = 'results'; - -const ARGS_CONFIG_EXT = '.args.json'; -const DIFF_EXT = '.diff'; -const TEST_EXTENSION_ETS = '.ets'; -const TEST_EXTENSION_ETSX = '.etsx'; -const TEST_EXTENSION_D_ETS = '.d.ets'; - interface TestStatistics { passed: number; failed: number; } -enum TestMode { - DEFAULT, - AUTOFIX, - ARKTS2, - MIGRATE -} - -interface CreateTestConfigurationOptions { - runTestFileOpts: RunTestFileOptions; - testModeProps: TestModeProperties; - testModeArgs?: string; - testCommonOpts?: LinterOptions; -} - -interface TestRunnerOptions { - linterOptions: LinterOptions; - testDirs: string[]; - testPattern?: string; -} - -interface RunTestFileOptions { - testDir: string; - testFile: string; - testRunnerOpts: TestRunnerOptions; -} - -interface TestModeProperties { - resultFileExt: string; - mode: TestMode; - modeOpts: LinterOptions; -} - -const DEFAULT_MODE_PROPERTIES: TestModeProperties = { - resultFileExt: '.json', - mode: TestMode.DEFAULT, - modeOpts: {} -}; -const AUTOFIX_MODE_PROPERTIES: TestModeProperties = { - resultFileExt: '.autofix.json', - mode: TestMode.AUTOFIX, - modeOpts: { - enableAutofix: true - } -}; -const ARKTS2_MODE_PROPERTIES: TestModeProperties = { - resultFileExt: '.arkts2.json', - mode: TestMode.ARKTS2, - modeOpts: { - arkts2: true - } -}; - -const MIGRATE_MODE_PROPERTIES: TestModeProperties = { - resultFileExt: '.migrate.json', - mode: TestMode.MIGRATE, - modeOpts: { - arkts2: true, - migratorMode: true, - ideMode: false - } -}; - -interface TestConfiguration { - testDir: string; - testFile: string; - testModeProps: TestModeProperties; - cmdOptions: CommandLineOptions; -} - export function getSdkConfigOptions(configFile: string): ts.CompilerOptions { // initial configuration const options = ts.readConfigFile(configFile, ts.sys.readFile).config.compilerOptions; @@ -219,12 +130,12 @@ function runTests(): boolean { collectTestFilesWithGlob(testDir, testRunnerOpts.testPattern) : fs.readdirSync(testDir); testFiles = testFiles.filter((x) => { + const file = x.trimEnd(); return ( - x.trimEnd().endsWith(ts.Extension.Ts) && !x.trimEnd().endsWith(ts.Extension.Dts) || - x.trimEnd().endsWith(ts.Extension.Tsx) || - x.trimEnd().endsWith(ts.Extension.Ets) || - x.trimEnd().endsWith(TEST_EXTENSION_ETS) && !x.trimEnd().endsWith(TEST_EXTENSION_D_ETS) || - x.trimEnd().endsWith(TEST_EXTENSION_ETSX) + (file.endsWith(ts.Extension.Ts) && !file.endsWith(ts.Extension.Dts) || + file.endsWith(ts.Extension.Tsx) || + file.endsWith(ts.Extension.Ets)) && + !file.endsWith(MIGRATE_RESULT_SUFFIX + path.extname(file)) ); }); runTestFiles(testFiles, testDir, testRunnerOpts, testStats); @@ -264,41 +175,10 @@ function runTestFiles( } function runTestFile(runTestFileOpts: RunTestFileOptions, testStats: TestStatistics): void { - const testConfigs: TestConfiguration[] = []; - - const testArgs = processTestArgsFile(runTestFileOpts.testDir, runTestFileOpts.testFile); - if (testArgs) { - const testCommonOpts = testArgs.commonArgs ? getLinterOptionsFromCommandLine(testArgs.commonArgs) : undefined; - addTestConfiguration(testConfigs, { - runTestFileOpts, - testModeProps: DEFAULT_MODE_PROPERTIES, - testModeArgs: testArgs.mode?.default, - testCommonOpts - }); - addTestConfiguration(testConfigs, { - runTestFileOpts, - testModeProps: AUTOFIX_MODE_PROPERTIES, - testModeArgs: testArgs.mode?.autofix, - testCommonOpts - }); - addTestConfiguration(testConfigs, { - runTestFileOpts, - testModeProps: ARKTS2_MODE_PROPERTIES, - testModeArgs: testArgs.mode?.arkts2, - testCommonOpts - }); - addTestConfiguration(testConfigs, { - runTestFileOpts, - testModeProps: MIGRATE_MODE_PROPERTIES, - testModeArgs: testArgs.mode?.migrate, - testCommonOpts - }); - } else { - addTestConfiguration(testConfigs, { runTestFileOpts, testModeProps: DEFAULT_MODE_PROPERTIES }); - } + const tests: LintTest[] = createTests(runTestFileOpts); - testConfigs.forEach((config: TestConfiguration) => { - if (runTest(config)) { + tests.forEach((test: LintTest) => { + if (test.run()) { ++testStats.passed; } else { ++testStats.failed; @@ -306,259 +186,4 @@ function runTestFile(runTestFileOpts: RunTestFileOptions, testStats: TestStatist }); } -function processTestArgsFile(testDir: string, testFile: string): TestArguments | undefined { - const argsFileName = path.join(testDir, testFile + ARGS_CONFIG_EXT); - if (fs.existsSync(argsFileName)) { - try { - const data = fs.readFileSync(argsFileName).toString(); - const json = JSON.parse(data); - return validateTestArgs(json); - } catch (error) { - throw new Error(`Failed to process ${argsFileName}: ${(error as Error).message}`); - } - } - return undefined; -} - -function addTestConfiguration( - testConfigs: TestConfiguration[], - createTestConfigOpts: CreateTestConfigurationOptions -): void { - const { runTestFileOpts, testModeProps, testModeArgs, testCommonOpts } = createTestConfigOpts; - const { testDir, testFile, testRunnerOpts } = runTestFileOpts; - - if (testModeArgs === undefined && testModeProps.mode !== TestMode.DEFAULT) { - return; - } - - /* - * Test options are formed in the following order (from lowest to highest priority): - * - default test options; - * - [test_args_file] --> 'commonArgs'; - * - [test_args_file] --> the arguments specified for a mode; - * - options specified by TestRunner command-line arguments; - * - options that enable specific mode. - */ - const linterOpts = getDefaultTestOptions(); - if (testCommonOpts) { - Object.assign(linterOpts, testCommonOpts); - } - if (testModeArgs) { - Object.assign(linterOpts, getLinterOptionsFromCommandLine(testModeArgs)); - } - Object.assign(linterOpts, testRunnerOpts.linterOptions); - Object.assign(linterOpts, testModeProps.modeOpts); - - const cmdOptions: CommandLineOptions = { - inputFiles: [path.join(testDir, testFile)], - linterOptions: linterOpts - }; - - testConfigs.push({ - testDir, - testFile, - testModeProps, - cmdOptions - }); -} - -function getDefaultTestOptions(): LinterOptions { - - /* - * Set the IDE mode manually to enable storing information - * about found bad nodes and also disable the log output. - */ - return { - ideMode: true, - useRtLogic: true, - checkTsAsSource: true /* Currently, tests have '.ts' extension, therefore, enable this flag by default */, - compatibleSdkVersion: 12, - compatibleSdkVersionStage: 'beta3' - }; -} - -function getLinterOptionsFromCommandLine(cmdLine: string): LinterOptions { - return parseLinterCommandLine(getCommandLineArguments(cmdLine), { exitOnFail: false, disableErrorOutput: true }). - linterOptions; -} - -function runTest(testConfig: TestConfiguration): boolean { - Logger.info(`Running test ${testConfig.testFile} (${TestMode[testConfig.testModeProps.mode]} mode)`); - - TypeScriptLinter.initGlobals(); - InteropTypescriptLinter.initGlobals(); - - const linterConfig = compileLintOptions(testConfig.cmdOptions); - const linterResult = lint(linterConfig, getEtsLoaderPath(linterConfig)); - - // Get actual test results. - const fileProblems = linterResult.problemsInfos.get(path.normalize(testConfig.cmdOptions.inputFiles[0])); - if (fileProblems === undefined) { - return true; - } - const actualResult = transformProblemInfos(fileProblems, testConfig.testModeProps.mode); - - // Read file with expected test result. - const resultDiff = compareExpectedAndActual(testConfig, actualResult); - - // Write file with actual test results. - writeActualResultFile(testConfig, actualResult, resultDiff); - - return !resultDiff; -} - -function readTestResultFile(testDir: string, testResultFileName: string): TestProblemInfo[] { - const filePath = path.join(testDir, testResultFileName); - try { - const testResult = fs.readFileSync(filePath).toString(); - return validateTestResult(JSON.parse(testResult)).result; - } catch (error) { - throw new Error(`Failed to process ${filePath}: ${(error as Error).message}`); - } -} - -function transformProblemInfos(fileProblems: ProblemInfo[], mode: TestMode): TestProblemInfo[] { - return fileProblems.map((x) => { - return { - line: x.line, - column: x.column, - endLine: x.endLine, - endColumn: x.endColumn, - problem: x.problem, - autofix: mode === TestMode.AUTOFIX ? x.autofix : undefined, - suggest: x.suggest, - rule: x.rule, - severity: ProblemSeverity[x.severity] - }; - }); -} - -function compareExpectedAndActual(testConfig: TestConfiguration, actual: TestProblemInfo[]): string { - const { - testDir, - testFile, - cmdOptions: { linterOptions }, - testModeProps: { resultFileExt } - } = testConfig; - - // Read file with expected test result. - let diff: string = ''; - const testResultFileName = testFile + resultFileExt; - try { - let expected = readTestResultFile(testDir, testResultFileName); - - /** - * The exclusive field is added to identify whether the use case is exclusive to the RT or SDK - * RT means the RT exclusive - * SDK means the SDK exclusive - * undefined means shared - */ - expected = expected.filter((x) => { - return !x?.exclusive || x.exclusive === (linterOptions.useRtLogic ? 'RT' : 'SDK'); - }); - - if (!expected || expected.length !== actual.length) { - const expectedResultCount = expected ? expected.length : 0; - diff = `Expected count: ${expectedResultCount} vs actual count: ${actual.length}`; - Logger.info(`${TAB}${diff}`); - } else { - diff = expectedAndActualMatch(expected, actual); - } - - if (diff) { - Logger.info(`${TAB}Test failed. Expected and actual results differ.`); - } - } catch (error) { - // Write error message to diff, as non-empty diff indicates that test has failed. - diff = (error as Error).message; - Logger.info(`${TAB}Failed to compare expected and actual results. ` + diff); - } - - return diff; -} - -function expectedAndActualMatch(expectedNodes: TestProblemInfo[], actualNodes: TestProblemInfo[]): string { - // Compare expected and actual results. - for (let i = 0; i < actualNodes.length; i++) { - const actual = actualNodes[i]; - const expect = expectedNodes[i]; - if (!locationMatch(expect, actual) || actual.problem !== expect.problem) { - return reportDiff(expect, actual); - } - if (!autofixArraysMatch(expect.autofix, actual.autofix)) { - return reportDiff(expect, actual); - } - if (expect.suggest && actual.suggest !== expect.suggest) { - return reportDiff(expect, actual); - } - if (expect.rule && actual.rule !== expect.rule) { - return reportDiff(expect, actual); - } - if (expect.severity && actual.severity !== expect.severity) { - return reportDiff(expect, actual); - } - } - - return ''; -} - -function locationMatch(expected: TestProblemInfo, actual: TestProblemInfo): boolean { - return ( - actual.line === expected.line && - actual.column === expected.column && - (!expected.endLine || actual.endLine === expected.endLine) && - (!expected.endColumn || actual.endColumn === expected.endColumn) - ); -} - -function autofixArraysMatch(expected: Autofix[] | undefined, actual: Autofix[] | undefined): boolean { - if (!expected && !actual) { - return true; - } - if (!(expected && actual) || expected.length !== actual.length) { - return false; - } - for (let i = 0; i < actual.length; ++i) { - if ( - actual[i].start !== expected[i].start || - actual[i].end !== expected[i].end || - actual[i].replacementText !== expected[i].replacementText - ) { - return false; - } - } - return true; -} - -function writeActualResultFile(testConfig: TestConfiguration, actual: TestProblemInfo[], diff: string): void { - const { - testModeProps: { resultFileExt } - } = testConfig; - const actualResultsDir = path.join(testConfig.testDir, RESULTS_DIR); - if (!fs.existsSync(actualResultsDir)) { - fs.mkdirSync(actualResultsDir); - } - - const actualTestResult: TestResult = { result: actual }; - const actualResultJSON = JSON.stringify(actualTestResult, null, 4); - fs.writeFileSync(path.join(actualResultsDir, testConfig.testFile + resultFileExt), actualResultJSON); - - if (diff) { - fs.writeFileSync(path.join(actualResultsDir, testConfig.testFile + resultFileExt + DIFF_EXT), diff); - } -} - -function reportDiff(expected: TestProblemInfo, actual: TestProblemInfo): string { - const expectedNode = JSON.stringify({ nodes: [expected] }, null, 4); - const actualNode = JSON.stringify({ nodes: [actual] }, null, 4); - - const diff = `Expected: -${expectedNode} -Actual: -${actualNode}`; - - Logger.info(diff); - return diff; -} - runTests(); diff --git a/ets2panda/linter/src/testRunner/TestRunnerOptions.ts b/ets2panda/linter/src/testRunner/TestRunnerOptions.ts new file mode 100644 index 0000000000000000000000000000000000000000..bae4b12fd87ef3762f772b2c49ade58ae4867f70 --- /dev/null +++ b/ets2panda/linter/src/testRunner/TestRunnerOptions.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { LinterOptions } from '../lib/LinterOptions'; + +export interface TestRunnerOptions { + linterOptions: LinterOptions; + testDirs: string[]; + testPattern?: string; +} diff --git a/ets2panda/linter/src/lib/utils/consts/WhiteListProblemType.ts b/ets2panda/linter/src/testRunner/TestUtil.ts similarity index 47% rename from ets2panda/linter/src/lib/utils/consts/WhiteListProblemType.ts rename to ets2panda/linter/src/testRunner/TestUtil.ts index 084fa5f156450c24b2918b77d4f8b4753a3a0f47..aab666fef07b4789e1735762d2193b221b1f2fed 100644 --- a/ets2panda/linter/src/lib/utils/consts/WhiteListProblemType.ts +++ b/ets2panda/linter/src/testRunner/TestUtil.ts @@ -13,19 +13,23 @@ * limitations under the License. */ -export enum SdkProblem { - LimitedVoidType = 'LimitedVoidType', - ConstructorIface = 'ConstructorIface', - LiteralAsPropertyName = 'LiteralAsPropertyName', - OptionalMethod = 'OptionalMethod', - ConstructorFuncs = 'ConstructorFuncs', - IndexedAccessType = 'IndexedAccessType', - SendablePropType = 'SendablePropType', - TypeQuery = 'TypeQuery', - GlobalThisError = 'GlobalThisError', - InterfaceExtendsClass = 'InterfaceExtendsClass', - DeclWithDuplicateName = 'DeclWithDuplicateName', - ComputedPropertyName = 'ComputedPropertyName' -} +import type { ProblemInfo } from '../lib/ProblemInfo'; +import { ProblemSeverity } from '../lib/ProblemSeverity'; +import { TestMode } from './TestMode'; +import type { TestProblemInfo } from './TestResult'; -export const ARKTS_WHITE_API_PATH_TEXTSTYLE = 'component/styled_string.d.ts'; +export function transformProblemInfos(fileProblems: ProblemInfo[], mode: TestMode): TestProblemInfo[] { + return fileProblems.map((x) => { + return { + line: x.line, + column: x.column, + endLine: x.endLine, + endColumn: x.endColumn, + problem: x.problem, + autofix: mode === TestMode.AUTOFIX ? x.autofix : undefined, + suggest: x.suggest, + rule: x.rule, + severity: ProblemSeverity[x.severity] + }; + }); +} diff --git a/ets2panda/linter/test/builtin/builtin_callsignature.ets b/ets2panda/linter/test/builtin/builtin_callsignature.ets new file mode 100644 index 0000000000000000000000000000000000000000..ccb7f4de952f3bc32e079f785565ea9e8f313d9f --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_callsignature.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024-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. + */ + +function createArray(ctor: ArrayConstructor) { // ERROR + return ctor(1, 2, 3); // ERROR +} +function createArrayDirect() { + return Array(1, 2, 3) +} + +function createBigInt(ctor: BigIntConstructor) { // ERROR + return ctor(1); // ERROR +} +function createBigIntDirect() { + return BigInt(1); +} + +function anotherName(ctorName0: BigIntConstructor) { // ERROR + ctorName0(1); // ERROR + const ctorName1 = ctorName0 + const rs1 = ctorName1(1); // ERROR + type BigIntConstructor1 = BigIntConstructor; // ERROR + let ctorName2:BigIntConstructor1 = ctorName1 // ERROR + const rs2 = ctorName2(1); // ERROR +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/ConstructorIface4.ets.args.json b/ets2panda/linter/test/builtin/builtin_callsignature.ets.args.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/ConstructorIface4.ets.args.json rename to ets2panda/linter/test/builtin/builtin_callsignature.ets.args.json diff --git a/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..82638906838c1734e3d4c539b65ac8ad583f7425 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json @@ -0,0 +1,118 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 16, + "column": 28, + "endLine": 16, + "endColumn": 44, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 14, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 29, + "endLine": 23, + "endColumn": 46, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 14, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 33, + "endLine": 30, + "endColumn": 50, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 12, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 24, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 29, + "endLine": 34, + "endColumn": 46, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 17, + "endLine": 35, + "endColumn": 35, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 15, + "endLine": 36, + "endColumn": 24, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.json b/ets2panda/linter/test/builtin/builtin_callsignature.ets.json similarity index 100% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.json rename to ets2panda/linter/test/builtin/builtin_callsignature.ets.json diff --git a/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets new file mode 100644 index 0000000000000000000000000000000000000000..bbcf905f52086774901aaaf5935b292117222037 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets @@ -0,0 +1,61 @@ +/* + * 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. + */ + +function f(a: PropertyDescriptor) { + a.configurable; + a.enumerable; + a.value; + a.writable; + a.get; + a.set; +} + +let desc: TypedPropertyDescriptor = { + value:1, + get():number {return this.value}, + set(v): void {this.value = v}, + enumerable: false, + configurable: false, + writable: true +} + +type MyPropertyDescriptor = PropertyDescriptor; +type MyTypedPropertyDescriptor = TypedPropertyDescriptor; + +function f(a: MyPropertyDescriptor) { + a.configurable; + a.enumerable; + a.value; + a.writable; + a.get; + a.set; +} + +let desc: MyTypedPropertyDescriptor = { + value: 1, + get(): number { return this.value; }, + set(v): void {this.value = v}, + enumerable: false, + configurable: false, + writable: true +}; + +interface APropertyDescriptor {} +interface PropertyDescriptorA {} +interface PropertyDescriptor {} + +let a1: APropertyDescriptor = {} +let a2: PropertyDescriptorA = {} +let a3: PropertyDescriptor = {} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.args.json b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/function_expression.ts.json b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.arkts2.json similarity index 31% rename from ets2panda/linter/test/migrate/function_expression.ts.json rename to ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.arkts2.json index cd0c60aca76683778d948101f392bacba88dffbd..1903c3e2db6fab4db83853f6b6de1ccf22dac0ae 100644 --- a/ets2panda/linter/test/migrate/function_expression.ts.json +++ b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2022-2024 Huawei Device Co., Ltd.", + "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", @@ -16,332 +16,292 @@ "result": [ { "line": 16, - "column": 15, - "endLine": 16, - "endColumn": 29, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 18, - "endLine": 20, + "column": 1, + "endLine": 23, "endColumn": 2, - "problem": "FunctionExpression", + "problem": "TsOverload", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" }, { - "line": 18, - "column": 39, - "endLine": 18, - "endColumn": 40, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 10, - "endLine": 25, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 16, + "column": 12, + "endLine": 16, + "endColumn": 13, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 28, - "column": 17, - "endLine": 30, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 16, + "column": 15, + "endLine": 16, + "endColumn": 33, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 32, + "line": 17, "column": 2, - "endLine": 34, - "endColumn": 2, - "problem": "FunctionExpression", + "endLine": 17, + "endColumn": 3, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 36, - "column": 7, - "endLine": 38, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 26, - "endLine": 43, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 3, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 44, - "column": 27, - "endLine": 46, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 3, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 48, - "column": 22, - "endLine": 50, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 3, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 48, - "column": 22, - "endLine": 50, - "endColumn": 2, - "problem": "LimitedReturnTypeInference", + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 3, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 48, - "column": 35, - "endLine": 48, - "endColumn": 38, - "problem": "AnyType", + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 3, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 52, - "column": 19, - "endLine": 54, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 9, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 52, - "column": 19, - "endLine": 54, - "endColumn": 2, - "problem": "GeneratorFunction", + "line": 25, + "column": 11, + "endLine": 25, + "endColumn": 34, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Generator functions are not supported (arkts-no-generators)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 53, + "line": 27, "column": 3, - "endLine": 53, - "endColumn": 10, - "problem": "YieldExpression", + "endLine": 27, + "endColumn": 35, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Generator functions are not supported (arkts-no-generators)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 56, - "column": 17, - "endLine": 58, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 28, + "column": 3, + "endLine": 28, + "endColumn": 32, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 60, - "column": 18, - "endLine": 62, + "line": 37, + "column": 1, + "endLine": 44, "endColumn": 2, - "problem": "FunctionExpression", + "problem": "TsOverload", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" }, { - "line": 64, - "column": 19, - "endLine": 66, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 13, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 71, - "column": 25, - "endLine": 76, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 6, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 78, - "column": 12, - "endLine": 80, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 6, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 82, + "line": 40, "column": 5, - "endLine": 84, - "endColumn": 5, - "problem": "AnyType", + "endLine": 40, + "endColumn": 6, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 82, - "column": 19, - "endLine": 84, - "endColumn": 5, - "problem": "PropertyAccessByIndex", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 6, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 82, - "column": 19, - "endLine": 84, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 42, + "column": 5, + "endLine": 42, + "endColumn": 6, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 86, - "column": 6, - "endLine": 88, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 43, + "column": 5, + "endLine": 43, + "endColumn": 6, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 91, - "column": 9, - "endLine": 93, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 9, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 96, - "column": 25, - "endLine": 98, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 41, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 102, - "column": 9, - "endLine": 104, - "endColumn": 17, - "problem": "AnyType", + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 34, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 104, - "column": 7, - "endLine": 104, - "endColumn": 17, - "problem": "FunctionBind", - "suggest": "", - "rule": "'Function.bind' is not supported (arkts-no-func-bind)", - "severity": "WARNING" - }, - { - "line": 102, - "column": 15, - "endLine": 104, - "endColumn": 6, - "problem": "FunctionExpression", + "line": 57, + "column": 11, + "endLine": 57, + "endColumn": 29, + "problem": "InvalidIdentifier", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" }, { - "line": 108, - "column": 16, - "endLine": 108, - "endColumn": 55, - "problem": "FunctionExpression", + "line": 57, + "column": 1, + "endLine": 57, + "endColumn": 32, + "problem": "InterfaceMerging", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Declaration merging is not supported (arkts-no-decl-merging)", "severity": "ERROR" }, { - "line": 109, - "column": 24, - "endLine": 109, - "endColumn": 75, - "problem": "FunctionExpression", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 7, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 112, - "column": 5, - "endLine": 112, - "endColumn": 45, - "problem": "FunctionExpression", + "line": 61, + "column": 9, + "endLine": 61, + "endColumn": 27, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { - "line": 113, - "column": 10, - "endLine": 113, - "endColumn": 50, - "problem": "FunctionExpression", + "line": 61, + "column": 30, + "endLine": 61, + "endColumn": 31, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.json b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..53088745400793978e1891873f56604fa1470ae9 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.json @@ -0,0 +1,38 @@ +{ + "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": 57, + "column": 1, + "endLine": 57, + "endColumn": 32, + "problem": "InterfaceMerging", + "suggest": "", + "rule": "Declaration merging is not supported (arkts-no-decl-merging)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 30, + "endLine": 61, + "endColumn": 31, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets new file mode 100755 index 0000000000000000000000000000000000000000..331af9c7c152be315a62ab0e0062787ff2d29f1c --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets @@ -0,0 +1,18 @@ +/* + * 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. + */ + +class MyClass {} +const myClass = new MyClass(); +Object.getOwnPropertyNames(a); diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.args.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..6958168fef2a70000342107f7d5f2b5805c14fae --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..699eba3d8526bc0607ed09da4e67988ec9896a5e --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.arkts2.json @@ -0,0 +1,28 @@ +{ + "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": 1, + "endLine": 18, + "endColumn": 27, + "problem": "BuiltinGetOwnPropertyNames", + "suggest": "", + "rule": "Using \"Object.getOwnPropertyNames\" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.autofix.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..f2aa6d9af0353f48106c09ea44013acdd4ace123 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.autofix.json @@ -0,0 +1,35 @@ +{ + "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": 1, + "endLine": 18, + "endColumn": 27, + "problem": "BuiltinGetOwnPropertyNames", + "autofix": [ + { + "start": 653, + "end": 679, + "replacementText": "Object.keys" + } + ], + "suggest": "", + "rule": "Using \"Object.getOwnPropertyNames\" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/api_path_changed.ets.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/api_path_changed.ets.json rename to ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.json diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.ets b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..eecf3e8f2af7c95151171fbd66405c3c2588ecef --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.ets @@ -0,0 +1,18 @@ +/* + * 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. + */ + +class MyClass {} +const myClass = new MyClass(); +Object.keys(a); diff --git a/ets2panda/linter/test/interop/ts_decorator.ets.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/interop/ts_decorator.ets.json rename to ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.json diff --git a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets new file mode 100755 index 0000000000000000000000000000000000000000..2b2843d8b18aa41a7d8b21e83cf6b7cf51a755de --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets @@ -0,0 +1,20 @@ +/* + * 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. + */ + +let map: Map = new Map(); +let iterFromReflect = Reflect.get(map, Symbol.iterator); +let iterFromProp = map[Symbol.iterator](); + +let symbolIter = Symbol.iterator; diff --git a/ets2panda/linter/test/interop/no_js_await.ets.args.json b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.args.json similarity index 100% rename from ets2panda/linter/test/interop/no_js_await.ets.args.json rename to ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.args.json diff --git a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..36254158540286646fc21063b6b306396f132eb7 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 40, + "endLine": 17, + "endColumn": 55, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 20, + "endLine": 18, + "endColumn": 40, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 24, + "endLine": 18, + "endColumn": 39, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 18, + "endLine": 20, + "endColumn": 33, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..8af4f78669b31c787e4cd40ae005aff560769df3 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_thisArgs.ets b/ets2panda/linter/test/builtin/builtin_thisArgs.ets new file mode 100755 index 0000000000000000000000000000000000000000..2a73669055134cc6b5b85d4c122a6da9a8e27bfb --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.ets @@ -0,0 +1,31 @@ +/* + * 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. + */ + +Class MyClass { + base: number; + constructor(base: number) { + this.base = base; + } + compare((value: number, index:number, arr: Array)) { + return value < this.base + } +} + +let arr: Array = new Array(1, 2, 3); +let a = new MyClass(2); +let b = new MyClass(3); +arr.filter(a.compare, a); +arr.filter(a.compare); +arr.filter(a.compare, b); \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/api_path_changed.ets.args.json b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.args.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/api_path_changed.ets.args.json rename to ets2panda/linter/test/builtin/builtin_thisArgs.ets.args.json diff --git a/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..937b8aef5ee8b2d2f9113c13c5d489145ea28cd6 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json @@ -0,0 +1,118 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 21, + "column": 11, + "endLine": 21, + "endColumn": 60, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 13, + "endLine": 27, + "endColumn": 20, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 13, + "endLine": 28, + "endColumn": 20, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 25, + "problem": "BuiltinThisArgs", + "suggest": "", + "rule": "Using thisArgs as a type is not allowed in this API (arkts-builtin-thisArgs)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 1, + "endLine": 31, + "endColumn": 25, + "problem": "BuiltinThisArgs", + "suggest": "", + "rule": "Using thisArgs as a type is not allowed in this API (arkts-builtin-thisArgs)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 1, + "endLine": 31, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_thisArgs.ets.json b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..132dc5e988043d737f194d6ab97afc52cf5e6429 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.json @@ -0,0 +1,48 @@ +{ + "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": 21, + "column": 11, + "endLine": 21, + "endColumn": 60, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets similarity index 87% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets rename to ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets index a51746c471d5f265702e081fc3ed0bee48498f92..91b0af14666257a5ce36d9dcd94ef1242c8ec5f1 100644 --- a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * 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 @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' @Concurrent // ERROR function func() {} @@ -24,4 +25,4 @@ let n18: a2 = 10; type funtType1 = () => void @Concurrent -type funtType2 = () => void | number \ No newline at end of file +type funtType2 = () => void | number diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.args.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.args.json similarity index 92% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.args.json rename to ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.args.json index 4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100644 --- a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.args.json +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json similarity index 64% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.arkts2.json rename to ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json index 7989c221a587bdfcc77a4964e54d2efbb666c684..a392b58e6916b7f1c713e54314a1f43d02d4763e 100644 --- a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json @@ -15,49 +15,49 @@ ], "result": [ { - "line": 16, + "line": 17, "column": 1, - "endLine": 16, + "endLine": 17, "endColumn": 12, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoDoncurrentDecorator", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", "severity": "ERROR" }, { - "line": 19, + "line": 20, "column": 1, - "endLine": 19, + "endLine": 20, "endColumn": 12, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoDoncurrentDecorator", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", "severity": "ERROR" }, { - "line": 23, + "line": 24, "column": 1, - "endLine": 23, + "endLine": 24, "endColumn": 12, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoDoncurrentDecorator", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", "severity": "ERROR" }, { - "line": 26, + "line": 27, "column": 1, - "endLine": 26, + "endLine": 27, "endColumn": 12, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoDoncurrentDecorator", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", "severity": "ERROR" }, { - "line": 27, + "line": 28, "column": 24, - "endLine": 27, + "endLine": 28, "endColumn": 28, "problem": "LimitedVoidType", "suggest": "", @@ -65,4 +65,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.autofix.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.autofix.json similarity index 64% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.autofix.json rename to ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.autofix.json index 586af08091a666076edf1d128202fcb3597ba635..3a526714e45c4e0615ea0d437830a3d900eac89e 100644 --- a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.autofix.json @@ -15,77 +15,77 @@ ], "result": [ { - "line": 16, + "line": 17, "column": 1, - "endLine": 16, + "endLine": 17, "endColumn": 12, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoDoncurrentDecorator", "autofix": [ { - "start": 610, - "end": 621, + "start": 618, + "end": 629, "replacementText": "" } ], "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", "severity": "ERROR" }, { - "line": 19, + "line": 20, "column": 1, - "endLine": 19, + "endLine": 20, "endColumn": 12, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoDoncurrentDecorator", "autofix": [ { - "start": 651, - "end": 662, + "start": 659, + "end": 670, "replacementText": "" } ], "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", "severity": "ERROR" }, { - "line": 23, + "line": 24, "column": 1, - "endLine": 23, + "endLine": 24, "endColumn": 12, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoDoncurrentDecorator", "autofix": [ { - "start": 699, - "end": 710, + "start": 707, + "end": 718, "replacementText": "" } ], "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", "severity": "ERROR" }, { - "line": 26, + "line": 27, "column": 1, - "endLine": 26, + "endLine": 27, "endColumn": 12, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoDoncurrentDecorator", "autofix": [ { - "start": 740, - "end": 751, + "start": 748, + "end": 759, "replacementText": "" } ], "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", "severity": "ERROR" }, { - "line": 27, + "line": 28, "column": 24, - "endLine": 27, + "endLine": 28, "endColumn": 28, "problem": "LimitedVoidType", "suggest": "", @@ -93,4 +93,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.json similarity index 100% rename from ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets.json rename to ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.json diff --git a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.ets b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6364fb63ab8824f66cde1cd3ed8fb21b0057c794 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ +'use static' + + // ERROR +function func() {} + + +type a2 = number +let n18: a2 = 10; + + +type funtType1 = () => void + + +type funtType2 = () => void | number diff --git a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..1dde4c017ff67ea59646f54c9659df8ebbe66411 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 28, + "column": 24, + "endLine": 28, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets new file mode 100644 index 0000000000000000000000000000000000000000..d3e0b2ca58ad6fde6ac4d5ba2e1d5e38bafd84a0 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024-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. + */ + +let typeName: SharedArrayBuffer; // ERROR +let sab: SharedArrayBuffer = new SharedArrayBuffer(0) // 2 ERROR + +type NewTypeName = SharedArrayBuffer // ERROR +let newTypeName: NewTypeName +// disable use new NewTypeName() +let ntn: NewTypeName = new SharedArrayBuffer(0) // ERROR + +function foo(atmo: Atomics) {} // NOT ERROR \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.args.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..4914a0e04a5e8b68080870d071e75a4b4e158639 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.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": 16, + "column": 15, + "endLine": 16, + "endColumn": 32, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 27, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 34, + "endLine": 17, + "endColumn": 51, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 20, + "endLine": 19, + "endColumn": 37, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 28, + "endLine": 22, + "endColumn": 45, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..da0b259374868118fedbdc520d2e21a9ac29ba80 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json @@ -0,0 +1,103 @@ +{ + "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": 15, + "endLine": 16, + "endColumn": 32, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 624, + "end": 641 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 27, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 661, + "end": 678 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 34, + "endLine": 17, + "endColumn": 51, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 685, + "end": 702 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 20, + "endLine": 19, + "endColumn": 37, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 737, + "end": 754 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 28, + "endLine": 22, + "endColumn": 45, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 853, + "end": 870 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/sdkwhite/constructor_types_deprecated_sdk.ets.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.json old mode 100755 new mode 100644 similarity index 100% rename from ets2panda/linter/test/sdkwhite/constructor_types_deprecated_sdk.ets.json rename to ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.json diff --git a/ets2panda/test/parser/ets/user_defined_1.ets b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets similarity index 68% rename from ets2panda/test/parser/ets/user_defined_1.ets rename to ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets index 14809fc3b1fc9f0862660f712be0b7a84c749bf5..6eaad40c1a5ffbe1fc2f9504cccec7da44362ec9 100644 --- a/ets2panda/test/parser/ets/user_defined_1.ets +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets @@ -13,12 +13,12 @@ * limitations under the License. */ -function main() { - let float : boolean = false; - let double : boolean = false; - let byte : boolean = false; - let short : boolean = false; - let int : boolean = false; - let char : boolean = false; +let typeName: ArrayBuffer; // ERROR +let sab: ArrayBuffer = new ArrayBuffer(0) // 2 ERROR -} +type NewTypeName = ArrayBuffer // ERROR +let newTypeName: NewTypeName +// disable use new NewTypeName() +let ntn: NewTypeName = new ArrayBuffer(0) // ERROR + +function foo(atmo: Atomics) {} // NOT ERROR \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..43cb4a27bcc78710d4aa5130c22ee053f66c3fbc --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json @@ -0,0 +1,3 @@ +{ + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets new file mode 100644 index 0000000000000000000000000000000000000000..40c096babbf596df9d09e3532d3f9035f2bfc0d8 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { taskpool } from '../main/oh_modules/@kit.ArkTS' +import { taskpool as tp } from '../main/oh_modules/@ohos.taskpool' +import { taskpool as kp } from '@some.module' + +@Concurrent +function test() { } + +let result: Boolean = taskpool.isConcurrent(test); + +let result2: Boolean = tp.isConcurrent(test); + +let result3: Boolean = kp.isConcurrent(test); + +let result4: Boolean = taskpool.foo(test); + +class testObject { + isConcurrent(): string { + return "Test"; + } +}; + +const result: string = testObject.isConcurrent(); diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.args.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..e2b903f0aa82e6ca4108ff67d5272bf49d6c2a5b --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca28292f8e4d54b3a473114b5d2238f3fa55c03f --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 23, + "column": 32, + "endLine": 23, + "endColumn": 44, + "problem": "IsConcurrentDeprecated", + "suggest": "", + "rule": "isConcurrent is not supported (arkts-limited-stdlib-no-support-isConcurrent)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 39, + "problem": "IsConcurrentDeprecated", + "suggest": "", + "rule": "isConcurrent is not supported (arkts-limited-stdlib-no-support-isConcurrent)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..b9331d05ba1f182a8a451c219c9e51bcd4e67188 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] + } \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets new file mode 100644 index 0000000000000000000000000000000000000000..22ef20b645ce008ca5ad7b59f5a35eed82cac0c0 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets @@ -0,0 +1,41 @@ +/* + * 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. + */ + +"use shared" +export function sharedFunction() {} + +function concurrentFunc() { + "use concurrent" +} + +function normal() {} + +normal('use concurrent'); + +const variable = 'use concurrent'; + +switch (variable) { + case 'use concurrent: + break; +} + +normal('use shared'); + +const variable2 = 'use shared'; + +switch (variable2) { + case 'use shared': + break; +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.args.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..6958168fef2a70000342107f7d5f2b5805c14fae --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.arkts2.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..0a82914a53a6b965b052de59bd9d4bfe1d740554 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.arkts2.json @@ -0,0 +1,48 @@ +{ + "copyright": [ + "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 13, + "problem": "UseSharedDeprecated", + "suggest": "", + "rule": "\"use shared\" is not supported (arkts-limited-stdlib-no-use-shared)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 17, + "endLine": 17, + "endColumn": 31, + "problem": "SharedModuleExports", + "suggest": "", + "rule": "Only \"Sendable\" entities can be exported in shared module (arkts-shared-module-exports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 21, + "problem": "UseConcurrentDeprecated", + "suggest": "", + "rule": "\"use concurrent\" is not supported (arkts-limited-stdlib-no-use-concurrent)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.autofix.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..052fc5f382c68d4ab6c6584c022fc23f840cb135 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.autofix.json @@ -0,0 +1,62 @@ +{ + "copyright": [ + "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 13, + "problem": "UseSharedDeprecated", + "autofix": [ + { + "start": 605, + "end": 617, + "replacementText": "" + } + ], + "suggest": "", + "rule": "\"use shared\" is not supported (arkts-limited-stdlib-no-use-shared)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 17, + "endLine": 17, + "endColumn": 31, + "problem": "SharedModuleExports", + "suggest": "", + "rule": "Only \"Sendable\" entities can be exported in shared module (arkts-shared-module-exports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 21, + "problem": "UseConcurrentDeprecated", + "autofix": [ + { + "start": 687, + "end": 703, + "replacementText": "" + } + ], + "suggest": "", + "rule": "\"use concurrent\" is not supported (arkts-limited-stdlib-no-use-concurrent)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..443a9bc21b1895e83165cb1648e9e101f1d11877 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.json @@ -0,0 +1,28 @@ +{ + "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": 17, + "endLine": 17, + "endColumn": 31, + "problem": "SharedModuleExports", + "suggest": "", + "rule": "Only \"Sendable\" entities can be exported in shared module (arkts-shared-module-exports)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.ets b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5224e3b79f6ce4d369dcfc9ebaa26a63bc1b9219 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.ets @@ -0,0 +1,41 @@ +/* + * 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. + */ + + +export function sharedFunction() {} + +function concurrentFunc() { + +} + +function normal() {} + +normal('use concurrent'); + +const variable = 'use concurrent'; + +switch (variable) { + case 'use concurrent: + break; +} + +normal('use shared'); + +const variable2 = 'use shared'; + +switch (variable2) { + case 'use shared': + break; +} diff --git a/ets2panda/linter/test/main/data_observation_1.ets.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/main/data_observation_1.ets.json rename to ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.json diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json index 64b4d19108275fee4616415887ca594e048b5b95..3318ebbbcfd0ce90dc5f69df69452a3201e4204d 100755 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json index b47ee3c9b53a9c245da5ee06e388666acb08490c..cf8ab0e5ee0d29567a66579c525bfcff6284988e 100755 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 49, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 14, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 14, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 14, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 14, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json index 895325b061c0fe9fa6b75bab6ed4259b5343c199..39d941b73fa9f5a260bd97728a1c4e292919e08a 100755 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json @@ -14,5 +14,142 @@ "limitations under the License." ], "result": [ + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 49, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 617, + "end": 665, + "replacementText": "" + }, + { + "start": 665, + "end": 665, + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./binary_operation_js_obj_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 674, + "end": 679, + "replacementText": "foo.getPropertyByName(\"a\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('a').toNumber()", + "start": 674, + "end": 679 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 688, + "end": 693, + "replacementText": "foo.getPropertyByName(\"b\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('b').toNumber()", + "start": 688, + "end": 693 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 5, + "problem": "ExponentOp", + "autofix": [ + { + "replacementText": "Math.pow(a, b)", + "start": 724, + "end": 730 + } + ], + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets similarity index 70% rename from ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets rename to ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets index ea2407ae1b20524691bed56a3282a85bec918c02..b8312ed47e269fe6e0cab7bd8dc9b4497db4bdf1 100644 --- a/ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets @@ -1,32 +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. - */ - -const styleMap: ProgressStyleMap = { - 1: { // Error - strokeWidth: 1, - }, - 2: { // Error - strokeWidth: 1, - }, - 3: { // Error - strokeWidth: 1, - }, - 4: { // Error - strokeWidth: 1, - }, - 0: { // Error - - } -}; +/* + * 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. + */ +'use static' +let GeneratedImportVar_1 = ESObject.load('./binary_operation_js_obj_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); + +let a = foo.getPropertyByName("a") +let b = foo.getPropertyByName("b") +a + b +a - b +a * b +a / b +a % b +Math.pow(a, b) \ No newline at end of file diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..2d5cf16415581dd7948488a6b9d733264bb45774 --- /dev/null +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.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": 16, + "column": 5, + "endLine": 16, + "endColumn": 73, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 15, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_function.ets.arkts2.json b/ets2panda/linter/test/interop/call_function.ets.arkts2.json index 64199c1b99086c60efbf0f714f3a5031fbfc2bff..7ab8a8de0ec9c79ca03a6256077c43dbcdeabacc 100644 --- a/ets2panda/linter/test/interop/call_function.ets.arkts2.json +++ b/ets2panda/linter/test/interop/call_function.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 43, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -39,9 +39,9 @@ "column": 1, "endLine": 18, "endColumn": 6, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -51,17 +51,7 @@ "endColumn": 6, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 1, - "endLine": 18, - "endColumn": 6, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -69,9 +59,9 @@ "column": 1, "endLine": 19, "endColumn": 9, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -81,17 +71,7 @@ "endColumn": 9, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 1, - "endLine": 19, - "endColumn": 9, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/call_object_methods.ets b/ets2panda/linter/test/interop/call_object_methods.ets index f1aeeec2f2e5f7caf39f31fd83fcbb1213c15826..ee45f2bcf310af18a40e73daac122f063494253f 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets +++ b/ets2panda/linter/test/interop/call_object_methods.ets @@ -1,19 +1,19 @@ -/* - * 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. - */ -'use static' -import { foo } from "./call_object_methods_js" - -foo.bar(123) - +/* + * 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. + */ +'use static' +import { foo } from "./call_object_methods_js" + +foo.bar(123) + diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.args.json b/ets2panda/linter/test/interop/call_object_methods.ets.args.json index 70f3351f7e1b5d85779d95122bc450939d493cfd..b023016d6bc3b2713d4e02b6f765940828db476b 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.args.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix":"--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json b/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json index c80f4a095babb9dbeabb070268e927e330aa2fe0..db5e5b5f975b37094e186a4cd0156697d9175b7d 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 47, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -39,19 +39,9 @@ "column": 1, "endLine": 18, "endColumn": 13, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 1, - "endLine": 18, - "endColumn": 13, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -61,7 +51,7 @@ "endColumn": 13, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json b/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json index 75701bd0cf6dd9d8640c41bbc206eeb875cd0fe9..5831cf051021f917ffd4bae670b8366c6b275fd1 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json @@ -1,4 +1,3 @@ - { "copyright": [ "Copyright (c) 2025 Huawei Device Co., Ltd.", @@ -33,18 +32,18 @@ "problem": "InterOpImportJs", "autofix": [ { - "start": 632, - "end": 678, + "start": 617, + "end": 663, "replacementText": "" }, { - "start": 678, - "end": 678, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./call_object_methods_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');" + "start": 663, + "end": 663, + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./call_object_methods_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -52,19 +51,9 @@ "column": 1, "endLine": 18, "endColumn": 13, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 1, - "endLine": 18, - "endColumn": 13, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -74,7 +63,7 @@ "endColumn": 13, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..68b5f0fb6ec187e516f776f78c8b881cd2f57741 --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ +'use static' +let GeneratedImportVar_1 = ESObject.load('./call_object_methods_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); + + +foo.bar(123) + diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..eb6c6ba8e76491e7e89b0bf9c4a41b19de74bc7e --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 69, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ignore_files/unique_types.ts b/ets2panda/linter/test/interop/ignore_files/unique_types.ts index 795b8bd6655adfc2ac301ec07ef5d5b7f83c245d..1c19752b632c2db52b8a99eee6213add566520d7 100644 --- a/ets2panda/linter/test/interop/ignore_files/unique_types.ts +++ b/ets2panda/linter/test/interop/ignore_files/unique_types.ts @@ -30,5 +30,7 @@ export let mixedEnumType: X; export let intersectionType: SomeType & X; export let templateLiteralType: TemplateLiteralType; -export function tsFunction() {}; +export function tsFunction() { + throw 123; +}; export let stringType: string; diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.args.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.args.json index 64b4d19108275fee4616415887ca594e048b5b95..3318ebbbcfd0ce90dc5f69df69452a3201e4204d 100755 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.args.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.args.json @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json index 7b34fd236b7e05a9191af9818e4e0ff610b6f78c..188523c143f3ab493bb3b4f0265a1bdce075661f 100755 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 52, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 14, "problem": "InteropIncrementDecrement", "suggest": "", - "rule": "Interop objects can't be incremented or decremented (arkts-no-js-obj-increases-decreases)", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 12, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 12, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 14, "problem": "InteropIncrementDecrement", "suggest": "", - "rule": "Interop objects can't be incremented or decremented (arkts-no-js-obj-increases-decreases)", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 14, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 14, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 14, "problem": "InteropIncrementDecrement", "suggest": "", - "rule": "Interop objects can't be incremented or decremented (arkts-no-js-obj-increases-decreases)", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 12, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 12, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 14, "problem": "InteropIncrementDecrement", "suggest": "", - "rule": "Interop objects can't be incremented or decremented (arkts-no-js-obj-increases-decreases)", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 14, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -191,7 +191,7 @@ "endColumn": 14, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json index 895325b061c0fe9fa6b75bab6ed4259b5343c199..4afb86a9323ee3ef2733e4dce39c5631a4cf024d 100755 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json @@ -14,5 +14,253 @@ "limitations under the License." ], "result": [ + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 52, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 617, + "end": 668, + "replacementText": "" + }, + { + "start": 668, + "end": 668, + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./increases_decreases_js_obj_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 690, + "end": 697, + "replacementText": "foo.getPropertyByName(\"num\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 690, + "end": 697 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 706, + "end": 713, + "replacementText": "foo.getPropertyByName(\"num\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 706, + "end": 713 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 718, + "end": 725, + "replacementText": "foo.getPropertyByName(\"num\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 718, + "end": 725 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 734, + "end": 741, + "replacementText": "foo.getPropertyByName(\"num\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 734, + "end": 741 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6abfb3b85cda23d6f198d736c9508551ecedb40d --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ +'use static' +let GeneratedImportVar_1 = ESObject.load('./increases_decreases_js_obj_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); + +let a: number =0 +a = foo.getPropertyByName("num")++ +a = ++foo.getPropertyByName("num") +a = foo.getPropertyByName("num")-- +a = --foo.getPropertyByName("num") diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..3cbe2b5da335c01a2bbfb1dcf277bfe1681fcbc7 --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 76, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.args.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.args.json index e237d4be2874381852a10b15e933b0991b8016b6..06cb3b904659ffe15c21fcd31bec1c4209becfe2 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.args.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json index ed6c8b7f73bcb70bd7f0b5bba5ac5bf5777a7db1..20dfb7a06a067f6e23a2c32e5c1ba8138c621478 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 51, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 13, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 17, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 17, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 15, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 11, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 16, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 23, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json index d426879406f2c8dc11055e7108c274ce26dfbb26..a71b9e42ad902ca36566fbc2bfa5a3c1638941d0 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json @@ -39,11 +39,11 @@ { "start": 668, "end": 668, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./instantiated_js_obj_js');\nlet Foo = GeneratedImportVar_1.getPropertyByName('Foo');\nlet Foo1 = GeneratedImportVar_1.getPropertyByName('Foo1');" + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./instantiated_js_obj_js');\nlet Foo = GeneratedImportVar_1.getPropertyByName('Foo');\nlet Foo1 = GeneratedImportVar_1.getPropertyByName('Foo1');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -60,7 +60,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -77,7 +77,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -94,7 +94,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -128,7 +128,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -145,7 +145,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -162,7 +162,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3baba970a3a84124533b3ff37a6b09dfd8a566bd --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets @@ -0,0 +1,36 @@ +/* + * 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. + */ + +'use static' +let GeneratedImportVar_1 = ESObject.load('./instantiated_js_obj_js'); +let Foo = GeneratedImportVar_1.getPropertyByName('Foo'); +let Foo1 = GeneratedImportVar_1.getPropertyByName('Foo1'); + +class A { + num: number = 1; + constructor() { + } +} +Foo.instantiate(ESObject.wrap(123)) +Foo.instantiate(ESObject.wrap('hello')) +Foo.instantiate(ESObject.wrap(new A())) +let a: A = new A(); +Foo.instantiate(ESObject.wrap(a.num)) +Foo.instantiate(ESObject.wrap(a)) +function test(): number { + return 1; +} +Foo.instantiate(ESObject.wrap(test())) +Foo1.instantiate(ESObject.wrap(123), ESObject.wrap('hello')) \ No newline at end of file diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..bb4772469b1dd697d47aeb3159530442609ad076 --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json @@ -0,0 +1,48 @@ +{ + "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": 69, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets b/ets2panda/linter/test/interop/interop_convert_import.ets index 15717d92ccca208661f26c1c21221667618fa9cc..296d7bb3ed6204c3e6836a9274e9afd1ad8dffe1 100755 --- a/ets2panda/linter/test/interop/interop_convert_import.ets +++ b/ets2panda/linter/test/interop/interop_convert_import.ets @@ -14,6 +14,9 @@ */ 'use static' - import {foo} from "./interop_convert_import_js.js" + import {foo, foo2, foo3, foo4} from "./interop_convert_import_js.js" - let a: number = foo.num as number \ No newline at end of file + let a: number = foo.num as number + let a: boolean = foo2.bool as boolean + let a: string = foo3.str as string + let a: bigint = foo4.big as bigint" \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json b/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json index 038f42ab255a844b2b29ee1c223aea0f2094e928..ffc1d767e80fd403f30da3fb8a254b5eef434a61 100755 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json @@ -18,7 +18,7 @@ "line": 17, "column": 2, "endLine": 17, - "endColumn": 52, + "endColumn": 70, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", @@ -28,10 +28,10 @@ "line": 17, "column": 2, "endLine": 17, - "endColumn": 52, + "endColumn": 70, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 35, "problem": "InterOpConvertImport", "suggest": "", - "rule": "Casting interop JS objects to \"number\" type is not allowed (arkts-no-js-number-import)", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", "severity": "ERROR" }, { @@ -61,7 +61,127 @@ "endColumn": 25, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, + "endLine": 20, + "endColumn": 40, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, + "endLine": 20, + "endColumn": 28, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, + "endLine": 20, + "endColumn": 28, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, + "endLine": 20, + "endColumn": 28, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 18, + "endLine": 21, + "endColumn": 37, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 18, + "endLine": 21, + "endColumn": 26, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 18, + "endLine": 21, + "endColumn": 26, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 18, + "endLine": 21, + "endColumn": 26, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 37, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 26, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 26, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 26, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.json b/ets2panda/linter/test/interop/interop_convert_import.ets.json index a543d164167059495e267880429e168a0123f81d..1d059f0d382adbf11dac846f30473a60ba3985a2 100755 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.json @@ -18,7 +18,7 @@ "line": 17, "column": 2, "endLine": 17, - "endColumn": 52, + "endColumn": 70, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", diff --git a/ets2panda/linter/test/interop/interop_convert_import_js.js b/ets2panda/linter/test/interop/interop_convert_import_js.js index 16cbaf6cf80397b20205827afe07e72fb3b736a7..f3895baaa7f2e4cf2d75b9c4ecfc5a1c50879481 100755 --- a/ets2panda/linter/test/interop/interop_convert_import_js.js +++ b/ets2panda/linter/test/interop/interop_convert_import_js.js @@ -13,4 +13,7 @@ * limitations under the License. */ -export let foo = {name: 123} \ No newline at end of file +export let foo = {name: 123} +export let foo2 = {bool: true} +export let foo3 = {str: '123'} +export let foo4 = {big: 123n} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.args.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.args.json index a2c0f14eb2d79969407309c83200850554d409d3..ef3938e967322a0c7551d84c7b6d280de94144c8 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.args.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json index 5f133df9b955cc6a581cd31b56e9d16634422ad6..916e1b51ca421151b76bc22d2ee1aa9b32f60213 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 52, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 7, "problem": "InteropEqualityJudgment", "suggest": "", - "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-js-equality-judgment)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 7, "problem": "InteropEqualityJudgment", "suggest": "", - "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-js-equality-judgment)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 8, "problem": "InteropEqualityJudgment", "suggest": "", - "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-js-equality-judgment)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 8, "problem": "InteropEqualityJudgment", "suggest": "", - "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-js-equality-judgment)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json index cbfed6ea9e907c294ed0d04e413bd9c3e3f71b36..9c6a9f3e3157abecbaa3c562d1777b0aac24a1f1 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json @@ -39,11 +39,11 @@ { "start": 669, "end": 669, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_equality_judgment_js');\nlet a = GeneratedImportVar_1.getPropertyByName('a');\nlet b = GeneratedImportVar_1.getPropertyByName('b');" + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_equality_judgment_js');\nlet a = GeneratedImportVar_1.getPropertyByName('a');\nlet b = GeneratedImportVar_1.getPropertyByName('b');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -60,7 +60,7 @@ } ], "suggest": "", - "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-js-equality-judgment)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" }, { @@ -77,7 +77,7 @@ } ], "suggest": "", - "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-js-equality-judgment)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" }, { @@ -94,7 +94,7 @@ } ], "suggest": "", - "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-js-equality-judgment)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ } ], "suggest": "", - "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-js-equality-judgment)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..50a1b8457ac0eebf8bbde78aaffa49985affc818 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +'use static' +let GeneratedImportVar_1 = ESObject.load('./interop_equality_judgment_js'); +let a = GeneratedImportVar_1.getPropertyByName('a'); +let b = GeneratedImportVar_1.getPropertyByName('b'); + +a.areEqual(b) +!a.areEqual(b) +a.areStrictlyEqual(b) +!a.areStrictlyEqual(b) \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..543f81469d9239369a6e95092f0cf13270314eae --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json @@ -0,0 +1,48 @@ +{ + "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": 75, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets b/ets2panda/linter/test/interop/interop_export_js_rules.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c9355e6c8b262dadd4a3da48bfcb5c7c4b631a7 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ +'use static' + +import { ff1 } from "./interop_import_js_rules_js" + +export {ff1} // imported from js. Error is shown + +export { ff2 } from "./interop_import_js_rules_js" // ff2 is imported from js. Error is shown + +export { MyDecorator } from "./oh_modules/ets_decorator" // MyDecorator is imported from arkts1. Error is shown + +export { foo as bar } from "./oh_modules/reflect_export" // foo is imported from arkts1.2. No error. diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.args.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..6958168fef2a70000342107f7d5f2b5805c14fae --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.arkts2.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8aafb129daa0d9e56a4e5f754740dc1c83957296 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.arkts2.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 13, + "problem": "InteropJsObjectExport", + "suggest": "", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 51, + "problem": "InteropJsObjectExport", + "suggest": "", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 57, + "problem": "InteropArkTs1ObjectExport", + "suggest": "", + "rule": "Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.autofix.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..58c2313941355575e380c540f740b590f10c5723 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.autofix.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 618, + "end": 668, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51 + }, + { + "start": 668, + "end": 668, + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_import_js_rules_js');\nlet ff1 = GeneratedImportVar_1.getPropertyByName('ff1');\n", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 13, + "problem": "InteropJsObjectExport", + "suggest": "", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 51, + "problem": "InteropJsObjectExport", + "suggest": "", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 57, + "problem": "InteropArkTs1ObjectExport", + "suggest": "", + "rule": "Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..91f5b61ed193b5db1f2d82123a53ba9fe017a31c --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.json @@ -0,0 +1,28 @@ +{ + "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": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.ets b/ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..ad8d86948bece0717323ce0a50f0afe3820ac6aa --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.ets @@ -0,0 +1,27 @@ +/* + * 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. + */ +'use static' + +let GeneratedImportVar_1 = ESObject.load('./interop_import_js_rules_js'); +let ff1 = GeneratedImportVar_1.getPropertyByName('ff1'); + + +export {ff1} // imported from js. Error is shown + +export { ff2 } from "./interop_import_js_rules_js" // ff2 is imported from js. Error is shown + +export { MyDecorator } from "./oh_modules/ets_decorator" // MyDecorator is imported from arkts1. Error is shown + +export { foo as bar } from "./oh_modules/reflect_export" // foo is imported from arkts1.2. No error. diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..1291e15d5ef455b1073fb6db7bb313b74c2f232e --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 73, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "InteropJsObjectExport", + "suggest": "", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 57, + "problem": "InteropArkTs1ObjectExport", + "suggest": "", + "rule": "Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.args.json b/ets2panda/linter/test/interop/interop_import_js.ets.args.json index 815373beb6e083ba357c4eb952ab7bc777bdade6..df6e67a5c9292c4c7e7aa5e976a3b8d1104fa082 100755 --- a/ets2panda/linter/test/interop/interop_import_js.ets.args.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json index d8a70abf600a25f7418ad5e6a902e322594b5069..17f26fd8dcbe4b296c8ad46a6dbf16de2323964d 100755 --- a/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 38, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 38, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 64, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 44, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 57, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 53, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 59, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json index f1de093cb7ccf7865ff3dfca68a960c9913076e9..947b0ed85ee44445966768577e0e4cbe2756915a 100755 --- a/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json @@ -39,11 +39,11 @@ { "start": 971, "end": 971, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('../main/js_lib');\nlet Cjs = GeneratedImportVar_1.getPropertyByName('Cjs');" + "replacementText": "let GeneratedImportVar_1 = ESObject.load('../main/js_lib');\nlet Cjs = GeneratedImportVar_1.getPropertyByName('Cjs');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -71,11 +71,11 @@ { "start": 971, "end": 971, - "replacementText": "let GeneratedImportVar_2 = ESObject.load('../main/js_lib');\nlet fjs = GeneratedImportVar_2.getPropertyByName('fjs');" + "replacementText": "let GeneratedImportVar_2 = ESObject.load('../main/js_lib');\nlet fjs = GeneratedImportVar_2.getPropertyByName('fjs');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -103,11 +103,11 @@ { "start": 971, "end": 971, - "replacementText": "let GeneratedImportVar_3 = ESObject.load('./jsfiles/preview_import_js');\nlet CPreview = GeneratedImportVar_3.getPropertyByName('CPreview');\nlet bar = GeneratedImportVar_3.getPropertyByName('bar');\nlet foo = GeneratedImportVar_3.getPropertyByName('foo');" + "replacementText": "let GeneratedImportVar_3 = ESObject.load('./jsfiles/preview_import_js');\nlet CPreview = GeneratedImportVar_3.getPropertyByName('CPreview');\nlet bar = GeneratedImportVar_3.getPropertyByName('bar');\nlet foo = GeneratedImportVar_3.getPropertyByName('foo');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -135,11 +135,11 @@ { "start": 971, "end": 971, - "replacementText": "let GeneratedImportVar_4 = ESObject.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_4.getPropertyByName('aaa');" + "replacementText": "let GeneratedImportVar_4 = ESObject.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_4.getPropertyByName('aaa');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -167,11 +167,11 @@ { "start": 971, "end": 971, - "replacementText": "let GeneratedImportVar_5 = ESObject.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_5.getPropertyByName('aaa');\nlet ClassA = GeneratedImportVar_5.getPropertyByName('ClassA');\nlet Dog = GeneratedImportVar_5.getPropertyByName('Dog');" + "replacementText": "let GeneratedImportVar_5 = ESObject.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_5.getPropertyByName('aaa');\nlet ClassA = GeneratedImportVar_5.getPropertyByName('ClassA');\nlet Dog = GeneratedImportVar_5.getPropertyByName('Dog');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -199,11 +199,11 @@ { "start": 971, "end": 971, - "replacementText": "let GeneratedImportVar_6 = ESObject.load('./interop_import_js_js');" + "replacementText": "let GeneratedImportVar_6 = ESObject.load('./interop_import_js_js');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -231,11 +231,11 @@ { "start": 971, "end": 971, - "replacementText": "let GeneratedImportVar_7 = ESObject.load('./interop_import_js_js');\nlet Wiki = GeneratedImportVar_7.getPropertyByName('Wiki');\nlet Doge = GeneratedImportVar_7.getPropertyByName('Dog');" + "replacementText": "let GeneratedImportVar_7 = ESObject.load('./interop_import_js_js');\nlet Wiki = GeneratedImportVar_7.getPropertyByName('Wiki');\nlet Doge = GeneratedImportVar_7.getPropertyByName('Dog');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..fb72fa188216462a9e6d92325927aa9fd925021d --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets @@ -0,0 +1,40 @@ +/* + * 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. + */ + +'use static' + + + + + + +let GeneratedImportVar_7 = ESObject.load('./interop_import_js_js'); +let Wiki = GeneratedImportVar_7.getPropertyByName('Wiki'); +let Doge = GeneratedImportVar_7.getPropertyByName('Dog'); +let GeneratedImportVar_6 = ESObject.load('./interop_import_js_js'); +let GeneratedImportVar_5 = ESObject.load('./interop_import_js_js'); +let myAaa = GeneratedImportVar_5.getPropertyByName('aaa'); +let ClassA = GeneratedImportVar_5.getPropertyByName('ClassA'); +let Dog = GeneratedImportVar_5.getPropertyByName('Dog'); +let GeneratedImportVar_4 = ESObject.load('./interop_import_js_js'); +let myAaa = GeneratedImportVar_4.getPropertyByName('aaa'); +let GeneratedImportVar_3 = ESObject.load('./jsfiles/preview_import_js'); +let CPreview = GeneratedImportVar_3.getPropertyByName('CPreview'); +let bar = GeneratedImportVar_3.getPropertyByName('bar'); +let foo = GeneratedImportVar_3.getPropertyByName('foo'); +let GeneratedImportVar_2 = ESObject.load('../main/js_lib'); +let fjs = GeneratedImportVar_2.getPropertyByName('fjs'); +let GeneratedImportVar_1 = ESObject.load('../main/js_lib'); +let Cjs = GeneratedImportVar_1.getPropertyByName('Cjs'); diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c1173895c427bbbe366e24b9412139837b44971c --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json @@ -0,0 +1,198 @@ +{ + "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": 23, + "column": 5, + "endLine": 23, + "endColumn": 67, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 67, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 67, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 62, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 67, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 72, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 5, + "endLine": 37, + "endColumn": 59, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 59, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets b/ets2panda/linter/test/interop/interop_import_js_compare.ets index 7b719e70d0927230a0376e9ae03da3317bb80514..496fe91c554cc5de1e7fafcb58c00041a11234a9 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets @@ -39,4 +39,6 @@ let x2 = bar.a, y2 = bar.b; x2 > y2; x2 < y2; x2 >= y2; -x2 <= y2; \ No newline at end of file +x2 <= y2; + +foo.a > foo.b; \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.arkts2.json index db1438446cb5e744b78440a2f302cfbfba97f797..083e145c479c1f2226dcfe5ac02503f6b50970de 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 57, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 14, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 14, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 14, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 14, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 2, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 6, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 2, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 6, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -141,7 +141,7 @@ "endColumn": 2, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 7, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 2, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -171,17 +171,7 @@ "endColumn": 7, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 1, - "endLine": 25, - "endColumn": 2, - "problem": "InterOpImportJsDataCompare", - "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -191,7 +181,7 @@ "endColumn": 2, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -201,17 +191,7 @@ "endColumn": 6, "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 1, - "endLine": 28, - "endColumn": 2, - "problem": "InterOpImportJsDataCompare", - "suggest": "", - "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-js-data-compare)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -263,6 +243,86 @@ "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" + }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 9, + "endLine": 44, + "endColumn": 14, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 6, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 6, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 9, + "endLine": 44, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 9, + "endLine": 44, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 9, + "endLine": 44, + "endColumn": 14, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.args.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.args.json index 6bbb5430dd3c73817760cbf163629bfe6cc6002f..fb061d2224432ee084a838573999bd32414cad57 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.args.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.arkts2.json index c8e9598d333c16cb8830eebf2f42fa395f2902b7..8049b299332196ac2e744813b9281aab97d25fc5 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 49, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 18, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 18, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -69,9 +69,9 @@ "column": 1, "endLine": 19, "endColumn": 7, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectTraverseJsInstance", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 7, "problem": "InterOpImportJsIndex", "suggest": "", - "rule": "Interop objects can't be indexed directly (arkts-no-js-index-import)", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", "severity": "ERROR" }, { @@ -89,9 +89,9 @@ "column": 1, "endLine": 20, "endColumn": 7, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectTraverseJsInstance", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 11, "problem": "InterOpImportJsIndex", "suggest": "", - "rule": "Interop objects can't be indexed directly (arkts-no-js-index-import)", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json index 9e8c533fc24701e702adc10caebad2e7140dc168..7b4806fa65d8cc800a8efdb074903ce9fd3d7e6d 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json @@ -39,11 +39,11 @@ { "start": 667, "end": 667, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_import_js_index_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');" + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_import_js_index_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -60,7 +60,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -87,7 +87,7 @@ "endColumn": 18, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -95,7 +95,7 @@ "column": 1, "endLine": 19, "endColumn": 7, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectTraverseJsInstance", "autofix": [ { "replacementText": "arr.getPropertyByIndex(1).toNumber()", @@ -104,7 +104,7 @@ } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ } ], "suggest": "", - "rule": "Interop objects can't be indexed directly (arkts-no-js-index-import)", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", "severity": "ERROR" }, { @@ -129,7 +129,7 @@ "column": 1, "endLine": 20, "endColumn": 7, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectTraverseJsInstance", "autofix": [ { "replacementText": "arr.setPropertyByIndex(3, ESObject.wrap(4))", @@ -138,7 +138,7 @@ } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", "severity": "ERROR" }, { @@ -155,7 +155,7 @@ } ], "suggest": "", - "rule": "Interop objects can't be indexed directly (arkts-no-js-index-import)", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..17caa7fd96a19dc2e316f05696f01dbed39136ea --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +'use static' +let GeneratedImportVar_1 = ESObject.load('./interop_import_js_index_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); + +let arr = foo.getPropertyByName("arr") +arr.getPropertyByIndex(1).toNumber() +arr.setPropertyByIndex(3, ESObject.wrap(4)) \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a9df6f95e72b69ed5927226f9a9f737c7d9f0e21 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json @@ -0,0 +1,48 @@ +{ + "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": 73, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets b/ets2panda/linter/test/interop/interop_import_js_rules.ets index 9962b58ee522d22705f1e9f9cbfff9da09ae46d2..3b88109fc29630d3e6a092967366596f836c6936 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets @@ -12,18 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static'; -import { foo } from "./oh_modules/interop_import_js_rules" -import { ff1, ff2 } from "./oh_modules/interop_import_js_rules" +import { foo } from "./interop_import_js_rules_js" +import { ff1, ff2 } from "./interop_import_js_rules_js" -import { A } from "./oh_modules/interop_import_js_rules" -import { C } from "./oh_modules/interop_import_js_rules" +import { A } from "./interop_import_js_rules_js" +import { C } from "./interop_import_js_rules_js" -import { ff3 } from "./oh_modules/interop_import_js_rules" +import { ff3 } from "./interop_import_js_rules_js" -import { ff4 } from "./oh_modules/interop_import_js_rules" +import { ff4 } from "./interop_import_js_rules_js" -import { handle } from "./oh_modules/interop_import_js_rules" +import { handle } from "./interop_import_js_rules_js" + +import { expand } from "./interop_import_js_rules_js" if (foo.isGood) {} @@ -59,3 +62,6 @@ let lambda = (p: Person) => {} handle(foo2) handle(lambda) + +class X{a = 1; b= 2; c= 3} +expand(new X()) // ERROR expand-static diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json index aff72256ec08c37cbf9c962edc1c747d4e1d7852..ad917d5f3cfba972a2aeed3dad9107fe63332924 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json @@ -14,185 +14,485 @@ "limitations under the License." ], "result": [ - { - "line": 28, - "column": 5, - "endLine": 28, - "endColumn": 15, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 5, - "endLine": 30, - "endColumn": 11, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 21, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 1, - "endLine": 38, - "endColumn": 21, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 3, - "endLine": 41, - "endColumn": 8, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 3, - "endLine": 41, - "endColumn": 8, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 3, - "endLine": 41, - "endColumn": 8, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 11, - "endLine": 46, - "endColumn": 18, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 11, - "endLine": 47, - "endColumn": 21, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 48, - "column": 10, - "endLine": 48, - "endColumn": 15, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 49, - "column": 11, - "endLine": 49, - "endColumn": 17, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 50, - "column": 3, - "endLine": 50, - "endColumn": 9, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 60, - "column": 1, - "endLine": 60, - "endColumn": 13, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 60, - "column": 1, - "endLine": 60, - "endColumn": 13, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 60, - "column": 1, - "endLine": 60, - "endColumn": 13, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 1, - "endLine": 61, - "endColumn": 15, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 1, - "endLine": 61, - "endColumn": 15, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 1, - "endLine": 61, - "endColumn": 15, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", - "severity": "ERROR" - } - ] -} \ No newline at end of file + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "InteropJsObjectConditionJudgment", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InteropJsObjectConditionJudgment", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 1, + "endLine": 37, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "InteropJSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch JS errors is not permitted (arkts-interop-js2s-js-exception)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 47, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 11, + "endLine": 50, + "endColumn": 21, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 13, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 13, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 13, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 15, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 15, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 9, + "endLine": 66, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 22, + "endLine": 66, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 16, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 16, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json index bd6352540970ae4202e019cc9129f6f09bf3fe8f..ec42a706b85a55d583c0ad8f58a4ffcb21484f78 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json @@ -14,234 +14,810 @@ "limitations under the License." ], "result": [ + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "autofix": [ { - "line": 28, - "column": 5, - "endLine": 28, - "endColumn": 15, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "foo.getPropertyByName('isGood').toBoolean()", - "start": 1031, - "end": 1041 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" + "start": 619, + "end": 669, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51 }, { - "line": 30, - "column": 5, - "endLine": 30, - "endColumn": 11, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "ff1.getPropertyByName('f1').toNumber()", - "start": 1051, - "end": 1057 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, + "start": 1038, + "end": 1038, + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_import_js_rules_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "InterOpImportJs", + "autofix": [ { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 21, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" + "start": 670, + "end": 725, + "replacementText": "", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56 }, { - "line": 38, - "column": 1, - "endLine": 38, - "endColumn": 21, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, + "start": 1038, + "end": 1038, + "replacementText": "let GeneratedImportVar_2 = ESObject.load('./interop_import_js_rules_js');\nlet ff1 = GeneratedImportVar_2.getPropertyByName('ff1');\nlet ff2 = GeneratedImportVar_2.getPropertyByName('ff2');\n", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "InterOpImportJs", + "autofix": [ { - "line": 41, - "column": 3, - "endLine": 41, - "endColumn": 8, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" + "start": 727, + "end": 775, + "replacementText": "", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49 }, { - "line": 41, - "column": 3, - "endLine": 41, - "endColumn": 8, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, + "start": 1038, + "end": 1038, + "replacementText": "let GeneratedImportVar_3 = ESObject.load('./interop_import_js_rules_js');\nlet A = GeneratedImportVar_3.getPropertyByName('A');\n", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "InterOpImportJs", + "autofix": [ { - "line": 41, - "column": 3, - "endLine": 41, - "endColumn": 8, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", - "severity": "ERROR" + "start": 776, + "end": 824, + "replacementText": "", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49 }, { - "line": 46, - "column": 11, - "endLine": 46, - "endColumn": 18, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "ff3.getPropertyByName('arr')", - "start": 1277, - "end": 1284 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, + "start": 1038, + "end": 1038, + "replacementText": "let GeneratedImportVar_4 = ESObject.load('./interop_import_js_rules_js');\nlet C = GeneratedImportVar_4.getPropertyByName('C');\n", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "InterOpImportJs", + "autofix": [ { - "line": 47, - "column": 11, - "endLine": 47, - "endColumn": 21, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "arr.getPropertyByName('length').toNumber()", - "start": 1295, - "end": 1315 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" + "start": 826, + "end": 876, + "replacementText": "", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51 }, { - "line": 48, - "column": 10, - "endLine": 48, - "endColumn": 15, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1325, - "end": 1330, - "replacementText": "i: number = 0" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, + "start": 1038, + "end": 1038, + "replacementText": "let GeneratedImportVar_5 = ESObject.load('./interop_import_js_rules_js');\nlet ff3 = GeneratedImportVar_5.getPropertyByName('ff3');\n", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "InterOpImportJs", + "autofix": [ { - "line": 49, - "column": 11, - "endLine": 49, - "endColumn": 17, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "arr.getPropertyByIndex(i).toNumber()", - "start": 1358, - "end": 1364 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" + "start": 878, + "end": 928, + "replacementText": "", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51 }, { - "line": 50, - "column": 3, - "endLine": 50, - "endColumn": 9, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "arr.setPropertyByIndex(i, ESObject.wrap(0))", - "start": 1367, - "end": 1377 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, + "start": 1038, + "end": 1038, + "replacementText": "let GeneratedImportVar_6 = ESObject.load('./interop_import_js_rules_js');\nlet ff4 = GeneratedImportVar_6.getPropertyByName('ff4');\n", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "InterOpImportJs", + "autofix": [ { - "line": 60, - "column": 1, - "endLine": 60, - "endColumn": 13, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" + "start": 930, + "end": 983, + "replacementText": "", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54 }, { - "line": 60, - "column": 1, - "endLine": 60, - "endColumn": 13, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, + "start": 1038, + "end": 1038, + "replacementText": "let GeneratedImportVar_7 = ESObject.load('./interop_import_js_rules_js');\nlet handle = GeneratedImportVar_7.getPropertyByName('handle');\n", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "InterOpImportJs", + "autofix": [ { - "line": 60, - "column": 1, - "endLine": 60, - "endColumn": 13, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", - "severity": "ERROR" + "start": 985, + "end": 1038, + "replacementText": "", + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54 }, { - "line": 61, - "column": 1, - "endLine": 61, - "endColumn": 15, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, + "start": 1038, + "end": 1038, + "replacementText": "let GeneratedImportVar_8 = ESObject.load('./interop_import_js_rules_js');\nlet expand = GeneratedImportVar_8.getPropertyByName('expand');\n", + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "InteropObjectProperty", + "autofix": [ { - "line": 61, - "column": 1, - "endLine": 61, - "endColumn": 15, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, + "start": 1044, + "end": 1054, + "replacementText": "foo.getPropertyByName(\"isGood\")", + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "InteropJsObjectConditionJudgment", + "autofix": [ { - "line": 61, - "column": 1, - "endLine": 61, - "endColumn": 15, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", - "severity": "ERROR" - } - ] -} \ No newline at end of file + "replacementText": "foo.getPropertyByName('isGood').toBoolean()", + "start": 1044, + "end": 1054, + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1064, + "end": 1070, + "replacementText": "ff1.getPropertyByName(\"f1\")", + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InteropJsObjectConditionJudgment", + "autofix": [ + { + "replacementText": "ff1.getPropertyByName('f1').toNumber()", + "start": 1064, + "end": 1070, + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 1, + "endLine": 37, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "InteropJSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch JS errors is not permitted (arkts-interop-js2s-js-exception)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 47, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1290, + "end": 1297, + "replacementText": "ff3.getPropertyByName(\"arr\")", + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "ff3.getPropertyByName('arr')", + "start": 1290, + "end": 1297, + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 11, + "endLine": 50, + "endColumn": 21, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "arr.getPropertyByName('length').toNumber()", + "start": 1308, + "end": 1328, + "line": 50, + "column": 11, + "endLine": 50, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1338, + "end": 1343, + "replacementText": "i: number = 0", + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr.getPropertyByIndex(i).toNumber()", + "start": 1371, + "end": 1377, + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 1371, + "end": 1377, + "replacementText": "arr.getPropertyByIndex(i)", + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr.setPropertyByIndex(i, ESObject.wrap(0))", + "start": 1380, + "end": 1390, + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 13, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 1380, + "end": 1390, + "replacementText": "arr.setPropertyByIndex(i, ESObject.wrap(0))", + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 13, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 13, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 15, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 15, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 9, + "endLine": 66, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1528, + "end": 1534, + "replacementText": "a: number = 1;", + "line": 66, + "column": 9, + "endLine": 66, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1535, + "end": 1540, + "replacementText": "b: number = 2;", + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 22, + "endLine": 66, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1541, + "end": 1545, + "replacementText": "c: number = 3;", + "line": 66, + "column": 22, + "endLine": 66, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 16, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 16, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.json index dd03fcf5442488620bcd4b3447f0fcdd89e1905b..a3db4edec87910df49c7a5933852334694aba188 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets.json +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.json @@ -13,5 +13,86 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] } diff --git a/ets2panda/linter/test/interop/oh_modules/interop_import_js_rules.js b/ets2panda/linter/test/interop/interop_import_js_rules_js.js similarity index 92% rename from ets2panda/linter/test/interop/oh_modules/interop_import_js_rules.js rename to ets2panda/linter/test/interop/interop_import_js_rules_js.js index 13f6e3cd5838cde58718d2e91476058e3d6e5da3..31951e24a4d58862665252d17ce37482eb8f45ac 100644 --- a/ets2panda/linter/test/interop/oh_modules/interop_import_js_rules.js +++ b/ets2panda/linter/test/interop/interop_import_js_rules_js.js @@ -30,3 +30,8 @@ export function handle(cb) { let p = {name: 'hello'} cb(p) } + +export function expand(obj) { + let x = obj; + let {a, b, c} = obj; +} diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.args.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.args.json index 815373beb6e083ba357c4eb952ab7bc777bdade6..df6e67a5c9292c4c7e7aa5e976a3b8d1104fa082 100755 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.args.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.arkts2.json index dbe38c107ae57b56a963172b86bd2dd78b28def0..fa257d85ca304283a7f1f0361ccd59565b5dc5d2 100755 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 69, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 54, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 55, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 15, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -89,9 +89,9 @@ "column": 8, "endLine": 21, "endColumn": 15, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -101,17 +101,7 @@ "endColumn": 15, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 8, - "endLine": 21, - "endColumn": 15, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -119,9 +109,9 @@ "column": 11, "endLine": 22, "endColumn": 18, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -131,17 +121,7 @@ "endColumn": 18, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 11, - "endLine": 22, - "endColumn": 18, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -151,7 +131,7 @@ "endColumn": 11, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -161,7 +141,7 @@ "endColumn": 19, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -179,9 +159,9 @@ "column": 8, "endLine": 25, "endColumn": 19, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -191,17 +171,7 @@ "endColumn": 19, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 8, - "endLine": 25, - "endColumn": 19, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -211,7 +181,7 @@ "endColumn": 20, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -229,9 +199,9 @@ "column": 8, "endLine": 26, "endColumn": 20, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -241,17 +211,7 @@ "endColumn": 20, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 8, - "endLine": 26, - "endColumn": 20, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -261,7 +221,7 @@ "endColumn": 12, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -271,7 +231,7 @@ "endColumn": 17, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -281,7 +241,7 @@ "endColumn": 17, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -301,7 +261,7 @@ "endColumn": 17, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -311,7 +271,7 @@ "endColumn": 12, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -321,7 +281,7 @@ "endColumn": 20, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -341,7 +301,7 @@ "endColumn": 20, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -351,7 +311,7 @@ "endColumn": 35, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -361,7 +321,7 @@ "endColumn": 20, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -371,7 +331,7 @@ "endColumn": 20, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -381,7 +341,7 @@ "endColumn": 33, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -391,17 +351,7 @@ "endColumn": 22, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 12, - "endLine": 37, - "endColumn": 28, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -411,17 +361,7 @@ "endColumn": 28, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 12, - "endLine": 40, - "endColumn": 28, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -431,7 +371,7 @@ "endColumn": 28, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -444,16 +384,6 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, - { - "line": 43, - "column": 12, - "endLine": 43, - "endColumn": 30, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, { "line": 43, "column": 12, @@ -461,7 +391,7 @@ "endColumn": 30, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -471,7 +401,7 @@ "endColumn": 24, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -481,7 +411,7 @@ "endColumn": 24, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -494,16 +424,6 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, - { - "line": 48, - "column": 21, - "endLine": 48, - "endColumn": 39, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, { "line": 48, "column": 21, @@ -511,7 +431,7 @@ "endColumn": 39, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -531,7 +451,7 @@ "endColumn": 21, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -541,7 +461,7 @@ "endColumn": 21, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -561,7 +481,7 @@ "endColumn": 21, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -571,7 +491,7 @@ "endColumn": 47, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -581,7 +501,7 @@ "endColumn": 47, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -591,7 +511,7 @@ "endColumn": 13, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -601,7 +521,7 @@ "endColumn": 25, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -611,7 +531,7 @@ "endColumn": 25, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -631,7 +551,7 @@ "endColumn": 20, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -641,7 +561,7 @@ "endColumn": 30, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -649,19 +569,9 @@ "column": 8, "endLine": 72, "endColumn": 30, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 8, - "endLine": 72, - "endColumn": 30, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -671,7 +581,7 @@ "endColumn": 30, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -681,7 +591,7 @@ "endColumn": 20, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -691,7 +601,7 @@ "endColumn": 31, "problem": "InterOpImportJsForTypeOf", "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -709,19 +619,9 @@ "column": 8, "endLine": 73, "endColumn": 31, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 8, - "endLine": 73, - "endColumn": 31, - "problem": "CallJSFunction", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -731,7 +631,7 @@ "endColumn": 31, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -741,7 +641,7 @@ "endColumn": 20, "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json index b3629587152144caf5da20099677f101b4d29ade..3f09bf75b91cb922131c688a58002cc28a5a6b5e 100755 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json @@ -39,11 +39,11 @@ { "start": 796, "end": 796, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_1.getPropertyByName('aaa');\nlet ClassA = GeneratedImportVar_1.getPropertyByName('ClassA');\nlet Dog = GeneratedImportVar_1.getPropertyByName('Dog');\nlet Person = GeneratedImportVar_1.getPropertyByName('Person');\nlet Wiki = GeneratedImportVar_1.getPropertyByName('Wiki');" + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_1.getPropertyByName('aaa');\nlet ClassA = GeneratedImportVar_1.getPropertyByName('ClassA');\nlet Dog = GeneratedImportVar_1.getPropertyByName('Dog');\nlet Person = GeneratedImportVar_1.getPropertyByName('Person');\nlet Wiki = GeneratedImportVar_1.getPropertyByName('Wiki');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -71,11 +71,11 @@ { "start": 796, "end": 796, - "replacementText": "let GeneratedImportVar_2 = ESObject.load('./interop_import_js_js');\nlet Doge = GeneratedImportVar_2.getPropertyByName('Dog');" + "replacementText": "let GeneratedImportVar_2 = ESObject.load('./interop_import_js_js');\nlet Doge = GeneratedImportVar_2.getPropertyByName('Dog');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -103,11 +103,11 @@ { "start": 796, "end": 796, - "replacementText": "let GeneratedImportVar_3 = ESObject.load('./interop_import_js_js');\nlet wiki = GeneratedImportVar_3.getPropertyByName('Wiki');" + "replacementText": "let GeneratedImportVar_3 = ESObject.load('./interop_import_js_js');\nlet wiki = GeneratedImportVar_3.getPropertyByName('Wiki');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -124,7 +124,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -132,9 +132,9 @@ "column": 8, "endLine": 21, "endColumn": 15, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -144,17 +144,7 @@ "endColumn": 15, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 8, - "endLine": 21, - "endColumn": 15, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -162,9 +152,9 @@ "column": 11, "endLine": 22, "endColumn": 18, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -174,17 +164,7 @@ "endColumn": 18, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 11, - "endLine": 22, - "endColumn": 18, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -201,7 +181,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -218,7 +198,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -236,9 +216,9 @@ "column": 8, "endLine": 25, "endColumn": 19, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -248,17 +228,7 @@ "endColumn": 19, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 8, - "endLine": 25, - "endColumn": 19, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -275,7 +245,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -293,9 +263,9 @@ "column": 8, "endLine": 26, "endColumn": 20, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -305,17 +275,7 @@ "endColumn": 20, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 8, - "endLine": 26, - "endColumn": 20, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -332,7 +292,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -349,7 +309,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -366,7 +326,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -393,7 +353,7 @@ "endColumn": 17, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -410,7 +370,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -427,7 +387,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -454,7 +414,7 @@ "endColumn": 20, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -471,7 +431,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -488,7 +448,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -505,7 +465,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -522,7 +482,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -539,17 +499,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 12, - "endLine": 37, - "endColumn": 28, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -559,17 +509,7 @@ "endColumn": 28, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 12, - "endLine": 40, - "endColumn": 28, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -579,7 +519,7 @@ "endColumn": 28, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -592,16 +532,6 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, - { - "line": 43, - "column": 12, - "endLine": 43, - "endColumn": 30, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, { "line": 43, "column": 12, @@ -609,7 +539,7 @@ "endColumn": 30, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -626,7 +556,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -643,7 +573,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -656,16 +586,6 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, - { - "line": 48, - "column": 21, - "endLine": 48, - "endColumn": 39, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, { "line": 48, "column": 21, @@ -673,7 +593,7 @@ "endColumn": 39, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -700,7 +620,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -717,7 +637,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -744,7 +664,7 @@ "endColumn": 21, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -761,7 +681,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -778,7 +698,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -795,7 +715,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -812,7 +732,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -829,7 +749,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -863,7 +783,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -880,7 +800,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -888,19 +808,9 @@ "column": 8, "endLine": 72, "endColumn": 30, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 8, - "endLine": 72, - "endColumn": 30, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -910,7 +820,7 @@ "endColumn": 30, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -927,7 +837,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { @@ -944,7 +854,7 @@ } ], "suggest": "", - "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-import-typeof-js)", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", "severity": "ERROR" }, { @@ -962,19 +872,9 @@ "column": 8, "endLine": 73, "endColumn": 31, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 8, - "endLine": 73, - "endColumn": 31, - "problem": "CallJSFunction", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -984,7 +884,7 @@ "endColumn": 31, "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { @@ -1001,7 +901,7 @@ } ], "suggest": "", - "rule": "ArkTS directly instantiated JS objects is not supported (arkts-no-js-obj-instantiated)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5914b7dfda835278185754ae30358b9017ec6e0d --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets @@ -0,0 +1,83 @@ +/* + * 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. + */ + +'use static' + + +let GeneratedImportVar_3 = ESObject.load('./interop_import_js_js'); +let wiki = GeneratedImportVar_3.getPropertyByName('Wiki'); +let GeneratedImportVar_2 = ESObject.load('./interop_import_js_js'); +let Doge = GeneratedImportVar_2.getPropertyByName('Dog'); +let GeneratedImportVar_1 = ESObject.load('./interop_import_js_js'); +let myAaa = GeneratedImportVar_1.getPropertyByName('aaa'); +let ClassA = GeneratedImportVar_1.getPropertyByName('ClassA'); +let Dog = GeneratedImportVar_1.getPropertyByName('Dog'); +let Person = GeneratedImportVar_1.getPropertyByName('Person'); +let Wiki = GeneratedImportVar_1.getPropertyByName('Wiki'); + + +myAaa.invoke().typeOf(); //error +let fun = myAaa(); +typeof fun; +Dog.typeOf(); //error +Dog.invoke(ESObject.wrap('doge')).typeOf(); //error +Doge.invoke(ESObject.wrap('doge')).typeOf(); //error +Wiki.typeOf() //error +Wiki.getPropertyByName('name').typeOf() //error +wiki.typeOf() //error +let val = wiki.getPropertyByName("name") +typeof val; +const aClass:ClassA = ClassA.instantiate() +ClassA.instantiate().typeOf() //error +typeof aClass; +let person:Person = Person.instantiate(); +let name =person.getPropertyByName("name") +let name2 =person.getName() +function getPersonInfo(){ + typeof person; + typeof person.getName(); + typeof name2; + typeof name; + typeof person.setAge(111); + typeof person; + Person.instantiate().typeOf(); //error +} + +const age = typeof person.setAge(111); +let person2 = typeof person +class Object { + code: string = "www" + location: string = typeof ('123') + getLocation(){ + console.log(`nameType=${ typeof code} `); + return typeof this.location; + } + setLocation(location: string){ + this.location = location; + typeof location; + } + tips(){ + wiki.getPropertyByName('name').typeOf(); //error + typeof age; + typeof person2; + typeof fun; + console.log(`ClassA=${ ClassA.instantiate().typeOf()} `); //error + } +} + +myAaa.typeOf(); //error +Person.instantiate().getPropertyByName('name').typeOf() //error +Person.instantiate().getPropertyByName('getName').invoke().typeOf() //error +Person.instantiate().getPropertyByName('setAge').invoke(ESObject.wrap(22)).typeOf() //error diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a2ce72e9414506a158aa975a040c644c962ce5b6 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.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": 19, + "column": 5, + "endLine": 19, + "endColumn": 67, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 67, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 67, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 62, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 62, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 41, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 7, + "endLine": 60, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.args.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.args.json index a2c0f14eb2d79969407309c83200850554d409d3..ef3938e967322a0c7551d84c7b6d280de94144c8 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.args.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.arkts2.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.arkts2.json index dbcf35243fe011bb13c09043d5a53174cecac55e..62322a01ef9933939311eff4bec680950d783656 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.arkts2.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ + "result": [ { "line": 17, "column": 1, @@ -31,7 +31,7 @@ "endColumn": 59, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 9, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 17, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 16, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 11, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 21, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 12, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json index 3b827973a4838cdc3a1fca0967cf587c5a3fa80c..f849dbbe047cb3f11eb136c7706f804f81e24688 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json @@ -39,11 +39,11 @@ { "start": 676, "end": 676, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_not_have_property_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\nlet person = GeneratedImportVar_1.getPropertyByName('person');" + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_not_have_property_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\nlet person = GeneratedImportVar_1.getPropertyByName('person');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -60,7 +60,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -87,7 +87,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -104,7 +104,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -148,7 +148,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -175,7 +175,7 @@ "endColumn": 11, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -192,7 +192,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -219,7 +219,7 @@ "endColumn": 12, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a96b2c80b70af6dac3fd39241a88ef028068a10f --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ +'use static' + +let GeneratedImportVar_1 = ESObject.load('./interop_not_have_property_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); +let person = GeneratedImportVar_1.getPropertyByName('person'); + + +foo.getPropertyByName("name") +foo.setPropertyByName("name", ESObject.wrap("456")) +person.setPropertyByName("age", ESObject.wrap(23)) +person.setPropertyByName("male", ESObject.wrap([2, 3])) \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..bc6054f74509a028c9ba595ca75bc51475e33b01 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json @@ -0,0 +1,48 @@ +{ + "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": 75, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 62, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets index 319ea1ded3c8267ac7bde587ec1b170d16ab5d86..1049aac0f00e701d6e1ad108fcc92ab88dcf7933 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets @@ -19,4 +19,8 @@ import {foo} from "./interop_property_num_js" +foo.num; -foo.num; !foo.num; -~foo.num; \ No newline at end of file +~foo.num; ++(foo.num); +-(foo.num); +!(foo.num); +~(foo.num); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.args.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.args.json index a2c0f14eb2d79969407309c83200850554d409d3..ef3938e967322a0c7551d84c7b6d280de94144c8 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.args.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.arkts2.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.arkts2.json index 91c86ce66777d6c3206ad07e480b16bd7c6b6bb6..bf5ffbc331d6a8a85b7127b68cc4d7e8e575cdf3 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 46, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 9, "problem": "InteropNoHaveNum", "suggest": "", - "rule": "Interop object does not have property num (arkts-interop-does-not-have-num)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 9, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 9, "problem": "InteropNoHaveNum", "suggest": "", - "rule": "Interop object does not have property num (arkts-interop-does-not-have-num)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 9, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 9, "problem": "InteropNoHaveNum", "suggest": "", - "rule": "Interop object does not have property num (arkts-interop-does-not-have-num)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 9, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 9, "problem": "InteropNoHaveNum", "suggest": "", - "rule": "Interop object does not have property num (arkts-interop-does-not-have-num)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 9, "problem": "InteropObjectProperty", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -191,7 +191,167 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json index b52102f1f98d5e41a81dc05903147183861c6e42..a5900c6c1f29aab112c270a972e80e81e9781ed1 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json @@ -39,11 +39,11 @@ { "start": 663, "end": 663, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_property_num_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');" + "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_property_num_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n" } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -60,7 +60,7 @@ } ], "suggest": "", - "rule": "Interop object does not have property num (arkts-interop-does-not-have-num)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -77,7 +77,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -104,7 +104,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ } ], "suggest": "", - "rule": "Interop object does not have property num (arkts-interop-does-not-have-num)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -138,7 +138,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -165,7 +165,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -182,7 +182,7 @@ } ], "suggest": "", - "rule": "Interop object does not have property num (arkts-interop-does-not-have-num)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -199,7 +199,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -226,7 +226,7 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -243,7 +243,7 @@ } ], "suggest": "", - "rule": "Interop object does not have property num (arkts-interop-does-not-have-num)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -260,7 +260,7 @@ } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-no-js-obj-property)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -287,7 +287,251 @@ "endColumn": 9, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 706, + "end": 715, + "replacementText": "(foo.getPropertyByName(\"num\").toNumber())" + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 707, + "end": 714, + "replacementText": "foo.getPropertyByName(\"num\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 707, + "end": 714 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 718, + "end": 727, + "replacementText": "(foo.getPropertyByName(\"num\").toNumber())" + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 719, + "end": 726, + "replacementText": "foo.getPropertyByName(\"num\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 719, + "end": 726 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 730, + "end": 739, + "replacementText": "(foo.getPropertyByName(\"num\").toNumber())" + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 731, + "end": 738, + "replacementText": "foo.getPropertyByName(\"num\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 731, + "end": 738 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 742, + "end": 751, + "replacementText": "(foo.getPropertyByName(\"num\").toNumber())" + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 743, + "end": 750, + "replacementText": "foo.getPropertyByName(\"num\")" + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 743, + "end": 750 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..ade780f491a275359f6f19ecae923ba66131e287 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ +'use static' + +let GeneratedImportVar_1 = ESObject.load('./interop_property_num_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); + + ++foo.getPropertyByName("num").toNumber(); +-foo.getPropertyByName("num").toNumber(); +!foo.getPropertyByName("num").toNumber(); +~foo.getPropertyByName("num").toNumber(); ++(foo.getPropertyByName("num").toNumber()); +-(foo.getPropertyByName("num").toNumber()); +!(foo.getPropertyByName("num").toNumber()); +~(foo.getPropertyByName("num").toNumber()); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c3adb8622499be3bad0d9bd535b96794f5dae698 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json @@ -0,0 +1,98 @@ +{ + "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": 70, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 41, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 41, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 41, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 43, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 43, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 43, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_js_await.ets b/ets2panda/linter/test/interop/no_await_js_promise.ets similarity index 86% rename from ets2panda/linter/test/interop/no_js_await.ets rename to ets2panda/linter/test/interop/no_await_js_promise.ets index 1df1f4f9e94e8f8cd4d571f7736bc6a70693cff2..9247c363b44ed65bb043a4311584031f31e6d8fd 100755 --- a/ets2panda/linter/test/interop/no_js_await.ets +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets @@ -1,71 +1,65 @@ -/* - * 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. - */ -'use static' - -import { p, foo, pFuncCall, arrowFunc, pArrowCall } from "./no_import_awai.js"; - -// 1. 基础 Promise -async function awaitPromise() { - return await p; -} - -// 2. 异步函数调用 -async function awaitFunctionCall() { - return await foo(); -} - -async function awaitFuncResult() { - return await pFuncCall; -} - -// 3. 箭头函数 -async function awaitArrowCall() { - return await arrowFunc(); -} - -async function awaitArrowResult() { - return await pArrowCall; -} - -// 4. 类中使用 -class ExampleClass { - async classMethod() { - return await p; - } - - handler = async () => { - return await pFuncCall; - }; -} - -// 5. 对象方法 -const exampleObj = { - async objMethod() { - return await pArrowCall; - }, - - arrowHandler: async () => { - return await foo(); - } -}; - -// 6. 立即执行函数 -(async function() { - console.log("IIFE result:", await p); -})(); - -(async () => { - console.log("IIFE Arrow result:", await arrowFunc()); +/* + * 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. + */ +'use static' + +import { p, foo, pFuncCall, arrowFunc, pArrowCall } from "./no_await_js_promise_export"; + +async function awaitPromise() { + return await p; +} + +async function awaitFunctionCall() { + return await foo(); +} + +async function awaitFuncResult() { + return await pFuncCall; +} + +async function awaitArrowCall() { + return await arrowFunc(); +} + +async function awaitArrowResult() { + return await pArrowCall; +} + +class ExampleClass { + async classMethod() { + return await p; + } + + handler = async () => { + return await pFuncCall; + }; +} + +const exampleObj = { + async objMethod() { + return await pArrowCall; + }, + + arrowHandler: async () => { + return await foo(); + } +}; + +(async function() { + console.log("IIFE result:", await p); +})(); + +(async () => { + console.log("IIFE Arrow result:", await arrowFunc()); })(); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets.args.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise.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/interop/no_await_js_promise.ets.arkts2.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..54dff3eb9234b3f09d0902f6ebbac8ea91691542 --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.arkts2.json @@ -0,0 +1,258 @@ +{ + "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": 1, + "endLine": 17, + "endColumn": 89, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 89, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 17, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 21, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 21, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 21, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 10, + "endLine": 28, + "endColumn": 25, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 10, + "endLine": 32, + "endColumn": 27, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 16, + "endLine": 32, + "endColumn": 27, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 16, + "endLine": 32, + "endColumn": 27, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 10, + "endLine": 36, + "endColumn": 26, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 19, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 12, + "endLine": 45, + "endColumn": 27, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 20, + "endLine": 49, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 3, + "endLine": 52, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 12, + "endLine": 51, + "endColumn": 28, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 12, + "endLine": 55, + "endColumn": 23, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 18, + "endLine": 55, + "endColumn": 23, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 18, + "endLine": 55, + "endColumn": 23, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 2, + "endLine": 61, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 31, + "endLine": 60, + "endColumn": 38, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 37, + "endLine": 64, + "endColumn": 54, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 43, + "endLine": 64, + "endColumn": 54, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 43, + "endLine": 64, + "endColumn": 54, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_js_await.ets.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.json similarity index 92% rename from ets2panda/linter/test/interop/no_js_await.ets.json rename to ets2panda/linter/test/interop/no_await_js_promise.ets.json index 145ba7afed8f76d05342a86b578a41b9d876f0a9..5285bc41f634a1abbb69521c2609a6c4aebd006d 100755 --- a/ets2panda/linter/test/interop/no_js_await.ets.json +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.json @@ -18,16 +18,16 @@ "line": 17, "column": 1, "endLine": 17, - "endColumn": 80, + "endColumn": 89, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 54, + "line": 49, "column": 20, - "endLine": 54, + "endLine": 49, "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 65, + "line": 59, "column": 2, - "endLine": 67, + "endLine": 61, "endColumn": 2, "problem": "FunctionExpression", "suggest": "", diff --git a/ets2panda/linter/test/interop/no_js_awai.js b/ets2panda/linter/test/interop/no_await_js_promise_export.js similarity index 100% rename from ets2panda/linter/test/interop/no_js_awai.js rename to ets2panda/linter/test/interop/no_await_js_promise_export.js diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json index d50f0569e1d1b8f5c982d6d672c05cb1f8aa7cb7..38edbb018939e1ec137b90fb20851cbb1f89a667 100755 --- a/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 88, "problem": "InterOpImportJs", "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-no-js-import)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 22, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 23, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 23, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -69,9 +69,9 @@ "column": 28, "endLine": 39, "endColumn": 50, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -81,17 +81,7 @@ "endColumn": 50, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 39, - "column": 28, - "endLine": 39, - "endColumn": 50, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -101,7 +91,7 @@ "endColumn": 34, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -111,7 +101,7 @@ "endColumn": 38, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -121,7 +111,7 @@ "endColumn": 38, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -131,7 +121,7 @@ "endColumn": 42, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -141,7 +131,7 @@ "endColumn": 22, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -151,7 +141,7 @@ "endColumn": 24, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -159,9 +149,9 @@ "column": 4, "endLine": 69, "endColumn": 7, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectCallStaticFunc", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", "severity": "ERROR" }, { @@ -171,17 +161,7 @@ "endColumn": 7, "problem": "CallJSFunction", "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-no-call-js-function)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 4, - "endLine": 69, - "endColumn": 7, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-no-call-class-method)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { @@ -211,7 +191,7 @@ "endColumn": 51, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { @@ -221,7 +201,7 @@ "endColumn": 37, "problem": "InteropJsInstanceof", "suggest": "", - "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-no-import-obj-type)", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", "severity": "ERROR" }, { @@ -229,9 +209,9 @@ "column": 22, "endLine": 75, "endColumn": 37, - "problem": "InteropJsObjectUsage", + "problem": "InteropJsObjectConditionJudgment", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", "severity": "ERROR" }, { @@ -241,7 +221,7 @@ "endColumn": 37, "problem": "BinaryOperations", "suggest": "", - "rule": "Binary operations on js objects (arkts-no-js-obj-binary-operation)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/object_built_in.ets b/ets2panda/linter/test/interop/object_built_in.ets index 52776ecdd455ee96dbf548f5ca4091eb1e49cfd0..7797930ffdc48c71b861f8f690b58f811efd2319 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets +++ b/ets2panda/linter/test/interop/object_built_in.ets @@ -12,9 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' -import { foo } from "./oh_modules/object_built_in" +import { X } from "./oh_modules/object_built_in" -class X { a = 1 }; +export function foo(prx: Object) { + Object.assign({}, prx); + Object.entries(prx); + Object.keys(prx); + Object.values(prx); + prx.hasOwnProperty("a"); +} foo(new X()); // Illegal diff --git a/ets2panda/linter/test/interop/object_built_in.ets.args.json b/ets2panda/linter/test/interop/object_built_in.ets.args.json index 0adede204e309a92c8aac08d89f6af16d9c93f78..aac366be5e8658d7672f4da2855a3c4740c7bcd3 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets.args.json +++ b/ets2panda/linter/test/interop/object_built_in.ets.args.json @@ -14,5 +14,6 @@ "limitations under the License." ], "mode": { + "arkts2": "" } } diff --git a/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json b/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..0e40297d99c1d7cc0071bcbd6b59f080a270cae5 --- /dev/null +++ b/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json @@ -0,0 +1,69 @@ +{ + "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": 1, + "endLine": 17, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 12, + "endLine": 20, + "endColumn": 18, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, + "endLine": 20, + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 23, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 13, + "problem": "InteropCallObjectParam", + "suggest": "", + "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)", + "severity": "ERROR" + } + ] +} + diff --git a/ets2panda/linter/test/interop/object_built_in.ets.json b/ets2panda/linter/test/interop/object_built_in.ets.json index f40eed4436c9903da018d74dede387d7041d5beb..582a700d940a62a7f8b6fae343ed7bf79d4da05e 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets.json +++ b/ets2panda/linter/test/interop/object_built_in.ets.json @@ -14,14 +14,44 @@ "limitations under the License." ], "result": [ - { - "line": 20, + { + "line": 17, "column": 1, + "endLine": 17, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 27, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, "endLine": 20, - "endColumn": 13, - "problem": "InteropCallObjectParam", + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 28, + "problem": "LimitedStdLibApi", "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets b/ets2panda/linter/test/interop/object_literal_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..c60cfdf0ebf7df10bd76b9e9c2f29dbc04971c69 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets @@ -0,0 +1,25 @@ +'use static' +/* + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { User, Person, Fruit, Apple } from "./oh_modules/object_literal_constructor" + +let user: User = { id: 1 } + +let fruit: Fruit = new Fruit("fruit"); // legal + +let person: Person = { name: "Furkan", age: "25" } + +let apple: Apple = { name: "apple", color: "green" } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ts_decorator.ets.args.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.args.json similarity index 100% rename from ets2panda/linter/test/interop/ts_decorator.ets.args.json rename to ets2panda/linter/test/interop/object_literal_constructor.ets.args.json diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1891f69fe39ff675c02949bfb1721d1906cd48a9 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 1, + "endLine": 17, + "endColumn": 85, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 27, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 51, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 53, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..c57b713f15e0606479b9a1eab3f083468ad780f2 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets.json @@ -0,0 +1,28 @@ +{ + "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": 1, + "endLine": 17, + "endColumn": 85, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets b/ets2panda/linter/test/interop/object_literal_union_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..f57fd51379483dadc616f4982de7a53d521c2656 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets @@ -0,0 +1,29 @@ +'use static' +/* + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {X, Y, Z} from "./oh_modules/object_literal_union_type" + +import {A, B} from "./oh_modules/object_literal_union_type_arkts2" + +let xy: X | Y = { name: "xy" } + +let yz: Y | Z = { name: "yz" } + +let xyz: X | Y | Z = { name: "xyz" } + +let ab: A | B = { name: "hello" } // legal + +let y: X | Y = { name: "hello" } as Y; // legal \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets.args.json b/ets2panda/linter/test/interop/object_literal_union_type.ets.args.json similarity index 100% rename from ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets.args.json rename to ets2panda/linter/test/interop/object_literal_union_type.ets.args.json diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json b/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5c02f0cb4d9911bc2709610266b70dc0caf4d404 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 63, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 67, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 31, + "problem": "InteropObjectLiteralAmbiguity", + "suggest": "", + "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 31, + "problem": "InteropObjectLiteralAmbiguity", + "suggest": "", + "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 37, + "problem": "InteropObjectLiteralAmbiguity", + "suggest": "", + "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets.json b/ets2panda/linter/test/interop/object_literal_union_type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..25154ac0c6605dd88492da69d54ca7d7a2cda0d5 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets.json @@ -0,0 +1,38 @@ +{ + "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": 1, + "endLine": 17, + "endColumn": 63, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 67, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/oh_modules/object_built_in.ets b/ets2panda/linter/test/interop/oh_modules/object_built_in.ets index 0d30fa2156dff4eb11c6477da1f32fdbe495b82a..e06b3e23f981bc11f0556445e190d436daa48ab1 100644 --- a/ets2panda/linter/test/interop/oh_modules/object_built_in.ets +++ b/ets2panda/linter/test/interop/oh_modules/object_built_in.ets @@ -1,5 +1,3 @@ -'use static' - /* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,13 +13,6 @@ * limitations under the License. */ -export function foo(prx: Object) { - Object.assign({}, prx); - Object.entries(prx); - Object.keys(prx); - Object.values(prx); - prx.hasOwnProperty("a"); -} - +export class X { a = 1 }; diff --git a/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets b/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..3ffe607d9d0b85dbe0dd9abd6d8a5573df035d68 --- /dev/null +++ b/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets @@ -0,0 +1,42 @@ +/* + * 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. + */ + +export class User { + id: number; + constructor(arg: number) { + this.id = arg + } +} +export class Person { + name: string; + age: number; + constructor(arg1: string, arg2: number) { + this.name = arg1; + this.age = arg2; + } +} +export class Fruit { + name: string; + constructor(arg: string) { + this.name = arg; + } +} +export class Apple extends Fruit { + color: string; + constructor(string: string, arg2: string) { + super(string) + this.color = arg2; + } +} diff --git a/ets2panda/linter/test/interop/oh_modules/object_literal_union_type.ets b/ets2panda/linter/test/interop/oh_modules/object_literal_union_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..34b50528bd07629c1060f3fa524fcf1e1778eddd --- /dev/null +++ b/ets2panda/linter/test/interop/oh_modules/object_literal_union_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. + */ + +export class X { + name: string = '' + str: string = '' +} + +export class Y { + name: string = '' + bool: boolean = false +} + +export interface Z {name: string, age: number} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/oh_modules/object_literal_union_type_arkts2.ets b/ets2panda/linter/test/interop/oh_modules/object_literal_union_type_arkts2.ets new file mode 100644 index 0000000000000000000000000000000000000000..dad32c88bac85147e6236659ba62ac53ecb691ea --- /dev/null +++ b/ets2panda/linter/test/interop/oh_modules/object_literal_union_type_arkts2.ets @@ -0,0 +1,18 @@ +/* + * 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. + */ +'use static' + +export class A { name: string = '' } +export interface B { name: string, age?: number } diff --git a/ets2panda/linter/test/interop/oh_modules/reflect_export.ets b/ets2panda/linter/test/interop/oh_modules/reflect_export.ets index d7e2351412eae61ef01109655a97ad97bd9d129d..4fd2894dd8489f827482c493f3d1782ef57e0d1a 100644 --- a/ets2panda/linter/test/interop/oh_modules/reflect_export.ets +++ b/ets2panda/linter/test/interop/oh_modules/reflect_export.ets @@ -24,3 +24,7 @@ export function bar(obj: Object) { return Reflect.has(obj, 'prop'); } +export class X { + a: string = 'hello' + getName() { return this.a } +} diff --git a/ets2panda/linter/test/interop/oh_modules/static_object_literals_export.ets b/ets2panda/linter/test/interop/oh_modules/static_object_literals_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..2191e0197101822d16e3f3af4bc71f7162305b9b --- /dev/null +++ b/ets2panda/linter/test/interop/oh_modules/static_object_literals_export.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ +'use static' + +export class X { name: string = '' } + +export interface Y { data: number } + +export function foo(arg: X) {} + +export function bar(arg: Y) {} + +export function CreateY(d: number): Y { + let y: Y = {data: d} + return y +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets b/ets2panda/linter/test/interop/reflect_built_in.ets index b108f1bc48bd8cc588066dd261a5fe10492745e9..96b0800185e89fcc3bdf12c6ce9ac7dfd106ec0e 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets +++ b/ets2panda/linter/test/interop/reflect_built_in.ets @@ -12,32 +12,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' -import { foo, bar, safe } from "./oh_modules/reflect_export" -import { safeVersion } from "./oh_modules/reflect_export_safe" +import { X } from "./oh_modules/reflect_export" -class X { - a: string = 'hello' - getName() { return this.a } +export function foo(prx: Object) { + Reflect.get(prx, 'a') // 'hello' + Reflect.set(prx, 'a', 'world') // true + Reflect.ownKeys(prx) // ['a'] } -foo(new X()); - -class Y { - prop = 42; -} - -bar(new Y()); - -class Z { - a: string = 'hello'; - getName() { return this.a; } +export function bar(obj: Object) { + return Reflect.has(obj, 'prop'); } -safe(new Z()); //legal - -class A { - prop = 34; -} +foo(new X()); //illegal -safeVersion(new A()) //legal \ No newline at end of file +bar(new X()); //illegal diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets.args.json b/ets2panda/linter/test/interop/reflect_built_in.ets.args.json index c90ca155ab68f764f82b37c70e465eda447db3c1..bc4d2071daf6e9354e711c3b74b6be2b56659066 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets.args.json +++ b/ets2panda/linter/test/interop/reflect_built_in.ets.args.json @@ -13,5 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "mode": {} -} \ No newline at end of file + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.json b/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..851c3577e750d6777b04cffa069e4da5ab2cb2f2 --- /dev/null +++ b/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 48, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 13, + "problem": "InteropCallObjectParam", + "suggest": "", + "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 14, + "problem": "InteropCallReflect", + "suggest": "", + "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-d2s-static-reflect-on-dynamic-instance)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 1, + "endLine": 31, + "endColumn": 13, + "problem": "InteropCallObjectParam", + "suggest": "", + "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 1, + "endLine": 31, + "endColumn": 14, + "problem": "InteropCallReflect", + "suggest": "", + "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-d2s-static-reflect-on-dynamic-instance)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets.json b/ets2panda/linter/test/interop/reflect_built_in.ets.json index 3dd802b2f50f4c8cae1836ec7f0ce20405e22876..0ee87e87fb38c2290a997111c093fa85d4809a32 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets.json +++ b/ets2panda/linter/test/interop/reflect_built_in.ets.json @@ -15,63 +15,13 @@ ], "result": [ { - "line": 24, + "line": 17, "column": 1, - "endLine": 24, - "endColumn": 13, - "problem": "InteropCallObjectParam", + "endLine": 17, + "endColumn": 48, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 14, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-call-reflect)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 14, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-call-reflect)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 13, - "problem": "InteropCallObjectParam", - "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 14, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-call-reflect)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 14, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-call-reflect)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/static_dynamic_import.ets b/ets2panda/linter/test/interop/static_dynamic_import.ets new file mode 100644 index 0000000000000000000000000000000000000000..2e2c993747bc431db12fcf5270cafc3ce7f20974 --- /dev/null +++ b/ets2panda/linter/test/interop/static_dynamic_import.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ +'use static' + +let arkTsMod = await import('./test_files/dummy_arkts1_file'); +let tsModule = await import('./test_files/dummy_ts_file'); +let jsModule = await import('./test_files/dummy_js_file'); + +function main(): void { + import('./test_files/dummy_ts_file').then((m) => { + console.log(m.Data.name) + }) +} diff --git a/ets2panda/linter/test/interop/static_dynamic_import.ets.args.json b/ets2panda/linter/test/interop/static_dynamic_import.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/interop/static_dynamic_import.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/static_dynamic_import.ets.arkts2.json b/ets2panda/linter/test/interop/static_dynamic_import.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..3b87fbdb1f540ab4bde448b1dbc5fb9749cd30d7 --- /dev/null +++ b/ets2panda/linter/test/interop/static_dynamic_import.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 16, + "endLine": 17, + "endColumn": 62, + "problem": "InteropDynamicImport", + "suggest": "", + "rule": "No support for static dynamic import (arkts-interop-d2s-dynamic-import)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 22, + "endLine": 17, + "endColumn": 62, + "problem": "DynamicImport", + "suggest": "", + "rule": "Dynamic import is not supported(arkts-no-dynamic-import)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 17, + "endLine": 18, + "endColumn": 59, + "problem": "InteropDynamicImportTs", + "suggest": "", + "rule": "No support for static dynamic import (arkts-interop-ts2s-dynamic-import-ts)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 23, + "endLine": 18, + "endColumn": 59, + "problem": "DynamicImport", + "suggest": "", + "rule": "Dynamic import is not supported(arkts-no-dynamic-import)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 16, + "endLine": 19, + "endColumn": 58, + "problem": "InteropDynamicImportJs", + "suggest": "", + "rule": "No support for static dynamic import (arkts-interop-js2s-dynamic-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 22, + "endLine": 19, + "endColumn": 58, + "problem": "DynamicImport", + "suggest": "", + "rule": "Dynamic import is not supported(arkts-no-dynamic-import)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 44, + "problem": "InteropDynamicImportTs", + "suggest": "", + "rule": "No support for static dynamic import (arkts-interop-ts2s-dynamic-import-ts)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 39, + "problem": "DynamicImport", + "suggest": "", + "rule": "Dynamic import is not supported(arkts-no-dynamic-import)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/data_observation_2.ets.arkts2.json b/ets2panda/linter/test/interop/static_dynamic_import.ets.json similarity index 100% rename from ets2panda/linter/test/main/data_observation_2.ets.arkts2.json rename to ets2panda/linter/test/interop/static_dynamic_import.ets.json diff --git a/ets2panda/linter/test/interop/static_object_literals.ets b/ets2panda/linter/test/interop/static_object_literals.ets new file mode 100644 index 0000000000000000000000000000000000000000..82b3db8dd11e119268fdcfae10a07e0bf417f189 --- /dev/null +++ b/ets2panda/linter/test/interop/static_object_literals.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { X, Y, foo, bar } from "./oh_modules/static_object_literals_export" + +let x: X = { name: "hello" } + +let a: X = new X("hello") // legal + +let y: Y = { data: 123 } + +let b: Y = createY(123) // legal + +foo({ name: "world" }); + +foo(new X("world")) // legal + +bar({ data: 456 }); + +bar(createY(456)) // legal + +function zoo(): X { + return { name: "hello" } +} + +interface Z { x: X } + +let z: Z = { x: { name: "hello" } } + + + + diff --git a/ets2panda/linter/test/sdkwhite/GlobalThisError&TypeQuery.ets.arkts2.json b/ets2panda/linter/test/interop/static_object_literals.ets.args.json similarity index 95% rename from ets2panda/linter/test/sdkwhite/GlobalThisError&TypeQuery.ets.arkts2.json rename to ets2panda/linter/test/interop/static_object_literals.ets.args.json index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..c90ca155ab68f764f82b37c70e465eda447db3c1 100644 --- a/ets2panda/linter/test/sdkwhite/GlobalThisError&TypeQuery.ets.arkts2.json +++ b/ets2panda/linter/test/interop/static_object_literals.ets.args.json @@ -13,7 +13,5 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - - ] + "mode": {} } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/static_object_literals.ets.json b/ets2panda/linter/test/interop/static_object_literals.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..12d46c0860e9c1e8e2b8ea429ab13cae1448e3da --- /dev/null +++ b/ets2panda/linter/test/interop/static_object_literals.ets.json @@ -0,0 +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": 18, + "column": 12, + "endLine": 18, + "endColumn": 29, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 12, + "endLine": 22, + "endColumn": 25, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 22, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 18, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 12, + "endLine": 35, + "endColumn": 29, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 17, + "endLine": 40, + "endColumn": 34, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/test/parser/ets/user_defined_4.ets b/ets2panda/linter/test/interop/test_files/dummy_arkts1_file.ets similarity index 88% rename from ets2panda/test/parser/ets/user_defined_4.ets rename to ets2panda/linter/test/interop/test_files/dummy_arkts1_file.ets index f429e7107f92d66c99dfdc60889b9a08649ec66f..5aad017834822967ec7249e5db93b39b94750059 100644 --- a/ets2panda/test/parser/ets/user_defined_4.ets +++ b/ets2panda/linter/test/interop/test_files/dummy_arkts1_file.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * 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 @@ -13,4 +13,4 @@ * limitations under the License. */ -function boolean(){} +export module arkts {} diff --git a/ets2panda/linter/test/interop/test_files/dummy_js_file.js b/ets2panda/linter/test/interop/test_files/dummy_js_file.js new file mode 100644 index 0000000000000000000000000000000000000000..fa09fbb12c4a5fa47c104c1173cb88dafe4b78b0 --- /dev/null +++ b/ets2panda/linter/test/interop/test_files/dummy_js_file.js @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {} diff --git a/ets2panda/linter/test/interop/test_files/dummy_ts_file.ts b/ets2panda/linter/test/interop/test_files/dummy_ts_file.ts new file mode 100644 index 0000000000000000000000000000000000000000..e2f4a0e44b486d7a8c9ba88bb4c7d9dd933145be --- /dev/null +++ b/ets2panda/linter/test/interop/test_files/dummy_ts_file.ts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export module tsModule {} diff --git a/ets2panda/linter/test/interop/unique_types.ets b/ets2panda/linter/test/interop/unique_types.ets index 6f7517f43c13ca2358cd2ca5ba7903e5b798f282..35f8bae39116bc89fb0ff43ffec5b8c810c399a3 100644 --- a/ets2panda/linter/test/interop/unique_types.ets +++ b/ets2panda/linter/test/interop/unique_types.ets @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' import { objectLiteralType, @@ -25,7 +26,10 @@ objectLiteralType.name = "test" intersectionType.name = "test"; +try { tsFunction(); +} catch (e) { +} stringType = "test" //should pass diff --git a/ets2panda/linter/test/interop/unique_types.ets.args.json b/ets2panda/linter/test/interop/unique_types.ets.args.json index 49519d7bde6102d3b0563bb8806158d7f10e383f..d3ae885df4b870f3e78bd30cc8960f4b2b72b3d9 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.args.json +++ b/ets2panda/linter/test/interop/unique_types.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "autofix": "--arkts-2", + "migrate": "--arkts-2", "arkts2": "" } } diff --git a/ets2panda/linter/test/interop/unique_types.ets.arkts2.json b/ets2panda/linter/test/interop/unique_types.ets.arkts2.json index 320d717b2ffa1a59609a7340edc81a898b12b549..30f972d7571aad394d08a4d6866d4215b01f1090 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.arkts2.json +++ b/ets2panda/linter/test/interop/unique_types.ets.arkts2.json @@ -15,44 +15,64 @@ ], "result": [ { - "line": 24, + "line": 17, "column": 1, - "endLine": 24, + "endLine": 23, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, "endColumn": 23, "problem": "InteropDirectAccessToTSTypes", "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-access-ts-types)", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, { - "line": 26, + "line": 27, "column": 1, - "endLine": 26, + "endLine": 27, "endColumn": 22, "problem": "InteropDirectAccessToTSTypes", "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-access-ts-types)", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, { - "line": 28, + "line": 30, "column": 1, - "endLine": 28, + "endLine": 30, "endColumn": 13, "problem": "InteropTSFunctionInvoke", "suggest": "", - "rule": "Cannot invoke functions implemented in TypeScript (arkts-interop-ts-function)", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", "severity": "ERROR" - }, - { - "line": 30, + }, + { + "line": 31, + "column": 3, + "endLine": 32, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 34, "column": 1, - "endLine": 30, + "endLine": 34, "endColumn": 20, "problem": "InteropDirectAccessToTSTypes", "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-access-ts-types)", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "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 7442071b2218ef46b5db34b636b2eebc0a329c57..14ba376badc88d5a1c4fc33670e5cd5e32c3b821 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.autofix.json +++ b/ets2panda/linter/test/interop/unique_types.ets.autofix.json @@ -15,58 +15,86 @@ ], "result": [ { - "line": 24, + "line": 17, "column": 1, - "endLine": 24, + "endLine": 23, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, "endColumn": 23, "problem": "InteropDirectAccessToTSTypes", "autofix": [ { - "start": 731, - "end": 762, - "replacementText": "objectLiteralType.setPropertyByName('name',ESObject.wrap(\"test\"))" + "start": 744, + "end": 775, + "replacementText": "objectLiteralType.setPropertyByName('name',ESObject.wrap(\"test\"))", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 23 } ], "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-access-ts-types)", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, { - "line": 26, + "line": 27, "column": 1, - "endLine": 26, + "endLine": 27, "endColumn": 22, "problem": "InteropDirectAccessToTSTypes", "autofix": [ { - "start": 764, - "end": 794, - "replacementText": "intersectionType.setPropertyByName('name',ESObject.wrap(\"test\"))" + "start": 777, + "end": 807, + "replacementText": "intersectionType.setPropertyByName('name',ESObject.wrap(\"test\"))", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 22 } ], "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-access-ts-types)", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, { - "line": 28, + "line": 30, "column": 1, - "endLine": 28, + "endLine": 30, "endColumn": 13, "problem": "InteropTSFunctionInvoke", "suggest": "", - "rule": "Cannot invoke functions implemented in TypeScript (arkts-interop-ts-function)", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", "severity": "ERROR" - }, - { - "line": 30, + }, + { + "line": 31, + "column": 3, + "endLine": 32, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 34, "column": 1, - "endLine": 30, + "endLine": 34, "endColumn": 20, "problem": "InteropDirectAccessToTSTypes", "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-access-ts-types)", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" - } + } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types.ets.json b/ets2panda/linter/test/interop/unique_types.ets.json index 9f305c86d7ff705098b1e480818e125d5e6e3a4a..3e8e488310b0cc25d757e85c0dad6e55c2c622c1 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.json +++ b/ets2panda/linter/test/interop/unique_types.ets.json @@ -1,17 +1,14 @@ { - "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": [] -} + "result": [ + { + "line": 17, + "column": 1, + "endLine": 23, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types.ets.migrate.ets b/ets2panda/linter/test/interop/unique_types.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..76dc6876ccb1e82d96fcc00a1e7f99d74ce192f2 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types.ets.migrate.ets @@ -0,0 +1,36 @@ +/* + * 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. +*/ +'use static' + +import { + objectLiteralType, + intersectionType, + tsFunction, + stringType, + enumType +} from "./ignore_files/unique_types"; + +objectLiteralType.setPropertyByName('name',ESObject.wrap("test")) + +intersectionType.setPropertyByName('name',ESObject.wrap("test")); + +try { +tsFunction(); +} catch (e) { +} + +stringType = "test" //should pass + +enumType = "A"; //should fail diff --git a/ets2panda/linter/test/interop/unique_types.ets.migrate.json b/ets2panda/linter/test/interop/unique_types.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..6e09d425c502ac388ee42e63dd94a6045ed3e8b4 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 1, + "endLine": 23, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 13, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 32, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 20, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.args.json b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.args.json index 5efbceacdc279d08c370af862c859f2d6300fafb..e7a5dbc614c695778265e9fb7d345a304a601675 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.args.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.ets b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1c0c40caa7491cddffb43f33ee27a0e153bab635 --- /dev/null +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI'; + +@AnimatableExtend +function animatableWidth(this: TextAttribute, width: number): this { + this.width(width); + return this; +} + +@Entry +@Component +struct AnimatablePropertyExample { + @State textWidth: number = 80; + + build() { + Column() { + Text("AnimatableProperty") + .animatableWidth(this.textWidth) + .animation({ duration: 2000, curve: Curve.Ease }) + Button("Play") + .onClick(() => { + this.textWidth = this.textWidth == 80 ? 160 : 80; + }) + }.width("100%") + .padding(10) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.json b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..32075de8acc822612c282834429443c8f3af2fbd --- /dev/null +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 12, + "endLine": 21, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 26, + "endLine": 19, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 63, + "endLine": 19, + "endColumn": 67, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.args.json b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.args.json index 5efbceacdc279d08c370af862c859f2d6300fafb..e7a5dbc614c695778265e9fb7d345a304a601675 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.args.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.ets b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..eebe111df2e33343a1fb5e71e0907fc66edadba9 --- /dev/null +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AnimatableExtend, TextAttribute, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI'; + +@AnimatableExtend +function animatableWidth(this: TextAttribute, width: number): this { + this.width(width); + return this; +} + +@Entry +@Component +struct AnimatablePropertyExample { + @State textWidth: number = 80; + + build() { + Column() { + Text("AnimatableProperty") + .animatableWidth(this.textWidth) + .animation({ duration: 2000, curve: Curve.Ease }) + Button("Play") + .onClick(() => { + this.textWidth = this.textWidth == 80 ? 160 : 80; + }) + }.width("100%") + .padding(10) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.json b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4e365eb63e844f5a0e63f2d388f14f693d0936c3 --- /dev/null +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 3, + "endLine": 20, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 26, + "endLine": 19, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 63, + "endLine": 19, + "endColumn": 67, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-array-type-immutable.ets b/ets2panda/linter/test/main/arkts-array-type-immutable.ets new file mode 100644 index 0000000000000000000000000000000000000000..75a02116dd78aca7e564933a329955ca512e8641 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.ets @@ -0,0 +1,37 @@ +/* + * 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. + */ + +let a: number[] = [1] +let b: (number | string)[] = a // error + +let a1: (number | string)[] = [1] +let b1: (number | string)[] = a1 // ok + +let b2: (number | string)[]; +b2 = a // error + +class A { + a: (number | string)[] = [1]; +} + +let aA: A = new A(); +aA.a = a; // error + +let a3: (number | string)[] = new Array(1, 2); // error + +function test(a: number[]): void { + let b: (number | string)[] = [1]; + b = a; // error +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-array-type-immutable.ets.args.json b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.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": "" + } +} \ 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 new file mode 100644 index 0000000000000000000000000000000000000000..802ecf8492f3cd9b72db09b1e1bc5f30e6b318a4 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.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": 17, + "column": 5, + "endLine": 17, + "endColumn": 31, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 7, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 9, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 54, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 8, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_2.ets.autofix.json b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.json similarity index 100% rename from ets2panda/linter/test/main/data_observation_2.ets.autofix.json rename to ets2panda/linter/test/main/arkts-array-type-immutable.ets.json diff --git a/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e05df4b070f3c8182a47729796cadd4024d4427 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +typeof new Number(1) // error +new Number(1) == new Number(1) // error +if (new Boolean(false)) {} // error +let a = new String('111') // error +new Boolean // error +new String // error +new Number // error \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.args.json b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-primitive-type-normalization.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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1b81953cde926b95f9f144bcb2c8500b78c402a8 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 8, + "endLine": 16, + "endColumn": 21, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 14, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 18, + "endLine": 17, + "endColumn": 31, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 23, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 9, + "endLine": 19, + "endColumn": 26, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 12, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 11, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 11, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_2.ets.json b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.json similarity index 100% rename from ets2panda/linter/test/main/data_observation_2.ets.json rename to ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.json diff --git a/ets2panda/linter/test/main/arktsutils_module.ets b/ets2panda/linter/test/main/arktsutils_module.ets new file mode 100644 index 0000000000000000000000000000000000000000..3bfeec6005331e400a16972a240767cc9f567293 --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { utils } from './oh_modules/@arkts.utils'; + +import { utils as ArkTSUtilsAlias } from './oh_modules/@arkts.utils'; + +import { utils as kitArkTSUtils } from './oh_modules/@kit.ArkTS'; + +import { utils as definedArkTSUtils } from 'user_defined_worker'; //legal + +export { utils } from './oh_modules/@arkts.utils'; + +function tesCollectionsUsage() { + + const utils1: string = utils.ASON.stringify(1); + + const utils2 = ArkTSUtilsAlias.ASON.stringify(1); + + const utils3 = kitArkTSUtils.ASON.stringify(1); + + const utils4: string = ArkTSUtilsAlias.ASON.stringify(1); +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.args.json b/ets2panda/linter/test/main/arktsutils_module.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b13bb90d5b5f6d3dc5f0d054663eeba637fcc7dd --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json b/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..6f9939410a6a6da1809a944a1ab49f898c81de50 --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 28, + "column": 32, + "endLine": 28, + "endColumn": 36, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 34, + "endLine": 30, + "endColumn": 38, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 32, + "endLine": 32, + "endColumn": 36, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 42, + "endLine": 34, + "endColumn": 46, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json b/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..05eac65f01caa029cdbabccb62bd89eee356c906 --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json @@ -0,0 +1,86 @@ +{ + "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": 28, + "column": 32, + "endLine": 28, + "endColumn": 36, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "autofix": [ + { + "start": 981, + "end": 991, + "replacementText": "JSON" + } + ], + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 34, + "endLine": 30, + "endColumn": 38, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "autofix": [ + { + "start": 1024, + "end": 1044, + "replacementText": "JSON" + } + ], + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 32, + "endLine": 32, + "endColumn": 36, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "autofix": [ + { + "start": 1077, + "end": 1095, + "replacementText": "JSON" + } + ], + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 42, + "endLine": 34, + "endColumn": 46, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "autofix": [ + { + "start": 1136, + "end": 1156, + "replacementText": "JSON" + } + ], + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/sdkwhite/ConstructorIface4.ets.json b/ets2panda/linter/test/main/arktsutils_module.ets.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/ConstructorIface4.ets.json rename to ets2panda/linter/test/main/arktsutils_module.ets.json diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.migrate.ets b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..c44acf5845a4f1c185a9a5c6c86a4032d4f7cd1e --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.ets @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { utils } from './oh_modules/@arkts.utils'; + +import { utils as ArkTSUtilsAlias } from './oh_modules/@arkts.utils'; + +import { utils as kitArkTSUtils } from './oh_modules/@kit.ArkTS'; + +import { utils as definedArkTSUtils } from 'user_defined_worker'; //legal + +export { utils } from './oh_modules/@arkts.utils'; + +function tesCollectionsUsage() { + + const utils1: string = JSON.stringify(1); + + const utils2 = JSON.stringify(1); + + const utils3 = JSON.stringify(1); + + const utils4: string = JSON.stringify(1); +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets b/ets2panda/linter/test/main/array_index_expr_type.ets index c8eed0c0d8ac0a70278db5cb3cd670dc886a2a94..fe370c16cdb5ee0ec55a04f685b25b665d6c4bb1 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets +++ b/ets2panda/linter/test/main/array_index_expr_type.ets @@ -78,8 +78,8 @@ let c:int = 1; let d:long = 1; let arr:number[] = [1,2,3] - +arr[true?1.3:1.2] arr[a] = 1; arr[b] = 1; arr[c] = 1; -arr[d] = 1; \ No newline at end of file +arr[d] = 1; diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.args.json b/ets2panda/linter/test/main/array_index_expr_type.ets.args.json index 1b80aa9e7367c4d206bb53f8fc43c77fc24045d7..e7a5dbc614c695778265e9fb7d345a304a601675 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.args.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.args.json @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json b/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json index 16b8d6a258bf2ddcf945e702628b0d3f5d2b70f1..5bf7d76719c3a74aedb85c6357fe83d323e30047 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json @@ -54,6 +54,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 19, + "column": 21, + "endLine": 19, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 20, "column": 7, @@ -64,6 +74,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 32, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 21, "column": 7, @@ -194,6 +214,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 27, + "column": 20, + "endLine": 27, + "endColumn": 23, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 28, "column": 7, @@ -204,6 +234,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 29, "column": 7, @@ -373,6 +413,16 @@ "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 17, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json b/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..e6e11862be7b395fe014aa219233b821b93a68ab --- /dev/null +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json @@ -0,0 +1,631 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 17, + "column": 7, + "endLine": 17, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 639, + "end": 657, + "replacementText": "an_array: number[] = [1, 2, 3]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 7, + "endLine": 18, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 664, + "end": 683, + "replacementText": "a: number = an_array[index]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 20, + "endLine": 18, + "endColumn": 25, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 677, + "end": 682, + "replacementText": "index as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 31, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 690, + "end": 714, + "replacementText": "a1: number = an_array[index + 1]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 21, + "endLine": 19, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 704, + "end": 713, + "replacementText": "(index + 1) as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 721, + "end": 747, + "replacementText": "a2: number = an_array[index + 1.1]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 32, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 735, + "end": 746, + "replacementText": "(index + 1.1) as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 754, + "end": 772, + "replacementText": "b: number = an_array[1.23]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 20, + "endLine": 21, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 767, + "end": 771, + "replacementText": "1.23 as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 20, + "endLine": 22, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 20, + "endLine": 23, + "endColumn": 27, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 20, + "endLine": 24, + "endColumn": 29, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 20, + "endLine": 25, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 7, + "endLine": 26, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 887, + "end": 901, + "replacementText": "g: number = an_array[]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 20, + "endLine": 26, + "endColumn": 20, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 908, + "end": 925, + "replacementText": "h: number = an_array[12.]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 20, + "endLine": 27, + "endColumn": 23, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 921, + "end": 924, + "replacementText": "12. as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 932, + "end": 950, + "replacementText": "i: number = an_array[12.0]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 945, + "end": 949, + "replacementText": "12.0 as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 957, + "end": 972, + "replacementText": "j: number = an_array[0]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 37, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 979, + "end": 1009, + "replacementText": "k: number = an_array[Number.MAX_VALUE]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 36, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 992, + "end": 1008, + "replacementText": "Number.MAX_VALUE as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 37, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1016, + "end": 1046, + "replacementText": "l: number = an_array[Number.MIN_VALUE]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 20, + "endLine": 31, + "endColumn": 36, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1029, + "end": 1045, + "replacementText": "Number.MIN_VALUE as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 44, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1053, + "end": 1090, + "replacementText": "m: number = an_array[Number.MAX_SAFE_INTEGER]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 20, + "endLine": 32, + "endColumn": 43, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1066, + "end": 1089, + "replacementText": "Number.MAX_SAFE_INTEGER as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1098, + "end": 1113, + "replacementText": "array: number[] = [1, 2, 3]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1201, + "end": 1208, + "replacementText": "index_1 as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1217, + "end": 1224, + "replacementText": "index_2 as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1391, + "end": 1409, + "replacementText": "array1: number[] = [1, 2, 3]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 18, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1418, + "end": 1428, + "replacementText": "getIndex() as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 5, + "endLine": 53, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1436, + "end": 1454, + "replacementText": "array2: number[] = [1, 2, 3]" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 3, + "endLine": 64, + "endColumn": 12, + "problem": "EnumMemberNonConstInit", + "suggest": "", + "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 6, + "endLine": 67, + "endColumn": 11, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1678, + "end": 1683, + "replacementText": "TE.AA as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 9, + "problem": "IndexNegative", + "suggest": "", + "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 6, + "endLine": 73, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1744, + "end": 1757, + "replacementText": "1.1 as int" + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 17, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0d5918aee10e9088cb8068f335cd2d3fbf8f1a27 --- /dev/null +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets @@ -0,0 +1,85 @@ +/* + * 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. + */ + +function foo(index:number){ + let an_array: number[] = [1, 2, 3] + let a: number = an_array[index as int] + let a1: number = an_array[(index + 1) as int] + let a2: number = an_array[(index + 1.1) as int] + let b: number = an_array[1.23 as int] + let c = an_array[true] + let d = an_array['index'] + let e = an_array[undefined] + let f = an_array[null] + let g: number = an_array[] + let h: number = an_array[12. as int] + let i: number = an_array[12.0 as int] + let j: number = an_array[0] + let k: number = an_array[Number.MAX_VALUE as int] + let l: number = an_array[Number.MIN_VALUE as int] + let m: number = an_array[Number.MAX_SAFE_INTEGER as int] +} + +let array: number[] = [1, 2, 3] +const index_1: number = 1.3; +let index_2: number = 1.3; +let index_3: number = 1; +array[index_1 as int]; +array[index_2 as int]; +array[index_3]; +let index_4: int = 2 +array[index_4]; +const index_5: number = 1.0; +array[index_5]; + +function getIndex(): number { + return Math.random() * 10; +} +let array1: number[] = [1, 2, 3]; +array1[getIndex() as int]; + +let array2: number[] = [1, 2, 3]; +for (let i: number = 0; i < array2.length; i++) { + console.log(array2[i]); +} + +for (let i: int = 0; i < array2.length; i++) { + console.log(array2[i]); +} + +let arr1:number[] = [1, 2, 3] +enum TE{ + AA = 1.12 + BB = 0 +} +arr1[TE.AA as int]; +arr1[TE.BB]; +arr1[+0]; +arr1[-0]; +arr1[+1]; +arr1[-1]; +arr1[1.1 as int]; + +let a:short = 1; +let b:byte = 1; +let c:int = 1; +let d:long = 1; + +let arr:number[] = [1,2,3] +arr[true?1.3:1.2] +arr[a] = 1; +arr[b] = 1; +arr[c] = 1; +arr[d] = 1; diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8407a76e0f1a39a6b7313c0ba4b4143b441bb8ad --- /dev/null +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json @@ -0,0 +1,138 @@ +{ + "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": 22, + "column": 7, + "endLine": 22, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 20, + "endLine": 22, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 20, + "endLine": 23, + "endColumn": 27, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 20, + "endLine": 24, + "endColumn": 29, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 20, + "endLine": 25, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 28, + "endLine": 26, + "endColumn": 28, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 3, + "endLine": 64, + "endColumn": 12, + "problem": "EnumMemberNonConstInit", + "suggest": "", + "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 9, + "problem": "IndexNegative", + "suggest": "", + "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 17, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/case_expr.ets.arkts2.json b/ets2panda/linter/test/main/case_expr.ets.arkts2.json index feece0064b76082f5b8d0a055bd6a5a44bd70921..6aac05a29b702d66a70faf39766582f1ed0a738a 100755 --- a/ets2panda/linter/test/main/case_expr.ets.arkts2.json +++ b/ets2panda/linter/test/main/case_expr.ets.arkts2.json @@ -61,7 +61,7 @@ "endColumn": 12, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/catch_clause.ets.args.json b/ets2panda/linter/test/main/catch_clause.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/catch_clause.ets.args.json +++ b/ets2panda/linter/test/main/catch_clause.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/catch_clause.ets.migrate.ets b/ets2panda/linter/test/main/catch_clause.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0559c93caa0efe8814e2116f7fa16fdd61fddb1b --- /dev/null +++ b/ets2panda/linter/test/main/catch_clause.ets.migrate.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022-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. + */ + +try { + if (true) throw "Catch with 'any' type"; +} catch (e) { + console.log(e); +} + +try { + if (true) throw "Catch with 'unknown' type"; +} catch (e) { + console.log(e); +} + +try { + if (true) throw 'Catch without explicit type'; +} catch (e) { + console.log(e); +} diff --git a/ets2panda/linter/test/main/catch_clause.ets.migrate.json b/ets2panda/linter/test/main/catch_clause.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..1ad3035275c5a4d94aa8e255c95a2bf7fe1b20d3 --- /dev/null +++ b/ets2panda/linter/test/main/catch_clause.ets.migrate.json @@ -0,0 +1,48 @@ +{ + "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": 13, + "endLine": 17, + "endColumn": 43, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 13, + "endLine": 23, + "endColumn": 47, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 13, + "endLine": 29, + "endColumn": 49, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 743b046cc0b5f7112647e3b9f4ba4f7e216e8d75..368d6ea3cad7777c00841d0645f8db69ae8ad8cd 100644 --- a/ets2panda/linter/test/main/class_as_object.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_as_object.ets.arkts2.json @@ -234,6 +234,16 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, + { + "line": 81, + "column": 14, + "endLine": 81, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, { "line": 87, "column": 10, @@ -344,16 +354,6 @@ "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, - { - "line": 128, - "column": 15, - "endLine": 128, - "endColumn": 23, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 129, "column": 15, @@ -774,16 +774,6 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 178, - "column": 14, - "endLine": 178, - "endColumn": 22, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 179, "column": 7, @@ -841,7 +831,7 @@ "endColumn": 12, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/class_no_constructor.ets b/ets2panda/linter/test/main/class_no_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..c13aa9b54ab1233ccdae9d6496c2f0e0147d1570 --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ +'use static' + +class A {} + +const variable = new A().constructor diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.args.json b/ets2panda/linter/test/main/class_no_constructor.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..8a4be28991e8164c0366b8b3ad0dffbc04910a27 --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.ets.args.json @@ -0,0 +1,20 @@ +{ + "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": "", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json b/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..12f07f6aefeab765323013130ba3901be22f8c2f --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json @@ -0,0 +1,28 @@ +{ + "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": 18, + "endLine": 19, + "endColumn": 37, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "The Class object does not have a constructor. (arkts-no-arkts-constructor)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.json b/ets2panda/linter/test/main/class_no_constructor.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd1b7140ca95b67336908f5fca6dec77fb46b2c0 --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.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_no_constructor.ets.migrate.ets b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..c13aa9b54ab1233ccdae9d6496c2f0e0147d1570 --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ +'use static' + +class A {} + +const variable = new A().constructor diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..12f07f6aefeab765323013130ba3901be22f8c2f --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 18, + "endLine": 19, + "endColumn": 37, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "The Class object does not have a constructor. (arkts-no-arkts-constructor)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/class_static_block.ets.args.json b/ets2panda/linter/test/main/class_static_block.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/class_static_block.ets.args.json +++ b/ets2panda/linter/test/main/class_static_block.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/migrate/class_static_block.sts b/ets2panda/linter/test/main/class_static_block.ets.migrate.ets similarity index 93% rename from ets2panda/linter/test/migrate/class_static_block.sts rename to ets2panda/linter/test/main/class_static_block.ets.migrate.ets index 2e9ad55a382e574292b3a88d72c0a90fad00b090..111e4f30bb45f109307f2db6c31d221583ec54c6 100644 --- a/ets2panda/linter/test/migrate/class_static_block.sts +++ b/ets2panda/linter/test/main/class_static_block.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -17,12 +17,11 @@ class C { static s: string; static { C.s = 'string'; - } + C.n = C.s.length; +} static n: number; - static { - C.n = C.s.length; - } + } class B { diff --git a/ets2panda/linter/test/sdkwhite/DeclWithDuplicateName5.ets.json b/ets2panda/linter/test/main/class_static_block.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/DeclWithDuplicateName5.ets.json rename to ets2panda/linter/test/main/class_static_block.ets.migrate.json diff --git a/ets2panda/linter/test/main/class_static_init.ets b/ets2panda/linter/test/main/class_static_init.ets index 29c91f9a869279c5e62eaa22dae20bb1e287e91c..c74ec693d923b780a737b7bae7c058db3e8696d4 100755 --- a/ets2panda/linter/test/main/class_static_init.ets +++ b/ets2panda/linter/test/main/class_static_init.ets @@ -50,4 +50,128 @@ struct Index { .height('100%') .width('100%') } -} \ No newline at end of file +} + +// Top 0 case +class BB {} + +class AA { + static b: BB; +} + +class CC { + static count: number; +} + +class DD { + static config: { theme: string}; +} + +class EE { + static name: string; + constructor() { + E.name = "default" + } +} + +// Basic Types +class PrimitiveTypes { + static uninitializedString: string; + static uninitializedNumber: number; + static uninitializedBoolean: boolean; +} + +// Array Types +class ArrayTypes { + static uninitializedStringArray: string[]; + static uninitializedNumberArray: number[]; + static uninitializedObjectArray: { id: number }[]; + static uninitializedUnionArray: (string | number)[]; +} + +// Object Types +class ObjectTypes { + static uninitializedSimpleObject: { name: string; age: number }; + static uninitializedNestedObject: { + id: number; + metadata: { + createdAt: Date; + tags: string[]; + }; + }; +} + +// Special Built-in Types +class BuiltInTypes { + static uninitializedDate: Date; + static uninitializedMap: Map; + static uninitializedSet: Set; + static uninitializedPromise: Promise; +} + +// Union and Intersection Types +class AdvancedTypes { + static uninitializedUnion: string | number; + static uninitializedIntersection: { name: string } & { age: number }; + static uninitializedLiteralUnion: 'success' | 'error'; +} + +// Optional and Nullable Types +class NullableTypes { + static uninitializedOptional?: string; + static uninitializedNull: null; + static uninitializedUndefined: undefined; +} + +// Generic Types +class GenericTypes { + static uninitializedGenericArray: T[]; + static uninitializedGenericValue: T; +} + +// Function Types +class FunctionTypes { + static uninitializedFunction: () => void; + static uninitializedCallback: (result: string) => number; +} + +// Complex Combined Types +class ComplexTypes { + static uninitializedComplexArray: Array<{ id: number; data: Map> }>; + static uninitializedRecord: Record; + static uninitializedTuple: [string, number, boolean?]; +} + +// Custom Class Types +class User { + id: number; + name: string; +} + +class CustomClassTypes { + static uninitializedUser: User; + static uninitializedUsers: User[]; +} + +// Enum Types +enum Status { + Active, + Inactive +} + +class EnumTypes { + static uninitializedStatus: Status; + static uninitializedStatusArray: Status[]; +} + +// Never and Unknown Types +class SpecialTypes { + static uninitializedNever: never; + static uninitializedUnknown: unknown; + static uninitializedAny: any; +} + + +class Test1 { + static count: string | undefined; +} diff --git a/ets2panda/linter/test/main/class_static_init.ets.args.json b/ets2panda/linter/test/main/class_static_init.ets.args.json index 3ef4496a819a201892114d1c90f78ae32053c334..4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0 100755 --- a/ets2panda/linter/test/main/class_static_init.ets.args.json +++ b/ets2panda/linter/test/main/class_static_init.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/class_static_init.ets.arkts2.json b/ets2panda/linter/test/main/class_static_init.ets.arkts2.json index 2b682eca6edc35d435e54a21fe6006b9ba6e70e6..17db245900a4df3e63c8fb82090b3ba1c3d0e4a1 100755 --- a/ets2panda/linter/test/main/class_static_init.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_static_init.ets.arkts2.json @@ -64,6 +64,436 @@ "rule": "The static property has no initializer (arkts-class-static-initialization)", "severity": "ERROR" }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 16, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 35, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 18, + "endLine": 67, + "endColumn": 19, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 3, + "endLine": 71, + "endColumn": 23, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 3, + "endLine": 79, + "endColumn": 38, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 3, + "endLine": 86, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 3, + "endLine": 87, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 3, + "endLine": 88, + "endColumn": 53, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 36, + "endLine": 88, + "endColumn": 37, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 3, + "endLine": 89, + "endColumn": 55, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 67, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 37, + "endLine": 94, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 3, + "endLine": 101, + "endColumn": 5, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 37, + "endLine": 95, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 15, + "endLine": 97, + "endColumn": 16, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 3, + "endLine": 106, + "endColumn": 34, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 3, + "endLine": 107, + "endColumn": 48, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 3, + "endLine": 108, + "endColumn": 40, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 3, + "endLine": 109, + "endColumn": 46, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, + "endColumn": 46, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 3, + "endLine": 115, + "endColumn": 72, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 71, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 56, + "endLine": 115, + "endColumn": 57, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 3, + "endLine": 116, + "endColumn": 57, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 3, + "endLine": 128, + "endColumn": 41, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 3, + "endLine": 129, + "endColumn": 39, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 3, + "endLine": 134, + "endColumn": 44, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 3, + "endLine": 135, + "endColumn": 60, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 3, + "endLine": 140, + "endColumn": 91, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 43, + "endLine": 140, + "endColumn": 44, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 3, + "endLine": 141, + "endColumn": 65, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 46, + "endLine": 141, + "endColumn": 47, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 3, + "endLine": 142, + "endColumn": 57, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 3, + "endLine": 152, + "endColumn": 34, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 3, + "endLine": 153, + "endColumn": 37, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 3, + "endLine": 163, + "endColumn": 38, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 3, + "endLine": 164, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 3, + "endLine": 169, + "endColumn": 36, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 3, + "endLine": 170, + "endColumn": 40, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 32, + "endLine": 170, + "endColumn": 39, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 3, + "endLine": 171, + "endColumn": 32, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 28, + "endLine": 171, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, { "line": 42, "column": 2, @@ -103,6 +533,26 @@ "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" + }, + { + "line": 147, + "column": 3, + "endLine": 147, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 148, + "column": 3, + "endLine": 148, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_static_init.ets.autofix.json b/ets2panda/linter/test/main/class_static_init.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..2be737a16e4dfb45b6d657993f04648d89d1736b --- /dev/null +++ b/ets2panda/linter/test/main/class_static_init.ets.autofix.json @@ -0,0 +1,876 @@ +{ + "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": 21, + "column": 3, + "endLine": 21, + "endColumn": 14, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 641, + "end": 652, + "replacementText": "static a: A | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 14, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 668, + "end": 679, + "replacementText": "static g: G | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 15, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 753, + "end": 765, + "replacementText": "static g: G | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 14, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 781, + "end": 792, + "replacementText": "static a: A | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 3, + "endLine": 46, + "endColumn": 29, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 933, + "end": 959, + "replacementText": "public static abc: string = \"\";" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 16, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1088, + "end": 1101, + "replacementText": "static b: BB | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 35, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1156, + "end": 1188, + "replacementText": "static config: {\n theme: string;\n} = {\n theme: \"\"\n };" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 18, + "endLine": 67, + "endColumn": 19, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 1143, + "end": 1143, + "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n theme: string;\n}\n" + }, + { + "start": 1171, + "end": 1187, + "replacementText": "GeneratedTypeLiteralInterface_1" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 3, + "endLine": 71, + "endColumn": 23, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1205, + "end": 1225, + "replacementText": "static name: string = \"\";" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 3, + "endLine": 79, + "endColumn": 38, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1314, + "end": 1349, + "replacementText": "static uninitializedString: string = \"\";" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 3, + "endLine": 86, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1467, + "end": 1509, + "replacementText": "static uninitializedStringArray: string[] = [];" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 3, + "endLine": 87, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1512, + "end": 1554, + "replacementText": "static uninitializedNumberArray: number[] = [];" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 3, + "endLine": 88, + "endColumn": 53, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1557, + "end": 1607, + "replacementText": "static uninitializedObjectArray: {\n id: number;\n }[] = [];" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 36, + "endLine": 88, + "endColumn": 37, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 1446, + "end": 1446, + "replacementText": "interface GeneratedTypeLiteralInterface_2 {\n id: number;\n}\n" + }, + { + "start": 1590, + "end": 1604, + "replacementText": "GeneratedTypeLiteralInterface_2" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 3, + "endLine": 89, + "endColumn": 55, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1610, + "end": 1662, + "replacementText": "static uninitializedUnionArray: (string | number)[] = [];" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 67, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1704, + "end": 1768, + "replacementText": "static uninitializedSimpleObject: {\n name: string;\n age: number;\n} = {\n name: \"\"\n };" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 37, + "endLine": 94, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 1682, + "end": 1682, + "replacementText": "interface GeneratedTypeLiteralInterface_3 {\n name: string;\n age: number;\n}\n" + }, + { + "start": 1738, + "end": 1767, + "replacementText": "GeneratedTypeLiteralInterface_3" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 3, + "endLine": 101, + "endColumn": 5, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1771, + "end": 1895, + "replacementText": "static uninitializedNestedObject: {\n id: number;\n metadata: {\n createdAt: Date;\n tags: string[];\n };\n} = {\n metadata: {\n createdAt: new Date(),\n tags: []\n }\n };" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 37, + "endLine": 95, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 1682, + "end": 1682, + "replacementText": "interface GeneratedTypeLiteralInterface_4 {\n id: number;\n metadata: {\n createdAt: Date;\n tags: string[];\n };\n}\n" + }, + { + "start": 1805, + "end": 1894, + "replacementText": "GeneratedTypeLiteralInterface_4" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 15, + "endLine": 97, + "endColumn": 16, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 1682, + "end": 1682, + "replacementText": "interface GeneratedTypeLiteralInterface_5 {\n createdAt: Date;\n tags: string[];\n}\n" + }, + { + "start": 1837, + "end": 1889, + "replacementText": "GeneratedTypeLiteralInterface_5" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 3, + "endLine": 106, + "endColumn": 34, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1948, + "end": 1979, + "replacementText": "static uninitializedDate: Date = new Date();" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 3, + "endLine": 107, + "endColumn": 48, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 1982, + "end": 2027, + "replacementText": "static uninitializedMap: Map = new Map();" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 3, + "endLine": 108, + "endColumn": 40, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 2030, + "end": 2067, + "replacementText": "static uninitializedSet: Set = new Set();" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 3, + "endLine": 109, + "endColumn": 46, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 2070, + "end": 2113, + "replacementText": "static uninitializedPromise: Promise = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, + "endColumn": 46, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 3, + "endLine": 115, + "endColumn": 72, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 71, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 2149, + "end": 2149, + "replacementText": "interface GeneratedTypeLiteralInterface_6 {\n name: string;\n}\n" + }, + { + "start": 2253, + "end": 2269, + "replacementText": "GeneratedTypeLiteralInterface_6" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 56, + "endLine": 115, + "endColumn": 57, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 2149, + "end": 2149, + "replacementText": "interface GeneratedTypeLiteralInterface_7 {\n age: number;\n}\n" + }, + { + "start": 2272, + "end": 2287, + "replacementText": "GeneratedTypeLiteralInterface_7" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 3, + "endLine": 116, + "endColumn": 57, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 3, + "endLine": 128, + "endColumn": 41, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 2567, + "end": 2605, + "replacementText": "static uninitializedGenericArray: T[] = [];" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 3, + "endLine": 129, + "endColumn": 39, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 2608, + "end": 2644, + "replacementText": "static uninitializedGenericValue: T | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 3, + "endLine": 134, + "endColumn": 44, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 3, + "endLine": 135, + "endColumn": 60, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 3, + "endLine": 140, + "endColumn": 91, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 43, + "endLine": 140, + "endColumn": 44, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 2821, + "end": 2821, + "replacementText": "interface GeneratedTypeLiteralInterface_8 {\n id: number;\n data: Map>;\n}\n" + }, + { + "start": 2884, + "end": 2930, + "replacementText": "GeneratedTypeLiteralInterface_8" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 3, + "endLine": 141, + "endColumn": 65, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 2935, + "end": 2997, + "replacementText": "static uninitializedRecord: Record | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 46, + "endLine": 141, + "endColumn": 47, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 2821, + "end": 2821, + "replacementText": "interface GeneratedTypeLiteralInterface_9 {\n value: number;\n}\n" + }, + { + "start": 2978, + "end": 2995, + "replacementText": "GeneratedTypeLiteralInterface_9" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 3, + "endLine": 142, + "endColumn": 57, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 3, + "endLine": 152, + "endColumn": 34, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 3153, + "end": 3184, + "replacementText": "static uninitializedUser: User | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 3, + "endLine": 153, + "endColumn": 37, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 3187, + "end": 3221, + "replacementText": "static uninitializedUsers: User[] = [];" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 3, + "endLine": 163, + "endColumn": 38, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 3297, + "end": 3332, + "replacementText": "static uninitializedStatus: Status | undefined = undefined;" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 3, + "endLine": 164, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "autofix": [ + { + "start": 3335, + "end": 3377, + "replacementText": "static uninitializedStatusArray: Status[] = [];" + } + ], + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 3, + "endLine": 169, + "endColumn": 36, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 3, + "endLine": 170, + "endColumn": 40, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 32, + "endLine": 170, + "endColumn": 39, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 3, + "endLine": 171, + "endColumn": 32, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 28, + "endLine": 171, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 2, + "endLine": 42, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Text } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 2, + "endLine": 43, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Text } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 4, + "endLine": 45, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Text } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 7, + "endLine": 49, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Text } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 3, + "endLine": 147, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 148, + "column": 3, + "endLine": 148, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_static_init.ets.json b/ets2panda/linter/test/main/class_static_init.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..d9c1c79cdcb82d17fe50614f5315786b6907bbaa 100755 --- a/ets2panda/linter/test/main/class_static_init.ets.json +++ b/ets2panda/linter/test/main/class_static_init.ets.json @@ -13,5 +13,146 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 67, + "column": 18, + "endLine": 67, + "endColumn": 19, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 36, + "endLine": 88, + "endColumn": 37, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 37, + "endLine": 94, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 37, + "endLine": 95, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 15, + "endLine": 97, + "endColumn": 16, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 71, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 56, + "endLine": 115, + "endColumn": 57, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 43, + "endLine": 140, + "endColumn": 44, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 46, + "endLine": 141, + "endColumn": 47, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 32, + "endLine": 170, + "endColumn": 39, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 28, + "endLine": 171, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 3, + "endLine": 147, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 148, + "column": 3, + "endLine": 148, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/void_operator.sts b/ets2panda/linter/test/main/collections_module.ets similarity index 45% rename from ets2panda/linter/test/migrate/void_operator.sts rename to ets2panda/linter/test/main/collections_module.ets index 1d0ace9453ceb6c8cba8f1ff007d5f2c89cabe84..5fba982f6b6426a38730e4019763ff9658df5fc2 100644 --- a/ets2panda/linter/test/migrate/void_operator.sts +++ b/ets2panda/linter/test/main/collections_module.ets @@ -13,60 +13,26 @@ * limitations under the License. */ -void 0; +import { collections } from './oh_modules/@arkts.collections'; -void 'hello'; +import { collections as collectionsAlias } from './oh_modules/@arkts.collections'; -void (1 + 2); +import { collections as kitCollections } from './oh_modules/@kit.ArkTS'; -void { a: 1, b: 2 }; +import { collections as definedCollections } from 'user_defined_worker'; //legal -void [1, 2, 3]; +function tesCollectionsUsage() { -void console.log('expression evaluated'); + const collections1: collections.Array = new collections.Array(); -const undefined_value = void 1; + const collections2 = new collectionsAlias.Array(); -const undefined_value2: undefined = void 2; + const collections3 = new kitCollections.Array(); -const undefined_value3: number | undefined = void 3; + let collections4: collectionsAlias.Array; -void void 1; + const collections5: collectionsAlias.Array = new collectionsAlias.Array(); -void function () { - console.log('foo'); -}; + let collections6: definedCollections.Array; // legal -void function () { - console.log("bar!"); -}(); - -void (function () { - console.log('baz!'); -})(); - -void class {}; - -void (class {}); - -void (() => {}); - -function foo() { - let a = 1; - void a++; - - let b = [1, 2, 3]; - void console.log(b.filter(x => x % 2 !== 0)); - - void function() { - console.log('foo'); - }; - - void function localFun() { - console.log('foo'); - }; - - void class {}; - - void class localClass{}; } diff --git a/ets2panda/linter/test/main/collections_module.ets.args.json b/ets2panda/linter/test/main/collections_module.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b13bb90d5b5f6d3dc5f0d054663eeba637fcc7dd --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/main/collections_module.ets.arkts2.json b/ets2panda/linter/test/main/collections_module.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..584e375a01ba06e7a2ecd03772a34d762c5ccbba --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.arkts2.json @@ -0,0 +1,138 @@ +{ + "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": 10, + "endLine": 16, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 25, + "endLine": 18, + "endColumn": 41, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 25, + "endLine": 20, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 23, + "endLine": 26, + "endColumn": 34, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 55, + "endLine": 26, + "endColumn": 66, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 44, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 28, + "endLine": 30, + "endColumn": 42, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 21, + "endLine": 32, + "endColumn": 37, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 23, + "endLine": 34, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 76, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/collections_module.ets.autofix.json b/ets2panda/linter/test/main/collections_module.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..3b091c13f428361247667bb4cc8bd51cef9274b9 --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.autofix.json @@ -0,0 +1,222 @@ +{ + "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": 10, + "endLine": 16, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 605, + "end": 667, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 669, + "end": 751, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 25, + "endLine": 18, + "endColumn": 41, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 669, + "end": 751, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 753, + "end": 825, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 25, + "endLine": 20, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 753, + "end": 825, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 23, + "endLine": 26, + "endColumn": 34, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 965, + "end": 982, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 55, + "endLine": 26, + "endColumn": 66, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 997, + "end": 1014, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 44, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1054, + "end": 1076, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 28, + "endLine": 30, + "endColumn": 42, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1116, + "end": 1136, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 21, + "endLine": 32, + "endColumn": 37, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1169, + "end": 1191, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 23, + "endLine": 34, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1224, + "end": 1246, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 76, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1261, + "end": 1283, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/sdkwhite/GlobalThisError&TypeQuery.ets.json b/ets2panda/linter/test/main/collections_module.ets.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/GlobalThisError&TypeQuery.ets.json rename to ets2panda/linter/test/main/collections_module.ets.json diff --git a/ets2panda/linter/test/main/collections_module.ets.migrate.ets b/ets2panda/linter/test/main/collections_module.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..02fc9aaad5de07117bf611e6701de10bcfd98aa1 --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.migrate.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + + + + + +import { collections as definedCollections } from 'user_defined_worker'; //legal + +function tesCollectionsUsage() { + + const collections1: Array = new Array(); + + const collections2: number[] = new Array(); + + const collections3: number[] = new Array(); + + let collections4: Array; + + const collections5: Array = new Array(); + + let collections6: definedCollections.Array; // legal + +} diff --git a/ets2panda/linter/test/main/collections_module.ets.migrate.json b/ets2panda/linter/test/main/collections_module.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4dcf9e56dbc14e1fbd427eeb3ad24f841cacf0ce --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.migrate.json @@ -0,0 +1,18 @@ +{ + "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/custom_layout.ets b/ets2panda/linter/test/main/custom_layout.ets new file mode 100644 index 0000000000000000000000000000000000000000..233a5aaa79d649a1bb3495a25e6cac4ec5b782e9 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets @@ -0,0 +1,100 @@ +/* + * 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. + */ + +@Entry +@Component +struct Index { + build() { + Column() { + CustomLayout1({ builder: ColumnChildren }) + CustomLayout2({ builder: ColumnChildren }) + } + } +} + +@Builder +function ColumnChildren() { + ForEach([1, 2, 3], (index: number) => { //暂不支持lazyForEach的写法 + Text('S' + index) + .fontSize(30) + .width(100) + .height(100) + .borderWidth(2) + .offset({ x: 10, y: 20 }) + }) +} + +@Component +struct CustomLayout1 { + @Builder + doNothingBuilder() { + }; + + @BuilderParam builder: () => void = this.doNothingBuilder; + @State startSize: number = 100; + result: SizeResult = { + width: 0, + height: 0 + }; + + onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { + let startPos = 300; + children.forEach((child) => { + let pos = startPos - child.measureResult.height; + child.layout({ x: pos, y: pos }) + }) + } + + build() { + this.builder() + } +} + +@Component +struct CustomLayout2 { + @Builder + doNothingBuilder() { + }; + + @BuilderParam builder: () => void = this.doNothingBuilder; + @State startSize: number = 100; + result: SizeResult = { + width: 0, + height: 0 + }; + + onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { + let size = 100; + children.forEach((child) => { + let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size }) + size += result.width / 2 + ; + }) + this.result.width = 100; + this.result.height = 400; + return this.result; + } + + build() { + this.builder() + } +} + +@Component +struct CustomLayout3 { + build { + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/custom_layout.ets.args.json b/ets2panda/linter/test/main/custom_layout.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_1.ets.arkts2.json b/ets2panda/linter/test/main/custom_layout.ets.arkts2.json similarity index 61% rename from ets2panda/linter/test/main/data_observation_1.ets.arkts2.json rename to ets2panda/linter/test/main/custom_layout.ets.arkts2.json index da9c036907b761695cf465d96df33b2501ea0c0c..7491a643b31af7bfc5d6037f36a32eaa74a9f7e1 100644 --- a/ets2panda/linter/test/main/data_observation_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/custom_layout.ets.arkts2.json @@ -15,149 +15,109 @@ ], "result": [ { - "line": 55, - "column": 3, - "endLine": 55, - "endColumn": 42, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 3, - "endLine": 56, - "endColumn": 44, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 3, - "endLine": 57, - "endColumn": 43, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 3, - "endLine": 58, - "endColumn": 39, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 3, - "endLine": 59, - "endColumn": 41, - "problem": "DataObservation", + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { - "line": 61, - "column": 3, - "endLine": 61, - "endColumn": 48, - "problem": "DataObservation", + "line": 53, + "column": 9, + "endLine": 53, + "endColumn": 23, + "problem": "NumericSemantics", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 62, - "column": 3, - "endLine": 62, - "endColumn": 41, - "problem": "DataObservation", + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 54, + "problem": "NumericSemantics", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 64, - "column": 3, - "endLine": 64, - "endColumn": 63, - "problem": "DataObservation", + "line": 66, + "column": 8, + "endLine": 66, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { - "line": 65, - "column": 3, - "endLine": 65, - "endColumn": 73, - "problem": "DataObservation", + "line": 79, + "column": 9, + "endLine": 79, + "endColumn": 19, + "problem": "NumericSemantics", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 66, + "line": 97, "column": 3, - "endLine": 66, - "endColumn": 58, - "problem": "DataObservation", + "endLine": 97, + "endColumn": 8, + "problem": "AnyType", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 67, - "column": 3, - "endLine": 67, - "endColumn": 61, - "problem": "DataObservation", + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 76, - "column": 3, - "endLine": 76, - "endColumn": 24, - "problem": "DataObservation", + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 36, - "column": 2, - "endLine": 36, - "endColumn": 10, + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 45, + "line": 27, "column": 2, - "endLine": 45, - "endColumn": 10, + "endLine": 27, + "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 48, - "column": 2, - "endLine": 48, + "line": 29, + "column": 3, + "endLine": 29, "endColumn": 10, "problem": "UIInterfaceImport", "suggest": "", @@ -165,19 +125,19 @@ "severity": "ERROR" }, { - "line": 51, - "column": 2, - "endLine": 51, - "endColumn": 7, + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 52, + "line": 39, "column": 2, - "endLine": 52, + "endLine": 39, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -185,29 +145,29 @@ "severity": "ERROR" }, { - "line": 54, + "line": 41, "column": 4, - "endLine": 54, - "endColumn": 9, + "endLine": 41, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 55, + "line": 45, "column": 4, - "endLine": 55, - "endColumn": 9, + "endLine": 45, + "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 56, + "line": 46, "column": 4, - "endLine": 56, + "endLine": 46, "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", @@ -215,139 +175,139 @@ "severity": "ERROR" }, { - "line": 57, - "column": 4, - "endLine": 57, - "endColumn": 9, + "line": 47, + "column": 11, + "endLine": 47, + "endColumn": 21, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 58, - "column": 4, - "endLine": 58, - "endColumn": 9, + "line": 52, + "column": 35, + "endLine": 52, + "endColumn": 47, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 59, - "column": 4, - "endLine": 59, - "endColumn": 8, + "line": 52, + "column": 65, + "endLine": 52, + "endColumn": 75, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 60, - "column": 4, - "endLine": 60, - "endColumn": 8, + "line": 52, + "column": 90, + "endLine": 52, + "endColumn": 111, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 61, - "column": 4, - "endLine": 61, - "endColumn": 8, + "line": 65, + "column": 2, + "endLine": 65, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 62, + "line": 67, "column": 4, - "endLine": 62, - "endColumn": 8, + "endLine": 67, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 63, + "line": 71, "column": 4, - "endLine": 63, - "endColumn": 11, + "endLine": 71, + "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 64, + "line": 72, "column": 4, - "endLine": 64, - "endColumn": 15, + "endLine": 72, + "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 65, - "column": 4, - "endLine": 65, - "endColumn": 20, + "line": 73, + "column": 11, + "endLine": 73, + "endColumn": 21, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 66, - "column": 4, - "endLine": 66, - "endColumn": 15, + "line": 78, + "column": 33, + "endLine": 78, + "endColumn": 45, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 67, - "column": 4, - "endLine": 67, - "endColumn": 20, + "line": 78, + "column": 63, + "endLine": 78, + "endColumn": 73, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 74, - "column": 2, - "endLine": 74, - "endColumn": 11, + "line": 78, + "column": 88, + "endLine": 78, + "endColumn": 109, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 76, - "column": 4, - "endLine": 76, - "endColumn": 8, + "line": 81, + "column": 19, + "endLine": 81, + "endColumn": 32, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 77, - "column": 4, - "endLine": 77, + "line": 95, + "column": 2, + "endLine": 95, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", diff --git a/ets2panda/linter/test/main/data_observation_1.ets.autofix.json b/ets2panda/linter/test/main/custom_layout.ets.autofix.json similarity index 51% rename from ets2panda/linter/test/main/data_observation_1.ets.autofix.json rename to ets2panda/linter/test/main/custom_layout.ets.autofix.json index 272ff28a6c7ed1d6f72eb111212e79d3ea5f4940..05aaabc6d85a1cc8a3a29a00fe92cb12e7e7299f 100644 --- a/ets2panda/linter/test/main/data_observation_1.ets.autofix.json +++ b/ets2panda/linter/test/main/custom_layout.ets.autofix.json @@ -15,198 +15,145 @@ ], "result": [ { - "line": 55, - "column": 3, - "endLine": 55, - "endColumn": 42, - "problem": "DataObservation", + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", "autofix": [ { - "start": 605, - "end": 605, - "replacementText": "@Observed\n" + "start": 1027, + "end": 1027, + "replacementText": "\n@Layoutable" } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { - "line": 56, - "column": 3, - "endLine": 56, - "endColumn": 44, - "problem": "DataObservation", + "line": 53, + "column": 9, + "endLine": 53, + "endColumn": 23, + "problem": "NumericSemantics", "autofix": [ { - "start": 624, - "end": 624, - "replacementText": "@Observed\n" + "start": 1367, + "end": 1381, + "replacementText": "startPos: number = 300" } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 57, - "column": 3, - "endLine": 57, - "endColumn": 43, - "problem": "DataObservation", + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 54, + "problem": "NumericSemantics", "autofix": [ { - "start": 760, - "end": 760, - "replacementText": "@Observed\n" - }, - { - "start": 722, - "end": 722, - "replacementText": "@Observed\n" - }, - { - "start": 684, - "end": 684, - "replacementText": "@Observed\n" - }, + "start": 1427, + "end": 1470, + "replacementText": "pos: number = startPos - child.measureResult.height" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 8, + "endLine": 66, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", + "autofix": [ { - "start": 664, - "end": 664, - "replacementText": "@Observed\n" + "start": 1571, + "end": 1571, + "replacementText": "\n@Layoutable" } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { - "line": 58, - "column": 3, - "endLine": 58, - "endColumn": 39, - "problem": "DataObservation", + "line": 79, + "column": 9, + "endLine": 79, + "endColumn": 19, + "problem": "NumericSemantics", "autofix": [ { - "start": 854, - "end": 854, - "replacementText": "@Observed\n" + "start": 1909, + "end": 1919, + "replacementText": "size: number = 100" } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 59, + "line": 97, "column": 3, - "endLine": 59, - "endColumn": 41, - "problem": "DataObservation", + "endLine": 97, + "endColumn": 8, + "problem": "AnyType", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 61, - "column": 3, - "endLine": 61, - "endColumn": 48, - "problem": "DataObservation", + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", "autofix": [ { - "start": 919, - "end": 919, - "replacementText": "@Observed\n" - }, - { - "start": 938, - "end": 938, - "replacementText": "@Observed\n" + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 62, - "column": 3, - "endLine": 62, - "endColumn": 41, - "problem": "DataObservation", + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", "autofix": [ { - "start": 957, - "end": 957, - "replacementText": "@Observed\n" + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 64, - "column": 3, - "endLine": 64, - "endColumn": 63, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 3, - "endLine": 65, - "endColumn": 73, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 66, - "column": 3, - "endLine": 66, - "endColumn": 58, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 3, - "endLine": 67, - "endColumn": 61, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 76, - "column": 3, - "endLine": 76, - "endColumn": 24, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 36, - "column": 2, - "endLine": 36, - "endColumn": 10, + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -214,16 +161,16 @@ "severity": "ERROR" }, { - "line": 45, + "line": 27, "column": 2, - "endLine": 45, - "endColumn": 10, + "endLine": 27, + "endColumn": 9, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -231,16 +178,16 @@ "severity": "ERROR" }, { - "line": 48, - "column": 2, - "endLine": 48, + "line": 29, + "column": 3, + "endLine": 29, "endColumn": 10, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -248,16 +195,16 @@ "severity": "ERROR" }, { - "line": 51, - "column": 2, - "endLine": 51, - "endColumn": 7, + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 9, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -265,16 +212,16 @@ "severity": "ERROR" }, { - "line": 52, + "line": 39, "column": 2, - "endLine": 52, + "endLine": 39, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -282,16 +229,16 @@ "severity": "ERROR" }, { - "line": 54, + "line": 41, "column": 4, - "endLine": 54, - "endColumn": 9, + "endLine": 41, + "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -299,16 +246,16 @@ "severity": "ERROR" }, { - "line": 55, + "line": 45, "column": 4, - "endLine": 55, - "endColumn": 9, + "endLine": 45, + "endColumn": 16, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -316,16 +263,16 @@ "severity": "ERROR" }, { - "line": 56, + "line": 46, "column": 4, - "endLine": 56, + "endLine": 46, "endColumn": 9, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -333,16 +280,16 @@ "severity": "ERROR" }, { - "line": 57, - "column": 4, - "endLine": 57, - "endColumn": 9, + "line": 47, + "column": 11, + "endLine": 47, + "endColumn": 21, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -350,16 +297,16 @@ "severity": "ERROR" }, { - "line": 58, - "column": 4, - "endLine": 58, - "endColumn": 9, + "line": 52, + "column": 35, + "endLine": 52, + "endColumn": 47, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -367,16 +314,16 @@ "severity": "ERROR" }, { - "line": 59, - "column": 4, - "endLine": 59, - "endColumn": 8, + "line": 52, + "column": 65, + "endLine": 52, + "endColumn": 75, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -384,16 +331,16 @@ "severity": "ERROR" }, { - "line": 60, - "column": 4, - "endLine": 60, - "endColumn": 8, + "line": 52, + "column": 90, + "endLine": 52, + "endColumn": 111, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -401,16 +348,16 @@ "severity": "ERROR" }, { - "line": 61, - "column": 4, - "endLine": 61, - "endColumn": 8, + "line": 65, + "column": 2, + "endLine": 65, + "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -418,16 +365,16 @@ "severity": "ERROR" }, { - "line": 62, + "line": 67, "column": 4, - "endLine": 62, - "endColumn": 8, + "endLine": 67, + "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -435,16 +382,16 @@ "severity": "ERROR" }, { - "line": 63, + "line": 71, "column": 4, - "endLine": 63, - "endColumn": 11, + "endLine": 71, + "endColumn": 16, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -452,16 +399,16 @@ "severity": "ERROR" }, { - "line": 64, + "line": 72, "column": 4, - "endLine": 64, - "endColumn": 15, + "endLine": 72, + "endColumn": 9, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -469,16 +416,16 @@ "severity": "ERROR" }, { - "line": 65, - "column": 4, - "endLine": 65, - "endColumn": 20, + "line": 73, + "column": 11, + "endLine": 73, + "endColumn": 21, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -486,16 +433,16 @@ "severity": "ERROR" }, { - "line": 66, - "column": 4, - "endLine": 66, - "endColumn": 15, + "line": 78, + "column": 33, + "endLine": 78, + "endColumn": 45, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -503,16 +450,16 @@ "severity": "ERROR" }, { - "line": 67, - "column": 4, - "endLine": 67, - "endColumn": 20, + "line": 78, + "column": 63, + "endLine": 78, + "endColumn": 73, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -520,16 +467,16 @@ "severity": "ERROR" }, { - "line": 74, - "column": 2, - "endLine": 74, - "endColumn": 11, + "line": 78, + "column": 88, + "endLine": 78, + "endColumn": 109, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -537,16 +484,16 @@ "severity": "ERROR" }, { - "line": 76, - "column": 4, - "endLine": 76, - "endColumn": 8, + "line": 81, + "column": 19, + "endLine": 81, + "endColumn": 32, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", @@ -554,16 +501,16 @@ "severity": "ERROR" }, { - "line": 77, - "column": 4, - "endLine": 77, + "line": 95, + "column": 2, + "endLine": 95, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" } ], "suggest": "", diff --git a/ets2panda/linter/test/main/custom_layout.ets.json b/ets2panda/linter/test/main/custom_layout.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..5d769b466be894ca7e944a9048b170f15ac0ae1c --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.json @@ -0,0 +1,38 @@ +{ + "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": 78, + "column": 3, + "endLine": 78, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/custom_layout.ets.migrate.ets b/ets2panda/linter/test/main/custom_layout.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d98301abfceb216cb6a73f5cd01afa820994638 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.migrate.ets @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI'; + +@Entry +@Component +struct Index { + build() { + Column() { + CustomLayout1({ builder: ColumnChildren }) + CustomLayout2({ builder: ColumnChildren }) + } + } +} + +@Builder +function ColumnChildren() { + ForEach([1, 2, 3], (index: number) => { //暂不支持lazyForEach的写法 + Text('S' + index) + .fontSize(30) + .width(100) + .height(100) + .borderWidth(2) + .offset({ x: 10, y: 20 }) + }) +} + +@Component +@Layoutable +struct CustomLayout1 { + @Builder + doNothingBuilder() { + }; + + @BuilderParam builder: () => void = this.doNothingBuilder; + @State startSize: number = 100; + result: SizeResult = { + width: 0, + height: 0 + }; + + onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { + let startPos: number = 300; + children.forEach((child) => { + let pos: number = startPos - child.measureResult.height; + child.layout({ x: pos, y: pos }) + }) + } + + build() { + this.builder() + } +} + +@Component +@Layoutable +struct CustomLayout2 { + @Builder + doNothingBuilder() { + }; + + @BuilderParam builder: () => void = this.doNothingBuilder; + @State startSize: number = 100; + result: SizeResult = { + width: 0, + height: 0 + }; + + onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { + let size: number = 100; + children.forEach((child) => { + let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size }) + size += result.width / 2 + ; + }) + this.result.width = 100; + this.result.height = 400; + return this.result; + } + + build() { + this.builder() + } +} + +@Component +struct CustomLayout3 { + build { + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/custom_layout.ets.migrate.json b/ets2panda/linter/test/main/custom_layout.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..6c283c3ef1beea2a8d290ae40cecd19853e44771 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.migrate.json @@ -0,0 +1,48 @@ +{ + "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": 42, + "column": 1, + "endLine": 42, + "endColumn": 12, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 1, + "endLine": 69, + "endColumn": 12, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 3, + "endLine": 101, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.args.json b/ets2panda/linter/test/main/debugger_statememt.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..f56752f2284e65fb08a317502e548ab26eee7c70 100644 --- a/ets2panda/linter/test/main/debugger_statememt.ets.args.json +++ b/ets2panda/linter/test/main/debugger_statememt.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json b/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json index f972e0b8b5b201938b2fac548ccdbf8c9bdd44ee..6c9d73e3d1b95d4073a99e0e9c4d36a103b55faa 100644 --- a/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json +++ b/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json @@ -24,7 +24,7 @@ { "start": 605, "end": 614, - "replacementText": "specialAutofixLib.debugger()" + "replacementText": "specialAutofixLib.debugger();" } ], "suggest": "", @@ -41,7 +41,7 @@ { "start": 633, "end": 642, - "replacementText": "specialAutofixLib.debugger()" + "replacementText": "specialAutofixLib.debugger();" } ], "suggest": "", diff --git a/ets2panda/linter/test/sdkwhite/InterfaceExtendsClass.ets b/ets2panda/linter/test/main/debugger_statememt.ets.migrate.ets similarity index 84% rename from ets2panda/linter/test/sdkwhite/InterfaceExtendsClass.ets rename to ets2panda/linter/test/main/debugger_statememt.ets.migrate.ets index 6606e1f3b99c679a30d8dfae5d0992d150cf3d54..04eeeb8969692e0bcd2becb26ad2df9437c05370 100644 --- a/ets2panda/linter/test/sdkwhite/InterfaceExtendsClass.ets +++ b/ets2panda/linter/test/main/debugger_statememt.ets.migrate.ets @@ -1,20 +1,22 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TypedFrameNode } from '@kit.ArkUI'; - -class nodes implements TypedFrameNode{ // Error - -} +/* + * 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. + */ + +specialAutofixLib.debugger(); + +function a() { + specialAutofixLib.debugger(); +} + +console.log('debugger'); \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/InterfaceExtendsClass.ets.json b/ets2panda/linter/test/main/debugger_statememt.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/InterfaceExtendsClass.ets.json rename to ets2panda/linter/test/main/debugger_statememt.ets.migrate.json diff --git a/ets2panda/linter/test/main/default_required_args.ets b/ets2panda/linter/test/main/default_required_args.ets new file mode 100644 index 0000000000000000000000000000000000000000..cbccdb42cf31c8bdadd160e270814f14ec671829 --- /dev/null +++ b/ets2panda/linter/test/main/default_required_args.ets @@ -0,0 +1,60 @@ +/* + * 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. + */ + +function foo(left: number = 0, right: number): number { + return left + right +} + +function foo3(a: number, b: number = 5, c: number): number { + return a + b + c; +} + +function foo4(a: number = 1, b: number = 2, c: number): number { + return a + b + c; +} + +function foo5(a: number = 1, b: number = 2, c: number = 3): number { //legal + return a + b + c; +} + +const bar = (x: boolean = true, y: boolean) => { + return x && y; +}; + +class MyClass { + myMethod(x: number = 0, y: number) { + return x + y; + } +} + +function fooLegal(a: number, b: number = 0): number { //legal + return a + b; +} + +function greetLegal(name: string, message: string = "Hi"): string { //legal + return message + ", " + name; +} + +const barLegal = (x: boolean, y: boolean = false) => { //legal + return x && y; +}; + +function log(level: string = 'info', some: string, message?: string): void { + console.log(`${some} [${level.toUpperCase()}] ${message ?? 'No message'}`); +} + +function config(debug: boolean = true, verbose?: boolean): string { //legal + return `Debug: ${debug ?? false}, Verbose: ${verbose ?? false}`; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/default_required_args.ets.args.json b/ets2panda/linter/test/main/default_required_args.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..9b16bb93a4605b3465a0f919cd2f678737401555 --- /dev/null +++ b/ets2panda/linter/test/main/default_required_args.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/default_required_args.ets.arkts2.json b/ets2panda/linter/test/main/default_required_args.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..73fb6559a8b55f9b09b1c9c0853f42b9e521c38c --- /dev/null +++ b/ets2panda/linter/test/main/default_required_args.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": 16, + "column": 14, + "endLine": 16, + "endColumn": 18, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 30, + "endLine": 24, + "endColumn": 31, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 15, + "endLine": 24, + "endColumn": 16, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 14, + "endLine": 32, + "endColumn": 15, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 13, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 14, + "endLine": 54, + "endColumn": 19, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/default_required_args.ets.json b/ets2panda/linter/test/main/default_required_args.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/main/default_required_args.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/destructuring_assignments.ets.args.json b/ets2panda/linter/test/main/destructuring_assignments.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/destructuring_assignments.ets.args.json +++ b/ets2panda/linter/test/main/destructuring_assignments.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/destructuring_assignments.ets.autofix.json b/ets2panda/linter/test/main/destructuring_assignments.ets.autofix.json index 376b05b6dcc48b9a948d29b32cd6b15a99cebcd6..a9c281d2f38381ce20e29ef85d85963624f4add6 100644 --- a/ets2panda/linter/test/main/destructuring_assignments.ets.autofix.json +++ b/ets2panda/linter/test/main/destructuring_assignments.ets.autofix.json @@ -47,7 +47,7 @@ "end": 736 }, { - "replacementText": "a = GeneratedDestructObj_1.a;b = GeneratedDestructObj_1.b;s = GeneratedDestructObj_1.s;", + "replacementText": "\na = GeneratedDestructObj_1.a;\nb = GeneratedDestructObj_1.b;\ns = GeneratedDestructObj_1.s;\n", "start": 737, "end": 737 } @@ -119,7 +119,7 @@ "end": 892 }, { - "replacementText": "a = GeneratedDestructObj_2.a;({ c, d: s } = GeneratedDestructObj_2.b);", + "replacementText": "\na = GeneratedDestructObj_2.a;\n({ c, d: s } = GeneratedDestructObj_2.b);\n", "start": 893, "end": 893 } @@ -213,7 +213,7 @@ "end": 1047 }, { - "replacementText": "a = GeneratedDestructObj_3.a;b = GeneratedDestructObj_3.b;", + "replacementText": "\na = GeneratedDestructObj_3.a;\nb = GeneratedDestructObj_3.b;\n", "start": 1048, "end": 1048 } @@ -235,7 +235,7 @@ "end": 1092 }, { - "replacementText": "a = GeneratedDestructArray_1[0];b = GeneratedDestructArray_1[1];c = GeneratedDestructArray_1[2];", + "replacementText": "\na = GeneratedDestructArray_1[0];\nb = GeneratedDestructArray_1[1];\nc = GeneratedDestructArray_1[2];\n", "start": 1108, "end": 1108 } @@ -267,7 +267,7 @@ "end": 1155 }, { - "replacementText": "[a1, a2] = GeneratedDestructArray_2[0];[b1, b2] = GeneratedDestructArray_2[1];[c1, c2] = GeneratedDestructArray_2[2];", + "replacementText": "\n[a1, a2] = GeneratedDestructArray_2[0];\n[b1, b2] = GeneratedDestructArray_2[1];\n[c1, c2] = GeneratedDestructArray_2[2];\n", "start": 1183, "end": 1183 } @@ -289,7 +289,7 @@ "end": 1192 }, { - "replacementText": "a = GeneratedDestructArray_3[0];b = GeneratedDestructArray_3[1];", + "replacementText": "\na = GeneratedDestructArray_3[0];\nb = GeneratedDestructArray_3[1];\n", "start": 1202, "end": 1202 } @@ -391,7 +391,7 @@ "end": 1506 }, { - "replacementText": "a = GeneratedDestructArray_4[0];b = GeneratedDestructArray_4[1];", + "replacementText": "\na = GeneratedDestructArray_4[0];\nb = GeneratedDestructArray_4[1];\n", "start": 1520, "end": 1520 } @@ -565,7 +565,7 @@ "end": 1953 }, { - "replacementText": "a = GeneratedDestructObj_4.a;[c, d] = GeneratedDestructObj_4.b;", + "replacementText": "\na = GeneratedDestructObj_4.a;\n[c, d] = GeneratedDestructObj_4.b;\n", "start": 1954, "end": 1954 } @@ -597,7 +597,7 @@ "end": 2051 }, { - "replacementText": "a = GeneratedDestructObj_5.a;({\n s,\n c: [d, f],\n } = GeneratedDestructObj_5.b);", + "replacementText": "\na = GeneratedDestructObj_5.a;\n({\n s,\n c: [d, f],\n } = GeneratedDestructObj_5.b);\n", "start": 2052, "end": 2052 } @@ -739,7 +739,7 @@ "end": 2525 }, { - "replacementText": "a = GeneratedDestructObj_6.a;b = GeneratedDestructObj_6.b;s = GeneratedDestructObj_6.s;", + "replacementText": "\na = GeneratedDestructObj_6.a;\nb = GeneratedDestructObj_6.b;\ns = GeneratedDestructObj_6.s;\n", "start": 2526, "end": 2526 } diff --git a/ets2panda/linter/test/migrate/destructuring_assignments.sts b/ets2panda/linter/test/main/destructuring_assignments.ets.migrate.ets similarity index 41% rename from ets2panda/linter/test/migrate/destructuring_assignments.sts rename to ets2panda/linter/test/main/destructuring_assignments.ets.migrate.ets index e40bde0f0b0a549edd39b306d82eac6b9023019a..e3835ceaeb5a387819d4fc2906ff8c9b66e6a4dc 100644 --- a/ets2panda/linter/test/migrate/destructuring_assignments.sts +++ b/ets2panda/linter/test/main/destructuring_assignments.ets.migrate.ets @@ -16,22 +16,69 @@ // Object destructuring let a = 5, b = 10, c = 15, d = 20, s = 'foo'; let rest, rest2; -({ a, b, s } = { a: 100, b: 200, s: 'bar' }); // NOT OK +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: number; + s: string; +} +let GeneratedDestructObj_1: GeneratedObjectLiteralInterface_2 = { a: 100, b: 200, s: 'bar' }; +a = GeneratedDestructObj_1.a; +b = GeneratedDestructObj_1.b; +s = GeneratedDestructObj_1.s; + // NOT OK ({ a, b, s } = {}); // NOT OK, not fixable ({ a, ...rest } = { a: 1, b: 2 }); // NOT OK -({ a, b: { c, d: s } } = { a: 1, b: { c: 3, d: 'baz' }}); // NOT OK +interface GeneratedObjectLiteralInterface_3 { + c: number; + d: string; +} +interface GeneratedObjectLiteralInterface_6 { + a: number; + b: GeneratedObjectLiteralInterface_3; +} +let GeneratedDestructObj_2: GeneratedObjectLiteralInterface_6 = { a: 1, b: ({ c: 3, d: 'baz' } as GeneratedObjectLiteralInterface_3) }; +a = GeneratedDestructObj_2.a; +let GeneratedDestructObj_7 = GeneratedDestructObj_2.b; +c = GeneratedDestructObj_7.c; +s = GeneratedDestructObj_7.d; + + // NOT OK ({ a, b: { ...rest } } = { a: 1, b: { c: 3, d: 'bah' }}); // NOT OK +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: number; +} function getObject() { - return { a: 1, b: 2 }; + return ({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1); } -({ a, b } = getObject()); // NOT OK +let GeneratedDestructObj_3 = getObject(); +a = GeneratedDestructObj_3.a; +b = GeneratedDestructObj_3.b; + // NOT OK // Array destructuring -[a, b, c] = [10, 20, 30]; +let GeneratedDestructArray_1 = [10, 20, 30]; +a = GeneratedDestructArray_1[0]; +b = GeneratedDestructArray_1[1]; +c = GeneratedDestructArray_1[2]; + [a, b, c] = []; -[[a1, a2], [b1, b2], [c1, c2]] = [[1, 2], [3, 4], [5, 6]]; -[a, b] = [b, a]; +let GeneratedDestructArray_2 = [[1, 2], [3, 4], [5, 6]]; +a1 = GeneratedDestructArray_2[0][0]; +a2 = GeneratedDestructArray_2[0][1]; + +b1 = GeneratedDestructArray_2[1][0]; +b2 = GeneratedDestructArray_2[1][1]; + +c1 = GeneratedDestructArray_2[2][0]; +c2 = GeneratedDestructArray_2[2][1]; + + +let GeneratedDestructArray_3 = [b, a]; +a = GeneratedDestructArray_3[0]; +b = GeneratedDestructArray_3[1]; + [a, b, ...rest] = [10, 20, 30, 40, 50]; // NOT OK [a, b, [c, d]] = [10, 20, [300, 400], 50]; [a, b, [c, ...rest]] = [10, 20, [30, 40, 50]]; // NOT OK @@ -41,7 +88,10 @@ let tuple: [number, string, number] = [1, '2', 3]; [a, ...rest] = tuple; // NOT OK const getArray = (): number[] => [1, 2, 3]; -[a, b] = getArray(); +let GeneratedDestructArray_4 = getArray(); +a = GeneratedDestructArray_4[0]; +b = GeneratedDestructArray_4[1]; + const set: Set = new Set([1, 2, 3, 4]); [a, b, c] = set; // NOT OK @@ -50,19 +100,43 @@ const map: Map = new Map(); [[a, b], [c, d]] = map; // NOT OK // Mixed destructuring -let e: number, f: number, x: { e: number }, g; +interface GeneratedTypeLiteralInterface_1 { + e: number; +} +let e: number, f: number, x: GeneratedTypeLiteralInterface_1, g; [a, b, [x, { f }]] = [1, 2, [{ e: 20 }, { f: 5 }]]; // NOT OK [a, b, {e, e: f, ...g}] = [1, 2, {e: 10}]; // NOT OK [a, b, ...{length}] = [1, 2, {e: 10}]; // NOT OK -({ a, b : [c, d] } = { a: 1, b: [2, 3] }); // NOT OK -({ - a, - b: { - s, - c: [d, f], - }, -} = { a: 10, b: { s: 'foo', c: [30, 40] } }); // NOT OK +interface GeneratedObjectLiteralInterface_4 { + a: number; + b: number[]; +} +let GeneratedDestructObj_4: GeneratedObjectLiteralInterface_4 = { a: 1, b: [2, 3] }; +a = GeneratedDestructObj_4.a; +let GeneratedDestructArray_5 = GeneratedDestructObj_4.b; +c = GeneratedDestructArray_5[0]; +d = GeneratedDestructArray_5[1]; + + // NOT OK +interface GeneratedObjectLiteralInterface_5 { + s: string; + c: number[]; +} +interface GeneratedObjectLiteralInterface_7 { + a: number; + b: GeneratedObjectLiteralInterface_5; +} +let GeneratedDestructObj_5: GeneratedObjectLiteralInterface_7 = { a: 10, b: ({ s: 'foo', c: [30, 40] } as GeneratedObjectLiteralInterface_5) }; +a = GeneratedDestructObj_5.a; +let GeneratedDestructObj_8 = GeneratedDestructObj_5.b; +s = GeneratedDestructObj_8.s; +let GeneratedDestructArray_6 = GeneratedDestructObj_8.c; +d = GeneratedDestructArray_6[0]; +f = GeneratedDestructArray_6[1]; + + + // NOT OK // test for default value ({ a, b = 7, s } = { a: 100, b: 200, s: 'bar' }); // NOT OK @@ -84,5 +158,9 @@ class C { public s: string = "0000"; } -({ a, b, s } = new C()); // NOT OK +let GeneratedDestructObj_6 = new C(); +a = GeneratedDestructObj_6.a; +b = GeneratedDestructObj_6.b; +s = GeneratedDestructObj_6.s; + // NOT OK diff --git a/ets2panda/linter/test/migrate/destructuring_assignments.ts.json b/ets2panda/linter/test/main/destructuring_assignments.ets.migrate.json similarity index 60% rename from ets2panda/linter/test/migrate/destructuring_assignments.ts.json rename to ets2panda/linter/test/main/destructuring_assignments.ets.migrate.json index ed8cdee78e1e83178dd2042ac02b2e8ccdfa40a9..9627371dd3a363fc570da6be996be7096c2a38d5 100644 --- a/ets2panda/linter/test/migrate/destructuring_assignments.ts.json +++ b/ets2panda/linter/test/main/destructuring_assignments.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -35,29 +35,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 29, "column": 2, - "endLine": 19, - "endColumn": 44, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 16, - "endLine": 19, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 2, - "endLine": 20, + "endLine": 29, "endColumn": 18, "problem": "DestructuringAssignment", "suggest": "", @@ -65,9 +45,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 29, "column": 16, - "endLine": 20, + "endLine": 29, "endColumn": 17, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -75,9 +55,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 30, "column": 2, - "endLine": 21, + "endLine": 30, "endColumn": 33, "problem": "DestructuringAssignment", "suggest": "", @@ -85,9 +65,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 30, "column": 7, - "endLine": 21, + "endLine": 30, "endColumn": 14, "problem": "SpreadOperator", "suggest": "", @@ -95,9 +75,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 46, "column": 2, - "endLine": 22, + "endLine": 46, "endColumn": 56, "problem": "DestructuringAssignment", "suggest": "", @@ -105,39 +85,9 @@ "severity": "ERROR" }, { - "line": 22, - "column": 26, - "endLine": 22, - "endColumn": 27, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 37, - "endLine": 22, - "endColumn": 38, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 2, - "endLine": 23, - "endColumn": 56, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 23, + "line": 46, "column": 12, - "endLine": 23, + "endLine": 46, "endColumn": 19, "problem": "SpreadOperator", "suggest": "", @@ -145,9 +95,9 @@ "severity": "ERROR" }, { - "line": 23, + "line": 46, "column": 26, - "endLine": 23, + "endLine": 46, "endColumn": 27, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -155,39 +105,9 @@ "severity": "ERROR" }, { - "line": 26, - "column": 10, - "endLine": 26, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 2, - "endLine": 28, - "endColumn": 24, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 1, - "endLine": 31, - "endColumn": 25, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 32, + "line": 66, "column": 1, - "endLine": 32, + "endLine": 66, "endColumn": 15, "problem": "DestructuringAssignment", "suggest": "", @@ -195,29 +115,9 @@ "severity": "ERROR" }, { - "line": 33, - "column": 1, - "endLine": 33, - "endColumn": 58, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 16, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 35, + "line": 82, "column": 1, - "endLine": 35, + "endLine": 82, "endColumn": 39, "problem": "DestructuringAssignment", "suggest": "", @@ -225,9 +125,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 82, "column": 8, - "endLine": 35, + "endLine": 82, "endColumn": 15, "problem": "SpreadOperator", "suggest": "", @@ -235,9 +135,9 @@ "severity": "ERROR" }, { - "line": 36, + "line": 83, "column": 1, - "endLine": 36, + "endLine": 83, "endColumn": 42, "problem": "DestructuringAssignment", "suggest": "", @@ -245,9 +145,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 84, "column": 1, - "endLine": 37, + "endLine": 84, "endColumn": 46, "problem": "DestructuringAssignment", "suggest": "", @@ -255,9 +155,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 84, "column": 12, - "endLine": 37, + "endLine": 84, "endColumn": 19, "problem": "SpreadOperator", "suggest": "", @@ -265,9 +165,9 @@ "severity": "ERROR" }, { - "line": 40, + "line": 87, "column": 1, - "endLine": 40, + "endLine": 87, "endColumn": 17, "problem": "DestructuringAssignment", "suggest": "", @@ -275,9 +175,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 88, "column": 1, - "endLine": 41, + "endLine": 88, "endColumn": 21, "problem": "DestructuringAssignment", "suggest": "", @@ -285,9 +185,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 88, "column": 5, - "endLine": 41, + "endLine": 88, "endColumn": 12, "problem": "SpreadOperator", "suggest": "", @@ -295,19 +195,9 @@ "severity": "ERROR" }, { - "line": 44, - "column": 1, - "endLine": 44, - "endColumn": 20, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 47, + "line": 97, "column": 1, - "endLine": 47, + "endLine": 97, "endColumn": 16, "problem": "DestructuringAssignment", "suggest": "", @@ -315,9 +205,9 @@ "severity": "ERROR" }, { - "line": 50, + "line": 100, "column": 1, - "endLine": 50, + "endLine": 100, "endColumn": 23, "problem": "DestructuringAssignment", "suggest": "", @@ -325,29 +215,19 @@ "severity": "ERROR" }, { - "line": 53, - "column": 30, - "endLine": 53, - "endColumn": 31, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 45, - "endLine": 53, - "endColumn": 46, + "line": 106, + "column": 63, + "endLine": 106, + "endColumn": 64, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 54, + "line": 107, "column": 1, - "endLine": 54, + "endLine": 107, "endColumn": 51, "problem": "DestructuringAssignment", "suggest": "", @@ -355,9 +235,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 107, "column": 29, - "endLine": 54, + "endLine": 107, "endColumn": 50, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -365,19 +245,9 @@ "severity": "ERROR" }, { - "line": 54, - "column": 30, - "endLine": 54, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 54, + "line": 107, "column": 41, - "endLine": 54, + "endLine": 107, "endColumn": 42, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -385,9 +255,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 108, "column": 1, - "endLine": 55, + "endLine": 108, "endColumn": 42, "problem": "DestructuringAssignment", "suggest": "", @@ -395,9 +265,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 108, "column": 18, - "endLine": 55, + "endLine": 108, "endColumn": 22, "problem": "SpreadOperator", "suggest": "", @@ -405,9 +275,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 109, "column": 1, - "endLine": 56, + "endLine": 109, "endColumn": 38, "problem": "DestructuringAssignment", "suggest": "", @@ -415,9 +285,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 109, "column": 8, - "endLine": 56, + "endLine": 109, "endColumn": 19, "problem": "SpreadOperator", "suggest": "", @@ -425,9 +295,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 109, "column": 23, - "endLine": 56, + "endLine": 109, "endColumn": 38, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -435,9 +305,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 109, "column": 30, - "endLine": 56, + "endLine": 109, "endColumn": 31, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -445,59 +315,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 142, "column": 2, - "endLine": 58, - "endColumn": 41, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 22, - "endLine": 58, - "endColumn": 23, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 2, - "endLine": 65, - "endColumn": 44, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 5, - "endLine": 65, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 17, - "endLine": 65, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 2, - "endLine": 68, + "endLine": 142, "endColumn": 48, "problem": "DestructuringAssignment", "suggest": "", @@ -505,9 +325,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 142, "column": 20, - "endLine": 68, + "endLine": 142, "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -515,9 +335,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 143, "column": 2, - "endLine": 69, + "endLine": 143, "endColumn": 60, "problem": "DestructuringAssignment", "suggest": "", @@ -525,9 +345,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 143, "column": 30, - "endLine": 69, + "endLine": 143, "endColumn": 31, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -535,9 +355,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 143, "column": 41, - "endLine": 69, + "endLine": 143, "endColumn": 42, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -545,9 +365,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 144, "column": 2, - "endLine": 70, + "endLine": 144, "endColumn": 45, "problem": "DestructuringAssignment", "suggest": "", @@ -555,9 +375,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 144, "column": 26, - "endLine": 70, + "endLine": 144, "endColumn": 27, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -565,9 +385,9 @@ "severity": "ERROR" }, { - "line": 71, + "line": 145, "column": 2, - "endLine": 77, + "endLine": 151, "endColumn": 44, "problem": "DestructuringAssignment", "suggest": "", @@ -575,9 +395,9 @@ "severity": "ERROR" }, { - "line": 77, + "line": 151, "column": 5, - "endLine": 77, + "endLine": 151, "endColumn": 6, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -585,9 +405,9 @@ "severity": "ERROR" }, { - "line": 77, + "line": 151, "column": 17, - "endLine": 77, + "endLine": 151, "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -595,19 +415,9 @@ "severity": "ERROR" }, { - "line": 87, - "column": 2, - "endLine": 87, - "endColumn": 23, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 32, + "line": 66, "column": 2, - "endLine": 32, + "endLine": 66, "endColumn": 3, "problem": "StrictDiagnostic", "suggest": "Type 'undefined' is not assignable to type 'number'.", @@ -615,9 +425,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 66, "column": 5, - "endLine": 32, + "endLine": 66, "endColumn": 6, "problem": "StrictDiagnostic", "suggest": "Type 'undefined' is not assignable to type 'number'.", @@ -625,9 +435,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 66, "column": 8, - "endLine": 32, + "endLine": 66, "endColumn": 9, "problem": "StrictDiagnostic", "suggest": "Type 'undefined' is not assignable to type 'number'.", diff --git a/ets2panda/linter/test/main/destructuring_declarations.ets.args.json b/ets2panda/linter/test/main/destructuring_declarations.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/destructuring_declarations.ets.args.json +++ b/ets2panda/linter/test/main/destructuring_declarations.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/destructuring_declarations.ets.autofix.json b/ets2panda/linter/test/main/destructuring_declarations.ets.autofix.json index a76a73dd10b390453eaa1b53f194f221ef49186a..d4bd32c57f76df7ce021a99f9d25acc816b8351e 100644 --- a/ets2panda/linter/test/main/destructuring_declarations.ets.autofix.json +++ b/ets2panda/linter/test/main/destructuring_declarations.ets.autofix.json @@ -27,7 +27,7 @@ "end": 644 }, { - "replacementText": "let a = GeneratedDestructObj_1.a;let b = GeneratedDestructObj_1.b;let c = GeneratedDestructObj_1.c;", + "replacementText": "\nlet a = GeneratedDestructObj_1.a;\nlet b = GeneratedDestructObj_1.b;\nlet c = GeneratedDestructObj_1.c;\n", "start": 676, "end": 676 } @@ -79,7 +79,7 @@ "end": 768 }, { - "replacementText": "let a3 = GeneratedDestructObj_2.a3;let { c3, d3: e3 } = GeneratedDestructObj_2.b3;", + "replacementText": "\nlet a3 = GeneratedDestructObj_2.a3;\nlet { c3, d3: e3 } = GeneratedDestructObj_2.b3;\n", "start": 806, "end": 806 } @@ -193,7 +193,7 @@ "end": 1007 }, { - "replacementText": "let a5 = GeneratedDestructObj_3.a5;let b5 = GeneratedDestructObj_3.b5;", + "replacementText": "\nlet a5 = GeneratedDestructObj_3.a5;\nlet b5 = GeneratedDestructObj_3.b5;\n", "start": 1022, "end": 1022 } @@ -215,7 +215,7 @@ "end": 1075 }, { - "replacementText": "const a6 = GeneratedDestructArray_1[0];const b6 = GeneratedDestructArray_1[1];const c6 = GeneratedDestructArray_1[2];", + "replacementText": "\nconst a6 = GeneratedDestructArray_1[0];\nconst b6 = GeneratedDestructArray_1[1];\nconst c6 = GeneratedDestructArray_1[2];\n", "start": 1091, "end": 1091 } @@ -267,7 +267,7 @@ "end": 1308 }, { - "replacementText": "const [a1, a2] = GeneratedDestructArray_2[0];const [b1, b2] = GeneratedDestructArray_2[1];const [c1, c2] = GeneratedDestructArray_2[2];", + "replacementText": "\nconst [a1, a2] = GeneratedDestructArray_2[0];\nconst [b1, b2] = GeneratedDestructArray_2[1];\nconst [c1, c2] = GeneratedDestructArray_2[2];\n", "start": 1336, "end": 1336 } @@ -289,7 +289,7 @@ "end": 1387 }, { - "replacementText": "const [a1, a2, a3] = GeneratedDestructArray_3[0];const [b1, b2, b3] = GeneratedDestructArray_3[1];const [c1, c2, c3] = GeneratedDestructArray_3[2];", + "replacementText": "\nconst [a1, a2, a3] = GeneratedDestructArray_3[0];\nconst [b1, b2, b3] = GeneratedDestructArray_3[1];\nconst [c1, c2, c3] = GeneratedDestructArray_3[2];\n", "start": 1424, "end": 1424 } @@ -331,7 +331,7 @@ "end": 1603 }, { - "replacementText": "let a12 = GeneratedDestructArray_4[0];let b12 = GeneratedDestructArray_4[1];", + "replacementText": "\nlet a12 = GeneratedDestructArray_4[0];\nlet b12 = GeneratedDestructArray_4[1];\n", "start": 1617, "end": 1617 } @@ -443,7 +443,7 @@ "end": 2055 }, { - "replacementText": "let a18 = GeneratedDestructObj_4.a18;let [c18, d18] = GeneratedDestructObj_4.b18;", + "replacementText": "\nlet a18 = GeneratedDestructObj_4.a18;\nlet [c18, d18] = GeneratedDestructObj_4.b18;\n", "start": 2082, "end": 2082 } @@ -475,7 +475,7 @@ "end": 2151 }, { - "replacementText": "let a19 = GeneratedDestructObj_5.a19;let {\n c19,\n d19: [e19, f19],\n } = GeneratedDestructObj_5.b19;", + "replacementText": "\nlet a19 = GeneratedDestructObj_5.a19;\nlet {\n c19,\n d19: [e19, f19],\n } = GeneratedDestructObj_5.b19;\n", "start": 2202, "end": 2202 } @@ -627,7 +627,7 @@ "end": 2760 }, { - "replacementText": "let a = GeneratedDestructObj_6.a;let b = GeneratedDestructObj_6.b;let s = GeneratedDestructObj_6.s;", + "replacementText": "\nlet a = GeneratedDestructObj_6.a;\nlet b = GeneratedDestructObj_6.b;\nlet s = GeneratedDestructObj_6.s;\n", "start": 2771, "end": 2771 } diff --git a/ets2panda/linter/test/migrate/destructuring_declarations.sts b/ets2panda/linter/test/main/destructuring_declarations.ets.migrate.ets similarity index 39% rename from ets2panda/linter/test/migrate/destructuring_declarations.sts rename to ets2panda/linter/test/main/destructuring_declarations.ets.migrate.ets index 0ee8cd35379733529fe19b9ed3020a994f28ba1d..709d135068231bf91f0bbf35e4fc4652cdecc2bc 100644 --- a/ets2panda/linter/test/migrate/destructuring_declarations.sts +++ b/ets2panda/linter/test/main/destructuring_declarations.ets.migrate.ets @@ -14,33 +14,93 @@ */ // Object destructuring -let { a, b, c } = { a: 100, b: 200, c: 'bar' }; // NOT OK +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: number; + c: string; +} +let GeneratedDestructObj_1: GeneratedObjectLiteralInterface_2 = { a: 100, b: 200, c: 'bar' }; +let a = GeneratedDestructObj_1.a; +let b = GeneratedDestructObj_1.b; +let c = GeneratedDestructObj_1.c; + // NOT OK let { a2, ...rest2 } = { a2: 1, b2: 2 }; // NOT OK -let { a3, b3: { c3, d3: e3 } } = { a3: 1, b3: { c3: 3, d3: 'baz' }}; // NOT OK +interface GeneratedObjectLiteralInterface_3 { + c3: number; + d3: string; +} +interface GeneratedObjectLiteralInterface_6 { + a3: number; + b3: GeneratedObjectLiteralInterface_3; +} +let GeneratedDestructObj_2: GeneratedObjectLiteralInterface_6 = { a3: 1, b3: ({ c3: 3, d3: 'baz' } as GeneratedObjectLiteralInterface_3)}; +let a3 = GeneratedDestructObj_2.a3; +let GeneratedDestructObj_7 = GeneratedDestructObj_2.b3; +let c3 = GeneratedDestructObj_7.c3; +let e3 = GeneratedDestructObj_7.d3; + + // NOT OK let { a4, b4: { ...rest4 } } = { a4: 1, b4: { c4: 3, d4: 'bah' }}; // NOT OK let { a, b, c } = {}; // NOT OK, not fixable +interface GeneratedObjectLiteralInterface_1 { + a5: number; + b5: number; +} function getObject() { - return { a5: 1, b5: 2 }; + return ({ a5: 1, b5: 2 } as GeneratedObjectLiteralInterface_1); } -let { a5, b5 } = getObject(); // NOT OK +let GeneratedDestructObj_3 = getObject(); +let a5 = GeneratedDestructObj_3.a5; +let b5 = GeneratedDestructObj_3.b5; + // NOT OK // Array destructuring -const [a6, b6, c6] = [10, 20, 30]; +const GeneratedDestructArray_1 = [10, 20, 30]; +const a6 = GeneratedDestructArray_1[0]; +const b6 = GeneratedDestructArray_1[1]; +const c6 = GeneratedDestructArray_1[2]; + const [a7, b7, ...rest7] = [10, 20, 30, 40, 50]; // NOT OK const [a8, b8, [c8, e8]] = [10, 20, [300, 400], 50]; const [a9, b9, [c9, ...rest9]] = [10, 20, [30, 40, 50]]; // NOT OK -const [[a1, a2], [b1, b2], [c1, c2]] = [[1, 2], [3, 4], [5, 6]]; -const [[a1, a2, a3], [b1, b2, b3], [c1, c2, c3]] = [[1, 2, 3], [3, 4, 5], [5, 6, 7]]; +const GeneratedDestructArray_2 = [[1, 2], [3, 4], [5, 6]]; +const a1 = GeneratedDestructArray_2[0][0]; +const a2 = GeneratedDestructArray_2[0][1]; + +const b1 = GeneratedDestructArray_2[1][0]; +const b2 = GeneratedDestructArray_2[1][1]; + +const c1 = GeneratedDestructArray_2[2][0]; +const c2 = GeneratedDestructArray_2[2][1]; + + +const GeneratedDestructArray_3 = [[1, 2, 3], [3, 4, 5], [5, 6, 7]]; +const a1 = GeneratedDestructArray_3[0][0]; +const a2 = GeneratedDestructArray_3[0][1]; +const a3 = GeneratedDestructArray_3[0][2]; + +const b1 = GeneratedDestructArray_3[1][0]; +const b2 = GeneratedDestructArray_3[1][1]; +const b3 = GeneratedDestructArray_3[1][2]; + +const c1 = GeneratedDestructArray_3[2][0]; +const c2 = GeneratedDestructArray_3[2][1]; +const c3 = GeneratedDestructArray_3[2][2]; + + let tuple: [number, string, number] = [1, '2', 3]; let [a10, , b10] = tuple; let [a11, ...rest11] = tuple; // NOT OK const getArray = (): number[] => [1, 2, 3]; -let [a12, b12] = getArray(); +let GeneratedDestructArray_4 = getArray(); +let a12 = GeneratedDestructArray_4[0]; +let b12 = GeneratedDestructArray_4[1]; + const set: Set = new Set([1, 2, 3, 4]); let [a13, b13, c13] = set; // NOT OK @@ -53,14 +113,35 @@ let [a15, b15, [x15, { f15 }]] = [1, 2, [{ e15: 20 }, { f15: 5 }]]; // NOT OK let [a16, b16, {e16, e16: f16, ...g16}] = [1, 2, {e16: 10}]; // NOT OK { let [a17, b17, ...{length}] = [1, 2, 3, 4]; } // NOT OK -let { a18, b18: [c18, d18] } = { a18: 1, b18: [2, 3] }; // NOT OK -let { - a19, - b19: { - c19, - d19: [e19, f19], - }, -} = { a19: 10, b19: { c19: 'foo', d19: [30, 40] } }; // NOT OK +interface GeneratedObjectLiteralInterface_4 { + a18: number; + b18: number[]; +} +let GeneratedDestructObj_4: GeneratedObjectLiteralInterface_4 = { a18: 1, b18: [2, 3] }; +let a18 = GeneratedDestructObj_4.a18; +let GeneratedDestructArray_5 = GeneratedDestructObj_4.b18; +let c18 = GeneratedDestructArray_5[0]; +let d18 = GeneratedDestructArray_5[1]; + + // NOT OK +interface GeneratedObjectLiteralInterface_5 { + c19: string; + d19: number[]; +} +interface GeneratedObjectLiteralInterface_7 { + a19: number; + b19: GeneratedObjectLiteralInterface_5; +} +let GeneratedDestructObj_5: GeneratedObjectLiteralInterface_7 = { a19: 10, b19: ({ c19: 'foo', d19: [30, 40] } as GeneratedObjectLiteralInterface_5) }; +let a19 = GeneratedDestructObj_5.a19; +let GeneratedDestructObj_8 = GeneratedDestructObj_5.b19; +let c19 = GeneratedDestructObj_8.c19; +let GeneratedDestructArray_6 = GeneratedDestructObj_8.d19; +let e19 = GeneratedDestructArray_6[0]; +let f19 = GeneratedDestructArray_6[1]; + + + // NOT OK // test for default value let { a, b, c = 9 } = { a: 100, b: 200, c: 'bar' }; // NOT OK @@ -82,4 +163,8 @@ class C { public s: string = "0000"; } -let { a, b, s } = new C(); // NOT OK \ No newline at end of file +let GeneratedDestructObj_6 = new C(); +let a = GeneratedDestructObj_6.a; +let b = GeneratedDestructObj_6.b; +let s = GeneratedDestructObj_6.s; + // NOT OK \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/destructuring_declarations.ts.json b/ets2panda/linter/test/main/destructuring_declarations.ets.migrate.json similarity index 58% rename from ets2panda/linter/test/migrate/destructuring_declarations.ts.json rename to ets2panda/linter/test/main/destructuring_declarations.ets.migrate.json index 2d0805cb0e52a24340c998044c01d4b1f28ed45c..825250c726041e35485f461b596bf9bf4b0d7b0c 100644 --- a/ets2panda/linter/test/migrate/destructuring_declarations.ts.json +++ b/ets2panda/linter/test/main/destructuring_declarations.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -15,29 +15,9 @@ ], "result": [ { - "line": 17, - "column": 5, - "endLine": 17, - "endColumn": 47, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 19, - "endLine": 17, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 18, + "line": 27, "column": 5, - "endLine": 18, + "endLine": 27, "endColumn": 40, "problem": "DestructuringDeclaration", "suggest": "", @@ -45,9 +25,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 27, "column": 24, - "endLine": 18, + "endLine": 27, "endColumn": 25, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -55,39 +35,9 @@ "severity": "ERROR" }, { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 68, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 34, - "endLine": 19, - "endColumn": 35, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 47, - "endLine": 19, - "endColumn": 48, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 20, + "line": 43, "column": 5, - "endLine": 20, + "endLine": 43, "endColumn": 66, "problem": "DestructuringDeclaration", "suggest": "", @@ -95,9 +45,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 43, "column": 32, - "endLine": 20, + "endLine": 43, "endColumn": 33, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -105,9 +55,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 43, "column": 45, - "endLine": 20, + "endLine": 43, "endColumn": 46, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -115,9 +65,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 45, "column": 5, - "endLine": 22, + "endLine": 45, "endColumn": 21, "problem": "DestructuringDeclaration", "suggest": "", @@ -125,9 +75,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 45, "column": 19, - "endLine": 22, + "endLine": 45, "endColumn": 20, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -135,39 +85,9 @@ "severity": "ERROR" }, { - "line": 25, - "column": 10, - "endLine": 25, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 27, - "column": 5, - "endLine": 27, - "endColumn": 29, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 30, + "line": 65, "column": 7, - "endLine": 30, - "endColumn": 34, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 7, - "endLine": 31, + "endLine": 65, "endColumn": 48, "problem": "DestructuringDeclaration", "suggest": "", @@ -175,9 +95,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 66, "column": 7, - "endLine": 32, + "endLine": 66, "endColumn": 52, "problem": "DestructuringDeclaration", "suggest": "", @@ -185,9 +105,9 @@ "severity": "ERROR" }, { - "line": 33, + "line": 67, "column": 7, - "endLine": 33, + "endLine": 67, "endColumn": 56, "problem": "DestructuringDeclaration", "suggest": "", @@ -195,29 +115,9 @@ "severity": "ERROR" }, { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 64, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 7, - "endLine": 36, - "endColumn": 85, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 39, + "line": 96, "column": 5, - "endLine": 39, + "endLine": 96, "endColumn": 25, "problem": "DestructuringDeclaration", "suggest": "", @@ -225,9 +125,9 @@ "severity": "ERROR" }, { - "line": 40, + "line": 97, "column": 5, - "endLine": 40, + "endLine": 97, "endColumn": 29, "problem": "DestructuringDeclaration", "suggest": "", @@ -235,19 +135,9 @@ "severity": "ERROR" }, { - "line": 43, - "column": 5, - "endLine": 43, - "endColumn": 28, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 46, + "line": 106, "column": 5, - "endLine": 46, + "endLine": 106, "endColumn": 26, "problem": "DestructuringDeclaration", "suggest": "", @@ -255,9 +145,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 109, "column": 5, - "endLine": 49, + "endLine": 109, "endColumn": 35, "problem": "DestructuringDeclaration", "suggest": "", @@ -265,9 +155,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 112, "column": 5, - "endLine": 52, + "endLine": 112, "endColumn": 67, "problem": "DestructuringDeclaration", "suggest": "", @@ -275,9 +165,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 112, "column": 41, - "endLine": 52, + "endLine": 112, "endColumn": 66, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -285,9 +175,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 112, "column": 55, - "endLine": 52, + "endLine": 112, "endColumn": 56, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -295,9 +185,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 113, "column": 5, - "endLine": 53, + "endLine": 113, "endColumn": 60, "problem": "DestructuringDeclaration", "suggest": "", @@ -305,9 +195,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 113, "column": 43, - "endLine": 53, + "endLine": 113, "endColumn": 60, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -315,9 +205,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 113, "column": 50, - "endLine": 53, + "endLine": 113, "endColumn": 51, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -325,9 +215,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 114, "column": 7, - "endLine": 54, + "endLine": 114, "endColumn": 45, "problem": "DestructuringDeclaration", "suggest": "", @@ -335,59 +225,9 @@ "severity": "ERROR" }, { - "line": 56, - "column": 5, - "endLine": 56, - "endColumn": 55, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 32, - "endLine": 56, - "endColumn": 33, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 5, - "endLine": 63, - "endColumn": 52, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 5, - "endLine": 63, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 21, - "endLine": 63, - "endColumn": 22, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 66, + "line": 147, "column": 5, - "endLine": 66, + "endLine": 147, "endColumn": 51, "problem": "DestructuringDeclaration", "suggest": "", @@ -395,9 +235,9 @@ "severity": "ERROR" }, { - "line": 66, + "line": 147, "column": 23, - "endLine": 66, + "endLine": 147, "endColumn": 24, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -405,9 +245,9 @@ "severity": "ERROR" }, { - "line": 67, + "line": 148, "column": 5, - "endLine": 67, + "endLine": 148, "endColumn": 73, "problem": "DestructuringDeclaration", "suggest": "", @@ -415,9 +255,9 @@ "severity": "ERROR" }, { - "line": 67, + "line": 148, "column": 39, - "endLine": 67, + "endLine": 148, "endColumn": 40, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -425,9 +265,9 @@ "severity": "ERROR" }, { - "line": 67, + "line": 148, "column": 52, - "endLine": 67, + "endLine": 148, "endColumn": 53, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -435,9 +275,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 149, "column": 5, - "endLine": 68, + "endLine": 149, "endColumn": 33, "problem": "DestructuringDeclaration", "suggest": "", @@ -445,9 +285,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 150, "column": 5, - "endLine": 69, + "endLine": 150, "endColumn": 60, "problem": "DestructuringDeclaration", "suggest": "", @@ -455,9 +295,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 150, "column": 37, - "endLine": 69, + "endLine": 150, "endColumn": 38, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -465,9 +305,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 151, "column": 5, - "endLine": 76, + "endLine": 157, "endColumn": 52, "problem": "DestructuringDeclaration", "suggest": "", @@ -475,9 +315,9 @@ "severity": "ERROR" }, { - "line": 76, + "line": 157, "column": 5, - "endLine": 76, + "endLine": 157, "endColumn": 6, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -485,24 +325,14 @@ "severity": "ERROR" }, { - "line": 76, + "line": 157, "column": 21, - "endLine": 76, + "endLine": 157, "endColumn": 22, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" - }, - { - "line": 85, - "column": 5, - "endLine": 85, - "endColumn": 26, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_parameters.ets.args.json b/ets2panda/linter/test/main/destructuring_parameters.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/destructuring_parameters.ets.args.json +++ b/ets2panda/linter/test/main/destructuring_parameters.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.ets b/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c3acdce95dc7db6cc20be549fe097b2f92fe553 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.ets @@ -0,0 +1,99 @@ +/* + * 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. + */ + +// issue: 24982: Enable 'autofix' mode for this test to ensure it finishes without crashing + +function drawText({ text = '', position: [x, y] = [0, 0] }): void { // NOT OK + // Draw text +} +drawText({ text: 'Figure 1', position: [10, 20] }); + +interface GeneratedTypeLiteralInterface_1 { + firstName: string; + lastName: string; +} +const hello = ({ // NOT OK + firstName, + lastName, +}: GeneratedTypeLiteralInterface_1): string => `Hello ${firstName} ${lastName}`; +console.log(hello({ firstName: 'Karl', lastName: 'Marks' })); + +interface GeneratedObjectLiteralInterface_1 { + firstName: string; + lastName: string; +} +const person: GeneratedObjectLiteralInterface_1 = { firstName: 'Adam', lastName: 'Smith' }; +console.log(hello(person)); + +interface I { + d: number +} + +function f1({d = 1}: I) { // NOT OK +} +f1({d:2}) + +interface GeneratedTypeLiteralInterface_2 { + d: number; +} +function f2({d = 1}: GeneratedTypeLiteralInterface_2) { // NOT OK +} +f2({d:2}) + +function f3({x, ...y}) { // NOT OK + console.log(x); + Object.keys(y).forEach(k => console.log(k, y[k])) +} +f3({x: 1, b: 2, c: 3}) + +function f4([a, b]): void { + console.log(a, b); +} +f4(['Hello', 'Wolrd']); + +function f5([a, b]: number[]): void { + console.log(a, b); +} +f5([1, 2, 3]); + +function f6([a, [b, c]]): void { + console.log(a, b, c); +} +f6([1, [2, 3]]); + +function f7([a, b, ...c]) { // NOT OK + console.log(a, b, c); +} +f7([1, 2, 3, 4]) + +function f8([a, b, [c, ...d]]) { // NOT OK + console.log(a, b, c, d); +} +f8([1, 2, [3, 4, 5]]) + +function f9([a, {b, c}]): void { // NOT OK + console.log(a, b, c); +} +f9([1, {b: 2, c: 3}]); + +function f10([a, [b, {c: d, e: f}]]): void { // NOT OK + console.log(a, b, d, f); +} +f10([1, [2, {c : 3, e: 4}]]); + +function f11([a, b]: Set): void { // NOT OK + console.log(a, b); +} +f11(new Set([1, 2, 3, 4])); diff --git a/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.json b/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca33c3f4997e9e606c510232135028e2e085f00a --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.json @@ -0,0 +1,228 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 18, + "column": 19, + "endLine": 18, + "endColumn": 59, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 16, + "endLine": 30, + "endColumn": 35, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 19, + "endLine": 38, + "endColumn": 25, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 13, + "endLine": 44, + "endColumn": 23, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 13, + "endLine": 51, + "endColumn": 53, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 13, + "endLine": 55, + "endColumn": 22, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 46, + "endLine": 57, + "endColumn": 50, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 4, + "endLine": 59, + "endColumn": 5, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 13, + "endLine": 61, + "endColumn": 19, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 13, + "endLine": 66, + "endColumn": 29, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 13, + "endLine": 71, + "endColumn": 24, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 13, + "endLine": 76, + "endColumn": 25, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 13, + "endLine": 81, + "endColumn": 30, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 13, + "endLine": 86, + "endColumn": 24, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 4, + "endLine": 89, + "endColumn": 21, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 8, + "endLine": 89, + "endColumn": 9, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 14, + "endLine": 91, + "endColumn": 36, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 9, + "endLine": 94, + "endColumn": 27, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 13, + "endLine": 94, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 14, + "endLine": 96, + "endColumn": 33, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets b/ets2panda/linter/test/main/dollar_binding_1.ets index 6ba7a322f1a3e835ac67d33a57906c2c6d69c7e8..e2b25273dab296827be248c4ec6c4558665f0ba3 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets +++ b/ets2panda/linter/test/main/dollar_binding_1.ets @@ -16,12 +16,16 @@ @Component struct MyComponent { @State count: number = 0 + @State $$: number = 0 build() { Column() { MyCounter({ count: $count }) + MyCounter({ + count: $$$ + }) } } } diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.args.json b/ets2panda/linter/test/main/dollar_binding_1.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.args.json +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json b/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json index 2d1bdf9c5a27a4307f148aa8cc696ba84a3c1bed..367b3ca3444ac8860fdc83befd563b101de460d2 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json @@ -15,15 +15,25 @@ ], "result": [ { - "line": 23, + "line": 24, "column": 9, - "endLine": 23, + "endLine": 24, "endColumn": 22, "problem": "DollarBindingNotSupported", "suggest": "", "rule": "\"${variable}\" for decorator binding is not supported (arkui-link-decorator-passing)", "severity": "ERROR" }, + { + "line": 27, + "column": 9, + "endLine": 27, + "endColumn": 19, + "problem": "DollarBindingNotSupported", + "suggest": "", + "rule": "\"${variable}\" for decorator binding is not supported (arkui-link-decorator-passing)", + "severity": "ERROR" + }, { "line": 16, "column": 2, @@ -45,9 +55,19 @@ "severity": "ERROR" }, { - "line": 21, + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, "column": 5, - "endLine": 21, + "endLine": 22, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -55,9 +75,9 @@ "severity": "ERROR" }, { - "line": 29, + "line": 33, "column": 2, - "endLine": 29, + "endLine": 33, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -65,9 +85,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 35, "column": 4, - "endLine": 31, + "endLine": 35, "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", @@ -75,9 +95,9 @@ "severity": "ERROR" }, { - "line": 34, + "line": 38, "column": 5, - "endLine": 34, + "endLine": 38, "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", @@ -85,9 +105,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 39, "column": 7, - "endLine": 35, + "endLine": 39, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json b/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json index b07e1eb473e7c805aa12d33638c0d945ea660a13..89ffaf32c0daa1d59d220779c924aa8613098740 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json @@ -1,29 +1,29 @@ { "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." + "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": 23, + "line": 24, "column": 9, - "endLine": 23, + "endLine": 24, "endColumn": 22, "problem": "DollarBindingNotSupported", "autofix": [ { - "start": 725, - "end": 731, + "start": 749, + "end": 755, "replacementText": "this.count" } ], @@ -31,6 +31,23 @@ "rule": "\"${variable}\" for decorator binding is not supported (arkui-link-decorator-passing)", "severity": "ERROR" }, + { + "line": 27, + "column": 9, + "endLine": 27, + "endColumn": 19, + "problem": "DollarBindingNotSupported", + "autofix": [ + { + "start": 798, + "end": 801, + "replacementText": "this.$$" + } + ], + "suggest": "", + "rule": "\"${variable}\" for decorator binding is not supported (arkui-link-decorator-passing)", + "severity": "ERROR" + }, { "line": 16, "column": 2, @@ -66,9 +83,26 @@ "severity": "ERROR" }, { - "line": 21, + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, "column": 5, - "endLine": 21, + "endLine": 22, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -83,9 +117,9 @@ "severity": "ERROR" }, { - "line": 29, + "line": 33, "column": 2, - "endLine": 29, + "endLine": 33, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -100,9 +134,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 35, "column": 4, - "endLine": 31, + "endLine": 35, "endColumn": 8, "problem": "UIInterfaceImport", "autofix": [ @@ -117,9 +151,9 @@ "severity": "ERROR" }, { - "line": 34, + "line": 38, "column": 5, - "endLine": 34, + "endLine": 38, "endColumn": 8, "problem": "UIInterfaceImport", "autofix": [ @@ -134,9 +168,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 39, "column": 7, - "endLine": 35, + "endLine": 39, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets b/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..244e4156a9e756c896fa0c9356ae003bee616597 --- /dev/null +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, State, Column, Link, Row, Text } from '@kit.ArkUI'; + +@Component +struct MyComponent { + @State count: number = 0 + @State $$: number = 0 + + build() { + Column() { + MyCounter({ + count: this.count + }) + MyCounter({ + count: this.$$ + }) + } + } +} + +@Component +struct MyCounter { + @Link count: number + + build() { + Row() { + Text(`${this.count}`) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/LiteralAsPropertyName2.ets.json b/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/LiteralAsPropertyName2.ets.json rename to ets2panda/linter/test/main/dollar_binding_1.ets.migrate.json diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets b/ets2panda/linter/test/main/dollar_binding_2.ets index f776eb8d17f8aa2b04f3dce7c68f543ea408a087..244e4156a9e756c896fa0c9356ae003bee616597 100644 --- a/ets2panda/linter/test/main/dollar_binding_2.ets +++ b/ets2panda/linter/test/main/dollar_binding_2.ets @@ -18,12 +18,16 @@ import { Component, State, Column, Link, Row, Text } from '@kit.ArkUI'; @Component struct MyComponent { @State count: number = 0 + @State $$: number = 0 build() { Column() { MyCounter({ count: this.count }) + MyCounter({ + count: this.$$ + }) } } } diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets.args.json b/ets2panda/linter/test/main/dollar_binding_2.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/dollar_binding_2.ets.args.json +++ b/ets2panda/linter/test/main/dollar_binding_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.ets b/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..244e4156a9e756c896fa0c9356ae003bee616597 --- /dev/null +++ b/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, State, Column, Link, Row, Text } from '@kit.ArkUI'; + +@Component +struct MyComponent { + @State count: number = 0 + @State $$: number = 0 + + build() { + Column() { + MyCounter({ + count: this.count + }) + MyCounter({ + count: this.$$ + }) + } + } +} + +@Component +struct MyCounter { + @Link count: number + + build() { + Row() { + Text(`${this.count}`) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/OptionalMethod1.ets.json b/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/OptionalMethod1.ets.json rename to ets2panda/linter/test/main/dollar_binding_2.ets.migrate.json diff --git a/ets2panda/linter/test/main/double_dollar_binding_1.ets.args.json b/ets2panda/linter/test/main/double_dollar_binding_1.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_1.ets.args.json +++ b/ets2panda/linter/test/main/double_dollar_binding_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.ets b/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e598afe1a5c9ef6cc608c902b7bade026786bfd8 --- /dev/null +++ b/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.ets @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI'; + +@Component +struct MyComponent { + @State value: number = 0 + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +@Component +struct Test { + @State checked: boolean = false + + build() { + Row() { + Checkbox().select($$(this.checked)) + Blank() + Text(this.checked ? '开启': '关闭') + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/SendablePropType.ets.json b/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/SendablePropType.ets.json rename to ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.json diff --git a/ets2panda/linter/test/main/double_dollar_binding_2.ets.args.json b/ets2panda/linter/test/main/double_dollar_binding_2.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_2.ets.args.json +++ b/ets2panda/linter/test/main/double_dollar_binding_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.ets b/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e598afe1a5c9ef6cc608c902b7bade026786bfd8 --- /dev/null +++ b/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.ets @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI'; + +@Component +struct MyComponent { + @State value: number = 0 + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +@Component +struct Test { + @State checked: boolean = false + + build() { + Row() { + Checkbox().select($$(this.checked)) + Blank() + Text(this.checked ? '开启': '关闭') + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets.arkts2.json b/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.json similarity index 95% rename from ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets.arkts2.json rename to ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.json index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets.arkts2.json +++ b/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.json @@ -13,7 +13,5 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets.args.json b/ets2panda/linter/test/main/double_excla_binding_1.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/double_excla_binding_1.ets.args.json +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.ets b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..30d62a94677fd337d9f627513c429737d4afca7a --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.ets @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI'; + +import { MyCard } from './' + +@Component +struct MyComponent1 { + @State value: number = 0 + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +@Component +struct Test { + @State checked: boolean = false + + build() { + Row() { + Checkbox().select($$(this.checked)) + Blank() + Text(this.checked ? '开启': '关闭') + } + } +} + +@Component +struct MyComponent2 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!! + }) + } + } +} + +@Component +struct MyComponent3 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!!! + }) + } + } +} + +@Component +struct MyComponent4 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!!!! + }) + } + } +} + +@Entry +@ComponentV2 +struct Index { + @Local value: number = 0; + @Local str: string = ''; + + build() { + Column() { + Text(`${this.value}`) + Button(`change value`).onClick(() => { + this.value++; + }) + Star({ + value: this.value, + $value: value => { + this.value = value; + } + }) + MyCard({ + str: this.str, + $str: value => { + this.str = value; + } + }) + } + } +} + + +@ComponentV2 +struct Star { + @Param value: number = 0; + @Event $value: (val: number) => void = (val: number) => {}; + + build() { + Column() { + Text(`${this.value}`) + Button(`change value `).onClick(() => { + this.$value(10); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.json b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c697fe6484ca72352bfc6b04ba5b73eade8a1961 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 102, + "column": 15, + "endLine": 102, + "endColumn": 20, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.args.json b/ets2panda/linter/test/main/double_excla_binding_2.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/double_excla_binding_2.ets.args.json +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.ets b/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3f5d8563a9e48b35c0d1fe7d20c2a743ba48438e --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.ets @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI'; + +import { MyCard } from './' + +@Component +struct MyComponent { + @State value: number = 0 + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +@Component +struct Test { + @State checked: boolean = false + + build() { + Row() { + Checkbox().select($$(this.checked)) + Blank() + Text(this.checked ? '开启': '关闭') + } + } +} + +@Component +struct MyComponent2 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!! + }) + } + } +} + +@Component +struct MyComponent3 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!!! + }) + } + } +} + +@Component +struct MyComponent4 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!!!! + }) + } + } +} + +@Entry +@ComponentV2 +struct Index { + @Local value: number = 0; + + build() { + Column() { + Text(`${this.value}`) + Button(`change value`).onClick(() => { + this.value++; + }) + Star({ + value: this.value, + $value: value => { + this.value = value; + } + }) + MyCard({ + str: this.str, + $str: value => { + this.str = value; + } + }) + } + } +} + + +@ComponentV2 +struct Star { + @Param value: number = 0; + @Event $value: (val: number) => void = (val: number) => {}; + + build() { + Column() { + Text(`${this.value}`) + Button(`change value `).onClick(() => { + this.$value(10); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.json b/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..9ce7a7e1390eb1866c6616e64e3c99b788cda1e4 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 101, + "column": 15, + "endLine": 101, + "endColumn": 20, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets b/ets2panda/linter/test/main/entry_annotation_test10_1.ets index 898d571593f9ecdb4313f2d65e00e01b9c85a2ea..1e06295870c7af4aed816109c2f2f1827f1c270e 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; -import { getLocalStorage } from './storage-manager'; - -@Entry({storage: getLocalStorage(1)}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; +import { getLocalStorage } from './storage-manager'; + +@Entry({storage: getLocalStorage(1)}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json index e47b36f3258fff1e5620f2b78fa36a93df5b8037..dbe2ad5dbe41f3fb63439880b4a063d7b0f1cab9 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json @@ -1,35 +1,35 @@ -{ - "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": 1, - "endLine": 19, - "endColumn": 38, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 756, - "end": 793, - "replacementText": "const __get_local_storage__ = (): LocalStorage => getLocalStorage(1);\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "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": 19, + "column": 1, + "endLine": 19, + "endColumn": 38, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 738, + "end": 775, + "replacementText": "const __get_local_storage__ = (): LocalStorage => getLocalStorage(1);\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..59b5cc120afe11a525557bea39d028065017d9dd --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; +import { getLocalStorage } from './storage-manager'; + +const __get_local_storage__ = (): LocalStorage => getLocalStorage(1); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/DeclWithDuplicateName5.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.json similarity index 95% rename from ets2panda/linter/test/sdkwhite/DeclWithDuplicateName5.ets.arkts2.json rename to ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.json index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/sdkwhite/DeclWithDuplicateName5.ets.arkts2.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.json @@ -13,7 +13,5 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_2.ets b/ets2panda/linter/test/main/entry_annotation_test10_2.ets index b6345be4c3bb6a7373886d766bc07acff6c34f79..59984ecfef0c835cfe7b08bf4d66fafa54667db5 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.ets @@ -1,26 +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. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; -import { getLocalStorage } from './storage-manager'; - -const __get_local_storage__ = (): LocalStorage => getLocalStorage(1); -@Entry({storage: "__get_local_storage__"}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; +import { getLocalStorage } from './storage-manager'; + +const __get_local_storage__ = (): LocalStorage => getLocalStorage(1); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..b6345be4c3bb6a7373886d766bc07acff6c34f79 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; +import { getLocalStorage } from './storage-manager'; + +const __get_local_storage__ = (): LocalStorage => getLocalStorage(1); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.json similarity index 95% rename from ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets.arkts2.json rename to ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.json index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets.arkts2.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.json @@ -13,7 +13,5 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_1.ets b/ets2panda/linter/test/main/entry_annotation_test1_1.ets index e62f535cac447db61b2257170bdb17f5107ad331..1d6b599d2471d61ac22a08af2e12f00ca0b43da6 100644 --- a/ets2panda/linter/test/main/entry_annotation_test1_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.ets @@ -1,24 +1,24 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text } from '@ohos.arkui.components'; - -@Entry -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text } from '@ohos.arkui.components'; + +@Entry +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test1_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/DeclWithDuplicateName5.ets b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.ets similarity index 82% rename from ets2panda/linter/test/sdkwhite/DeclWithDuplicateName5.ets rename to ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.ets index fb83e2bfe2ac15f1c11082c40b43296a5dcc9cf1..e62f535cac447db61b2257170bdb17f5107ad331 100644 --- a/ets2panda/linter/test/sdkwhite/DeclWithDuplicateName5.ets +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.ets @@ -13,11 +13,12 @@ * limitations under the License. */ +import { Entry, Component, Text } from '@ohos.arkui.components'; + @Entry @Component -struct Index { - fontStyleAttr1: TextStyle = new TextStyle({ fontColor: Color.Blue }); // Error +struct MyPage { build() { - Text() + Text("Hello World") } -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_2.ets b/ets2panda/linter/test/main/entry_annotation_test1_2.ets index e62f535cac447db61b2257170bdb17f5107ad331..1d6b599d2471d61ac22a08af2e12f00ca0b43da6 100644 --- a/ets2panda/linter/test/main/entry_annotation_test1_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.ets @@ -1,24 +1,24 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text } from '@ohos.arkui.components'; - -@Entry -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text } from '@ohos.arkui.components'; + +@Entry +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test1_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e62f535cac447db61b2257170bdb17f5107ad331 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text } from '@ohos.arkui.components'; + +@Entry +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets b/ets2panda/linter/test/main/entry_annotation_test2_1.ets index 09b330e06cb3a9426165c4cb7b88e486432bb3c5..8a6b6e367a224b8b1e6cd29897dbca714a8cad65 100644 --- a/ets2panda/linter/test/main/entry_annotation_test2_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const storage = new LocalStorage(); -@Entry(storage) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +@Entry(storage) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.autofix.json index 5fcc9d49f5c17eb9b3055730cb035976242cd07b..5430117ee12997f35363c2316f3da0a11496b6ac 100644 --- a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.autofix.json @@ -1,55 +1,55 @@ -{ - "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": 7, - "endLine": 18, - "endColumn": 35, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 21, - "endLine": 18, - "endColumn": 33, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 1, - "endLine": 19, - "endColumn": 16, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 739, - "end": 754, - "replacementText": "const __get_local_storage__ = (): LocalStorage => storage;\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 16, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 721, + "end": 736, + "replacementText": "const __get_local_storage__ = (): LocalStorage => storage;\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a7d2611b8743dcf4578b79a292ee60370555d11 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d9d95f393735b0e2928f47ea11b82f3d93353268 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets b/ets2panda/linter/test/main/entry_annotation_test2_2.ets index 52bd3e4f789c6d73bd0a5d04017b29a790c4be6d..b188329f6f2c30a64849e116822b6258b7a77319 100644 --- a/ets2panda/linter/test/main/entry_annotation_test2_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const storage = new LocalStorage(); -const __get_local_storage__ = (): LocalStorage => storage; -@Entry({storage: "__get_local_storage__"}) -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({storage: "__get_local_storage__"}) +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test2_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..52bd3e4f789c6d73bd0a5d04017b29a790c4be6d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({storage: "__get_local_storage__"}) +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d9d95f393735b0e2928f47ea11b82f3d93353268 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets b/ets2panda/linter/test/main/entry_annotation_test3_1.ets index 6dbca25bda34b1d8c10d267c60efedd7917404cb..adae2542f2ac9494a4bfecf0090ced768370f9c1 100644 --- a/ets2panda/linter/test/main/entry_annotation_test3_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets @@ -1,24 +1,24 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -@Entry(new LocalStorage()) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry(new LocalStorage()) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.autofix.json index b61a99047a8b0d22717ac546bf5406cdb25d60c4..177c74ca80e95e1bdb023147eee803520d49d368 100644 --- a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.autofix.json @@ -1,45 +1,45 @@ -{ - "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": 1, - "endLine": 18, - "endColumn": 27, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 702, - "end": 728, - "replacementText": "const __get_local_storage__ = (): LocalStorage => new LocalStorage();\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 12, - "endLine": 18, - "endColumn": 24, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 27, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 711, + "replacementText": "const __get_local_storage__ = (): LocalStorage => new LocalStorage();\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 12, + "endLine": 18, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d30dad8c7689ec649f4be551916268c5ec1e5f0 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8ecb23f92c00e0e43cd69914e10283866b396780 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets b/ets2panda/linter/test/main/entry_annotation_test3_2.ets index 5d9cf9c567f9629ad3f8806ef02536fca3233163..14d0661094d30187826c74309b69d7397c5cd740 100644 --- a/ets2panda/linter/test/main/entry_annotation_test3_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const __get_local_storage__ = (): LocalStorage => new LocalStorage(); -@Entry({storage: "__get_local_storage__"}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test3_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d9cf9c567f9629ad3f8806ef02536fca3233163 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8ecb23f92c00e0e43cd69914e10283866b396780 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets b/ets2panda/linter/test/main/entry_annotation_test4_1.ets index c6c4d34956e81d7f038e61c26a3ab28be2b12a5a..b0e972cd29805948ad48eaf1746ba31022f6e740 100644 --- a/ets2panda/linter/test/main/entry_annotation_test4_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.ets @@ -1,24 +1,24 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -@Entry(LocalStorage.getShared()) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry(LocalStorage.getShared()) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.autofix.json index e765741f4cb287e62294ecc8e2a050f20990661c..845f1133f9da9dcdad5d6167041ccac0aa989fe4 100644 --- a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.autofix.json @@ -1,35 +1,35 @@ -{ - "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": 1, - "endLine": 18, - "endColumn": 33, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 702, - "end": 734, - "replacementText": "const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared();\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 33, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 717, + "replacementText": "const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared();\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe0711cbc54f5d6fa47bbc98c912af01e7225269 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_2.ets b/ets2panda/linter/test/main/entry_annotation_test4_2.ets index 6638d8b755d3c79ea395770df0ef629b21d44e1b..33c63bb35c7022f650b528687666580ae85afee3 100644 --- a/ets2panda/linter/test/main/entry_annotation_test4_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); -@Entry({storage: "__get_local_storage__"}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test4_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6638d8b755d3c79ea395770df0ef629b21d44e1b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets b/ets2panda/linter/test/main/entry_annotation_test5_1.ets index 7bea704097eee3703a9d2bbbe6b56f72a8307792..b5a754f0e2daa676d59fc80af3d51d3f31c1af89 100644 --- a/ets2panda/linter/test/main/entry_annotation_test5_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const storage = new LocalStorage(); -@Entry({storage: storage}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +@Entry({storage: storage}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.autofix.json index f6c124af239e36dc267b81e05d86a6db44cccaee..ee459b5f4abb7bc6d559ef47311e74df4e0d646f 100644 --- a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.autofix.json @@ -1,55 +1,55 @@ -{ - "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": 7, - "endLine": 18, - "endColumn": 35, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 21, - "endLine": 18, - "endColumn": 33, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 1, - "endLine": 19, - "endColumn": 27, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 739, - "end": 765, - "replacementText": "const __get_local_storage__ = (): LocalStorage => storage;\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 27, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 721, + "end": 747, + "replacementText": "const __get_local_storage__ = (): LocalStorage => storage;\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a7d2611b8743dcf4578b79a292ee60370555d11 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d9d95f393735b0e2928f47ea11b82f3d93353268 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets b/ets2panda/linter/test/main/entry_annotation_test5_2.ets index 52bd3e4f789c6d73bd0a5d04017b29a790c4be6d..b188329f6f2c30a64849e116822b6258b7a77319 100644 --- a/ets2panda/linter/test/main/entry_annotation_test5_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const storage = new LocalStorage(); -const __get_local_storage__ = (): LocalStorage => storage; -@Entry({storage: "__get_local_storage__"}) -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({storage: "__get_local_storage__"}) +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test5_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..52bd3e4f789c6d73bd0a5d04017b29a790c4be6d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({storage: "__get_local_storage__"}) +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d9d95f393735b0e2928f47ea11b82f3d93353268 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets b/ets2panda/linter/test/main/entry_annotation_test6_1.ets index e17333cbfff0bee900b91e739c6e5799daf7b5e0..570e2082a99c8b9c872f19faec9a6be7674601e1 100644 --- a/ets2panda/linter/test/main/entry_annotation_test6_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets @@ -1,24 +1,24 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -@Entry({storage: new LocalStorage()}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry({storage: new LocalStorage()}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.autofix.json index 0c300530e876bfb8a99bacbdcd2144faa0fbfb2a..838b1b21a4d33f0578dd32e103d9380e49308469 100644 --- a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.autofix.json @@ -1,45 +1,45 @@ -{ - "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": 1, - "endLine": 18, - "endColumn": 38, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 702, - "end": 739, - "replacementText": "const __get_local_storage__ = (): LocalStorage => new LocalStorage();\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 22, - "endLine": 18, - "endColumn": 34, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 38, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 722, + "replacementText": "const __get_local_storage__ = (): LocalStorage => new LocalStorage();\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 22, + "endLine": 18, + "endColumn": 34, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d30dad8c7689ec649f4be551916268c5ec1e5f0 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8ecb23f92c00e0e43cd69914e10283866b396780 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets b/ets2panda/linter/test/main/entry_annotation_test6_2.ets index 5d9cf9c567f9629ad3f8806ef02536fca3233163..14d0661094d30187826c74309b69d7397c5cd740 100644 --- a/ets2panda/linter/test/main/entry_annotation_test6_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const __get_local_storage__ = (): LocalStorage => new LocalStorage(); -@Entry({storage: "__get_local_storage__"}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test6_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d9cf9c567f9629ad3f8806ef02536fca3233163 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8ecb23f92c00e0e43cd69914e10283866b396780 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets b/ets2panda/linter/test/main/entry_annotation_test7_1.ets index 5de5fc213a694103370cc00ee29ec50d4e2077e8..b246bb838178afd64d62dd5a8baacd405f31a61d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test7_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.ets @@ -1,24 +1,24 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -@Entry({storage: LocalStorage.getShared()}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry({storage: LocalStorage.getShared()}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.autofix.json index 655059a71dbd3f59c47e9433580ef51e03239006..45c5a879bc8dc241b3f7e755fb8c3a8775029da8 100644 --- a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.autofix.json @@ -1,35 +1,35 @@ -{ - "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": 1, - "endLine": 18, - "endColumn": 44, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 702, - "end": 745, - "replacementText": "const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared();\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 44, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 728, + "replacementText": "const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared();\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe0711cbc54f5d6fa47bbc98c912af01e7225269 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_2.ets b/ets2panda/linter/test/main/entry_annotation_test7_2.ets index 6638d8b755d3c79ea395770df0ef629b21d44e1b..33c63bb35c7022f650b528687666580ae85afee3 100644 --- a/ets2panda/linter/test/main/entry_annotation_test7_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); -@Entry({storage: "__get_local_storage__"}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test7_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6638d8b755d3c79ea395770df0ef629b21d44e1b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets b/ets2panda/linter/test/main/entry_annotation_test8_1.ets index f5895dae8cc5dd7e883bae56506bb7b945dbb2aa..2db526a74087ba340a2c9f83764da8dcbe364967 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const source = globalThis.localStorage; -@Entry({storage: source}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const source = globalThis.localStorage; +@Entry({storage: source}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json index 9f9ef341aa09f7b82cd54306a9b07b800a9de359..c1e82092cbc8411d1014db7524fa9e02b3151d6c 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json @@ -1,52 +1,52 @@ -{ - "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": 39, - "problem": "GlobalThisError", - "autofix": [ - { - "start": 717, - "end": 740, - "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" - } - ], - "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 1, - "endLine": 19, - "endColumn": 26, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 743, - "end": 768, - "replacementText": "const __get_local_storage__ = (): LocalStorage => source;\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "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": 18, + "column": 16, + "endLine": 18, + "endColumn": 39, + "problem": "GlobalThisError", + "autofix": [ + { + "start": 700, + "end": 723, + "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" + } + ], + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 26, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 725, + "end": 750, + "replacementText": "const __get_local_storage__ = (): LocalStorage => source;\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1159381e1c3c5eae9a51f58e38fae68cb7e2e27a --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const source = specialAutofixLib.globalThis.get("localStorage"); +const __get_local_storage__ = (): LocalStorage => source; +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..045feeac1b91ac7e0aaa3fc613760478fdcaa478 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 7, + "endLine": 18, + "endColumn": 64, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets b/ets2panda/linter/test/main/entry_annotation_test8_2.ets index 1120a5a86040563916efc4fdd7eeba88f852e5ea..435ff1addfd0011813aea9cebc03da93d0b9107f 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets @@ -1,26 +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. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const source = globalThis.localStorage; -const __get_local_storage__ = (): LocalStorage => source; -@Entry({storage: "__get_local_storage__"}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const source = globalThis.localStorage; +const __get_local_storage__ = (): LocalStorage => source; +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json index e111a09d28564987a7d38e7488b47b073d0b3f57..f73277ba2c6e5588e6920e22bfe177ab72d3790a 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json @@ -1,35 +1,35 @@ -{ - "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": 39, - "problem": "GlobalThisError", - "autofix": [ - { - "start": 717, - "end": 740, - "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" - } - ], - "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", - "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": 18, + "column": 16, + "endLine": 18, + "endColumn": 39, + "problem": "GlobalThisError", + "autofix": [ + { + "start": 700, + "end": 723, + "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" + } + ], + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0c20666abffa48687f2ec8cd3bd6587609d30ff2 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const source = specialAutofixLib.globalThis.get("localStorage"); +const __get_local_storage__ = (): LocalStorage => source; +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..045feeac1b91ac7e0aaa3fc613760478fdcaa478 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 7, + "endLine": 18, + "endColumn": 64, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets b/ets2panda/linter/test/main/entry_annotation_test9_1.ets index 6d77c4401bf1aaf7cc50bd99b0dc76c8ec2973e3..24563d7f73aa6ccbaafef9316a128b6f3aa37c03 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_1.ets +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets @@ -1,24 +1,24 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -@Entry({storage: globalThis.localStorage}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry({storage: globalThis.localStorage}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json index b2105691ce59a14de0012b91e19b152f08f6855f..f8e2a1ef6c88975cdd9dfddc0d5cd8451a81ca3b 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json @@ -1,52 +1,52 @@ -{ - "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": 1, - "endLine": 18, - "endColumn": 43, - "problem": "EntryAnnotation", - "autofix": [ - { - "start": 702, - "end": 744, - "replacementText": "const __get_local_storage__ = (): LocalStorage => globalThis.localStorage;\n@Entry({ storage: \"__get_local_storage__\" })" - } - ], - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 18, - "endLine": 18, - "endColumn": 41, - "problem": "GlobalThisError", - "autofix": [ - { - "start": 719, - "end": 742, - "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" - } - ], - "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", - "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 43, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 727, + "replacementText": "const __get_local_storage__ = (): LocalStorage => globalThis.localStorage;\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 18, + "endLine": 18, + "endColumn": 41, + "problem": "GlobalThisError", + "autofix": [ + { + "start": 702, + "end": 725, + "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" + } + ], + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..8c9d2b20122520a1036755a7aab58b9807fc626f --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => specialAutofixLib.globalThis.get("localStorage"); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets b/ets2panda/linter/test/main/entry_annotation_test9_2.ets index f6f5bf039ff2d569fd321183011cb8933ab65f24..20d1b06bd96f166f9a5ead5c6cade2e6e30f043b 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; - -const __get_local_storage__ = (): LocalStorage => globalThis.localStorage; -@Entry({storage: "__get_local_storage__"}) -@Component -struct MyPage { - build() { - Text("Hello World") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => globalThis.localStorage; +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.args.json index 66e8f07a19115bc2e1dede7ad6a9be2ab042c7dc..95b475ab3ce2f06558faffcd414f7e6ad9766f0d 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.args.json +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json index 0727f2fce616980ba5010f0c89929761273d4a2a..17f6fcde033bbf37a56d9c1ce4d514a029e8e332 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json @@ -1,35 +1,35 @@ -{ - "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": 51, - "endLine": 18, - "endColumn": 74, - "problem": "GlobalThisError", - "autofix": [ - { - "start": 752, - "end": 775, - "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" - } - ], - "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", - "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": 18, + "column": 51, + "endLine": 18, + "endColumn": 74, + "problem": "GlobalThisError", + "autofix": [ + { + "start": 735, + "end": 758, + "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" + } + ], + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f1162ccfd9b4bd32b22eda12ce9773232e37e9b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => specialAutofixLib.globalThis.get("localStorage"); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/equals_token_option.ets b/ets2panda/linter/test/main/equals_token_option.ets new file mode 100755 index 0000000000000000000000000000000000000000..0c3da5b2574ea6fc0c52e7b53ec280a0f25472c4 --- /dev/null +++ b/ets2panda/linter/test/main/equals_token_option.ets @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022-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. + */ +let a =1; +a &&=2; +a ||=2; +a ??=2; +typeof (a ||=2); +let person = { name: "Alice", age: 30 }; + +function setAge(){ + person.age &&= - 1; +} +person.age = 0; +person.age &&= 5; + +let count: number | null = null; +count ??= 10; + +count = 0; +count ??= 5; +console.log((count ??= 5)+'') +function getCount(){ + return (count ??= 5); +} +let message: string | null = null; + +message ||= "msg"; +console.log(message); + +message = "msg1"; +message ||= "newMsg"; +console.log(message); +class Demo{ + constructor() { + message ||= "defaultMsg"; + } + setMes(){ + message ||= "defaultMsg"; + } + getMes(){ + return message ??= "newMsg"; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/IndexedAccessType.ets.args.json b/ets2panda/linter/test/main/equals_token_option.ets.args.json old mode 100644 new mode 100755 similarity index 100% rename from ets2panda/linter/test/sdkwhite/IndexedAccessType.ets.args.json rename to ets2panda/linter/test/main/equals_token_option.ets.args.json diff --git a/ets2panda/linter/test/main/equals_token_option.ets.arkts2.json b/ets2panda/linter/test/main/equals_token_option.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..7100f9b7970a9327a5f72c3c3ad611843d961c0a --- /dev/null +++ b/ets2panda/linter/test/main/equals_token_option.ets.arkts2.json @@ -0,0 +1,198 @@ +{ + "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": 15, + "column": 5, + "endLine": 15, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 3, + "endLine": 16, + "endColumn": 6, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 6, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 6, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 12, + "endLine": 19, + "endColumn": 15, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 14, + "endLine": 20, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 14, + "endLine": 23, + "endColumn": 17, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 12, + "endLine": 26, + "endColumn": 15, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 10, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 10, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 20, + "endLine": 33, + "endColumn": 23, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 36, + "endColumn": 2, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 17, + "endLine": 35, + "endColumn": 20, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 9, + "endLine": 39, + "endColumn": 12, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 12, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 13, + "endLine": 47, + "endColumn": 16, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 13, + "endLine": 50, + "endColumn": 16, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 20, + "endLine": 53, + "endColumn": 23, + "problem": "UnsupportOperator", + "suggest": "", + "rule": "Operator is not support (arkts-unsupport-operator)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/equals_token_option.ets.json b/ets2panda/linter/test/main/equals_token_option.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..4dccd5bab8034ecea69fdd2c1339d88827958515 --- /dev/null +++ b/ets2panda/linter/test/main/equals_token_option.ets.json @@ -0,0 +1,28 @@ +{ + "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": 14, + "endLine": 20, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/explicit_function_type.ets b/ets2panda/linter/test/main/explicit_function_type.ets index ee7f99ecd5df56663b926ed8aba9585243d88464..9b440521971be16a2666905393f3b541f642d724 100755 --- a/ets2panda/linter/test/main/explicit_function_type.ets +++ b/ets2panda/linter/test/main/explicit_function_type.ets @@ -161,4 +161,15 @@ function compose45(...fns: Function[]): Function { } export let add: (a: number, b: number) => number; -export let add1: (a: string) => object; \ No newline at end of file +export let add1: (a: string) => object; + +f1(); + +class AB3 { + fn3: Function = () => {}; +} +let ab3 = new AB3(); +ab3.fn3(); + +const fn29: Function[] = []; +fn29[1](); \ No newline at end of file diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.args.json b/ets2panda/linter/test/main/explicit_function_type.ets.args.json index 4d93062f69db6d74420adeb506e0ca28c5580728..a89d885810708ad03d96e3e14bb6590efd1a7547 100755 --- a/ets2panda/linter/test/main/explicit_function_type.ets.args.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.args.json @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json b/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json index 0260c350e183f128847ed8cd28ef02def823a775..1d761807b3983d3a4286f9524be975a4e864cf30 100755 --- a/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json @@ -14,535 +14,225 @@ "limitations under the License." ], "result": [ - { - "line": 15, - "column": 9, - "endLine": 15, - "endColumn": 17, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 9, - "endLine": 16, - "endColumn": 17, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 20, - "endLine": 16, - "endColumn": 33, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 9, - "endLine": 17, - "endColumn": 17, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 24, - "endLine": 17, - "endColumn": 32, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 10, - "endLine": 18, - "endColumn": 23, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 14, - "endLine": 19, - "endColumn": 22, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 7, - "endLine": 37, - "endColumn": 15, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 10, - "endLine": 41, - "endColumn": 18, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 7, - "endLine": 45, - "endColumn": 15, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 7, - "endLine": 53, - "endColumn": 15, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 19, - "endLine": 56, - "endColumn": 27, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 60, - "column": 26, - "endLine": 60, - "endColumn": 34, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 17, - "endLine": 65, - "endColumn": 25, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 25, - "endLine": 69, - "endColumn": 33, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 12, - "endLine": 70, - "endColumn": 20, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 12, - "endLine": 70, - "endColumn": 20, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 75, - "column": 20, - "endLine": 75, - "endColumn": 28, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 11, - "endLine": 79, - "endColumn": 19, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 11, - "endLine": 79, - "endColumn": 19, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 87, - "column": 12, - "endLine": 87, - "endColumn": 20, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 21, - "endLine": 96, - "endColumn": 29, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 22, - "endLine": 101, - "endColumn": 30, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 38, - "endLine": 101, - "endColumn": 46, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 56, - "endLine": 101, - "endColumn": 64, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 105, - "column": 23, - "endLine": 105, - "endColumn": 31, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 109, - "column": 27, - "endLine": 109, - "endColumn": 35, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 114, - "column": 80, - "endLine": 114, - "endColumn": 88, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 16, - "endLine": 118, - "endColumn": 24, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 16, - "endLine": 118, - "endColumn": 24, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 121, - "column": 3, - "endLine": 121, - "endColumn": 10, - "problem": "TsOverload", - "suggest": "", - "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 35, - "problem": "TsOverload", - "suggest": "", - "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 12, - "endLine": 122, - "endColumn": 20, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 123, - "column": 3, - "endLine": 125, - "endColumn": 4, - "problem": "TsOverload", - "suggest": "", - "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", - "severity": "ERROR" - }, - { - "line": 123, - "column": 13, - "endLine": 123, - "endColumn": 21, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 21, - "endLine": 128, - "endColumn": 29, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 31, - "endLine": 128, - "endColumn": 32, - "problem": "LimitedLiteralType", - "suggest": "", - "rule": "Literal types are restricted(arkts-limited-literal-types)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 33, - "endLine": 128, - "endColumn": 37, - "problem": "LimitedLiteralType", - "suggest": "", - "rule": "Literal types are restricted(arkts-limited-literal-types)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 39, - "endLine": 128, - "endColumn": 44, - "problem": "LimitedLiteralType", - "suggest": "", - "rule": "Literal types are restricted(arkts-limited-literal-types)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 57, - "endLine": 128, - "endColumn": 65, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 132, - "column": 3, - "endLine": 132, - "endColumn": 11, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 138, - "column": 34, - "endLine": 138, - "endColumn": 42, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 142, - "column": 11, - "endLine": 142, - "endColumn": 19, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 143, - "column": 36, - "endLine": 143, - "endColumn": 44, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 150, - "column": 16, - "endLine": 150, - "endColumn": 21, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 151, - "column": 14, - "endLine": 151, - "endColumn": 22, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 153, - "column": 20, - "endLine": 153, - "endColumn": 28, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 154, - "column": 9, - "endLine": 154, - "endColumn": 31, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 155, - "column": 17, - "endLine": 155, - "endColumn": 25, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 159, - "column": 28, - "endLine": 159, - "endColumn": 36, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 159, - "column": 41, - "endLine": 159, - "endColumn": 49, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 160, - "column": 47, - "endLine": 160, - "endColumn": 55, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 160, - "column": 85, - "endLine": 160, - "endColumn": 93, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - } - ] -} + { + "line": 16, + "column": 20, + "endLine": 16, + "endColumn": 33, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 23, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 20, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 19, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 16, + "endLine": 118, + "endColumn": 24, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 10, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 35, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 3, + "endLine": 125, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 32, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 33, + "endLine": 128, + "endColumn": 37, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 39, + "endLine": 128, + "endColumn": 44, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 3, + "endLine": 132, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 3, + "endLine": 139, + "endColumn": 11, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 16, + "endLine": 150, + "endColumn": 21, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 14, + "endLine": 151, + "endColumn": 22, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 9, + "endLine": 154, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 62, + "endLine": 160, + "endColumn": 66, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 67, + "endLine": 160, + "endColumn": 71, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 1, + "endLine": 166, + "endColumn": 3, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 172, + "column": 1, + "endLine": 172, + "endColumn": 8, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 1, + "endLine": 175, + "endColumn": 8, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/func_return_type.ts.migrate.json b/ets2panda/linter/test/main/explicit_function_type.ets.autofix.json similarity index 30% rename from ets2panda/linter/test/migrate/func_return_type.ts.migrate.json rename to ets2panda/linter/test/main/explicit_function_type.ets.autofix.json index 567dd757ee06a50bc311a9a0a0bb0f09817bef33..5f69b7bd511d6f196df6e1cd707d3619254be6bf 100644 --- a/ets2panda/linter/test/migrate/func_return_type.ts.migrate.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.autofix.json @@ -1,263 +1,300 @@ { + "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": 10, + "column": 20, "endLine": 16, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 10, - "endLine": 23, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 10, - "endLine": 33, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 10, - "endLine": 40, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 10, - "endLine": 46, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "endColumn": 33, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 668, + "end": 681, + "replacementText": "() => { }" + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", "severity": "ERROR" }, { - "line": 54, + "line": 18, "column": 10, - "endLine": 54, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "endLine": 18, + "endColumn": 23, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 760, + "end": 773, + "replacementText": "() => { }" + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", "severity": "ERROR" }, { "line": 57, - "column": 10, + "column": 3, "endLine": 57, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "endColumn": 5, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "fn.unSafeCall", + "start": 1572, + "end": 1574 + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { - "line": 57, - "column": 15, - "endLine": 57, - "endColumn": 18, - "problem": "AnyType", + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 20, + "problem": "ClassAsObjectError", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, { - "line": 62, - "column": 12, - "endLine": 64, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 19, + "problem": "ClassAsObjectError", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, { - "line": 65, - "column": 12, - "endLine": 67, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 118, + "column": 16, + "endLine": 118, + "endColumn": 24, + "problem": "ClassAsObjectError", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, { - "line": 69, - "column": 12, - "endLine": 71, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 10, + "problem": "TsOverload", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" }, { - "line": 73, - "column": 12, - "endLine": 75, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 35, + "problem": "TsOverload", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" }, { - "line": 76, - "column": 12, - "endLine": 78, + "line": 123, + "column": 3, + "endLine": 125, "endColumn": 4, - "problem": "FunctionExpression", + "problem": "TsOverload", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" }, { - "line": 80, - "column": 12, - "endLine": 82, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 32, + "problem": "LimitedLiteralType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Literal types are restricted(arkts-limited-literal-types)", "severity": "ERROR" }, { - "line": 80, - "column": 12, - "endLine": 82, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 128, + "column": 33, + "endLine": 128, + "endColumn": 37, + "problem": "LimitedLiteralType", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Literal types are restricted(arkts-limited-literal-types)", "severity": "ERROR" }, { - "line": 86, - "column": 12, - "endLine": 88, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 128, + "column": 39, + "endLine": 128, + "endColumn": 44, + "problem": "LimitedLiteralType", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Literal types are restricted(arkts-limited-literal-types)", "severity": "ERROR" }, { - "line": 97, - "column": 12, - "endLine": 99, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 132, + "column": 3, + "endLine": 132, + "endColumn": 11, + "problem": "InvalidIdentifier", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" }, { - "line": 104, - "column": 12, - "endLine": 106, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 139, + "column": 3, + "endLine": 139, + "endColumn": 11, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "callback.unSafeCall", + "start": 2921, + "end": 2929 + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 4, + "line": 150, + "column": 16, + "endLine": 150, + "endColumn": 21, "problem": "LimitedReturnTypeInference", "suggest": "", "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 114, - "column": 3, - "endLine": 114, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", + "line": 151, + "column": 14, + "endLine": 151, + "endColumn": 22, + "problem": "DynamicCtorCall", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", + "line": 154, + "column": 9, + "endLine": 154, + "endColumn": 31, + "problem": "AnyType", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 126, - "column": 3, - "endLine": 126, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", + "line": 160, + "column": 62, + "endLine": 160, + "endColumn": 66, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "curr.unSafeCall", + "start": 3458, + "end": 3462 + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { - "line": 131, - "column": 10, - "endLine": 131, - "endColumn": 30, - "problem": "LimitedReturnTypeInference", + "line": 160, + "column": 67, + "endLine": 160, + "endColumn": 71, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "prev.unSafeCall", + "start": 3463, + "end": 3467 + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { - "line": 135, - "column": 18, - "endLine": 135, - "endColumn": 40, - "problem": "LimitedReturnTypeInference", + "line": 166, + "column": 1, + "endLine": 166, + "endColumn": 3, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "f1.unSafeCall", + "start": 3586, + "end": 3588 + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { - "line": 139, - "column": 3, - "endLine": 139, - "endColumn": 10, - "problem": "LimitedReturnTypeInference", + "line": 172, + "column": 1, + "endLine": 172, + "endColumn": 8, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "ab3.fn3.unSafeCall", + "start": 3656, + "end": 3663 + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { - "line": 144, - "column": 3, - "endLine": 144, - "endColumn": 7, - "problem": "LimitedReturnTypeInference", + "line": 175, + "column": 1, + "endLine": 175, + "endColumn": 8, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "fn29[1].unSafeCall", + "start": 3697, + "end": 3704 + } + ], "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.migrate.ets b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e5584d49c72d97b78cee2c333bf39ef0522c2f99 --- /dev/null +++ b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.ets @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2024-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. + */ +let f1: Function = () => {}; // NOT OK +let g1: Function = () => { }; // NOT OK +let h1: Function = new Function('return 42'); // NOT OK +let g2 = () => { }; // OK +let h2 = new Function('return 42'); // NOT OK +let j1 = () => {}; // OK +let f2 = (x: number) => x + 1; // OK + + +type F = () => R; +type F1 = (p: P) => R; +type F2 = (p1: P1, p2: P2) => R; + +let f3: F = () => {}; // OK +let g3: F = () => 42; // OK +let h3: F1 = (s: string) => s.length; // OK +let i: F2 = (n: number, s: string) => s.length > n; // OK + +export let add: (a: number, b: number) => number; // OK +export let add1: (a: string) => object; // OK + +interface C2 { + f2: Function // NOK +} + +class A3 { + func3: Function = () => {} // NOK +} + +class A4 extends A3 { + f4: Function = () => {} // NOK +} + +interface C5 { + a5; +} + +class D5 implements C5 { + a5: Function = () => {} // NOK +} + +function run6(fn: Function) { + fn.unSafeCall(); +} + +function getFunction8(): Function { + return () => {}; +} + +abstract class F17 { + abstract f17: Function; +} + +class H23 { + async foo1(): Promise { + return Function; + } +} + +class I24 { + constructor(par: Function, par1?: string) {} +} +class I24_1 extends I24 { + constructor() { + super(Function) + } +} + + +class I25 { + constructor(par: number, par1?: string) {} + + foo3(fn: Function) { + console.log("this is Arkts1") + } +} +class I25_1 extends I25 { + constructor() { + super(2) + } + + override foo3(fn: Function): void { + console.log("this is Arkts2") + } +} + +function foo30(par1: Function, par2: Function[], par3: Function) { + console.log("ArkTs foo30") +} + +function foo31(par1?: Function) { + console.log("ArkTs foo31") +} + +function push32(...items: Function[]) { + items.forEach(item => { + }); +} + +function foo33(par1: number, par2: boolean, par3: string, par4: [string, Array]) { + console.log("ArkTs foo33") +} + +let array34 = [Function, 1, 2, 3]; + +class L36 { + foo1(); + foo1(par:Function, par1:string); + foo1(par?:Function, par1?:string){ + console.log('arkts36') + } +} + +let tup38:[['arkts'|Function, 1|true, false], string[], Function] = [['arkts', 1, false], ['arkts1', 'arkts2'], tup38_1]; + +//枚举 +enum E39 { + Function, + BLUE = 1, + YELLOW +} + +//回调参数不明确 +function handleEvent41(callback: Function) { + callback.unSafeCall("event", Date.now()); +} + +let fn43: Function = (x: number) => x + 1; +function process43(input: number): Function { + if (typeof input === "string") return fn43; + if (typeof input === "number") return fn43; + return fn43; +} + +//as +async function fetch(url: string) { + return new Animal42(); +} +const fetchData44: Function = async (url: string) => { + const res = await fetch(url); + return res as Function; +}; + +//高阶函数 +function compose45(...fns: Function[]): Function { + return fns.reduce((prev, curr) => (...args: Function[]) => curr.unSafeCall(prev.unSafeCall(...args)) as Function); +} + +export let add: (a: number, b: number) => number; +export let add1: (a: string) => object; + +f1.unSafeCall(); + +class AB3 { + fn3: Function = () => {}; +} +let ab3 = new AB3(); +ab3.fn3.unSafeCall(); + +const fn29: Function[] = []; +fn29[1].unSafeCall(); \ No newline at end of file diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8b449e6619a40fc8803e44c3a933540290cf7c90 --- /dev/null +++ b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json @@ -0,0 +1,148 @@ +{ + "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": 70, + "column": 12, + "endLine": 70, + "endColumn": 20, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 19, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 16, + "endLine": 118, + "endColumn": 24, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 10, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 35, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 3, + "endLine": 125, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 32, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 33, + "endLine": 128, + "endColumn": 37, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 39, + "endLine": 128, + "endColumn": 44, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 3, + "endLine": 132, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 16, + "endLine": 150, + "endColumn": 21, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 14, + "endLine": 151, + "endColumn": 22, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 9, + "endLine": 154, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/exponent.ets.args.json b/ets2panda/linter/test/main/exponent.ets.args.json index c0636ac689f243039f0ead525df4e6ba5763d93d..0476e60c0bb38d48ebb1411ba3249c22948eb658 100644 --- a/ets2panda/linter/test/main/exponent.ets.args.json +++ b/ets2panda/linter/test/main/exponent.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "autofix": "--arkts-2", - "arkts2": "" + "arkts2": "", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/exponent.ets.migrate.ets b/ets2panda/linter/test/main/exponent.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..056294b8642bd9924cedb2b159320ca5b0db143d --- /dev/null +++ b/ets2panda/linter/test/main/exponent.ets.migrate.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. + */ + +let kk: number = Math.pow(6, 3); +console.log(kk); + +let k: number = Math.pow(5, 2); +console.log(k); + +k = Math.pow(k, 2); +console.log(k); + +k = Math.pow(-1, Infinity); +console.log(k); diff --git a/ets2panda/linter/test/main/exponent.ets.migrate.json b/ets2panda/linter/test/main/exponent.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..daeb5bf97a9cb257e346839c0c2d883e71bca3c7 --- /dev/null +++ b/ets2panda/linter/test/main/exponent.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 18, + "endLine": 16, + "endColumn": 32, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 17, + "endLine": 19, + "endColumn": 31, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 19, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 27, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.args.json b/ets2panda/linter/test/main/extend_decorator_1.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/extend_decorator_1.ets.args.json +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..829d53b38afd3152d1421b0441e8dc04fdb5ac1f --- /dev/null +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI'; + +@Component +struct MyCard { + build() { + Column() { + Text('Card') + } + .cardStyle() + } +} + +const mycolor: string = "#ffffff" + +function cardStyle(this: ColumnAttribute): this { + this.backgroundColor("#ffff00"); + this.backgroundColor("#00ffff"); + this.backgroundColor("#ff00ff"); + this.backgroundColor(mycolor); + this.backgroundColor(Color.Red); + this.borderRadius(8); + this.padding(8); + this.backgroundImagePosition({ + x: 0, + y: 0 + }); + return this; +} + +function superCard(this: ColumnAttribute, padding: number): this { + this.cardStyle(); + this.padding(10); + return this; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..be60c934865f47fd861687847b25781c212573e6 --- /dev/null +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json @@ -0,0 +1,178 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 5, + "endLine": 37, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 12, + "endLine": 42, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 44, + "endLine": 30, + "endColumn": 48, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 20, + "endLine": 45, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 61, + "endLine": 45, + "endColumn": 65, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.args.json b/ets2panda/linter/test/main/extend_decorator_2.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/extend_decorator_2.ets.args.json +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.ets b/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..c53497da05239bbde8ecdfb75b4ec103560e15e8 --- /dev/null +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI'; + +@Component +struct MyCard { + build() { + Column() { + Text('Card') + } + .cardStyle() + } +} + +const mycolor: string = "#ffffff" + +function cardStyle(this: ColumnAttribute): this { + this.backgroundColor("#ffff00"); + this.backgroundColor("#00ffff"); + this.backgroundColor("#ff00ff"); + this.backgroundColor(mycolor); + this.backgroundColor(Color.Red); + this.borderRadius(8); + this.padding(8); + this.backgroundImagePosition({ + x: 0, + y: 0 + }); + return this; +} + +function superCard(this: ColumnAttribute, padding: number): this { + .cardStyle() + .padding(10) +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.json b/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0f332deca642333fc8f530a70ee3252badc85eef --- /dev/null +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.json @@ -0,0 +1,148 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 3, + "endLine": 33, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 3, + "endLine": 37, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 44, + "endLine": 30, + "endColumn": 48, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 20, + "endLine": 45, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 61, + "endLine": 45, + "endColumn": 65, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extends_expression.ets b/ets2panda/linter/test/main/extends_expression.ets index d95b96aee46807155fdb9e4892ed40750b773a71..fde6f5729d4b0322841a8770a80b1b512deaa41f 100755 --- a/ets2panda/linter/test/main/extends_expression.ets +++ b/ets2panda/linter/test/main/extends_expression.ets @@ -12,6 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' + class A { v: number = 0 } diff --git a/ets2panda/linter/test/main/extends_expression.ets.arkts2.json b/ets2panda/linter/test/main/extends_expression.ets.arkts2.json index 1c73b16814b46f2982585207b979eec493fec4e0..d157d2e206fad21ce70c0b407679dfd378a9ff63 100755 --- a/ets2panda/linter/test/main/extends_expression.ets.arkts2.json +++ b/ets2panda/linter/test/main/extends_expression.ets.arkts2.json @@ -13,116 +13,116 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - { - "line": 19, - "column": 9, - "endLine": 19, - "endColumn": 10, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 17, - "endLine": 21, - "endColumn": 18, - "problem": "ExtendsExpression", - "suggest": "", - "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", - "severity": "ERROR" - }, - { - "line": 29, - "column": 37, - "endLine": 29, - "endColumn": 44, - "problem": "InterfaceExtendsClass", - "suggest": "", - "rule": "Interfaces cannot extend classes (arkts-extends-only-class)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 10, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 22, - "endLine": 56, - "endColumn": 23, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 24, - "endLine": 56, - "endColumn": 32, - "problem": "ConstructorType", - "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 10, - "endLine": 59, - "endColumn": 22, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 12, - "endLine": 71, - "endColumn": 13, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 12, - "endLine": 73, - "endColumn": 13, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 77, - "column": 20, - "endLine": 77, - "endColumn": 39, - "problem": "ExtendsExpression", - "suggest": "", - "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", - "severity": "ERROR" - }, - { - "line": 83, - "column": 21, - "endLine": 83, - "endColumn": 39, - "problem": "ExtendsExpression", - "suggest": "", - "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", - "severity": "ERROR" - } - ] + "result": [ + { + "line": 21, + "column": 9, + "endLine": 21, + "endColumn": 10, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 17, + "endLine": 23, + "endColumn": 18, + "problem": "ExtendsExpression", + "suggest": "", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 37, + "endLine": 31, + "endColumn": 44, + "problem": "InterfaceExtendsClass", + "suggest": "", + "rule": "Interfaces cannot extend classes (arkts-extends-only-class)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 10, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 22, + "endLine": 58, + "endColumn": 23, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 24, + "endLine": 58, + "endColumn": 32, + "problem": "ConstructorType", + "suggest": "", + "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 10, + "endLine": 61, + "endColumn": 22, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 12, + "endLine": 73, + "endColumn": 13, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 12, + "endLine": 75, + "endColumn": 13, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 20, + "endLine": 79, + "endColumn": 39, + "problem": "ExtendsExpression", + "suggest": "", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 21, + "endLine": 85, + "endColumn": 39, + "problem": "ExtendsExpression", + "suggest": "", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", + "severity": "ERROR" + } + ] } diff --git a/ets2panda/linter/test/main/extends_expression.ets.json b/ets2panda/linter/test/main/extends_expression.ets.json index d8afa3d8c88a9eab2d30ddda57f14a3bd6dbd28e..390e52b7818f4c3f731b3deb7b96c5afc04e0855 100644 --- a/ets2panda/linter/test/main/extends_expression.ets.json +++ b/ets2panda/linter/test/main/extends_expression.ets.json @@ -13,76 +13,76 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - { - "line": 19, - "column": 9, - "endLine": 19, - "endColumn": 10, - "problem": "ClassAsObject", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "WARNING" - }, - { - "line": 29, - "column": 37, - "endLine": 29, - "endColumn": 44, - "problem": "InterfaceExtendsClass", - "suggest": "", - "rule": "Interfaces cannot extend classes (arkts-extends-only-class)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 10, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 22, - "endLine": 56, - "endColumn": 23, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 24, - "endLine": 56, - "endColumn": 32, - "problem": "ConstructorType", - "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 12, - "endLine": 71, - "endColumn": 13, - "problem": "ClassAsObject", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "WARNING" - }, - { - "line": 73, - "column": 12, - "endLine": 73, - "endColumn": 13, - "problem": "ClassAsObject", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "WARNING" - } - ] -} \ No newline at end of file + "result": [ + { + "line": 21, + "column": 9, + "endLine": 21, + "endColumn": 10, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 31, + "column": 37, + "endLine": 31, + "endColumn": 44, + "problem": "InterfaceExtendsClass", + "suggest": "", + "rule": "Interfaces cannot extend classes (arkts-extends-only-class)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 10, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 22, + "endLine": 58, + "endColumn": 23, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 24, + "endLine": 58, + "endColumn": 32, + "problem": "ConstructorType", + "suggest": "", + "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 12, + "endLine": 73, + "endColumn": 13, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 75, + "column": 12, + "endLine": 75, + "endColumn": 13, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + } + ] +} diff --git a/ets2panda/linter/test/main/func_inferred_type_args.ets b/ets2panda/linter/test/main/func_inferred_type_args.ets index 91bf75c577039236224ac5fd14f487a62b795bb3..f5bcd5b762e5ffd23272d3eecad9d9de1438b931 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args.ets +++ b/ets2panda/linter/test/main/func_inferred_type_args.ets @@ -14,7 +14,17 @@ */ import { bad_func } from "./dynamic_lib" - +import { Deque } from '@kit.ArkTS'; +import ArrayList from '@ohos.util.ArrayList'; +import Deque from '@ohos.util.Deque'; +import HashMap from '@ohos.util.HashMap'; +import HashSet from '@ohos.util.HashSet'; +import LinkedList from '@ohos.util.LinkedList'; +import PlainArray from '@ohos.util.PlainArray'; +import Queue from '@ohos.util.Queue'; +import TreeMap from '@ohos.util.TreeMap'; +import TreeSet from '@ohos.util.TreeSet'; +import { LinkedList } from '@kit.ArkTS'; function choose(x: T, y: T): T { return Math.random() < 0.5 ? x : y } @@ -89,3 +99,36 @@ const stringBox1: Box1 = new Box1(); // NOK const stringBox2: Box1 = new Box1(); // OK const stringBox3: Box1 = new Box1(); // OK const stringBox4 = new Box1(); // NOK + +let de: Deque = new Deque(); //error +function newDeque():Deque{ + return new Deque(); //error +} +class D{ + dd: Deque; + constructor(){ + new Deque(); //error + } + + initDD(){ + dd = new Deque(); + } +} + +class Base{} +class NewClass extends Base{} +export let obj = new NewClass(); +class NewClass2 extends Base{} +export let obj2 = new NewClass2(); + +let test_arrayList_e: ArrayList = new ArrayList(); // +let test_deque_e: Deque = new Deque(); // +let test_hashMap_e: HashMap = new HashMap(); // +let test_hashSet_e: HashSet = new HashSet(); // +let test_linkedList_e: LinkedList = new LinkedList(); // +let test_plainArray_e: PlainArray = new PlainArray(); // +let test_queue_e: Queue = new Queue(); // +let test_treeMap_e: TreeMap = new TreeMap(); // +let test_treeSet_e: TreeSet = new TreeSet(); // +let test_treeSet_set_e: TreeSet> = new TreeSet(); +let listenerList: LinkedList = new LinkedList(); \ 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 ac441596b11ce2074c853c6a3039f5106d250e35..3d6311cc42123c86e67d74652f142cca73a4093a 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 @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2025 Huawei Device Co., Ltd.", + "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", @@ -15,9 +15,9 @@ ], "result": [ { - "line": 21, + "line": 31, "column": 5, - "endLine": 21, + "endLine": 31, "endColumn": 23, "problem": "NumericSemantics", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 36, "column": 5, - "endLine": 26, + "endLine": 36, "endColumn": 16, "problem": "UnknownType", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 36, "column": 9, - "endLine": 26, + "endLine": 36, "endColumn": 16, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 38, "column": 1, - "endLine": 30, + "endLine": 40, "endColumn": 2, "problem": "NumericSemantics", "suggest": "", @@ -55,9 +55,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 38, "column": 21, - "endLine": 28, + "endLine": 38, "endColumn": 24, "problem": "AnyType", "suggest": "", @@ -65,9 +65,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 41, "column": 1, - "endLine": 31, + "endLine": 41, "endColumn": 6, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -75,9 +75,9 @@ "severity": "ERROR" }, { - "line": 38, + "line": 48, "column": 1, - "endLine": 38, + "endLine": 48, "endColumn": 6, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -85,9 +85,9 @@ "severity": "ERROR" }, { - "line": 42, + "line": 52, "column": 5, - "endLine": 42, + "endLine": 52, "endColumn": 14, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -95,9 +95,9 @@ "severity": "ERROR" }, { - "line": 43, + "line": 53, "column": 1, - "endLine": 43, + "endLine": 53, "endColumn": 31, "problem": "NumericSemantics", "suggest": "", @@ -105,9 +105,9 @@ "severity": "ERROR" }, { - "line": 46, + "line": 56, "column": 8, - "endLine": 46, + "endLine": 56, "endColumn": 11, "problem": "AnyType", "suggest": "", @@ -115,9 +115,9 @@ "severity": "ERROR" }, { - "line": 47, + "line": 57, "column": 16, - "endLine": 47, + "endLine": 57, "endColumn": 19, "problem": "AnyType", "suggest": "", @@ -125,9 +125,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 59, "column": 8, - "endLine": 49, + "endLine": 59, "endColumn": 9, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -135,9 +135,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 61, "column": 5, - "endLine": 51, + "endLine": 61, "endColumn": 20, "problem": "UnknownType", "suggest": "", @@ -145,9 +145,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 61, "column": 11, - "endLine": 51, + "endLine": 61, "endColumn": 20, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -155,9 +155,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 63, "column": 3, - "endLine": 53, + "endLine": 63, "endColumn": 22, "problem": "TsOverload", "suggest": "", @@ -165,9 +165,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 64, "column": 3, - "endLine": 54, + "endLine": 64, "endColumn": 19, "problem": "TsOverload", "suggest": "", @@ -175,9 +175,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 66, "column": 5, - "endLine": 56, + "endLine": 66, "endColumn": 16, "problem": "UnknownType", "suggest": "", @@ -185,9 +185,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 66, "column": 9, - "endLine": 56, + "endLine": 66, "endColumn": 16, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -195,9 +195,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 68, "column": 5, - "endLine": 58, + "endLine": 68, "endColumn": 17, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -205,9 +205,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 68, "column": 11, - "endLine": 58, + "endLine": 68, "endColumn": 16, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -215,9 +215,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 69, "column": 5, - "endLine": 59, + "endLine": 69, "endColumn": 15, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -225,9 +225,9 @@ "severity": "ERROR" }, { - "line": 60, + "line": 70, "column": 5, - "endLine": 60, + "endLine": 70, "endColumn": 26, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -235,9 +235,9 @@ "severity": "ERROR" }, { - "line": 60, + "line": 70, "column": 19, - "endLine": 60, + "endLine": 70, "endColumn": 22, "problem": "AnyType", "suggest": "", @@ -245,9 +245,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 72, "column": 10, - "endLine": 62, + "endLine": 72, "endColumn": 11, "problem": "ObjectTypeLiteral", "suggest": "", @@ -255,9 +255,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 79, "column": 11, - "endLine": 69, + "endLine": 79, "endColumn": 14, "problem": "AnyType", "suggest": "", @@ -265,9 +265,9 @@ "severity": "ERROR" }, { - "line": 79, + "line": 89, "column": 5, - "endLine": 79, + "endLine": 89, "endColumn": 23, "problem": "AnyType", "suggest": "", @@ -275,9 +275,9 @@ "severity": "ERROR" }, { - "line": 79, + "line": 89, "column": 12, - "endLine": 79, + "endLine": 89, "endColumn": 23, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -285,9 +285,9 @@ "severity": "ERROR" }, { - "line": 80, + "line": 90, "column": 5, - "endLine": 80, + "endLine": 90, "endColumn": 21, "problem": "AnyType", "suggest": "", @@ -295,9 +295,9 @@ "severity": "ERROR" }, { - "line": 80, + "line": 90, "column": 5, - "endLine": 80, + "endLine": 90, "endColumn": 21, "problem": "AnyType", "suggest": "", @@ -305,9 +305,9 @@ "severity": "ERROR" }, { - "line": 80, + "line": 90, "column": 12, - "endLine": 80, + "endLine": 90, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -315,9 +315,9 @@ "severity": "ERROR" }, { - "line": 81, + "line": 91, "column": 5, - "endLine": 81, + "endLine": 91, "endColumn": 39, "problem": "AnyType", "suggest": "", @@ -325,9 +325,9 @@ "severity": "ERROR" }, { - "line": 81, + "line": 91, "column": 24, - "endLine": 81, + "endLine": 91, "endColumn": 37, "problem": "DynamicCtorCall", "suggest": "", @@ -335,9 +335,9 @@ "severity": "ERROR" }, { - "line": 81, + "line": 91, "column": 20, - "endLine": 81, + "endLine": 91, "endColumn": 39, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -345,9 +345,9 @@ "severity": "ERROR" }, { - "line": 82, + "line": 92, "column": 5, - "endLine": 82, + "endLine": 92, "endColumn": 52, "problem": "UnknownType", "suggest": "", @@ -355,9 +355,9 @@ "severity": "ERROR" }, { - "line": 82, + "line": 92, "column": 16, - "endLine": 82, + "endLine": 92, "endColumn": 52, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -365,9 +365,9 @@ "severity": "ERROR" }, { - "line": 83, + "line": 93, "column": 5, - "endLine": 83, + "endLine": 93, "endColumn": 29, "problem": "AnyType", "suggest": "", @@ -375,9 +375,9 @@ "severity": "ERROR" }, { - "line": 83, + "line": 93, "column": 16, - "endLine": 83, + "endLine": 93, "endColumn": 29, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -385,9 +385,9 @@ "severity": "ERROR" }, { - "line": 84, + "line": 94, "column": 16, - "endLine": 84, + "endLine": 94, "endColumn": 29, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -395,9 +395,9 @@ "severity": "ERROR" }, { - "line": 88, + "line": 98, "column": 34, - "endLine": 88, + "endLine": 98, "endColumn": 44, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -405,9 +405,9 @@ "severity": "ERROR" }, { - "line": 91, + "line": 101, "column": 7, - "endLine": 91, + "endLine": 101, "endColumn": 30, "problem": "UnknownType", "suggest": "", @@ -415,9 +415,9 @@ "severity": "ERROR" }, { - "line": 91, + "line": 101, "column": 20, - "endLine": 91, + "endLine": 101, "endColumn": 30, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -425,9 +425,299 @@ "severity": "ERROR" }, { - "line": 63, + "line": 103, + "column": 21, + "endLine": 103, + "endColumn": 26, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 17, + "endLine": 103, + "endColumn": 28, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 14, + "endLine": 105, + "endColumn": 19, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 10, + "endLine": 105, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 9, + "endLine": 110, + "endColumn": 14, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 5, + "endLine": 110, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 14, + "endLine": 114, + "endColumn": 19, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 47, + "endLine": 124, + "endColumn": 56, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 43, + "endLine": 124, + "endColumn": 58, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 39, + "endLine": 125, + "endColumn": 44, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 35, + "endLine": 125, + "endColumn": 46, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 51, + "endLine": 126, + "endColumn": 58, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 47, + "endLine": 126, + "endColumn": 60, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 43, + "endLine": 127, + "endColumn": 50, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 39, + "endLine": 127, + "endColumn": 52, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 49, + "endLine": 128, + "endColumn": 59, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 45, + "endLine": 128, + "endColumn": 61, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 49, + "endLine": 129, + "endColumn": 59, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 45, + "endLine": 129, + "endColumn": 61, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 39, + "endLine": 130, + "endColumn": 44, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 35, + "endLine": 130, + "endColumn": 46, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 131, + "column": 51, + "endLine": 131, + "endColumn": 58, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 131, + "column": 47, + "endLine": 131, + "endColumn": 60, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 43, + "endLine": 132, + "endColumn": 50, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 39, + "endLine": 132, + "endColumn": 52, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 56, + "endLine": 133, + "endColumn": 63, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 52, + "endLine": 133, + "endColumn": 65, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 44, + "endLine": 134, + "endColumn": 54, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 40, + "endLine": 134, + "endColumn": 56, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 73, "column": 1, - "endLine": 63, + "endLine": 73, "endColumn": 2, "problem": "StrictDiagnostic", "suggest": "Variable 'd' is used before being assigned.", diff --git a/ets2panda/linter/test/main/func_inferred_type_args.ets.json b/ets2panda/linter/test/main/func_inferred_type_args.ets.json index bd681a3a67351b5089da4854c094a3a52fac490d..2d86c954b2772f916aefe6ee54dbcd73100e9674 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args.ets.json +++ b/ets2panda/linter/test/main/func_inferred_type_args.ets.json @@ -1,278 +1,278 @@ { - "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": 26, - "column": 5, - "endLine": 26, - "endColumn": 16, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 9, - "endLine": 26, - "endColumn": 16, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 21, - "endLine": 28, - "endColumn": 24, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 1, - "endLine": 31, - "endColumn": 6, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 1, - "endLine": 38, - "endColumn": 6, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 8, - "endLine": 46, - "endColumn": 11, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 16, - "endLine": 47, - "endColumn": 19, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 49, - "column": 8, - "endLine": 49, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 5, - "endLine": 51, - "endColumn": 20, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 11, - "endLine": 51, - "endColumn": 20, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "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": 16, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 9, - "endLine": 56, - "endColumn": 16, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 11, - "endLine": 58, - "endColumn": 16, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 60, - "column": 19, - "endLine": 60, - "endColumn": 22, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 62, - "column": 10, - "endLine": 62, - "endColumn": 11, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 11, - "endLine": 69, - "endColumn": 14, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 5, - "endLine": 79, - "endColumn": 23, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 5, - "endLine": 80, - "endColumn": 21, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 5, - "endLine": 80, - "endColumn": 21, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 5, - "endLine": 81, - "endColumn": 39, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 82, - "column": 5, - "endLine": 82, - "endColumn": 52, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 82, - "column": 16, - "endLine": 82, - "endColumn": 52, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 83, - "column": 5, - "endLine": 83, - "endColumn": 29, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 7, - "endLine": 91, - "endColumn": 30, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 20, - "endLine": 91, - "endColumn": 30, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 1, - "endLine": 63, - "endColumn": 2, - "problem": "StrictDiagnostic", - "suggest": "Variable 'd' is used before being assigned.", - "rule": "Variable 'd' is used before being assigned.", - "severity": "ERROR" - } - ] -} + "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": 36, + "column": 5, + "endLine": 36, + "endColumn": 16, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 9, + "endLine": 36, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 21, + "endLine": 38, + "endColumn": 24, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 6, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 1, + "endLine": 48, + "endColumn": 6, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 8, + "endLine": 56, + "endColumn": 11, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 16, + "endLine": 57, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 8, + "endLine": 59, + "endColumn": 9, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 20, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 11, + "endLine": 61, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 16, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 9, + "endLine": 66, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 11, + "endLine": 68, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 19, + "endLine": 70, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 10, + "endLine": 72, + "endColumn": 11, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 5, + "endLine": 90, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 5, + "endLine": 90, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 5, + "endLine": 91, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 5, + "endLine": 92, + "endColumn": 52, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 16, + "endLine": 92, + "endColumn": 52, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 5, + "endLine": 93, + "endColumn": 29, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 7, + "endLine": 101, + "endColumn": 30, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 20, + "endLine": 101, + "endColumn": 30, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 2, + "problem": "StrictDiagnostic", + "suggest": "Variable 'd' is used before being assigned.", + "rule": "Variable 'd' is used before being assigned.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets b/ets2panda/linter/test/main/func_inferred_type_args_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..636e016aeadd253445251567c7f09fa7da3bd996 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets @@ -0,0 +1,74 @@ +/* + * 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. + */ + +const irreparableArr = new Array(); +let repairableArr: Array = new Array(); +repairableArr = new Array(); + +const irreparableMap = new Map(); +const repairableMap: Map = new Map(); +repairableMap = new Map(); + +class MyClass { + public irreparableMap = new Map(); + public repairableSet: Set = new Map(); + public repairableMap: Map string[]> = new Map(); + static repairableStaticMap: Map string[]> = new Map(); + constructor() {} +} + +const irreparableA = new MyClass(); +const irreparableB = new MyClass(); +const repairableC: MyClass = new MyClass(); +repairableC.irreparableMap = new Map(); +repairableC.repairableSet = new Set(); +repairableC.repairableMap = new Map(); +MyClass.repairableStaticMap = new Map(); + +const promise: Promise = new Promise(()=> {return ''}); + +function testA(): Map { + return new Map(); +} + +async function testB(): Promise> { + return new Map(); +} + +function testC(): Map { + return new Set(); +} + +async function testD(): Promise> { + return new Set(); +} + +class MyClassB { + testA(): Map { + return new Map(); + } + + async testB(): Promise> { + return new Map(); + } + + testC(): Map { + return new Set(); + } + + async testD(): Promise> { + return new Set(); + } +} diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.args.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..30973c00a22aa0a072616f644b02c89a4a4dd4fa --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8332379fa7ccc19ab8c5ff0b28b5ca38417e962e --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json @@ -0,0 +1,378 @@ +{ + "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": 7, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 24, + "endLine": 16, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 36, + "endLine": 17, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 17, + "endLine": 18, + "endColumn": 28, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 24, + "endLine": 20, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 44, + "endLine": 21, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 26, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 36, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 23, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 39, + "endLine": 26, + "endColumn": 48, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 55, + "endLine": 27, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 61, + "endLine": 28, + "endColumn": 70, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 35, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 38, + "endLine": 34, + "endColumn": 51, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 30, + "endLine": 35, + "endColumn": 39, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 29, + "endLine": 36, + "endColumn": 38, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 29, + "endLine": 37, + "endColumn": 38, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 31, + "endLine": 38, + "endColumn": 40, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 34, + "endLine": 40, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 10, + "endLine": 43, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 10, + "endLine": 47, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 12, + "endLine": 60, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..773fea5ff8c4e90cfc4e962f87f7eb24ea4edf71 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json @@ -0,0 +1,483 @@ +{ + "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": 7, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 24, + "endLine": 16, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 36, + "endLine": 17, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 676, + "end": 687, + "replacementText": "new Array()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 17, + "endLine": 18, + "endColumn": 28, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 705, + "end": 716, + "replacementText": "new Array()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 24, + "endLine": 20, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 44, + "endLine": 21, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 796, + "end": 805, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 26, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 823, + "end": 832, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 36, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 23, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 39, + "endLine": 26, + "endColumn": 48, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 55, + "endLine": 27, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 994, + "end": 1003, + "replacementText": "new Map string[]>()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 61, + "endLine": 28, + "endColumn": 70, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1065, + "end": 1074, + "replacementText": "new Map string[]>()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 35, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 38, + "endLine": 34, + "endColumn": 51, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1215, + "end": 1228, + "replacementText": "new MyClass()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 30, + "endLine": 35, + "endColumn": 39, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 29, + "endLine": 36, + "endColumn": 38, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1298, + "end": 1307, + "replacementText": "new Set()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 29, + "endLine": 37, + "endColumn": 38, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1337, + "end": 1346, + "replacementText": "new Map string[]>()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 31, + "endLine": 38, + "endColumn": 40, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1378, + "end": 1387, + "replacementText": "new Map string[]>()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 34, + "endLine": 40, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1423, + "end": 1452, + "replacementText": "new Promise(() => { return ''; })" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 10, + "endLine": 43, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1504, + "end": 1513, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 10, + "endLine": 47, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1582, + "end": 1591, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 12, + "endLine": 60, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1798, + "end": 1807, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1873, + "end": 1882, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..1f00081d43be7bede54b70559d1f112d1b9b47ab --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.json @@ -0,0 +1,128 @@ +{ + "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": 7, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 35, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..01a5d89f97c06ce79226ada89136f658d4d19bdb --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets @@ -0,0 +1,74 @@ +/* + * 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. + */ + +const irreparableArr = new Array(); +let repairableArr: Array = new Array(); +repairableArr = new Array(); + +const irreparableMap = new Map(); +const repairableMap: Map = new Map(); +repairableMap = new Map(); + +class MyClass { + public irreparableMap = new Map(); + public repairableSet: Set = new Map(); + public repairableMap: Map string[]> = new Map string[]>(); + static repairableStaticMap: Map string[]> = new Map string[]>(); + constructor() {} +} + +const irreparableA = new MyClass(); +const irreparableB = new MyClass(); +const repairableC: MyClass = new MyClass(); +repairableC.irreparableMap = new Map(); +repairableC.repairableSet = new Set(); +repairableC.repairableMap = new Map string[]>(); +MyClass.repairableStaticMap = new Map string[]>(); + +const promise: Promise = new Promise(() => { return ''; }); + +function testA(): Map { + return new Map(); +} + +async function testB(): Promise> { + return new Map(); +} + +function testC(): Map { + return new Set(); +} + +async function testD(): Promise> { + return new Set(); +} + +class MyClassB { + testA(): Map { + return new Map(); + } + + async testB(): Promise> { + return new Map(); + } + + testC(): Map { + return new Set(); + } + + async testD(): Promise> { + return new Set(); + } +} diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a3d92d0d965596b23b8e137b426e01275b3f7847 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json @@ -0,0 +1,228 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 16, + "column": 7, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 24, + "endLine": 16, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 24, + "endLine": 20, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 36, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 23, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 39, + "endLine": 26, + "endColumn": 48, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 35, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 30, + "endLine": 35, + "endColumn": 39, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_return_type.ets.args.json b/ets2panda/linter/test/main/func_return_type.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/func_return_type.ets.args.json +++ b/ets2panda/linter/test/main/func_return_type.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/migrate/func_return_type.sts b/ets2panda/linter/test/main/func_return_type.ets.migrate.ets similarity index 77% rename from ets2panda/linter/test/migrate/func_return_type.sts rename to ets2panda/linter/test/main/func_return_type.ets.migrate.ets index c2167e6373157ff748ad9ee044c39b09e3f2c36e..cbcf3e1fb8ea652207ff978c7368b50927b98173 100644 --- a/ets2panda/linter/test/migrate/func_return_type.sts +++ b/ets2panda/linter/test/main/func_return_type.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,14 +13,14 @@ * limitations under the License. */ -function q(x: number) { // Need fix +function q(x: number): number { // Need fix return w(x) } function w(x: number) { - return x; + return x; } -function e(x: string) { // Need fix +function e(x: string): string { // Need fix return r(x) } function r(x: string) { @@ -30,7 +30,7 @@ function t(x: string): string { return x; } -function y() { // Need fix +function y(): number[] { // Need fix return u(); } function u() { @@ -59,23 +59,23 @@ function z(a: any) { // Not fixable } function functionExpressions() { - let f1 = function (c: C) { // Need fix + let f1 = (c: C): C => { return f2(c); - }; - let f2 = function (c: C) { +}; + let f2 = (c: C) => { return new C(); - }; - - let f3 = function (x: number, y: number) { +}; + + let f3 = (x: number, y: number) => { return x + y; - }; +}; - let f4 = function () { // Need fix + let f4 = (): Map => { return f5(); - }; - let f5 = function () { +}; + let f5 = () => { return new Map(); - }; +}; let f6 = function () { // Not fixable return z(0); @@ -83,20 +83,20 @@ function functionExpressions() { } function lambdas() { - let l1 = (t: T) => { // Need fix + let l1 = (t: T): T => { return l2(t); - }; +}; let l2 = (t: T) => { return t; }; - + let l3 = (x: number, y: number) => { return x + y; }; - let l4 = () => { // Need fix + let l4 = (): (x: number) => string => { return l5(); - }; +}; let l5 = () => { return (x: number) => x.toString(); }; @@ -107,19 +107,19 @@ function lambdas() { } class C { - m(x: number) { // Need fix + m(x: number): number { // Need fix return q(x) } - - m2(x: number) { // Need fix + + m2(x: number): number { // Need fix return this.m(x) } m3(x: number) { return 10; } - - m4() { // Need fix + + m4(): number { // Need fix return this.m2(20); } @@ -128,7 +128,7 @@ class C { } } -function no_space_before_body(x: number){ // Need fix +function no_space_before_body(x: number): number{ // Need fix return w(x) } diff --git a/ets2panda/linter/test/interop/no_js_await.ets.arkts2.json b/ets2panda/linter/test/main/func_return_type.ets.migrate.json old mode 100755 new mode 100644 similarity index 66% rename from ets2panda/linter/test/interop/no_js_await.ets.arkts2.json rename to ets2panda/linter/test/main/func_return_type.ets.migrate.json index 7b4e6053442c8f846491531958ebbf6be830132c..4d8789634f9daf40ac0655cd549af1ee9a74946d --- a/ets2panda/linter/test/interop/no_js_await.ets.arkts2.json +++ b/ets2panda/linter/test/main/func_return_type.ets.migrate.json @@ -15,79 +15,69 @@ ], "result": [ { - "line": 17, - "column": 1, - "endLine": 17, - "endColumn": 80, - "problem": "ImportAfterStatement", - "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 16, - "endLine": 20, - "endColumn": 28, + "line": 40, + "column": 10, + "endLine": 40, + "endColumn": 11, "problem": "LimitedReturnTypeInference", "suggest": "", "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 25, - "column": 16, - "endLine": 25, - "endColumn": 33, + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 11, "problem": "LimitedReturnTypeInference", "suggest": "", "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 29, - "column": 16, - "endLine": 29, - "endColumn": 31, + "line": 54, + "column": 10, + "endLine": 54, + "endColumn": 11, "problem": "LimitedReturnTypeInference", "suggest": "", "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 34, - "column": 16, - "endLine": 34, - "endColumn": 30, + "line": 57, + "column": 10, + "endLine": 57, + "endColumn": 11, "problem": "LimitedReturnTypeInference", "suggest": "", "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 38, - "column": 16, - "endLine": 38, - "endColumn": 32, - "problem": "LimitedReturnTypeInference", + "line": 57, + "column": 15, + "endLine": 57, + "endColumn": 18, + "problem": "AnyType", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 44, - "column": 9, - "endLine": 44, - "endColumn": 20, - "problem": "LimitedReturnTypeInference", + "line": 80, + "column": 12, + "endLine": 82, + "endColumn": 4, + "problem": "FunctionExpression", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", "severity": "ERROR" }, { - "line": 48, - "column": 13, - "endLine": 50, + "line": 80, + "column": 12, + "endLine": 82, "endColumn": 4, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -95,53 +85,53 @@ "severity": "ERROR" }, { - "line": 54, - "column": 20, - "endLine": 54, - "endColumn": 21, - "problem": "ObjectLiteralNoContextType", + "line": 104, + "column": 12, + "endLine": 106, + "endColumn": 4, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 55, + "line": 126, "column": 3, - "endLine": 57, - "endColumn": 4, - "problem": "ObjectLiteralProperty", + "endLine": 126, + "endColumn": 5, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 55, - "column": 9, - "endLine": 55, - "endColumn": 18, + "line": 135, + "column": 18, + "endLine": 135, + "endColumn": 40, "problem": "LimitedReturnTypeInference", "suggest": "", "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 59, - "column": 17, - "endLine": 61, - "endColumn": 4, + "line": 139, + "column": 3, + "endLine": 139, + "endColumn": 10, "problem": "LimitedReturnTypeInference", "suggest": "", "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 65, - "column": 2, - "endLine": 67, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 144, + "column": 3, + "endLine": 144, + "endColumn": 7, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/function_expression.ets.args.json b/ets2panda/linter/test/main/function_expression.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/function_expression.ets.args.json +++ b/ets2panda/linter/test/main/function_expression.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/migrate/function_expression.sts b/ets2panda/linter/test/main/function_expression.ets.migrate.ets similarity index 42% rename from ets2panda/linter/test/migrate/function_expression.sts rename to ets2panda/linter/test/main/function_expression.ets.migrate.ets index 0806c249b8cc5275b5e03f8acc15df5d16e49e18..5e0cd324c204719bae12bd2340e58d3dbd7bad5e 100644 --- a/ets2panda/linter/test/migrate/function_expression.sts +++ b/ets2panda/linter/test/main/function_expression.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,36 +13,36 @@ * limitations under the License. */ -const empty = function () {}; +const empty = () => { }; -const multiply = function (x: number, y): number { - return x * y; +const multiply = (x: number, y): number => { + return x * y; }; function createFunc(): () => number { - return function () { + return () => { return 100; - }; +}; } -const foobar = (function () { - return 'get result immediately'; +const foobar = (() => { + return 'get result immediately'; })(); -(function () { - console.log('foo!'); +(() => { + console.log('foo!'); })(); -void (function () { - console.log('bar!'); +void (() => { + console.log('bar!'); })(); const array = [1, 2, 3, 4, 5, 6]; -const double = array.map(function (e) { - return e * 2; +const double = array.map((e) => { + return e * 2; }); -const even = array.filter(function (x) { - return x % 2 === 0; +const even = array.filter((x) => { + return x % 2 === 0; }); const retTypeInfer = function (p: any) { @@ -53,12 +53,12 @@ const generator = function * () { yield 1; }; -const generic = function (t: T, e: E) { - return t; +const generic = (t: T, e: E) => { + return t; }; -const asyncFun = async function() { - console.log('baz!'); +const asyncFun = async () => { + console.log('baz!'); }; const factorial = function f(n: number): number { @@ -68,46 +68,46 @@ const factorial = function f(n: number): number { class C { m() {} } -const noRecursiveCall = function f(p: () => number): void { // Doesn't have recursive call, should be autofixable - let a = factorial(3); - let b = p(); - let c = new C() - c.m(); +const noRecursiveCall = (p: () => number): void => { + let a = factorial(3); + let b = p(); + let c = new C(); + c.m(); }; -let iife = function() { - console.log('called immediately'); -}(); +let iife = (() => { + console.log('called immediately'); +})(); -let indexAccess = function() { - console.log('index access'); -}[0]; +let indexAccess = (() => { + console.log('index access'); +})[0]; -void function() { - console.log('void'); -}; +void (() => { + console.log('void'); +}); -async function awaitFun() { - await function() { +async function awaitFun() { + await (() => { console.log('async'); - }; +}); } -let typeofFunc = typeof function() { - console.log('typeof'); -} +let typeofFunc = typeof (() => { + console.log('typeof'); +}) class BindFuncExpr { foo() { - let bar = function(p: boolean) { - console.log('Function.bind(this)'); - }.bind(this); + let bar = ((p: boolean) => { + console.log('Function.bind(this)'); +}).bind(this); } } -let callback = function() { console.log('callback'); } -callback = callback || function() { console.log('expr || function(){}'); }; +let callback = () => { console.log('callback'); } +callback = callback || (() => { console.log('expr || function(){}'); }); let ternaryExpr = !!callback - ? function() { console.log('ternary 1'); } || 2 - : 3 && function() { console.log('ternary 2'); }; \ No newline at end of file + ? (() => { console.log('ternary 1'); }) || 2 + : 3 && (() => { console.log('ternary 2'); }); \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/void_operator.ts.json b/ets2panda/linter/test/main/function_expression.ets.migrate.json similarity index 46% rename from ets2panda/linter/test/migrate/void_operator.ts.json rename to ets2panda/linter/test/main/function_expression.ets.migrate.json index 4903dda8202cfce0bcc049087d1c68051e76f8cf..71e6ea80028dbae025ae4ace5f6a34693ed279f0 100644 --- a/ets2panda/linter/test/migrate/void_operator.ts.json +++ b/ets2panda/linter/test/main/function_expression.ets.migrate.json @@ -15,19 +15,19 @@ ], "result": [ { - "line": 22, - "column": 6, - "endLine": 22, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", + "line": 18, + "column": 30, + "endLine": 18, + "endColumn": 31, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 36, - "column": 6, - "endLine": 38, + "line": 48, + "column": 22, + "endLine": 50, "endColumn": 2, "problem": "FunctionExpression", "suggest": "", @@ -35,19 +35,29 @@ "severity": "ERROR" }, { - "line": 40, - "column": 6, - "endLine": 42, + "line": 48, + "column": 22, + "endLine": 50, "endColumn": 2, - "problem": "FunctionExpression", + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 35, + "endLine": 48, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 44, - "column": 7, - "endLine": 46, + "line": 52, + "column": 19, + "endLine": 54, "endColumn": 2, "problem": "FunctionExpression", "suggest": "", @@ -55,64 +65,74 @@ "severity": "ERROR" }, { - "line": 48, - "column": 6, - "endLine": 48, - "endColumn": 11, - "problem": "ClassExpression", + "line": 52, + "column": 19, + "endLine": 54, + "endColumn": 2, + "problem": "GeneratorFunction", "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", + "rule": "Generator functions are not supported (arkts-no-generators)", "severity": "ERROR" }, { - "line": 50, - "column": 7, - "endLine": 50, - "endColumn": 12, - "problem": "ClassExpression", + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 10, + "problem": "YieldExpression", "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", + "rule": "Generator functions are not supported (arkts-no-generators)", "severity": "ERROR" }, { - "line": 61, - "column": 8, - "endLine": 63, - "endColumn": 4, + "line": 64, + "column": 19, + "endLine": 66, + "endColumn": 2, "problem": "FunctionExpression", "suggest": "", "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", "severity": "ERROR" }, { - "line": 65, - "column": 8, - "endLine": 67, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 82, + "column": 5, + "endLine": 84, + "endColumn": 6, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 69, - "column": 8, - "endLine": 69, - "endColumn": 13, - "problem": "ClassExpression", + "line": 82, + "column": 19, + "endLine": 84, + "endColumn": 6, + "problem": "PropertyAccessByIndex", "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, { - "line": 71, - "column": 8, - "endLine": 71, - "endColumn": 13, - "problem": "ClassExpression", + "line": 102, + "column": 9, + "endLine": 104, + "endColumn": 14, + "problem": "AnyType", "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 104, + "column": 4, + "endLine": 104, + "endColumn": 14, + "problem": "FunctionBind", + "suggest": "", + "rule": "'Function.bind' is not supported (arkts-no-func-bind)", + "severity": "WARNING" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/function_object_methods.ets.arkts2.json b/ets2panda/linter/test/main/function_object_methods.ets.arkts2.json index b4340103615c77dd8413bf3f8cffb809aa85140b..adb91f9c46eff8b5ca22a4d0d66f2180d5637b30 100644 --- a/ets2panda/linter/test/main/function_object_methods.ets.arkts2.json +++ b/ets2panda/linter/test/main/function_object_methods.ets.arkts2.json @@ -14,26 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 19, - "column": 16, - "endLine": 19, - "endColumn": 24, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 14, - "endLine": 20, - "endColumn": 22, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 29, "column": 5, @@ -134,16 +114,6 @@ "rule": "'Function.bind' is not supported (arkts-no-func-bind)", "severity": "ERROR" }, - { - "line": 75, - "column": 15, - "endLine": 75, - "endColumn": 23, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 75, "column": 48, @@ -155,13 +125,13 @@ "severity": "ERROR" }, { - "line": 78, - "column": 15, - "endLine": 78, - "endColumn": 23, + "line": 76, + "column": 9, + "endLine": 76, + "endColumn": 13, "problem": "ExplicitFunctionType", "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { @@ -174,6 +144,16 @@ "rule": "'Function.bind' is not supported (arkts-no-func-bind)", "severity": "ERROR" }, + { + "line": 79, + "column": 9, + "endLine": 79, + "endColumn": 13, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, { "line": 81, "column": 31, @@ -244,16 +224,6 @@ "rule": "'Function.bind' is not supported (arkts-no-func-bind)", "severity": "ERROR" }, - { - "line": 101, - "column": 14, - "endLine": 101, - "endColumn": 22, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 101, "column": 42, @@ -265,13 +235,13 @@ "severity": "ERROR" }, { - "line": 104, - "column": 14, - "endLine": 104, - "endColumn": 22, + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 6, "problem": "ExplicitFunctionType", "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { @@ -284,6 +254,16 @@ "rule": "'Function.bind' is not supported (arkts-no-func-bind)", "severity": "ERROR" }, + { + "line": 105, + "column": 3, + "endLine": 105, + "endColumn": 6, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, { "line": 107, "column": 20, diff --git a/ets2panda/linter/test/main/global_this.ets.args.json b/ets2panda/linter/test/main/global_this.ets.args.json index db044a3dff705d84beabaa2d833b7cf1b2debd01..a89d885810708ad03d96e3e14bb6590efd1a7547 100644 --- a/ets2panda/linter/test/main/global_this.ets.args.json +++ b/ets2panda/linter/test/main/global_this.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/global_this.ets.migrate.ets b/ets2panda/linter/test/main/global_this.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d1fb5d519f174c046533036129ee9e5653352f72 --- /dev/null +++ b/ets2panda/linter/test/main/global_this.ets.migrate.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022-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. + */ + +const pi: number = 3.1416; + +function circleArea(r: number): number { + foo(globalThis); + + return specialAutofixLib.globalThis.get("pi") * r * r; +} + +function foo(x: any): void { + console.log(x.pi); +} + +specialAutofixLib.globalThis.set("abc", 200); + +const value = specialAutofixLib.globalThis.get("obj").prop; + +delete specialAutofixLib.globalThis.get("property"); + +globalThisprop = 100; + +specialAutofixLib.globalThis.get("pi"); + +specialAutofixLib.globalThis.set("pi",3.1416); + +specialAutofixLib.globalThis; + diff --git a/ets2panda/linter/test/main/global_this.ets.migrate.json b/ets2panda/linter/test/main/global_this.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..cdc3cef837269d89e24bee549595845bda5cc72b --- /dev/null +++ b/ets2panda/linter/test/main/global_this.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 7, + "endLine": 19, + "endColumn": 17, + "problem": "GlobalThisError", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 20, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 59, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 7, + "problem": "DeleteOperator", + "suggest": "", + "rule": "\"delete\" operator is not supported (arkts-no-delete)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/index_negative.ets.arkts2.json b/ets2panda/linter/test/main/index_negative.ets.arkts2.json index 8c2d2b6a35d5ce0cc59465da582e18b4b3fa6ca3..f74d810960bf77a116281c44178ac50e57e4c9e5 100755 --- a/ets2panda/linter/test/main/index_negative.ets.arkts2.json +++ b/ets2panda/linter/test/main/index_negative.ets.arkts2.json @@ -64,6 +64,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 12, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 22, "column": 10, @@ -124,6 +134,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 13, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 42, "column": 1, @@ -134,6 +154,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 42, + "column": 5, + "endLine": 42, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 8, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 45, "column": 5, @@ -144,6 +184,26 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 10, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 13, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 50, "column": 1, @@ -154,6 +214,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 52, "column": 1, @@ -164,6 +234,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 5, + "endLine": 53, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 54, "column": 1, @@ -174,6 +264,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 6, + "endLine": 56, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 57, "column": 1, @@ -194,6 +304,26 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 58, + "column": 5, + "endLine": 58, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 60, "column": 1, @@ -204,6 +334,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 16, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 61, "column": 1, @@ -234,6 +374,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 63, + "column": 6, + "endLine": 63, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 65, "column": 1, @@ -244,6 +394,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 66, "column": 1, @@ -254,6 +414,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 68, "column": 1, @@ -264,6 +434,36 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 68, + "column": 5, + "endLine": 68, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 71, "column": 7, @@ -274,6 +474,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 73, "column": 1, @@ -284,6 +494,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 74, "column": 7, @@ -324,16 +544,6 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 77, - "column": 12, - "endLine": 77, - "endColumn": 16, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 78, "column": 7, @@ -354,6 +564,26 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 82, "column": 1, @@ -364,6 +594,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 83, "column": 1, @@ -374,6 +614,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 5, + "endLine": 84, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 85, "column": 1, @@ -384,6 +644,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 86, "column": 7, @@ -404,6 +674,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 88, "column": 5, @@ -424,6 +704,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 90, "column": 1, @@ -484,6 +774,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 92, + "column": 5, + "endLine": 92, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 96, "column": 11, @@ -494,6 +794,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 97, + "column": 15, + "endLine": 97, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 98, "column": 7, @@ -514,6 +824,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 99, + "column": 5, + "endLine": 99, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 100, "column": 1, @@ -523,6 +843,16 @@ "suggest": "", "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" + }, + { + "line": 100, + "column": 5, + "endLine": 100, + "endColumn": 8, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/interface_import_1.ets.args.json b/ets2panda/linter/test/main/interface_import_1.ets.args.json index f6c6b88ccf1c4f584046e33982847cab303736a4..631484dfeb6566327bedf2e0eaf8ba98e5589e2e 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.args.json +++ b/ets2panda/linter/test/main/interface_import_1.ets.args.json @@ -15,7 +15,8 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json index 745ac0fec0aee5a13e527a0e38127c98cfc5e762..87714d54f82072b210a623c6c869a8d9e97c02d5 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 22, - "column": 3, - "endLine": 22, - "endColumn": 38, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, { "line": 60, "column": 1, diff --git a/ets2panda/linter/test/main/interface_import_1.ets.autofix.json b/ets2panda/linter/test/main/interface_import_1.ets.autofix.json index cebc9338eff88f1ce05dd07c61803e6a2f4d3449..513f949766dacafdf5f6beeaa36e365041a64ab1 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.autofix.json +++ b/ets2panda/linter/test/main/interface_import_1.ets.autofix.json @@ -14,23 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 22, - "column": 3, - "endLine": 22, - "endColumn": 38, - "problem": "DataObservation", - "autofix": [ - { - "start": 1409, - "end": 1409, - "replacementText": "@Observed\n" - } - ], - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, { "line": 60, "column": 1, @@ -92,7 +75,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -109,7 +92,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -126,7 +109,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -143,7 +126,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -160,7 +143,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -177,7 +160,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -194,7 +177,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -211,7 +194,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -228,7 +211,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -245,7 +228,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -262,7 +245,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -279,7 +262,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -296,7 +279,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -313,7 +296,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", @@ -330,7 +313,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" } ], "suggest": "", diff --git a/ets2panda/linter/test/main/data_observation_1.ets b/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets similarity index 37% rename from ets2panda/linter/test/main/data_observation_1.ets rename to ets2panda/linter/test/main/interface_import_1.ets.migrate.ets index 3ccdd38f94342b0a943fbd3e07f87d795236cdea..231baa7371468bade2ef853c22cb7a7ec5896f61 100644 --- a/ets2panda/linter/test/main/data_observation_1.ets +++ b/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets @@ -13,70 +13,81 @@ * limitations under the License. */ -class MyClassA {} - -class MyClassB { - name: string = '' -} +import { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI'; -class MyClassC1 {} +import { Slider } from '@kit.ArkUI'; -class MyClassC2 extends MyClassC1 {} +@Entry +@Component +struct Test { + @State num: number = 0 + @State a: MyClassA = new MyClassA() -class MyClassC3 extends MyClassC2 {} + build() { + Column() { + Button('按钮') + .backgroundColor('#ffffff') + Circle() { + + } -class MyClassD extends MyClassC3 {} + MyComponent1() { -class MyClassC4 extends MyClassD {} + } -interface IntfA {} + Text("Test") + }.width("100%") + } +} -class MyClassE implements IntfA {} +enum Color { + Green +} -@Observed -class MyClassF {} +function Circle() { -class MyClassG {} +} -class MyClassH {} +@Component +struct MyComponent1 { + @State count: number = 0; -class MyClassI {} + build() { + Row() { + Slider(){} + } + } +} -@Observed -class MyClassJ extends MyClassI {} +function cardStyle(this: TextAttribute): this { + this.backgroundColor(Color.Green); + return this; +} -@Observed -class MyClassK extends MyClassJ {} +@AnimatableExtend +function animatableWidth(this: ColumnAttribute, width: number): this { + this.width(width); + return this; +} -@Entry @Component -struct Test { - @State data1: number = 0 - @State data2: MyClassA = new MyClassA() - @State data3: MyClassB = { name: "jack" } - @State data4: MyClassC2 = new MyClassD() - @State data5: IntfA = new MyClassE() - @Prop data6: MyClassE = new MyClassE() - @Prop data7: MyClassF = new MyClassF() - @Prop data8: MyClassG | MyClassH | number = 0 - @Prop data9: MyClassJ = new MyClassK() - @Provide selectedDate: Date = new Date('2021-08-08') - @StorageLink('PropB') storageLink: MyClassA = new MyClassA() - @LocalStorageLink('LinkB') localStorageLink: MyClassB = new MyClassB() - @StorageProp('test') test1: MyClassC2 = new MyClassC3() - @LocalStorageProp('test') test2: MyClassD = new MyClassD() +struct MyComponent2 { + @State value: number = 0; build() { - + Row() { + Slider({ + value: $$(this.value) + }) + } } } -@Component -struct MyComponent { - @Link data2: MyClassA - @Consume selectedDate: Date +class MyClassA {} - build() { +function processImageFit(imageFit: ImageFit): void { +} + +function Calendar() { - } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_1.ets.migrate.json b/ets2panda/linter/test/main/interface_import_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..400a3c703388b6e748b41fa890330385a7a325eb --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_1.ets.migrate.json @@ -0,0 +1,98 @@ +{ + "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": 63, + "column": 5, + "endLine": 63, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 20, + "endLine": 62, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 42, + "endLine": 62, + "endColumn": 46, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 26, + "endLine": 68, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 65, + "endLine": 68, + "endColumn": 69, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets b/ets2panda/linter/test/main/interface_import_2.ets index 49eea0d570e308d6e667f947a67d62b7bc735e8c..231baa7371468bade2ef853c22cb7a7ec5896f61 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets +++ b/ets2panda/linter/test/main/interface_import_2.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Entry, Component, State, Observed, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI'; +import { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI'; import { Slider } from '@kit.ArkUI'; @@ -83,7 +83,6 @@ struct MyComponent2 { } } -@Observed class MyClassA {} function processImageFit(imageFit: ImageFit): void { diff --git a/ets2panda/linter/test/main/interface_import_2.ets.args.json b/ets2panda/linter/test/main/interface_import_2.ets.args.json index f6c6b88ccf1c4f584046e33982847cab303736a4..631484dfeb6566327bedf2e0eaf8ba98e5589e2e 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets.args.json +++ b/ets2panda/linter/test/main/interface_import_2.ets.args.json @@ -15,7 +15,8 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..231baa7371468bade2ef853c22cb7a7ec5896f61 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_2.ets.migrate.ets @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI'; + +import { Slider } from '@kit.ArkUI'; + +@Entry +@Component +struct Test { + @State num: number = 0 + @State a: MyClassA = new MyClassA() + + build() { + Column() { + Button('按钮') + .backgroundColor('#ffffff') + Circle() { + + } + + MyComponent1() { + + } + + Text("Test") + }.width("100%") + } +} + +enum Color { + Green +} + +function Circle() { + +} + +@Component +struct MyComponent1 { + @State count: number = 0; + + build() { + Row() { + Slider(){} + } + } +} + +function cardStyle(this: TextAttribute): this { + this.backgroundColor(Color.Green); + return this; +} + +@AnimatableExtend +function animatableWidth(this: ColumnAttribute, width: number): this { + this.width(width); + return this; +} + +@Component +struct MyComponent2 { + @State value: number = 0; + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +class MyClassA {} + +function processImageFit(imageFit: ImageFit): void { +} + +function Calendar() { + +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets.migrate.json b/ets2panda/linter/test/main/interface_import_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..400a3c703388b6e748b41fa890330385a7a325eb --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_2.ets.migrate.json @@ -0,0 +1,98 @@ +{ + "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": 63, + "column": 5, + "endLine": 63, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 20, + "endLine": 62, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 42, + "endLine": 62, + "endColumn": 46, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 26, + "endLine": 68, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 65, + "endLine": 68, + "endColumn": 69, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "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 9704178b5e5016aec321fd841be4c4a05ec7f213..39bd99fe344bb3e011839b8bc6d1dfb9bc88ae56 100644 --- a/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json +++ b/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json @@ -81,7 +81,7 @@ "endColumn": 13, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/lazy_import.ets b/ets2panda/linter/test/main/lazy_import.ets index baea8b80e4a84b1cf03642560f5122792cc83bd7..a40b832b4fe0f040cf84a16ef13b9c7c58dc08a3 100755 --- a/ets2panda/linter/test/main/lazy_import.ets +++ b/ets2panda/linter/test/main/lazy_import.ets @@ -14,3 +14,6 @@ */ import lazy { m } from 'module' + +import lazy { a, b } from 'module1' +import { c } from 'module2' diff --git a/ets2panda/linter/test/main/lazy_import.ets.args.json b/ets2panda/linter/test/main/lazy_import.ets.args.json index 948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c..aaabef1e0a30f23f303a3fcf12ad9bd1973f6aa0 100755 --- a/ets2panda/linter/test/main/lazy_import.ets.args.json +++ b/ets2panda/linter/test/main/lazy_import.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/lazy_import.ets.arkts2.json b/ets2panda/linter/test/main/lazy_import.ets.arkts2.json index a55c1929eca32eecfd01eddc825276144a1e6687..bd0dee6544ca1c7f589ba627e4b38524d50d5777 100755 --- a/ets2panda/linter/test/main/lazy_import.ets.arkts2.json +++ b/ets2panda/linter/test/main/lazy_import.ets.arkts2.json @@ -23,6 +23,16 @@ "suggest": "", "rule": "Lazy import is not supported(arkts-no-lazy-import)", "severity": "ERROR" + }, + { + "line": 18, + "column": 8, + "endLine": 18, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/lazy_import.ets.autofix.json b/ets2panda/linter/test/main/lazy_import.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..765ce394d875c17c4ad49fe096ea073a84d6f57f --- /dev/null +++ b/ets2panda/linter/test/main/lazy_import.ets.autofix.json @@ -0,0 +1,52 @@ +{ + "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": 8, + "endLine": 16, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 612, + "end": 622, + "replacementText": "{ m }" + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 8, + "endLine": 18, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 645, + "end": 658, + "replacementText": "{ a, b }" + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/limit_void_type.ets b/ets2panda/linter/test/main/limit_void_type.ets index 603154118f31d1617a83cb23004224326f6a3818..d6ae5d427f0946f89ddb7962cda23e30a91be021 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets +++ b/ets2panda/linter/test/main/limit_void_type.ets @@ -189,3 +189,17 @@ class C { return; } } + +function foo(): void {} +function bar(): void {} + +let aa = '1'; +let bb = aa === '1' ? foo() : bar(); // Error + +aa === '1' ? foo() : bar(); // No error +let dd; +dd = aa === '1' ? foo() : bar(); // Error +interface testB{ + u:void; // Error + fooIf():void; +} \ No newline at end of file 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 b72341140b98057bd78add917905a1a4caba4c9a..3555b90375b19e0340c6444b89dabd0d60507238 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json @@ -965,13 +965,63 @@ "severity": "ERROR" }, { - "line": 177, - "column": 8, - "endLine": 177, - "endColumn": 16, - "problem": "ExplicitFunctionType", + "line": 197, + "column": 23, + "endLine": 197, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 31, + "endLine": 197, + "endColumn": 36, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 5, + "endLine": 200, + "endColumn": 7, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 19, + "endLine": 201, + "endColumn": 24, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 27, + "endLine": 201, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 5, + "endLine": 203, + "endColumn": 9, + "problem": "LimitedVoidType", "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/limit_void_type.ets.json b/ets2panda/linter/test/main/limit_void_type.ets.json index f095579e86c95ea104c69095d4ecaf0bc86e4745..c23430e5d2f182b83a08ba6b9c9c8445030b3948 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.json @@ -183,6 +183,16 @@ "suggest": "", "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "WARNING" + }, + { + "line": 200, + "column": 5, + "endLine": 200, + "endColumn": 7, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/limited_literal_type.ets b/ets2panda/linter/test/main/limited_literal_type.ets index eeb8ea827551afd4479dc0e653755723e74ba1fb..d44a76204c8a155569581637e733f27dedbe5b7a 100644 --- a/ets2panda/linter/test/main/limited_literal_type.ets +++ b/ets2panda/linter/test/main/limited_literal_type.ets @@ -34,3 +34,18 @@ class A{ } let x: number; let persons : Record; + +let s = "123"; +let c1 = s.length as number & 1; +let c2 = s.length & 1 + +function foo(p: 1) {} // CTE + +let arr: 1[]; // CTE + +let a = 1 as 1; // CTE + +let c1 = s.length as (number & 1); // error +let tup: [['arkts' | boolean, 1 | true, false], string[], number] = [['arkts', 1, false], ['arkts1', 'arkts2'], 1.5]; +let a : 1| boolean = 1; +let b : [1] = [1] \ 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 36751780874481751a6d9c81b0c470faff15abe2..08bcd5b26c682f11bfdd6e7d42ea431e7f85707b 100644 --- a/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json @@ -53,6 +53,166 @@ "suggest": "", "rule": "Literal types are restricted(arkts-limited-literal-types)", "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 22, + "endLine": 39, + "endColumn": 32, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 31, + "endLine": 39, + "endColumn": 32, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 17, + "endLine": 42, + "endColumn": 18, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 11, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 14, + "endLine": 46, + "endColumn": 15, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 23, + "endLine": 48, + "endColumn": 33, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 32, + "endLine": 48, + "endColumn": 33, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 31, + "endLine": 49, + "endColumn": 32, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 35, + "endLine": 49, + "endColumn": 39, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 41, + "endLine": 49, + "endColumn": 46, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 9, + "endLine": 50, + "endColumn": 10, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 11, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/limited_literal_type.ets.json b/ets2panda/linter/test/main/limited_literal_type.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..cc9bfbefca257da40202a9bde418239e0d673ada 100644 --- a/ets2panda/linter/test/main/limited_literal_type.ets.json +++ b/ets2panda/linter/test/main/limited_literal_type.ets.json @@ -13,5 +13,26 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 39, + "column": 22, + "endLine": 39, + "endColumn": 32, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 23, + "endLine": 48, + "endColumn": 33, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json b/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json index 2c05e0ccbc2ed9e68875c6b1ad460c78bdc989f5..115d052092240903c4c0013c4f3e219ff4c7e24f 100644 --- a/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json +++ b/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json @@ -85,14 +85,14 @@ "severity": "ERROR" }, { - "line": 34, - "column": 19, - "endLine": 34, - "endColumn": 27, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" + "line": 34, + "column": 19, + "endLine": 34, + "endColumn": 32, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" }, { "line": 56, @@ -304,6 +304,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 77, + "column": 13, + "endLine": 77, + "endColumn": 39, + "problem": "BuiltinGetOwnPropertyNames", + "suggest": "", + "rule": "Using \"Object.getOwnPropertyNames\" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))", + "severity": "ERROR" + }, { "line": 85, "column": 9, diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.args.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.args.json index 4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0..ff8738ddc9c94be0accd0958c036d94d30ce1764 100644 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.args.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json index bc8e2bf2321824a396ba4f6d99bf62c162b0bbf9..9d889b27b6d96e10cbfce88c6221ba819c65a722 100755 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json @@ -49,9 +49,9 @@ "column": 3, "endLine": 32, "endColumn": 4, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { @@ -59,16 +59,6 @@ "column": 3, "endLine": 33, "endColumn": 8, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 3, - "endLine": 32, - "endColumn": 4, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", @@ -119,19 +109,9 @@ "column": 10, "endLine": 57, "endColumn": 16, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 22, - "endLine": 57, - "endColumn": 23, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { @@ -209,9 +189,9 @@ "column": 3, "endLine": 80, "endColumn": 4, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { @@ -219,31 +199,11 @@ "column": 3, "endLine": 81, "endColumn": 8, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 3, - "endLine": 80, - "endColumn": 4, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 84, - "column": 36, - "endLine": 84, - "endColumn": 37, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 84, "column": 36, diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.autofix.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.autofix.json index 0b1642d1da1ec5c7c79b26be04fcab0356143ea1..69a6d4d352fdcc3396e6c1797e0444f4dc4cc168 100644 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.autofix.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.autofix.json @@ -90,26 +90,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 32, - "column": 3, - "endLine": 32, - "endColumn": 4, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 3, - "endLine": 33, - "endColumn": 8, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 32, "column": 3, @@ -137,6 +117,33 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 33, + "column": 3, + "endLine": 33, + "endColumn": 8, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "Two", + "start": 849, + "end": 854 + }, + { + "replacementText": "Two", + "start": 940, + "end": 945 + }, + { + "replacementText": "litAsPropName.Two", + "start": 1032, + "end": 1052 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, { "line": 36, "column": 13, @@ -214,18 +221,6 @@ "endLine": 57, "endColumn": 10, "problem": "ObjectLiteralNoContextType", - "autofix": [ - { - "start": 1416, - "end": 1416, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n \"name\": number;\n 2: number;\n}\n" - }, - { - "start": 1421, - "end": 1421, - "replacementText": ": GeneratedObjectLiteralInterface_1" - } - ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" @@ -235,19 +230,9 @@ "column": 10, "endLine": 57, "endColumn": 16, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 22, - "endLine": 57, - "endColumn": 23, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { @@ -290,12 +275,12 @@ { "start": 1556, "end": 1556, - "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n name: number;\n _2: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n name: number;\n _2: number;\n}\n" }, { "start": 1565, "end": 1565, - "replacementText": ": GeneratedObjectLiteralInterface_2" + "replacementText": ": GeneratedObjectLiteralInterface_1" } ], "suggest": "", @@ -356,26 +341,6 @@ "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" }, - { - "line": 80, - "column": 3, - "endLine": 80, - "endColumn": 4, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 3, - "endLine": 81, - "endColumn": 8, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 80, "column": 3, @@ -399,13 +364,25 @@ "severity": "ERROR" }, { - "line": 84, - "column": 36, - "endLine": 84, - "endColumn": 37, - "problem": "ObjectLiteralProperty", + "line": 81, + "column": 3, + "endLine": 81, + "endColumn": 8, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "__2", + "start": 1739, + "end": 1744 + }, + { + "replacementText": "__2", + "start": 1824, + "end": 1829 + } + ], "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/migrate/literals_as_prop_names.sts b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets similarity index 58% rename from ets2panda/linter/test/migrate/literals_as_prop_names.sts rename to ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets index 7d4da7fcddf56c6d4a937244e744d6e3c8d5fe50..322bb59464962c413fe980594f548f55391f1300 100644 --- a/ets2panda/linter/test/migrate/literals_as_prop_names.sts +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,23 +13,31 @@ * limitations under the License. */ +import { Component, State } from '@kit.ArkUI'; + import { ExportLitAsPropName } from './ignore_files/good'; +enum LiteralAsPropertyNameEnum { + One = "one", + PrivateTwo = "_2", + Two = "Two" +} + class LiteralAsPropertyName { public one: string = "1111111111"; - private 2: string; - 'Two': number; + private __2: string; + Two: number; } const litAsPropName: LiteralAsPropertyName = { one: "1", - 2: 'two', - 'Two': 2, + __2: 'two', + Two: 2, }; -console.log(litAsPropName["one"]); -console.log(litAsPropName[2]); -console.log(litAsPropName["Two"]); +console.log(litAsPropName.one); +console.log(litAsPropName.__2); +console.log(litAsPropName.Two); class LiteralAsPropertyName_fix { public one: string = "1111111111"; @@ -58,7 +66,11 @@ class X_class { public _2: number; } -let x_fix = {name: 20, _2: 20}; +interface GeneratedObjectLiteralInterface_1 { + name: number; + _2: number; +} +let x_fix: GeneratedObjectLiteralInterface_1 = {name: 20, _2: 20}; console.log("Fixed x object literal:"); console.log(x_fix.name); @@ -66,13 +78,50 @@ console.log(x_fix._2); interface litAsPropNameIface { one: string; - 2: string; - '__2': number; + ___2: string; + __2: number; } const int: litAsPropNameIface = { one: '12321', - 2: 'weqwewq', - '__2': 123 + ___2: 'weqwewq', + __2: 123 }; const imp: ExportLitAsPropName = { 1: 234 }; + +LiteralAsPropertyNameEnum['One'] + +LiteralAsPropertyNameEnum.PrivateTwo; + +{ + const enum Direction { + __empty = 1, + } +} + +const enum Direction16 { + ___x5c = 1, + __x5c = 1, +} + +const enum Direction17 { + ___x5c = 1, + __x5c = 1, +} +let case17: number = Direction17.___x5c +let case172: number = Direction17.__x5c + +const enum Direction11 { +__x21x21 = 1, +} +const enum Direction23 { +aaa = 1, +} +// ArkUI +@Component +struct Index { +@State message: string = 'Hello World'; +private case11 = Direction11.__x21x21 +build() { +} +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json similarity index 60% rename from ets2panda/linter/test/migrate/literals_as_prop_names.ts.json rename to ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json index 5a6fd813fa3ade1f04aaf73f12ab8151d662826e..f58bbbb8ee64ff10fe13db138a4a73365de42868 100644 --- a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "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", @@ -15,69 +15,29 @@ ], "result": [ { - "line": 20, - "column": 11, - "endLine": 20, - "endColumn": 12, - "problem": "LiteralAsPropertyName", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 10, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 26, - "column": 3, - "endLine": 26, - "endColumn": 4, + "line": 59, + "column": 10, + "endLine": 59, + "endColumn": 16, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 33, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 13, - "endLine": 31, - "endColumn": 29, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 13, - "endLine": 32, - "endColumn": 33, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 9, - "endLine": 51, - "endColumn": 10, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 51, + "line": 59, "column": 22, - "endLine": 51, + "endLine": 59, "endColumn": 23, "problem": "LiteralAsPropertyName", "suggest": "", @@ -85,9 +45,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 61, "column": 13, - "endLine": 53, + "endLine": 61, "endColumn": 22, "problem": "PropertyAccessByIndex", "suggest": "", @@ -95,9 +55,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 62, "column": 13, - "endLine": 54, + "endLine": 62, "endColumn": 17, "problem": "PropertyAccessByIndex", "suggest": "", @@ -105,49 +65,49 @@ "severity": "ERROR" }, { - "line": 61, - "column": 13, - "endLine": 61, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 84, + "column": 7, + "endLine": 84, + "endColumn": 10, + "problem": "InvalidIdentifier", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" }, { - "line": 69, - "column": 3, - "endLine": 69, - "endColumn": 4, + "line": 90, + "column": 36, + "endLine": 90, + "endColumn": 37, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 74, - "column": 3, - "endLine": 74, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "line": 28, + "column": 11, + "endLine": 28, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Property '__2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '__2' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" }, { - "line": 78, - "column": 36, - "endLine": 78, - "endColumn": 37, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" }, { - "line": 36, + "line": 44, "column": 11, - "endLine": 36, + "endLine": 44, "endColumn": 13, "problem": "StrictDiagnostic", "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", @@ -155,9 +115,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 45, "column": 3, - "endLine": 37, + "endLine": 45, "endColumn": 6, "problem": "StrictDiagnostic", "suggest": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", @@ -165,9 +125,9 @@ "severity": "ERROR" }, { - "line": 57, + "line": 65, "column": 12, - "endLine": 57, + "endLine": 65, "endColumn": 16, "problem": "StrictDiagnostic", "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", @@ -175,9 +135,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 66, "column": 12, - "endLine": 58, + "endLine": 66, "endColumn": 14, "problem": "StrictDiagnostic", "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", diff --git a/ets2panda/linter/test/main/localBuilder_1.ets b/ets2panda/linter/test/main/localBuilder_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..cdf32f53d6c695e2ba21ef8dd607af72c43c5d3d --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.ets @@ -0,0 +1,33 @@ +/* + * 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. + */ + +@Entry +@Component +struct Parent { + @State label: string = 'Hello'; + + @LocalBuilder + citeLocalBuilder(paramA1: string) { + Row() { + Text(`UseStateVarByValue: ${paramA1}`) + } + } + + build() { + Column() { + this.citeLocalBuilder(this.label) + } + } +} diff --git a/ets2panda/linter/test/main/data_observation_2.ets.args.json b/ets2panda/linter/test/main/localBuilder_1.ets.args.json similarity index 92% rename from ets2panda/linter/test/main/data_observation_2.ets.args.json rename to ets2panda/linter/test/main/localBuilder_1.ets.args.json index 5efbceacdc279d08c370af862c859f2d6300fafb..e7a5dbc614c695778265e9fb7d345a304a601675 100644 --- a/ets2panda/linter/test/main/data_observation_2.ets.args.json +++ b/ets2panda/linter/test/main/localBuilder_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ts_decorator.ets.arkts2.json b/ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json similarity index 51% rename from ets2panda/linter/test/interop/ts_decorator.ets.arkts2.json rename to ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json index 5c199b08051d5aa3486159a6e3603fd92e6d2f41..d25d1a3cb3e628d2e1c93e5d29b19d430e622fed 100644 --- a/ets2panda/linter/test/interop/ts_decorator.ets.arkts2.json +++ b/ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json @@ -15,70 +15,70 @@ ], "result": [ { - "line": 19, - "column": 1, - "endLine": 19, - "endColumn": 18, - "problem": "InteropNoDecorators", + "line": 21, + "column": 3, + "endLine": 21, + "endColumn": 16, + "problem": "LocalBuilderDecoratorNotSupported", "suggest": "", - "rule": "Typescript class decorators are not allowed (arkts-interop-no-decorators)", + "rule": "\"@LocalBuilder\" Decorator is not supported (arkui-no-localbuilder-decorator)", "severity": "ERROR" }, { - "line": 19, - "column": 1, - "endLine": 19, - "endColumn": 18, - "problem": "DecoratorsNotSupported", + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 25, - "column": 1, - "endLine": 25, - "endColumn": 13, - "problem": "DecoratorsNotSupported", + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 28, - "column": 1, - "endLine": 28, - "endColumn": 19, - "problem": "InteropNoDecorators", + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Typescript class decorators are not allowed (arkts-interop-no-decorators)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 28, - "column": 1, - "endLine": 28, - "endColumn": 19, - "problem": "DecoratorsNotSupported", + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 8, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 32, - "column": 3, - "endLine": 32, - "endColumn": 21, - "problem": "DecoratorsNotSupported", + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 22, - "column": 2, - "endLine": 22, - "endColumn": 7, + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.autofix.json b/ets2panda/linter/test/main/localBuilder_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..03374a941ac15fbb8447ff5882f0c9b24f25192e --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.ets.autofix.json @@ -0,0 +1,137 @@ +{ + "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": 21, + "column": 3, + "endLine": 21, + "endColumn": 16, + "problem": "LocalBuilderDecoratorNotSupported", + "autofix": [ + { + "start": 676, + "end": 689, + "replacementText": "@Builder" + } + ], + "suggest": "", + "rule": "\"@LocalBuilder\" Decorator is not supported (arkui-no-localbuilder-decorator)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.json b/ets2panda/linter/test/main/localBuilder_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.migrate.ets b/ets2panda/linter/test/main/localBuilder_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d9a2b55ebe936e012207a55d2db5de2634f3e8f7 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.ets.migrate.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Builder } from '@kit.ArkUI'; + +import { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI'; + +@Entry +@Component +struct Parent { + @State label: string = 'Hello'; + + @Builder + citeLocalBuilder(paramA1: string) { + Row() { + Text(`UseStateVarByValue: ${paramA1}`) + } + } + + build() { + Column() { + this.citeLocalBuilder(this.label) + } + } +} diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.migrate.json b/ets2panda/linter/test/main/localBuilder_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/localBuilder_2.ets b/ets2panda/linter/test/main/localBuilder_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..d9a2b55ebe936e012207a55d2db5de2634f3e8f7 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Builder } from '@kit.ArkUI'; + +import { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI'; + +@Entry +@Component +struct Parent { + @State label: string = 'Hello'; + + @Builder + citeLocalBuilder(paramA1: string) { + Row() { + Text(`UseStateVarByValue: ${paramA1}`) + } + } + + build() { + Column() { + this.citeLocalBuilder(this.label) + } + } +} diff --git a/ets2panda/linter/test/main/localBuilder_2.ets.args.json b/ets2panda/linter/test/main/localBuilder_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..e7a5dbc614c695778265e9fb7d345a304a601675 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/main/localBuilder_2.ets.arkts2.json b/ets2panda/linter/test/main/localBuilder_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.ets.arkts2.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/localBuilder_2.ets.autofix.json b/ets2panda/linter/test/main/localBuilder_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.ets.autofix.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/localBuilder_2.ets.json b/ets2panda/linter/test/main/localBuilder_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/localBuilder_2.ets.migrate.ets b/ets2panda/linter/test/main/localBuilder_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d9a2b55ebe936e012207a55d2db5de2634f3e8f7 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.ets.migrate.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Builder } from '@kit.ArkUI'; + +import { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI'; + +@Entry +@Component +struct Parent { + @State label: string = 'Hello'; + + @Builder + citeLocalBuilder(paramA1: string) { + Row() { + Text(`UseStateVarByValue: ${paramA1}`) + } + } + + build() { + Column() { + this.citeLocalBuilder(this.label) + } + } +} diff --git a/ets2panda/linter/test/main/localBuilder_2.ets.migrate.json b/ets2panda/linter/test/main/localBuilder_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_1.ets b/ets2panda/linter/test/main/make_observed_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..f85d77d9960d0cb043032595d27746b05072c615 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_1.ets @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { UIUtils } from '@kit.ArkUI'; + +class Info { + id: number = 0; + constructor(id: number) { + this.id = id; + } +} + +@Entry +@ComponentV2 +struct Index { + @Local message: Info = UIUtils.makeObserved(new Info(20)); + build() { + Column() { + Button(`change id`).onClick(() => { + this.message.id++; + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = new Info(30); + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = UIUtils.makeObserved(new Info(30)); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_1.ets.args.json b/ets2panda/linter/test/main/make_observed_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_1.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/api_path_changed.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json similarity index 59% rename from ets2panda/linter/test/sdkwhite/api_path_changed.ets.arkts2.json rename to ets2panda/linter/test/main/make_observed_1.ets.arkts2.json index cec30e7f8bf405d83ef585624fdd65d0c134bfd4..25479ad946f42f3dd678a6b7969c929657e281fd 100644 --- a/ets2panda/linter/test/sdkwhite/api_path_changed.ets.arkts2.json +++ b/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json @@ -15,49 +15,29 @@ ], "result": [ { - "line": 19, - "column": 19, - "endLine": 19, - "endColumn": 28, - "problem": "ApiPathChanged", + "line": 28, + "column": 26, + "endLine": 28, + "endColumn": 46, + "problem": "MakeObservedIsNotSupported", "suggest": "", - "rule": "API path have changed - please update your imports accordingly (arkts-sdk-no-decl-with-duplicate-name)", + "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", "severity": "ERROR" }, { - "line": 19, - "column": 35, - "endLine": 19, + "line": 38, + "column": 24, + "endLine": 38, "endColumn": 44, - "problem": "ApiPathChanged", + "problem": "MakeObservedIsNotSupported", "suggest": "", - "rule": "API path have changed - please update your imports accordingly (arkts-sdk-no-decl-with-duplicate-name)", + "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", "severity": "ERROR" }, { - "line": 19, - "column": 35, - "endLine": 19, - "endColumn": 44, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 19, - "endLine": 20, - "endColumn": 28, - "problem": "ApiPathChanged", - "suggest": "", - "rule": "API path have changed - please update your imports accordingly (arkts-sdk-no-decl-with-duplicate-name)", - "severity": "ERROR" - }, - { - "line": 16, + "line": 25, "column": 2, - "endLine": 16, + "endLine": 25, "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", @@ -65,60 +45,60 @@ "severity": "ERROR" }, { - "line": 17, + "line": 26, "column": 2, - "endLine": 17, - "endColumn": 11, + "endLine": 26, + "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 19, - "column": 19, - "endLine": 19, - "endColumn": 28, + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 19, - "column": 35, - "endLine": 19, - "endColumn": 44, + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 19, - "column": 57, - "endLine": 19, - "endColumn": 62, + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 20, - "column": 19, - "endLine": 20, - "endColumn": 28, + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 22, - "column": 5, - "endLine": 22, - "endColumn": 9, + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", diff --git a/ets2panda/linter/test/main/make_observed_1.ets.json b/ets2panda/linter/test/main/make_observed_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_1.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_2.ets b/ets2panda/linter/test/main/make_observed_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..f6f99b903f3c5c9f04e17c21b559f961f20e2077 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_2.ets @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { UIUtils as utils } from '@ohos.arkui.StateManagement'; + +class Info { + id: number = 0; + constructor(id: number) { + this.id = id; + } +} + +@Entry +@ComponentV2 +struct Index { + @Local message: Info = utils.makeObserved(new Info(20)); + build() { + Column() { + Button(`change id`).onClick(() => { + this.message.id++; + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = new Info(30); + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = utils.makeObserved(new Info(30)); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_2.ets.args.json b/ets2panda/linter/test/main/make_observed_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_2.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..9637e0d4ecb5005c28e884a9c3500654b30ac794 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json @@ -0,0 +1,108 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 28, + "column": 26, + "endLine": 28, + "endColumn": 44, + "problem": "MakeObservedIsNotSupported", + "suggest": "", + "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 24, + "endLine": 38, + "endColumn": 42, + "problem": "MakeObservedIsNotSupported", + "suggest": "", + "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 2, + "endLine": 25, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 2, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_2.ets.json b/ets2panda/linter/test/main/make_observed_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_2.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_3.ets b/ets2panda/linter/test/main/make_observed_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..1c9c6dcc19828207c5d2fc747d3f975d0aac8e2a --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_3.ets @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { UIUtils } from './utils'; + +class Info { + id: number = 0; + constructor(id: number) { + this.id = id; + } +} + +@Entry +@ComponentV2 +struct Index { + @Local message: Info = UIUtils.makeObserved(new Info(20)); + build() { + Column() { + Button(`change id`).onClick(() => { + this.message.id++; + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = new Info(30); + }) + Button(`change Info1 ${this.message.id}`).onClick(() => { + this.message = UIUtils.makeObserved(new Info(30)); + }) + Button(`change Info1 ${this.message.id}`).onClick(() => { + this.message = makeObserved(new Info(30)); + }) + } + } +} + +function makeObserved(source: T): T { + return source; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_3.ets.args.json b/ets2panda/linter/test/main/make_observed_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_3.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..19d2b241e60fca7ef5f66689b1c82a49dd52b1b5 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 25, + "column": 2, + "endLine": 25, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 2, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_3.ets.json b/ets2panda/linter/test/main/make_observed_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_3.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance.ets b/ets2panda/linter/test/main/method_inheritance.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff1895fc91560a5662f08d3eb401caa34da364e0 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance.ets @@ -0,0 +1,99 @@ +/* + * 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. + */ + +abstract class Y { + abstract getDataByName(name: string | number, albumUri: string): Promise; +} + +class X extends Y { + async getDataByName(name: string, albumUri: string): Promise { + return; + } +} + +abstract class B { + abstract getDataByName(name: string | number, albumUri: string): Promise | Promise; +} + +class A extends B { + async getDataByName(name: string | number | boolean, albumUri: string): Promise { //Legal + return undefined; + } +} + +abstract class W { + abstract getDataByName(name: string | number, albumUri: string): Promise; +} + +class Q extends W { + async getDataByName(name: string | number, albumUri: string | number): Promise { + return; + }; +} + +abstract class BaseClass3 { + abstract compute(value: string): string; +} + +class IncorrectWiderReturn extends BaseClass3 { + compute(value: string): string | number { + return value.length > 5 ? value : 0; + } +} + +abstract class BaseClass4 { + abstract setValues(x: string | number, y: boolean | number): void; +} + +class IncorrectMultipleParamMismatch extends BaseClass4 { + setValues(x: string, y: boolean): void { + console.log(x, y); + } +} + +abstract class BaseClass5 { + abstract transform(data: number | string): number; +} + +class IncorrectBothMismatch extends BaseClass5 { + transform(data: number): number | string { + return data > 10 ? data : "too small"; + } +} + +//legal +abstract class BaseClass { + abstract getData(a: string | number): string | number; +} + +class CorrectWiderParam extends BaseClass { + getData(a: string | number | boolean): string | number { + return typeof a === 'boolean' ? 0 : a; + } +} + +class CorrectNarrowerReturn extends BaseClass { + getData(a: string | number): string { + return typeof a === 'number' ? a.toString() : a; + } +} + +class CorrectBothWiderParamNarrowReturn extends BaseClass { + getData(a: string | number | boolean): string { + return String(a); + } +} + + diff --git a/ets2panda/linter/test/main/method_inheritance.ets.args.json b/ets2panda/linter/test/main/method_inheritance.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance.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": "" + } +} \ 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 new file mode 100644 index 0000000000000000000000000000000000000000..4a6d9d7c640d149afa79fccf76081d127aa4f7b1 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 21, + "column": 25, + "endLine": 21, + "endColumn": 37, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 58, + "endLine": 21, + "endColumn": 76, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 76, + "endLine": 41, + "endColumn": 94, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 29, + "endLine": 51, + "endColumn": 44, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 15, + "endLine": 61, + "endColumn": 24, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 26, + "endLine": 61, + "endColumn": 36, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 15, + "endLine": 71, + "endColumn": 27, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 30, + "endLine": 71, + "endColumn": 45, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance.ets.json b/ets2panda/linter/test/main/method_inheritance.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_overriding.ets b/ets2panda/linter/test/main/method_overriding.ets index f4f2e72de98b2ce5ea8160a2a6d92a3f3b70dcf4..d2c268492790b2404aab7a074565d7d6885b540b 100755 --- a/ets2panda/linter/test/main/method_overriding.ets +++ b/ets2panda/linter/test/main/method_overriding.ets @@ -54,3 +54,11 @@ interface Person8 { interface Person8_1 extends Person8 { fun: () => void } + +interface Person9 { + fun: () => void +} + +interface Person9_1 extends Person9 { + fun():void +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_overriding.ets.arkts2.json b/ets2panda/linter/test/main/method_overriding.ets.arkts2.json index 6353ca54f23734dac1ed7326a90ccf7745c9071f..4d9808c7f7409ff9c8cf051e3d44098b21c1fd97 100755 --- a/ets2panda/linter/test/main/method_overriding.ets.arkts2.json +++ b/ets2panda/linter/test/main/method_overriding.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 10, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 12, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 31, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 30, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 13, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -71,8 +71,18 @@ "endColumn": 18, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" - } + }, + { + "line": 63, + "column": 3, + "endLine": 63, + "endColumn": 13, + "problem": "MethodOverridingField", + "suggest": "", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", + "severity": "ERROR" + } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_enum_prop_as_type.ets b/ets2panda/linter/test/main/no_enum_prop_as_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..531ba328060333268e1f9b950802bedbb22cd419 --- /dev/null +++ b/ets2panda/linter/test/main/no_enum_prop_as_type.ets @@ -0,0 +1,20 @@ +/* + * 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. + */ + + +enum A { E = 'A' } +function foo(a: A.E) {} // ERROR + +let b: A.E = ''; \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_enum_prop_as_type.ets.args.json b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/no_enum_prop_as_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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_enum_prop_as_type.ets.arkts2.json b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5974b151459cc560e541b4b565b58b1bbfc11d17 --- /dev/null +++ b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 17, + "endLine": 18, + "endColumn": 20, + "problem": "NoEnumPropAsType", + "suggest": "", + "rule": "Enum prop as type are not supported (arkts-no-enum-prop-as-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 11, + "problem": "NoEnumPropAsType", + "suggest": "", + "rule": "Enum prop as type are not supported (arkts-no-enum-prop-as-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_enum_prop_as_type.ets.json b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/no_enum_prop_as_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": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets b/ets2panda/linter/test/main/no_import_concurrency.ets index 3414485f76eb9633505885993bda916478ab4900..d6f173602ac9b97d67ee5a86e8c873a096fc19ad 100644 --- a/ets2panda/linter/test/main/no_import_concurrency.ets +++ b/ets2panda/linter/test/main/no_import_concurrency.ets @@ -14,9 +14,13 @@ */ -import { taskpool }from '@kit.ArkTS'; +import { foo, util, taskpool as tpp } from '@ohos.taskpool'; import { anyClass } from '@kit.ArkTS'; //legal -import process from '@ohos.process'; +import foo2, { fooClass } from '@ohos.taskpool'; //legal +import taskpool, { ArkTSUtils as Atu, roo } from '@kit.ArkTS'; +import koo, { ArkTSUtils as Ark, process as pr } from '@kit.ArkTS'; +import doo, { ArkTSUtils as Ats, too } from '@kit.ArkTS'; import fooke from '@ohos.process'; //legal -import { fooClass } from '@ohos.process'; //legal -import { ArkTSUtils } from '@kit.ArkTS' \ No newline at end of file +import { process as ps } from '@ohos.process'; +import process from '@ohos.process'; +import ArkTSUtils, { taskpool as tsk, process as prs } from '@kit.ArkTS'; \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.args.json b/ets2panda/linter/test/main/no_import_concurrency.ets.args.json index d8d3390ad9befeca9b595017d9eea0f5ada3d049..ef3938e967322a0c7551d84c7b6d280de94144c8 100644 --- a/ets2panda/linter/test/main/no_import_concurrency.ets.args.json +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.args.json @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json b/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json index 66ab81cc70ad633dc0526f382b5beb083b99cab7..7d90da63697aff2fcbf4ea04318ef9be41fd6d1a 100644 --- a/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json @@ -16,29 +16,89 @@ "result": [ { "line": 17, - "column": 1, + "column": 21, "endLine": 17, - "endColumn": 38, + "endColumn": 36, "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", "severity": "ERROR" }, { - "line": 19, - "column": 1, - "endLine": 19, + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 16, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, "endColumn": 37, "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", "severity": "ERROR" }, + { + "line": 21, + "column": 15, + "endLine": 21, + "endColumn": 32, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 34, + "endLine": 21, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, { "line": 22, - "column": 1, + "column": 15, "endLine": 22, - "endColumn": 40, + "endColumn": 32, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 37, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 74, "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.autofix.json b/ets2panda/linter/test/main/no_import_concurrency.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..2a756c0a4edcbb1429418311fc03b308492aa42e --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.autofix.json @@ -0,0 +1,171 @@ +{ + "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": 21, + "endLine": 17, + "endColumn": 36, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 629, + "end": 646, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 16, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 783, + "end": 793, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 37, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 795, + "end": 814, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 15, + "endLine": 21, + "endColumn": 32, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 853, + "end": 872, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 34, + "endLine": 21, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 870, + "end": 885, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 32, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 921, + "end": 940, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1008, + "end": 1054, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 37, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1055, + "end": 1091, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 74, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1092, + "end": 1165, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a7dc1cccd1e7d3efc28ac56813a2342e849546cc --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import { foo, util } from '@ohos.taskpool'; +import { anyClass } from '@kit.ArkTS'; //legal +import foo2, { fooClass } from '@ohos.taskpool'; //legal +import { roo } from '@kit.ArkTS'; +import koo from '@kit.ArkTS'; +import doo, { too } from '@kit.ArkTS'; +import fooke from '@ohos.process'; //legal + + diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array.ets b/ets2panda/linter/test/main/no_sparse_array.ets new file mode 100644 index 0000000000000000000000000000000000000000..3298c36c9294e9ca7c6a20a5a0b06add4789a2d5 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array.ets @@ -0,0 +1,17 @@ +/* + * 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. + */ + +let a = [1, , , 3]; +let b = []; \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array.ets.args.json b/ets2panda/linter/test/main/no_sparse_array.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ddcd120faf3e98361f3f7d57d51d0137c8c25fe0 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array.ets.args.json @@ -0,0 +1,20 @@ +{ + "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": "" + } + } + \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json b/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..e6e42965237a4262fa2907e51c5dedcde372c47b --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 12, + "endLine": 16, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array are not supported (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 14, + "endLine": 16, + "endColumn": 14, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array are not supported (arkts-no-sparse-array)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array.ets.json b/ets2panda/linter/test/main/no_sparse_array.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets b/ets2panda/linter/test/main/no_ts_like_smart_type.ets new file mode 100755 index 0000000000000000000000000000000000000000..01a023bc1fb85ad7b5d4f8c352dd8ef27e1beb15 --- /dev/null +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets @@ -0,0 +1,34 @@ +/* + * 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. + */ +// static +class AA1 { + public static instance : number | string; + getInstance(): number { + if (AA1.instance instanceof string) { + return 0; + } + return AA1.instance; // Error + } +} + +class AA2 { + public instance : number | string; + getInstance(): number { + if (this.instance instanceof string) { + return 0; + } + return this.instance; // Error + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.args.json b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..aac366be5e8658d7672f4da2855a3c4740c7bcd3 --- /dev/null +++ b/ets2panda/linter/test/main/no_ts_like_smart_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/no_ts_like_smart_type.ets.arkts2.json b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ac0ca437fc37cfdeba0681473bb96adf041defe1 --- /dev/null +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 22, + "column": 9, + "endLine": 22, + "endColumn": 29, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 46, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 9, + "endLine": 32, + "endColumn": 30, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Property 'instance' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'instance' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..b9d40bdd285aa64170a36db11902a97e7d2644a9 --- /dev/null +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json @@ -0,0 +1,28 @@ +{ + "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": 27, + "column": 12, + "endLine": 27, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Property 'instance' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'instance' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_tuples_arrays.ets b/ets2panda/linter/test/main/no_tuples_arrays.ets index feddaf52a0dabfc95ca929fd3142a8935f10be3f..93ab572c518a56e3ecb59350ba3da3ffacd46945 100644 --- a/ets2panda/linter/test/main/no_tuples_arrays.ets +++ b/ets2panda/linter/test/main/no_tuples_arrays.ets @@ -72,4 +72,19 @@ let gg: (boolean | number | boolean)[] = new A().ee() let ff = new A().ff() let hh: (boolean | number | boolean)[] =ff let mm: (boolean | number | boolean)[] = a.gg(); -let test: (boolean | string | A)[] = this.test3() \ No newline at end of file +let test: (boolean | string | A)[] = this.test3() + +let tuple14: [number, boolean] = [3.14, true] +let array13: (number|boolean)[] = tuple as (number|boolean)[] //error +let array14: (number|boolean)[] = tuple14 as (number|boolean)[] //error +let array15: (number|boolean)[] = array as (number|boolean)[] +let array16: (boolean | number | boolean)[] = a.gg() as (boolean | number | boolean)[] //error +let tuple15: [string, number, boolean] = this.test2() as [string, number, boolean] +let tuple16: [number, number, boolean] = array as [number, number, boolean] +let tuple17: [number, string, boolean] = ['s', 3.14, true] as [number, string, boolean] +const array17 = Array.from({ length: 5 }, (_, index) => index % 2 === 0 ? index : index % 3 === 0); +let tuple19: [number, boolean] = array17 as [number, boolean] //error +const originalArray: [number] = [1, 2, 3, 4, 5]; +const array18 = originalArray.map((value) => value % 2 === 0 ? true : value * 2); +let tuple20: [number, boolean] = array18 as [number, boolean] //error +let array20: (number)[] = originalArray as (number)[] //error \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json b/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json index 38136a1694264b410ea9a1bdfae2e2980146f97d..b86a5ddb8048138ad9dac388e43b063f791fc0b7 100644 --- a/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json @@ -34,6 +34,16 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 25, + "column": 13, + "endLine": 25, + "endColumn": 59, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, { "line": 39, "column": 13, @@ -44,6 +54,16 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 39, + "column": 13, + "endLine": 39, + "endColumn": 62, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, { "line": 65, "column": 7, @@ -54,6 +74,16 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 65, + "column": 7, + "endLine": 65, + "endColumn": 42, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, { "line": 67, "column": 7, @@ -64,6 +94,16 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 67, + "column": 7, + "endLine": 67, + "endColumn": 53, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, { "line": 68, "column": 7, @@ -74,6 +114,16 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 68, + "column": 7, + "endLine": 68, + "endColumn": 53, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, { "line": 70, "column": 5, @@ -84,6 +134,16 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 53, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, { "line": 73, "column": 5, @@ -94,6 +154,16 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 43, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, { "line": 74, "column": 5, @@ -104,11 +174,121 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 74, + "column": 5, + "endLine": 74, + "endColumn": 48, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 50, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, { "line": 75, "column": 5, "endLine": 75, "endColumn": 50, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 35, + "endLine": 78, + "endColumn": 62, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 35, + "endLine": 79, + "endColumn": 64, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 47, + "endLine": 81, + "endColumn": 87, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 42, + "endLine": 83, + "endColumn": 76, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 17, + "endLine": 85, + "endColumn": 99, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 44, + "endLine": 85, + "endColumn": 45, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 34, + "endLine": 86, + "endColumn": 62, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 34, + "endLine": 89, + "endColumn": 62, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 27, + "endLine": 90, + "endColumn": 54, "problem": "NoTuplesArrays", "suggest": "", "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", diff --git a/ets2panda/linter/test/main/no_tuples_arrays.ets.json b/ets2panda/linter/test/main/no_tuples_arrays.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..f08af476724b403902b709a00b32a2edac1791bb 100644 --- a/ets2panda/linter/test/main/no_tuples_arrays.ets.json +++ b/ets2panda/linter/test/main/no_tuples_arrays.ets.json @@ -13,5 +13,26 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 85, + "column": 17, + "endLine": 85, + "endColumn": 99, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 44, + "endLine": 85, + "endColumn": 45, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/nondecimal-bigint.ets b/ets2panda/linter/test/main/nondecimal-bigint.ets new file mode 100755 index 0000000000000000000000000000000000000000..6ba019d0e5525a4b7d5e066c42b1bd6bbe631e59 --- /dev/null +++ b/ets2panda/linter/test/main/nondecimal-bigint.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ + +let a1: bigint = 0xBAD3n +let a2: bigint = 0o777n +let a3: bigint = 0b101n +let a3: bigint = 123n diff --git a/ets2panda/linter/test/main/nondecimal-bigint.ets.args.json b/ets2panda/linter/test/main/nondecimal-bigint.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/nondecimal-bigint.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/nondecimal-bigint.ets.arkts2.json b/ets2panda/linter/test/main/nondecimal-bigint.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..e23fd1b155f4be4f2187261ff320003e28b51deb --- /dev/null +++ b/ets2panda/linter/test/main/nondecimal-bigint.ets.arkts2.json @@ -0,0 +1,48 @@ +{ + "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": 18, + "endLine": 16, + "endColumn": 25, + "problem": "NondecimalBigint", + "suggest": "", + "rule": "Non-decimal BigInt literals (0x/0o/0b) are not supported. Use decimal format instead (arkts-only-support-decimal-bigint-literal)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 18, + "endLine": 17, + "endColumn": 24, + "problem": "NondecimalBigint", + "suggest": "", + "rule": "Non-decimal BigInt literals (0x/0o/0b) are not supported. Use decimal format instead (arkts-only-support-decimal-bigint-literal)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 18, + "endLine": 18, + "endColumn": 24, + "problem": "NondecimalBigint", + "suggest": "", + "rule": "Non-decimal BigInt literals (0x/0o/0b) are not supported. Use decimal format instead (arkts-only-support-decimal-bigint-literal)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/nondecimal-bigint.ets.json b/ets2panda/linter/test/main/nondecimal-bigint.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/nondecimal-bigint.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/api_path_changed.ets b/ets2panda/linter/test/main/numeric_bigint_compare.ets similarity index 78% rename from ets2panda/linter/test/sdkwhite/api_path_changed.ets rename to ets2panda/linter/test/main/numeric_bigint_compare.ets index 5f3d51d8799c85fcaaa19cc5ea25110cb353376e..74f1bf97da9e34c1f36711bb6468ee900ae9664f 100755 --- a/ets2panda/linter/test/sdkwhite/api_path_changed.ets +++ b/ets2panda/linter/test/main/numeric_bigint_compare.ets @@ -13,12 +13,22 @@ * limitations under the License. */ -@Entry -@Component -struct Index { - fontStyleAttr1: TextStyle = new TextStyle({fontColor: Color.Blue}); - fontStyleAttr2: TextStyle; - build() { - Text(); - } -} \ No newline at end of file +let n1:number = 123; +let n2:bigint = 456n; + +n1 <= n2 +n1 == n2 +n1 >= n2 + +n1 != n2 +n1 !== n2 +n1 === n2 +n1 > n2 +n1 < n2 + +n1 = n2 +n1 + n2 +n1 - n2 +n1 * n2 +n1 / n2 +n1 % n2 \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_1.ets.args.json b/ets2panda/linter/test/main/numeric_bigint_compare.ets.args.json old mode 100644 new mode 100755 similarity index 93% rename from ets2panda/linter/test/main/data_observation_1.ets.args.json rename to ets2panda/linter/test/main/numeric_bigint_compare.ets.args.json index 5efbceacdc279d08c370af862c859f2d6300fafb..b9d72da1744d61b8b6c738b008adb28a4b9bee3a --- a/ets2panda/linter/test/main/data_observation_1.ets.args.json +++ b/ets2panda/linter/test/main/numeric_bigint_compare.ets.args.json @@ -1,20 +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": "", - "autofix": "--arkts-2" - } +{ + "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": "" + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json b/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..30d46ababf470e719634f542093610e798cbeb0d --- /dev/null +++ b/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 1, + "endLine": 19, + "endColumn": 9, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 9, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 9, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 10, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 10, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_bigint_compare.ets.json b/ets2panda/linter/test/main/numeric_bigint_compare.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_bigint_compare.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets b/ets2panda/linter/test/main/numeric_semantics.ets index 34a471161c7a945a592928fd1aa7c5acaffe454c..e09d8b47cf7c1fe4bde0f446600b80eaa943059f 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets +++ b/ets2panda/linter/test/main/numeric_semantics.ets @@ -140,4 +140,66 @@ export class G{ readonly a5 = 4; } -const fingerprintPositionY = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0; \ No newline at end of file +const fingerprintPositionY = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0; + +private doCloseFolderBackgroundAnimation(): void { + openFolderLayout.getGridSwiperLayout().bgHeight = openFolderLayout.getBackgroundLayout().closedHeight; + openFolderLayout.getGridSwiperLayout().bgWidth = openFolderLayout.getBackgroundLayout().closedWidth; + + let pos = [-1, -1]; + pos = folderLayoutUtil.getFolderComponentCenterPosition(FolderData.getInstance().getOpenedFolder()); + let editModeTranslateY = this.getEditModeTranslateY(pos); + if (pos.length > 1) { + let translateXForScreenSplit: number = AppStorage.get('translateXForScreenSplit') ?? 0 as number; + let screenWidth: number = AppStorage.get('screenWidth') as number; + let screenHeight: number = AppStorage.get('screenHeight') as number; + if (screenWidth > screenHeight) { + log.showInfo('doCloseFolderBackgroundAnimation screenWidth: ' + screenWidth + ', height: ' + screenHeight); + screenWidth = screenHeight; + } + openFolderLayout.getGridSwiperLayout().bgTranslateX = pos[0] - screenWidth / 2 + translateXForScreenSplit; + openFolderLayout.getGridSwiperLayout().bgTranslateY = pos[1] + editModeTranslateY - + openFolderLayout.getBackgroundLayout().closedHeight * 0.5 - openFolderLayout.getBackgroundLayout().openedMargin; + } +} + +let f = 0.0; +let b5: number = 0; +f = b5; // OK + +let e = 0.0; +let g1: number = 0; + +e += g1; // OK +e -= g1; // OK +e *= g1; // OK +e /= g1; // OK +e <<= g1; // OK +e >>= g1; // OK +e &= g1; // OK +e = e & 3; // OK +e = e | 3; // OK +let arr1 = [1,2,3] +e += arr1[0]; // OK + +let a = 0.0; +a = fun1(); +a = fun2()!; + +function fun1():number{ + return 1; +} + +function fun2():number|undefined{ + return 1; +} + +import { ArrayList } from "@kit.ArkTS"; + +let arr = new ArrayList() +for (let i:number = 0; i < 100; i++) { + arr.add(i) +} +let cancelIds:ArrayList = arr.subArrayList(6, 86) +let a: Array = Array.from(cancelIds) +let arr1: Array = Array.from(new ArrayList()) \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.args.json b/ets2panda/linter/test/main/numeric_semantics.ets.args.json index 40bac500e37ee9b8de610a9bd90a1128e2bec858..b023016d6bc3b2713d4e02b6f765940828db476b 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets.args.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ 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 60878c95bd27bfcc172db3298a395a08775bd5d4..1c60c7069a211b8bbfcfcc317c24be08c56d5f6e 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json @@ -24,66 +24,6 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 21, - "column": 1, - "endLine": 21, - "endColumn": 8, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 9, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 13, - "endLine": 28, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 6, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 1, - "endLine": 35, - "endColumn": 7, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 39, "column": 5, @@ -94,26 +34,6 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 6, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 1, - "endLine": 41, - "endColumn": 7, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 45, "column": 5, @@ -124,16 +44,6 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 49, - "column": 13, - "endLine": 49, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 51, "column": 5, @@ -464,6 +374,216 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 145, + "column": 45, + "endLine": 145, + "endColumn": 49, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 50, + "endLine": 145, + "endColumn": 51, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 5, + "endLine": 146, + "endColumn": 21, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 5, + "endLine": 147, + "endColumn": 21, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 5, + "endLine": 149, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 9, + "endLine": 149, + "endColumn": 23, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 5, + "endLine": 150, + "endColumn": 104, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 5, + "endLine": 151, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 9, + "endLine": 151, + "endColumn": 61, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 12, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 5, + "endLine": 166, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 5, + "endLine": 170, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 5, + "endLine": 182, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 5, + "endLine": 185, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 1, + "endLine": 197, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 5, + "endLine": 199, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 15, + "endLine": 199, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 42, + "endLine": 205, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, { "line": 117, "column": 2, @@ -523,6 +643,36 @@ "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" + }, + { + "line": 153, + "column": 46, + "endLine": 153, + "endColumn": 56, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 33, + "endLine": 154, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json b/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json index 8344ba36aa5efab3cc82ab31bbe6d31a5ffc1b77..ea3285da99caa6e5cd5ba6bbcb174127c6a514bf 100644 --- a/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json @@ -24,73 +24,17 @@ { "start": 744, "end": 749, - "replacementText": "a: number = 1" + "replacementText": "a: number = 1", + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 10 } ], "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 21, - "column": 1, - "endLine": 21, - "endColumn": 8, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 9, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 13, - "endLine": 28, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 6, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 1, - "endLine": 35, - "endColumn": 7, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 39, "column": 5, @@ -101,33 +45,17 @@ { "start": 1377, "end": 1384, - "replacementText": "c: number = 1.5" + "replacementText": "c: number = 1.5", + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 12 } ], "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 6, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 1, - "endLine": 41, - "endColumn": 7, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 45, "column": 5, @@ -138,23 +66,17 @@ { "start": 1561, "end": 1566, - "replacementText": "d: number = 2" + "replacementText": "d: number = 2", + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 10 } ], "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 49, - "column": 13, - "endLine": 49, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 51, "column": 5, @@ -165,7 +87,11 @@ { "start": 1712, "end": 1717, - "replacementText": "n: number = 2" + "replacementText": "n: number = 2", + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 10 } ], "suggest": "", @@ -182,7 +108,11 @@ { "start": 1747, "end": 1760, - "replacementText": "g: number[] = [1, 2, 3]" + "replacementText": "g: number[] = [1, 2, 3]", + "line": 55, + "column": 5, + "endLine": 55, + "endColumn": 18 } ], "suggest": "", @@ -209,7 +139,11 @@ { "start": 1786, "end": 1799, - "replacementText": "t8: number = Infinity" + "replacementText": "t8: number = Infinity", + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 18 } ], "suggest": "", @@ -226,7 +160,11 @@ { "start": 1807, "end": 1821, - "replacementText": "t9: number = -Infinity" + "replacementText": "t9: number = -Infinity", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 19 } ], "suggest": "", @@ -243,7 +181,11 @@ { "start": 1830, "end": 1839, - "replacementText": "t10: number = NaN" + "replacementText": "t10: number = NaN", + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 14 } ], "suggest": "", @@ -260,7 +202,11 @@ { "start": 1848, "end": 1870, - "replacementText": "t11: number = Number.MAX_VALUE" + "replacementText": "t11: number = Number.MAX_VALUE", + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 27 } ], "suggest": "", @@ -277,7 +223,11 @@ { "start": 1879, "end": 1901, - "replacementText": "t12: number = Number.MIN_VALUE" + "replacementText": "t12: number = Number.MIN_VALUE", + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 27 } ], "suggest": "", @@ -294,7 +244,11 @@ { "start": 1959, "end": 1965, - "replacementText": "o2: number = o" + "replacementText": "o2: number = o", + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 11 } ], "suggest": "", @@ -311,7 +265,11 @@ { "start": 1975, "end": 1982, - "replacementText": "o3: number = oo" + "replacementText": "o3: number = oo", + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 12 } ], "suggest": "", @@ -328,7 +286,11 @@ { "start": 2001, "end": 2007, - "replacementText": "a: number = 1;" + "replacementText": "a: number = 1;", + "line": 78, + "column": 4, + "endLine": 78, + "endColumn": 10 } ], "suggest": "", @@ -345,7 +307,11 @@ { "start": 2043, "end": 2052, - "replacementText": "t2: number = +123" + "replacementText": "t2: number = +123", + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 14 } ], "suggest": "", @@ -362,7 +328,11 @@ { "start": 2061, "end": 2070, - "replacementText": "t3: number = -234" + "replacementText": "t3: number = -234", + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 14 } ], "suggest": "", @@ -379,7 +349,11 @@ { "start": 2079, "end": 2100, - "replacementText": "num: number = Math.floor(4.8)" + "replacementText": "num: number = Math.floor(4.8)", + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 26 } ], "suggest": "", @@ -396,7 +370,11 @@ { "start": 2124, "end": 2146, - "replacementText": "value: number = parseInt(\"42\")" + "replacementText": "value: number = parseInt(\"42\")", + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 27 } ], "suggest": "", @@ -413,7 +391,11 @@ { "start": 2188, "end": 2193, - "replacementText": "x: number = 2" + "replacementText": "x: number = 2", + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2 } ], "suggest": "", @@ -430,7 +412,11 @@ { "start": 2195, "end": 2200, - "replacementText": "y: number = 3" + "replacementText": "y: number = 3", + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2 } ], "suggest": "", @@ -447,7 +433,11 @@ { "start": 2201, "end": 2201, - "replacementText": ": number" + "replacementText": ": number", + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2 } ], "suggest": "", @@ -464,7 +454,11 @@ { "start": 2264, "end": 2264, - "replacementText": ": number" + "replacementText": ": number", + "line": 96, + "column": 1, + "endLine": 98, + "endColumn": 2 } ], "suggest": "", @@ -481,7 +475,11 @@ { "start": 2347, "end": 2359, - "replacementText": "identity(42)" + "replacementText": "identity(42)", + "line": 103, + "column": 1, + "endLine": 103, + "endColumn": 13 } ], "suggest": "", @@ -498,7 +496,11 @@ { "start": 2368, "end": 2386, - "replacementText": "an_array: number[] = [1, 2, 3]" + "replacementText": "an_array: number[] = [1, 2, 3]", + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 23 } ], "suggest": "", @@ -515,7 +517,11 @@ { "start": 2394, "end": 2408, - "replacementText": "g: number = an_array[]" + "replacementText": "g: number = an_array[]", + "line": 107, + "column": 5, + "endLine": 107, + "endColumn": 19 } ], "suggest": "", @@ -542,7 +548,11 @@ { "start": 2418, "end": 2423, - "replacementText": "a: number = 1" + "replacementText": "a: number = 1", + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 12 } ], "suggest": "", @@ -559,7 +569,11 @@ { "start": 2493, "end": 2506, - "replacementText": "test: number = Test.A" + "replacementText": "test: number = Test.A", + "line": 115, + "column": 7, + "endLine": 115, + "endColumn": 20 } ], "suggest": "", @@ -576,7 +590,11 @@ { "start": 2593, "end": 2609, - "replacementText": "readonly c1: number = 1;" + "replacementText": "readonly c1: number = 1;", + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 19 } ], "suggest": "", @@ -593,7 +611,11 @@ { "start": 2620, "end": 2638, - "replacementText": "readonly c4: number = 1.7;" + "replacementText": "readonly c4: number = 1.7;", + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 21 } ], "suggest": "", @@ -610,7 +632,11 @@ { "start": 2651, "end": 2671, - "replacementText": "readonly c5: number = 0x123;" + "replacementText": "readonly c5: number = 0x123;", + "line": 123, + "column": 3, + "endLine": 123, + "endColumn": 23 } ], "suggest": "", @@ -627,7 +653,11 @@ { "start": 2683, "end": 2703, - "replacementText": "readonly c6: number = 0o123;" + "replacementText": "readonly c6: number = 0o123;", + "line": 124, + "column": 3, + "endLine": 124, + "endColumn": 23 } ], "suggest": "", @@ -644,7 +674,11 @@ { "start": 2713, "end": 2733, - "replacementText": "readonly c7: number = 0b101;" + "replacementText": "readonly c7: number = 0b101;", + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 23 } ], "suggest": "", @@ -661,7 +695,11 @@ { "start": 2743, "end": 2764, - "replacementText": "readonly c8: number[] = [1, 2, 3];" + "replacementText": "readonly c8: number[] = [1, 2, 3];", + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 24 } ], "suggest": "", @@ -678,7 +716,11 @@ { "start": 2893, "end": 2899, - "replacementText": "c1: number = 1" + "replacementText": "c1: number = 1", + "line": 137, + "column": 7, + "endLine": 137, + "endColumn": 13 } ], "suggest": "", @@ -695,7 +737,11 @@ { "start": 2923, "end": 2939, - "replacementText": "readonly a5: number = 4;" + "replacementText": "readonly a5: number = 4;", + "line": 140, + "column": 3, + "endLine": 140, + "endColumn": 19 } ], "suggest": "", @@ -722,13 +768,359 @@ { "replacementText": "fingerprintPositionY: number = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0", "start": 2952, - "end": 3068 + "end": 3068, + "line": 143, + "column": 30, + "endLine": 143, + "endColumn": 118 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 45, + "endLine": 145, + "endColumn": 49, + "problem": "VoidOperator", + "autofix": [ + { + "start": 3117, + "end": 3558, + "replacementText": "(() => {\r\n ({\r\n openFolderLayout, : .getGridSwiperLayout().bgHeight = openFolderLayout.getBackgroundLayout().closedHeight,\r\n openFolderLayout, : .getGridSwiperLayout().bgWidth = openFolderLayout.getBackgroundLayout().closedWidth,\r\n let, pos = [-1, -1],\r\n pos = folderLayoutUtil.getFolderComponentCenterPosition(FolderData.getInstance().getOpenedFolder()),\r\n let, editModeTranslateY = this.getEditModeTranslateY(pos),\r\n if(pos) { }, : .length > 1\r\n });\r\n return undefined;\r\n})()", + "line": 145, + "column": 45, + "endLine": 145, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 50, + "endLine": 145, + "endColumn": 51, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 5, + "endLine": 146, + "endColumn": 21, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3129, + "end": 3145, + "replacementText": "openFolderLayout: openFolderLayout", + "line": 146, + "column": 5, + "endLine": 146, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 5, + "endLine": 147, + "endColumn": 21, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3237, + "end": 3253, + "replacementText": "openFolderLayout: openFolderLayout", + "line": 147, + "column": 5, + "endLine": 147, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 5, + "endLine": 149, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3345, + "end": 3348, + "replacementText": "let: let", + "line": 149, + "column": 5, + "endLine": 149, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 9, + "endLine": 149, + "endColumn": 23, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3349, + "end": 3363, + "replacementText": "pos: pos", + "line": 149, + "column": 9, + "endLine": 149, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 5, + "endLine": 150, + "endColumn": 104, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3370, + "end": 3469, + "replacementText": "pos: pos", + "line": 150, + "column": 5, + "endLine": 150, + "endColumn": 104 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 5, + "endLine": 151, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3476, + "end": 3479, + "replacementText": "let: let", + "line": 151, + "column": 5, + "endLine": 151, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 9, + "endLine": 151, + "endColumn": 61, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3480, + "end": 3532, + "replacementText": "editModeTranslateY: editModeTranslateY", + "line": 151, + "column": 9, + "endLine": 151, + "endColumn": 61 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 12, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 5, + "endLine": 166, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4388, + "end": 4395, + "replacementText": "f: number = 0.0", + "line": 166, + "column": 5, + "endLine": 166, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 5, + "endLine": 170, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4440, + "end": 4447, + "replacementText": "e: number = 0.0", + "line": 170, + "column": 5, + "endLine": 170, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 5, + "endLine": 182, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4627, + "end": 4641, + "replacementText": "arr1: number[] = [1, 2, 3]", + "line": 182, + "column": 5, + "endLine": 182, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 5, + "endLine": 185, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4670, + "end": 4677, + "replacementText": "a: number = 0.0", + "line": 185, + "column": 5, + "endLine": 185, + "endColumn": 12 } ], "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 197, + "column": 1, + "endLine": 197, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 5, + "endLine": 199, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 15, + "endLine": 199, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 42, + "endLine": 205, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, { "line": 117, "column": 2, @@ -739,7 +1131,11 @@ { "start": 738, "end": 738, - "replacementText": "\n\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\n" + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 } ], "suggest": "", @@ -756,7 +1152,11 @@ { "start": 738, "end": 738, - "replacementText": "\n\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\n" + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 } ], "suggest": "", @@ -773,7 +1173,11 @@ { "start": 738, "end": 738, - "replacementText": "\n\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\n" + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 } ], "suggest": "", @@ -790,7 +1194,11 @@ { "start": 738, "end": 738, - "replacementText": "\n\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\n" + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 } ], "suggest": "", @@ -807,7 +1215,11 @@ { "start": 738, "end": 738, - "replacementText": "\n\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\n" + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 } ], "suggest": "", @@ -824,7 +1236,74 @@ { "start": 738, "end": 738, - "replacementText": "\n\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\n" + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 46, + "endLine": 153, + "endColumn": 56, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 33, + "endLine": 154, + "endColumn": 43, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.json b/ets2panda/linter/test/main/numeric_semantics.ets.json index 95cc38ecceeb4333602fca02f447352881af1492..47737941ad04d6a390c617f5cd735c817853aba8 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.json @@ -1,38 +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": 57, - "column": 5, - "endLine": 57, - "endColumn": 15, - "problem": "DefiniteAssignment", - "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", - "severity": "WARNING" - }, - { - "line": 143, - "column": 7, - "endLine": 143, - "endColumn": 123, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "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": 57, + "column": 5, + "endLine": 57, + "endColumn": 15, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 143, + "column": 7, + "endLine": 143, + "endColumn": 123, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 50, + "endLine": 145, + "endColumn": 51, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 1, + "endLine": 197, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 5, + "endLine": 199, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..9afe1bb1ba8e09470a91547241062e05ae050111 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets @@ -0,0 +1,211 @@ +/* + * 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. + */ + +// TypeScript: treats 'n' as having type number +// ArkTS: treats 'n' as having type int to reach max code performance + +import { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI'; + +let a: number = 1; + +a = 1; // OK +a = 1.5; // CTE in ArkTS: Type 'double' can't be assigned to type 'int' + +a += 1; // OK +a += 1.5; // ArkTS: Result is integer value + +console.log(a + 1); // OK +console.log(a - 0.5); // OK +console.log(a / 2); // ArkTS: integer division is used, result is integer value +console.log(a / 2.5); // OK +console.log(2 / a); // ArkTS: integer division is used, result is integer value +console.log(2.5 / a); // OK + +let b: number = 1; +a = b; // CTE in ArkTS: Type 'double' can't be assigned to type 'int' +a += b; // ArkTS: Result is integer value +console.log(a + b); // OK +console.log(a / b); // OK + +let c: number = 1.5; +a = c; // CTE in ArkTS: Type 'double' can't be assigned to type 'int' +a += c; // ArkTS: Result is integer value +console.log(a + c); // OK +console.log(a / c); // OK + +let d: number = 2; +a = d; // OK +a += d; // OK +console.log(a + d); // OK +console.log(a / d); // ArkTS: integer division is used, result is integer value + +let n: number = 2; + +let f: number = 1 + +let g: number[] = [1, 2, 3] + +let x!: number + +let t8: number = Infinity + +let t9: number = -Infinity; + +let t10: number = NaN; + +let t11: number = Number.MAX_VALUE; + +let t12: number = Number.MIN_VALUE; + +let o:number = 123; + +const oo:number = 123; + +let o2: number = o; + +let o3: number = oo; + +class A{ + a: number = 1; + constructor() { + } +} + +let t2: number = +123; + +let t3: number = -234; + +let num: number = Math.floor(4.8); // num 可能是 int + +let value: number = parseInt("42"); // value 可能是 int + + +function multiply(x: number = 2, y: number = 3): number { + return x * y; +} + +function divide(x: number, y: number): number { + return x / y; +} + +function identity(value: T): T { + return value; +} +identity(42); + +let an_array: number[] = [1, 2, 3] + +let g: number = an_array[] + +const a: number = 1 + +enum Test { + A = 1, // 显式赋值为 1 + B = 2 // 显式赋值为 2 +} +const test: number = Test.A; + +@Entry +@Component +struct Index2 { + @State message: string = 'Hello World'; + readonly c1: number = 1; // int + readonly c4: number = 1.7; // float + readonly c5: number = 0x123; // 16进制 + readonly c6: number = 0o123; //8进制 + readonly c7: number = 0b101; //2进制 + readonly c8: number[] = [1, 2, 3]; + +build() { + RelativeContainer() { + Text(this.message) + .onClick(() => { + }) + } + } +} + +const c1: number = 1; + +export class G{ + readonly a5: number = 4; +} + +const fingerprintPositionY: number = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0; + +private doCloseFolderBackgroundAnimation(): (() => { + ({ + openFolderLayout: openFolderLayout, : .getGridSwiperLayout().bgHeight = openFolderLayout.getBackgroundLayout().closedHeight, + openFolderLayout: openFolderLayout, : .getGridSwiperLayout().bgWidth = openFolderLayout.getBackgroundLayout().closedWidth, + let: let, pos: pos, + pos: pos, + let: let, editModeTranslateY: editModeTranslateY, + if(pos) { }, : .length > 1 + }); + return undefined; +})() { + let translateXForScreenSplit: number = AppStorage.get('translateXForScreenSplit') ?? 0 as number; + let screenWidth: number = AppStorage.get('screenWidth') as number; + let screenHeight: number = AppStorage.get('screenHeight') as number; + if (screenWidth > screenHeight) { + log.showInfo('doCloseFolderBackgroundAnimation screenWidth: ' + screenWidth + ', height: ' + screenHeight); + screenWidth = screenHeight; + } + openFolderLayout.getGridSwiperLayout().bgTranslateX = pos[0] - screenWidth / 2 + translateXForScreenSplit; + openFolderLayout.getGridSwiperLayout().bgTranslateY = pos[1] + editModeTranslateY - + openFolderLayout.getBackgroundLayout().closedHeight * 0.5 - openFolderLayout.getBackgroundLayout().openedMargin; + } +} + +let f: number = 0.0; +let b5: number = 0; +f = b5; // OK + +let e: number = 0.0; +let g1: number = 0; + +e += g1; // OK +e -= g1; // OK +e *= g1; // OK +e /= g1; // OK +e <<= g1; // OK +e >>= g1; // OK +e &= g1; // OK +e = e & 3; // OK +e = e | 3; // OK +let arr1: number[] = [1, 2, 3] +e += arr1[0]; // OK + +let a: number = 0.0; +a = fun1(); +a = fun2()!; + +function fun1():number{ + return 1; +} + +function fun2():number|undefined{ + return 1; +} + +import { ArrayList } from "@kit.ArkTS"; + +let arr = new ArrayList() +for (let i:number = 0; i < 100; i++) { + arr.add(i) +} +let cancelIds:ArrayList = arr.subArrayList(6, 86) +let a: Array = Array.from(cancelIds) +let arr1: Array = Array.from(new ArrayList()) \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c86c2373e15de875d2b44d53c7a5dc66cf1713bf --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json @@ -0,0 +1,118 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 15, + "problem": "DefiniteAssignmentError", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 26, + "endLine": 110, + "endColumn": 26, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 6, + "endLine": 149, + "endColumn": 7, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 9, + "endLine": 155, + "endColumn": 20, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 9, + "endLine": 155, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 12, + "endLine": 155, + "endColumn": 15, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 1, + "endLine": 203, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 5, + "endLine": 205, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 15, + "endLine": 205, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 42, + "endLine": 211, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals.ets.args.json b/ets2panda/linter/test/main/object_literals.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals.ets.args.json +++ b/ets2panda/linter/test/main/object_literals.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals.ets.migrate.ets b/ets2panda/linter/test/main/object_literals.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7ae3763807c7b47563a5e35b16254919cc09c93b --- /dev/null +++ b/ets2panda/linter/test/main/object_literals.ets.migrate.ets @@ -0,0 +1,293 @@ +/* + * 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. + */ +import {ohFunction1, ohFunction2, OhosI} from './oh_modules/ohos_lib' +interface I { + a: number; + b: string; +} + +class C { + a: number; + b: string; +} + +interface GeneratedTypeLiteralInterface_1 { + x: number; + y: string; +} +class C2 { + q: GeneratedTypeLiteralInterface_1; + w: any; + e: I; + r: C; +} + +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_2 { + a: number; + b: string; +} +function localVariable(): void { + // Declaration + let a1: GeneratedObjectLiteralInterface_1 = { a: 1, b: 'a' }; // NOT OK + let a2: any = { a: 2, b: 'b' }; // OK - ASSIGNMENT TO ANY + let a3: GeneratedTypeLiteralInterface_2 = { a: 30, b: 'c' }; // NOT OK + let a4: I = { a: 4, b: 'd' }; // OK + let a5: C = { a: 5, b: 'e' }; // OK + let a6: C2 = { + // OK + q: { x: 6, y: 'f' }, // NOT OK + w: { a: 7, b: 'g' }, // OK - ASSIGNMENT TO ANY + e: { a: 8, b: 'h' }, // OK + r: { a: 9, b: 'i' }, // OK + }; + + // Assignment + a1 = { a: 11, b: 'a' }; // NOT OK + a2 = { a: 12, b: 'b' }; // OK - ASSIGNMENT TO ANY + a3 = { a: 13, b: 'c' }; // NOT OK + a4 = { a: 14, b: 'd' }; // OK + a5 = { a: 15, b: 'e' }; // OK + a6 = { + // OK + q: { x: 16, y: 'f' }, // NOT OK + w: { a: 17, b: 'g' }, // OK - ASSIGNMENT TO ANY + e: { a: 18, b: 'h' }, // OK + r: { a: 19, b: 'i' }, // OK + }; +} + +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_3 { + a: number; + b: string; +} +function defaultParamValue(): void { + function foo(x: GeneratedObjectLiteralInterface_2 = { a: 21, b: 'a' }) { + console.log(x.a, x.b); + } // NOT OK + function foo2(x: any = { a: 22, b: 'b' }) { + console.log(x.a, x.b); + } // NOT OK + function foo3(x: GeneratedTypeLiteralInterface_3 = { a: 23, b: 'c' }) { + console.log(x.a, x.b); + } // NOT OK + function foo4(x: I = { a: 24, b: 'd' }) { + console.log(x.a, x.b); + } // OK + function foo5(x: C = { a: 25, b: 'e' }) { + console.log(x.a, x.b); + } // OK + + // Function call + foo({ a: 21, b: 'a' }); // NOT OK + foo2({ a: 22, b: 'b' }); // OK - ASSIGNMENT TO ANY + foo3({ a: 23, b: 'c' }); // NOT OK + foo4({ a: 24, b: 'd' }); // OK + foo5({ a: 25, b: 'e' }); // OK +} + +interface GeneratedObjectLiteralInterface_3 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_4 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_5 { + a: number; + b: string; +} +function returnFromFunction(): void { + function bar() { + return ({ a: 31, b: 'a' } as GeneratedObjectLiteralInterface_3); + } // NOT OK + let bar2: () => any = (): any => { + return { a: 32, b: 'b' }; +}; // OK - ASSIGNMENT TO ANY + let bar3: () => GeneratedTypeLiteralInterface_4 = (): GeneratedTypeLiteralInterface_5 => { + return { a: 33, b: 'c' }; +}; // NOT OK + let bar4: () => I = (): I => { + return { a: 34, b: 'd' }; +}; // OK + let bar5: () => C = (): C => { + return { a: 35, b: 'e' }; +}; // OK +} + +interface GeneratedObjectLiteralInterface_4 { + a: number; + b: string; +} +interface GeneratedObjectLiteralInterface_5 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_6 { + a: number; + b: string; +} +function ternaryOperator(): void { + // In ternary operator + const condition = true; + const a1 = condition ? ({ a: 41, b: 'a' } as GeneratedObjectLiteralInterface_4) : ({ a: 42, b: 'b' } as GeneratedObjectLiteralInterface_5); // NOT OK + const a2: any = condition ? { a: 43, b: 'c' } : { a: 44, b: 'd' }; // OK - ASSIGNMENT TO ANY + const a3: GeneratedTypeLiteralInterface_6 = condition + ? { a: 45, b: 'e' } + : { a: 46, b: 'f' }; // NOT OK + const a4: I = condition ? { a: 47, b: 'g' } : { a: 48, b: 'h' }; // OK + const a5: C = condition ? { a: 49, b: 'i' } : { a: 50, b: 'j' }; // OK +} + +interface GeneratedObjectLiteralInterface_6 { + a: number; + b: string; +} +interface GeneratedObjectLiteralInterface_7 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_7 { + a: number; + b: string; +} +function arrayLiteral(): void { + const arr1 = [ + ({ a: 51, b: 'a' } as GeneratedObjectLiteralInterface_6), + ({ a: 52, b: 'b' } as GeneratedObjectLiteralInterface_7), + ]; // NOT OK + const arr2: any[] = [ + { a: 53, b: 'c' }, + { a: 54, b: 'd' }, + ]; // OK - ASSIGNMENT TO ANY + const arr3: GeneratedTypeLiteralInterface_7[] = [ + { a: 55, b: 'e' }, + { a: 56, b: 'f' }, + ]; // NOT OK + const arr4: I[] = [ + { a: 57, b: 'g' }, + { a: 58, b: 'h' }, + ]; // OK + const arr5: C[] = [ + { a: 59, b: 'i' }, + { a: 60, b: 'j' }, + ]; // OK +} + +enum E { + OK, + NO_OK, +} +interface I1 { + v: E | number +} + +interface I2 { + v: E +} + +let i1: I1 = {v:E.OK} +let i2: I2 = {v:E.NO_OK} + +function g1(a: E) { + let ii1: I1 = {v:a} + let ii2: I2 = {v:a} +} + +function g(): boolean { + return true; +} +interface CondI { + a: number; +} +let a1: CondI = { + a: g() ? 0 : 1, +}; +let b1: CondI = { + a: (g() ? 0 : 1) as number, +}; +let c1 = g() ? 0 : 1; +let d1: CondI = { + a: c1, +}; +let e1: CondI = { +a: 0|1|2|3 +} +let f1: 0|1|2|3 = 3 +let ff : CondI = { + a: f1 +} + +let dict = new Map(); +dict.set('1', 123) + +interface III { + param?: string | number | boolean +} + +let test1: III = { param: dict.get('1') } as III +let test2: III = { param: dict.get('1')! } as III +let test3: III = { param: dict.get('1') as number } as III +let test4: III = { param: dict.get('1') as (number | string) } as III +export interface Style { +} +export class SwitchMenuStyle implements Style { +} +export class ProfileOneLineSwitchMenuStyle extends SwitchMenuStyle { +} +export class ProfileSwitchMenuStyle extends SwitchMenuStyle { +} +export let hfpProfileSwitchMenuStyle = new ProfileSwitchMenuStyle(); +export let hfpProfileOneLineSwitchMenuStyle = new ProfileOneLineSwitchMenuStyle(); + +export interface SettingsBaseMenuData { + style?: Style; +} + +function test(isDisConnected:boolean){ + let a={style: isDisConnected ? hfpProfileOneLineSwitchMenuStyle: hfpProfileSwitchMenuStyle} as SettingsBaseMenuData +} + +interface PPP { + x: number + y: number | undefined + z?: number +} + +let p1: PPP = {x: 10, y: 10} +let p2: PPP = {x: 10, y: undefined} +let p3: PPP = {x: 10, y: undefined, z: undefined} +let p4: PPP = {x: 10, y: undefined, z: 10} +let p5: PPP = {x: 10, y: 10, z: 10} +const cp1: PPP = {x: 10, y: 10} +const cp2: PPP = {x: 10, y: undefined} +const cp3: PPP = {x: 10, y: undefined, z: undefined} +const cp4: PPP = {x: 10, y: undefined, z: 10} +const cp5: PPP = {x: 10, y: 10, z: 10} + +const oi: OhosI = { f: 1 }; + +ohFunction1({d: oi}) +ohFunction1({d: {f: 1}}) +ohFunction2({d: oi}) +ohFunction2({d: {f: 1}}) diff --git a/ets2panda/linter/test/main/object_literals.ets.migrate.json b/ets2panda/linter/test/main/object_literals.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a227223d64e4327ea0f2bd8d30cd531afce603cc --- /dev/null +++ b/ets2panda/linter/test/main/object_literals.ets.migrate.json @@ -0,0 +1,198 @@ +{ + "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": 6, + "endLine": 32, + "endColumn": 9, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 11, + "endLine": 48, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 3, + "endLine": 84, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 3, + "endLine": 87, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 20, + "endLine": 87, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 3, + "endLine": 90, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 93, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 3, + "endLine": 96, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 19, + "endLine": 124, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 29, + "endLine": 124, + "endColumn": 32, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 13, + "endLine": 154, + "endColumn": 16, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 15, + "endLine": 179, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'q' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'q' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 33, + "column": 3, + "endLine": 33, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'e' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'e' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'r' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'r' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_2.ets.args.json b/ets2panda/linter/test/main/object_literals_2.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_2.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_2.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_2.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1b08cb786e6c0f1b7e99342d223ee6ea7eb686e4 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_2.ets.migrate.ets @@ -0,0 +1,289 @@ +/* + * 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. + */ + +interface GeneratedObjectLiteralInterface_1 { + n: number; + s: string; +} +let obj: GeneratedObjectLiteralInterface_1 = {n: 42, s: 'foo'} // OK in TypeScript, CTE in ArkTS: unknown type of obj. + +class C { + n: number = 0; + s: string = ""; +} + +let c1: C = {n: 42, s: 'foo'} // Declaration + initialization: type of the literla is inferred from the type of c1. + +let c2: C; +c2 = {n: 42, s: 'foo'}; // Initialization after declaration: type of the literal is inferred from the type of c2. + +let c3: Object = {n: 42, s: 'foo'} as C as Object; // Type of the literal is inferred from the 'as' cast. +console.log(c3 instanceof C); // NB! Output is true in ArkTS, but is false in TS. + +function foo(c: C) { + console.log('foo is called'); +} + +foo({n: 42, s: 'foo'}); // Parsing as an argument: type of the literal is inferred from the type of parameter 'c' + +function bar(): C { + return {n: 42, s: 'foo'}; // Returning from function: type of the literal is inferred from the bar's return type. +} + +let cc: C[] = [{n: 1, s: '1'}, {n: 2, s: '2'}]; // Type of the literal is inferred from the type of the array. + +class D { + b: boolean = false; + c: C = {n: 0, s: ""}; +} + +let d: D = { + b: true, + c: { // Initialization of a field with a literal: type of the literal is inferred from the definition of class D. + n: 42, + s: 'foo' + } +} + +// Restrictions of classes that can be initialized with literal +// Default initializable class. +class C1 { + n: number = 0; + s?: string; +} + +let c4: C1 = {n: 42}; // OK in TS, OK in ArkTS, c.s is null + +class C2 { + s: string; + constructor(s: string) { + this.s = "s = " + s; + } +} + +let c5: C2 = {s: 'foo'} // OK in TS, CTE in ArkTS + +// All class fields are accessible at the point of initialization. +class C3 { + private n: number = 0; + public s: string = ''; +} + +// CTE in TypeScript, CTE in ArkTS // let c6: C3 = {n: 42, s: 'foo'}, + +class C4 { + readonly n: number = 0; + readonly s: string = ''; +} + +let c7: C4 = {n: 42, s: 'foo'}; // OK in TS, CTE in ArkTS + +// Class is non-abstract +abstract class A {} +let a: A = {}; // OK in TS, CTE in ArkTS + +// Class declares no methods, apart from optionally declared constructors and setters. +class C5 { + n: number = 0; + s: string = ''; + f() { + console.log('C5.f is called'); + } +} + +let c8: C5 = {n: 42, s: 'foo', f: () => {}} // OK in TS, CTE in ArkTS + +// NB! If a class has getters/setters the semantics of initialization differs: +class C6 { + n: number = 0; + _s: string = ''; + get s(): string { return this._s; } + set s(s: string) { this._s = s; } +} + +let c9: C6 = {n: 42, _s: 'foo', s: 'bar'} +console.log(c9.s); // TS: 'bar', ArkTS: 'bar' +console.log(c9._s); // TS: 'foo', ArkTS: 'bar' + +// Extra fields are not allowed (eventually it means that it's not possible to assign literals to Object / object): +class C7 { + n: number = 0; + s: string = ''; +} +// TS: CTE, ArtTS: CTE // let c10: C7 = {n: 42, s: '', extra: true}, +let o1: Object = {s: '', n: 42} // OK in TS, CTE in ArkTS: no fields 'n' and 's' in Object +let o2: object = {n: 42, s: ''} // OK in TS, CTE in ArkTS: no fields 'n' and 's' in object + +// If initialized class is inherited from another class, the base class must also be literal-initializable, +// and initialization should happen from the 'glattened' literal: +class Base { + n: number = 0; +} + +class Derived extends Base { + s: string = ''; +} + +let d2: Derived = {n: 42, s: ''}; + +// Interface should not declare methods, only properties are allowed. +interface I { + n: number; + s: string; + f(): void; +} + +let i: I = {n: 42, s: '', f: () => {console.log('I.f is called')}} // OK in TypeScript, CTE in ArkTS + +// Interface properties of reference types must be default-initializable: +interface I2 { + n: number; + s: string; // Assuming that 'string' is an alias for 'String', and there is String() constructor (what is true). +} + +let i2: I2 = {n: 42, s: ''}; + +interface CompilerOptions { + strict?: boolean; + sourcePath?: string; + targetPath?: string; +} + +const options: CompilerOptions = { // OK, as 'targetPath' field is optional + strict: true, + sourcePath: './src', +}; + +// Function parameter with union type. +function funcWithUnionParam(x: C | number): void { } +funcWithUnionParam({ n: 1, s: '2' }) // OK, union type is supported + +// issue 13022: property with union type +class UnionProperty { + a: number | string = 123; + b?: boolean | number; +} +let u: UnionProperty = { a: 1 }; // OK, union type is supported +u = { a: '2' }; // OK, union type is supported +u = { a: 3, b: true }; // OK, union type is supported + +// issue 13022: optional property +class OptionalProp { + a?: number; +} +let o: OptionalProp = {}; +o = {a: 1}; // OK + +class OptionalProp2 { + a?: number; + b: string; +} +function optProp(a: OptionalProp2) {} +optProp({b: ''}); // OK +optProp({a: 0, b: '1'}); // OK + +// Property with inheritance +class E1 { + x: number; + y: Base; +} +let e1 : E1 = { + x: 1, + y: new Derived() +} + +// Property with inheritance through generic type parameter +class E2 { + x: number; + y: T; +} +let e2 : E2 = { + x: 1, + y: new Derived() +} + +// Type alias chain to interface +interface ITypeAlias { a: number; b: T } +type ITA = ITypeAlias; +type ITA2 = ITA; +let ti: ITA2 = { // OK, 'ITA2' is an alias to interface 'ITypeAlias' + a: 12, + b: '34' +} + +// Type alias chain to class +class CTypeAlias { + a: number; + b: T; +} +type CTA = CTypeAlias; +type CTA2 = CTA; +let tc: CTA2 = { // OK, 'CTA' is an alias to class 'CTypeAlias' + a: 4, + b: '4' +} + +// issue 13114: Const enum value converted to string/number type. +const enum ATTRIBUTE { + ROW = 'Row', + COLUMN = 'Column', + COLUMN_REVERSE = 'ColumnReverse', +}; +const enum GROUP { + MAIN_DIRECTION = 'MAIN_DIRECTION', +}; +enum Orientation { + Horizontal, + Vertical +} +class ContainerModuleItem { + groupName: string = ''; + attributeList: string[] = []; + attribute: ATTRIBUTE = ATTRIBUTE.COLUMN; + orientation: number = 0; +} +const FLEX_MODULE: ContainerModuleItem[] = [ + { + groupName: GROUP.MAIN_DIRECTION, + attributeList: [ATTRIBUTE.COLUMN, ATTRIBUTE.ROW, ATTRIBUTE.COLUMN_REVERSE], + attribute: ATTRIBUTE.ROW, + orientation: Orientation.Horizontal + } +]; + +interface I3 {} + +class CCl implements I3 {} + +class CCl2 extends CCl implements I3 {} + +interface I4 { + a: I3; + b: I3; + c: CCl; + d: CCl2; +} + +class DCl { + constructor(a: I4) {} +} + +let c: I4 = {a: new CCl(), b: new CCl2(), c: new CCl2(), d: new CCl2()} + +new DCl({a: new CCl(), b: new CCl2(), c: new CCl2(), d: new CCl2()}) + +let oo1: Object = {} + +let oo2: Object = {a: 12} diff --git a/ets2panda/linter/test/main/object_literals_2.ets.migrate.json b/ets2panda/linter/test/main/object_literals_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..9d29201f6c1b9039667cfe207f1aaf9ac2a1090a --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_2.ets.migrate.json @@ -0,0 +1,178 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 76, + "column": 14, + "endLine": 76, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 14, + "endLine": 91, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 12, + "endLine": 95, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 14, + "endLine": 106, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 18, + "endLine": 126, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 18, + "endLine": 127, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 12, + "endLine": 148, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 19, + "endLine": 287, + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 289, + "column": 19, + "endLine": 289, + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 191, + "column": 5, + "endLine": 191, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 199, + "column": 3, + "endLine": 199, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'x' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'x' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 200, + "column": 3, + "endLine": 200, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'y' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'y' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 209, + "column": 3, + "endLine": 209, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'x' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'x' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 210, + "column": 3, + "endLine": 210, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'y' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'y' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 228, + "column": 5, + "endLine": 228, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 229, + "column": 5, + "endLine": 229, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_3.ets.args.json b/ets2panda/linter/test/main/object_literals_3.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_3.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_3.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_3.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..bce9e88fa1a7909ef4454eb93ee89fe432b527bf --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_3.ets.migrate.ets @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface GeneratedObjectLiteralInterface_1 { +} +const test1: GeneratedObjectLiteralInterface_1 = {} + +interface GeneratedObjectLiteralInterface_2 { + hello: string; +} +const test2: GeneratedObjectLiteralInterface_2 = { hello: "world" }; + +interface GeneratedTypeLiteralInterface_1 { +} +let test3:GeneratedTypeLiteralInterface_1 = {}; + +interface GeneratedObjectLiteralInterface_3 { + field: string; + field1: string; + field2: string; + field3: string; + field4: string; + field5: string; + field6: string; +} +const test4: GeneratedObjectLiteralInterface_3 = { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7", + }; + +interface GeneratedObjectLiteralInterface_4 { + field: number; + field1: number; + field2: number; + field3: number; + field4: number; + field5: number; + field6: number; +} +const test5: GeneratedObjectLiteralInterface_4 = { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +interface GeneratedObjectLiteralInterface_5 { + field: string; + field1: number; + field2: string; + field3: number; + field4: string; + field5: number; + field6: string; + field7: boolean; + field8: boolean; +} +const test6: GeneratedObjectLiteralInterface_5 = { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +interface test7 { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7" + }; + +interface test8 { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +interface test9 { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +const test10:object = { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7", + }; + +const test11:object = { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +const test12:object = { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +const test13:object = { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7", + }; + +const test14:object = { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +const test15:object = { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +interface GeneratedTypeLiteralInterface_2 { + field: String; + field1: String; + field2: String; + field3: String; + field4: String; + field5: String; + field6: String; +} +let test16:GeneratedTypeLiteralInterface_2 = { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7", + }; + +interface GeneratedTypeLiteralInterface_3 { + field: number; + field1: number; + field2: number; + field3: number; + field4: number; + field5: number; + field6: number; +} +let test17:GeneratedTypeLiteralInterface_3 = { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +interface GeneratedTypeLiteralInterface_4 { + field: String; + field1: number; + field2: String; + field3: number; + field4: String; + field5: number; + field6: String; + field7: boolean; + field8: boolean; +} +let test18:GeneratedTypeLiteralInterface_4 = { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +const test19:Record = { + "field": "world", + "field1": "hello2", + "field2": "hello3", + "field3": "hello4", + "field4": "hello5", + "field5": "hello6", + "field6": "hello7", + }; + +const test20:Record = { + "field": 1, + "field1": 2, + "field2": 3, + "field3": 4, + "field4": 5, + "field5": 6, + "field6": 7, + }; + +const test21:Record = { + "field": "world", + "field1": 2, + "field2": "hello3", + "field3": 4, + "field4": "hello5", + "field5": 6, + "field6": "hello7", + "field7": true, + "field8": false + }; \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_3.ets.migrate.json b/ets2panda/linter/test/main/object_literals_3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..69a3046345e42be615adc2be914a29c54ece744f --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_3.ets.migrate.json @@ -0,0 +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": 122, + "column": 23, + "endLine": 122, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 23, + "endLine": 132, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 23, + "endLine": 142, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 23, + "endLine": 154, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 23, + "endLine": 164, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 174, + "column": 23, + "endLine": 174, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_4.ets.args.json b/ets2panda/linter/test/main/object_literals_4.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_4.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_4.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_4.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_4.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..19e21b00c1b27f394376f2093fa5778f975e8b37 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_4.ets.migrate.ets @@ -0,0 +1,73 @@ +/* + * 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. + */ + +type T = () => void + +class A { + foo?: T + bar?: Function +} + +let a: A = { + foo: () => { + console.log("Hello") + }, + bar: () => { + console.log("Hello") + } +} + +//====================== +class Resource{} + +class ContainerModuleItem { + groupName: string = ""; + moduleName: Resource | null = null; + atributeList: string[] = []; +} + +const FLEX_MODULE: ContainerModuleItem[] = [{ + groupName: GROUP.MAIN_DIRECTION, + moduleName: "ASF", + atributeList: [ATTRIBUTE.COLUMN, ATTRIBUTE.ROW, ATTRIBUTE.COLUMN_REVERSE], +}] + +const enum ATTRIBUTE { + ROW = 'Row', + COLUMN = 'Column', + COLUMN_REVERSE = 'ColumnReverse' +} + +const enum GROUP { + MAIN_DIRECTION = 'MAIN_DIRECTION' +} + +//==================================== + +class C { + s: string = "" + n: number = 0 + l: () => void = () => {} +} + +let c : C = { + s: "foo", + n: 42, + l: () => { + console.log("Hi") + } +} + +c.l() \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_4.ets.migrate.json b/ets2panda/linter/test/main/object_literals_4.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_4.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_autofixes.ets b/ets2panda/linter/test/main/object_literals_autofixes.ets index 87814c7da5d5feafdf064a64253db60213519298..9bc2be4e2f61d64ec487b21f7b3ab8e7b6a5ec50 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets @@ -102,7 +102,7 @@ function bar(): void { let d = {g: 7, d: foo({q:1,w:2}.q + {q:3,w:4}.w)}; } -const o9 = { 1: '1', '2': 2 }; +const o9 = { 1: '1', '2': 2 }; // Not fixable, property name is string/numeric literal const o10 = { [3]: 3 }; // Not fixable, computed property value const o11 = { [o2.hello]: 'world' }; // Not fixable, computed property value @@ -110,9 +110,9 @@ const anyVal: any = 1; const o12 = { a: anyVal }; // Not fixable, type of property 'a' is not supported let val = 1; -const o13 = { val }; // Not fixable, property is not 'key:value' pair +const o13 = { val }; // Fixable const o14 = { ...o1 }; // Not fixable, property is not 'key:value' pair -const o15 = { m() {} }; // Not fixable, property is not 'key:value' pair +const o15 = { m() {} }; // Fixable const o16 = { // Not fixable, property 'c' is initialized with non-fixable nested object literal, and thus will always have unsupported type (object type literal) a: 1, diff --git a/ets2panda/linter/test/main/object_literals_autofixes.ets.args.json b/ets2panda/linter/test/main/object_literals_autofixes.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json b/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json index e139fc2d4af9bcea40ce57baac617c7ade95eb33..5f107cd9acf91e6c0e34bb23e215062f712baa54 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json @@ -738,18 +738,6 @@ "endLine": 105, "endColumn": 13, "problem": "ObjectLiteralNoContextType", - "autofix": [ - { - "start": 2600, - "end": 2600, - "replacementText": "interface GeneratedObjectLiteralInterface_37 {\n 1: string;\n '2': number;\n}\n" - }, - { - "start": 2608, - "end": 2608, - "replacementText": ": GeneratedObjectLiteralInterface_37" - } - ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" @@ -860,6 +848,18 @@ "endLine": 115, "endColumn": 14, "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 3051, + "end": 3051, + "replacementText": "class GeneratedObjectLiteralClass_1 {\n m() { }\n}\n\n" + }, + { + "start": 3063, + "end": 3073, + "replacementText": "new GeneratedObjectLiteralClass_1()" + } + ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" @@ -922,8 +922,8 @@ "problem": "ObjectTypeLiteral", "autofix": [ { - "start": 3779, - "end": 3819, + "start": 3759, + "end": 3799, "replacementText": "interface LocalType {\n a: number;\n b: string;\n}" } ], @@ -999,18 +999,18 @@ "problem": "ObjectLiteralNoContextType", "autofix": [ { - "start": 4301, - "end": 4302, + "start": 4281, + "end": 4282, "replacementText": "\"a\"" }, { - "start": 4311, - "end": 4312, + "start": 4291, + "end": 4292, "replacementText": "\"b\"" }, { - "start": 4321, - "end": 4322, + "start": 4301, + "end": 4302, "replacementText": "\"c\"" } ], @@ -1036,18 +1036,18 @@ "problem": "ObjectLiteralNoContextType", "autofix": [ { - "start": 4376, - "end": 4379, + "start": 4356, + "end": 4359, "replacementText": "\"foo\"" }, { - "start": 4388, - "end": 4391, + "start": 4368, + "end": 4371, "replacementText": "\"bar\"" }, { - "start": 4430, - "end": 4433, + "start": 4410, + "end": 4413, "replacementText": "\"baz\"" } ], @@ -1103,13 +1103,13 @@ "problem": "ObjectLiteralNoContextType", "autofix": [ { - "start": 4721, - "end": 4724, + "start": 4701, + "end": 4704, "replacementText": "\"key\"" }, { - "start": 4739, - "end": 4746, + "start": 4719, + "end": 4726, "replacementText": "\"message\"" } ], diff --git a/ets2panda/linter/test/migrate/object_literals_autofixes.sts b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.ets similarity index 40% rename from ets2panda/linter/test/migrate/object_literals_autofixes.sts rename to ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.ets index 48d3fe6aa346024a7f903a3fd274f45d201bbd9e..7022a9431a8d73e070ab3a752587dcf911fe6975 100644 --- a/ets2panda/linter/test/migrate/object_literals_autofixes.sts +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.ets @@ -20,7 +20,7 @@ import { GeneratedObjectLiteralInterface_8, foo as GeneratedObjectLiteralInterface_9 } from 'x'; -interface GeneratedObjectLiteralInterface_11 {} +interface GeneratedObjectLiteralInterface_11 {} class GeneratedObjectLiteralInterface_12 {} function GeneratedObjectLiteralInterface_15() {} @@ -30,10 +30,27 @@ function foo(x): number { return 1; } -const o1 = {}; -const o2 = { hello: "world" }; -const o3! = {a: 1, b: 2}; -const o4 = { +interface GeneratedObjectLiteralInterface_1 { +} +const o1: GeneratedObjectLiteralInterface_1 = {}; +interface GeneratedObjectLiteralInterface_2 { + hello: string; +} +const o2: GeneratedObjectLiteralInterface_2 = { hello: "world" }; +interface GeneratedObjectLiteralInterface_3 { + a: number; + b: number; +} +const o3!: GeneratedObjectLiteralInterface_3 = {a: 1, b: 2}; +interface GeneratedObjectLiteralInterface_5 { + field: string; + field1: number; + field2: string; + field3: number; + field4: boolean; + field5: boolean; +} +const o4: GeneratedObjectLiteralInterface_5 = { field: "hello", field1: 2, field2: "world", @@ -43,66 +60,184 @@ const o4 = { }; // Properties with various types. Nested object literals -const o5 = { +interface GeneratedObjectLiteralInterface_6 { +} +interface GeneratedObjectLiteralInterface_10 { + a: number; + b: string; +} +interface GeneratedObjectLiteralInterface_13 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_25 { + a: number; + b: string; + c: boolean; + d: C; + e: GeneratedObjectLiteralInterface_6; + f: GeneratedObjectLiteralInterface_10; + g: GeneratedObjectLiteralInterface_13; +} +const o5: GeneratedObjectLiteralInterface_25 = { a: 1, b: '2', c: true, d: new C(), - e: {}, - f: { a: 1, b: '2' }, - g: { - q: 10, - w: 20 - }, + e: ({} as GeneratedObjectLiteralInterface_6), + f: ({ a: 1, b: '2' } as GeneratedObjectLiteralInterface_10), + g: ({ q: 10, + w: 20 } as GeneratedObjectLiteralInterface_13), }; -const o6 = { +interface GeneratedObjectLiteralInterface_14 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_16 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_21 { + a: number; + b: string; + c: GeneratedObjectLiteralInterface_14; + d: boolean; + e: GeneratedObjectLiteralInterface_16; +} +const o6: GeneratedObjectLiteralInterface_21 = { a: 1, b: '2', - c: { q: 10, w: 20 }, + c: ({ q: 10, w: 20 } as GeneratedObjectLiteralInterface_14), d: true, - e: { q: 30, w: 40 } + e: ({ q: 30, w: 40 } as GeneratedObjectLiteralInterface_16) }; // Object literals inside another expression -const o7 = { a:1, b:2 }.a + { a:3, b:4 }.b; -const o8 = { - a: 1, +interface GeneratedObjectLiteralInterface_17 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_18 { + a: number; + b: number; +} +const o7 = ({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_17).a + ({ a: 3, b: 4 } as GeneratedObjectLiteralInterface_18).b; +interface GeneratedObjectLiteralInterface_19 { + x: number; + y: number; +} +interface GeneratedObjectLiteralInterface_20 { + a: number; + b: number; + c: GeneratedObjectLiteralInterface_19; + d: number; +} +interface GeneratedObjectLiteralInterface_23 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_27 { + q: number; + w: number; +} +const o8: GeneratedObjectLiteralInterface_20 = { + a: 1, b: 2, - c: ({x:1, y:2}), - d: foo({q:1, w:2}.q + {q:3, w:4}.w) + c: ({ x: 1, y: 2 } as GeneratedObjectLiteralInterface_19), + d: foo(({ q: 1, w: 2 } as GeneratedObjectLiteralInterface_23).q + ({ q: 3, w: 4 } as GeneratedObjectLiteralInterface_27).w) }; // Object literals inside class declaration +interface GeneratedObjectLiteralInterface_22 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_24 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_26 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_28 { + c: number; + d: number; +} +interface GeneratedObjectLiteralInterface_29 { + e: number; +} +interface GeneratedObjectLiteralInterface_32 { + f: number; + g: number; +} +interface GeneratedObjectLiteralInterface_34 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_36 { + c: number; + d: number; + e: number; +} class D { - f1 = {a: 1, b: 2}; - f2? = {a: 1, b: 2}; - f3! = {a: 1, b: 2}; - f4 = ({c: 3, d: 4}); - f5 = {e: 5}.e + {f: 6, g: 7}.f; + f1: GeneratedObjectLiteralInterface_22 = {a: 1, b: 2}; + f2?: GeneratedObjectLiteralInterface_24 = {a: 1, b: 2}; + f3!: GeneratedObjectLiteralInterface_26 = {a: 1, b: 2}; + f4 = ({ c: 3, d: 4 } as GeneratedObjectLiteralInterface_28); + f5 = ({ e: 5 } as GeneratedObjectLiteralInterface_29).e + ({ f: 6, g: 7 } as GeneratedObjectLiteralInterface_32).f; m() { - let x = {a:1, b:2}; - let y = {c:1, d:2, e:3}; + let x: GeneratedObjectLiteralInterface_34 = {a:1, b:2}; + let y: GeneratedObjectLiteralInterface_36 = {c:1, d:2, e:3}; } } // Object literals as function parameter initializer -function funInit(p = { a: 1, b: 2 }) {} +interface GeneratedObjectLiteralInterface_30 { + a: number; + b: number; +} +function funInit(p: GeneratedObjectLiteralInterface_30 = { a: 1, b: 2 }) {} function funInit2({a, b} = { a: 3, b: 4 }) {} // Not fixable, as in case of destructuring parameters, the contextual type of expression is implied by the binding pattern // Object literals inside function declaration +interface GeneratedObjectLiteralInterface_31 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_33 { + c: number; + d: number; +} +interface GeneratedObjectLiteralInterface_35 { + e: number; + f: number; +} +interface GeneratedObjectLiteralInterface_37 { + g: number; + d: number; +} +interface GeneratedObjectLiteralInterface_38 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_39 { + q: number; + w: number; +} function bar(): void { - let a = {a: 1, b: 2}; - let b = {c: 3, d: 4}; + let a: GeneratedObjectLiteralInterface_31 = {a: 1, b: 2}; + let b: GeneratedObjectLiteralInterface_33 = {c: 3, d: 4}; if (a.b > b.c) { - let c = {e: 5, f: 6}; + let c: GeneratedObjectLiteralInterface_35 = {e: 5, f: 6}; } - let d = {g: 7, d: foo({q:1,w:2}.q + {q:3,w:4}.w)}; + let d: GeneratedObjectLiteralInterface_37 = {g: 7, d: foo(({ q: 1, w: 2 } as GeneratedObjectLiteralInterface_38).q + ({ q: 3, w: 4 } as GeneratedObjectLiteralInterface_39).w)}; } -const o9 = { 1: '1', '2': 2 }; +const o9 = { 1: '1', '2': 2 }; // Not fixable, property name is string/numeric literal const o10 = { [3]: 3 }; // Not fixable, computed property value const o11 = { [o2.hello]: 'world' }; // Not fixable, computed property value @@ -110,9 +245,13 @@ const anyVal: any = 1; const o12 = { a: anyVal }; // Not fixable, type of property 'a' is not supported let val = 1; -const o13 = { val }; // Not fixable, property is not 'key:value' pair +const o13 = { val }; // Fixable const o14 = { ...o1 }; // Not fixable, property is not 'key:value' pair -const o15 = { m() {} }; // Not fixable, property is not 'key:value' pair +class GeneratedObjectLiteralClass_1 { + m() { } +} + +const o15 = new GeneratedObjectLiteralClass_1(); // Fixable const o16 = { // Not fixable, property 'c' is initialized with non-fixable nested object literal, and thus will always have unsupported type (object type literal) a: 1, @@ -130,30 +269,33 @@ function captureFromLocalScope(t: T): void { let v1 = {a: 1, b: '2', c: t}; // Not fixable, `c` references local type parameter `T` let v2 = {a: 1, b: '2', c: new X()}; // Not fixable, `c` references local type parameter `T` let v3 = {a: 1, b: '2', c: new Y>()}; // Not fixable, `c` references local type parameter `T` - - type LocalType = {a: number, b: string}; + + interface LocalType { + a: number; + b: string; +} let localTypeVar: LocalType = {a:1, b:'2'}; let v4 = { x: localTypeVar }; // Non-fixable, `x` references type `LocalType` declared in local scope - + class LocalClass {x: number = 1}; let v5 = { y: new LocalClass() }; // Non-fixable, `y` references type `LocalClass` declared in local scope - + let v6 = { z: LocalClass }; // Non-fixable, `z` references type `LocalClass` declared in local scope } // Record object literals let rec1: Record = { - a: 1, - b: 2, - c: 3 + "a": 1, + "b": 2, + "c": 3 } let rec2: Record = { - foo: 1, - bar: 2, + "foo": 1, + "bar": 2, 10: 'foo', 20: 'bar', - baz: 3, + "baz": 3, 'daz': 4 } @@ -169,7 +311,7 @@ interface NullableRecord { } let rec4: NullableRecord = { params: { - key: '1', - message: '2' + "key": '1', + "message": '2' } }; \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.json b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json similarity index 37% rename from ets2panda/linter/test/migrate/object_literals_autofixes.ts.json rename to ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json index ff838327c3663578824e6dc51fac496988831862..e69f8c28502e98e3389a8c244620b123c4cd1ca1 100644 --- a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -25,289 +25,29 @@ "severity": "ERROR" }, { - "line": 33, - "column": 12, - "endLine": 33, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 12, - "endLine": 34, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 35, + "line": 44, "column": 7, - "endLine": 35, - "endColumn": 25, + "endLine": 44, + "endColumn": 60, "problem": "DefiniteAssignment", "suggest": "", "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "WARNING" }, { - "line": 35, - "column": 13, - "endLine": 35, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 12, - "endLine": 36, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 12, - "endLine": 46, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 8, - "endLine": 51, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 8, - "endLine": 52, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 8, - "endLine": 53, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 12, - "endLine": 58, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 8, - "endLine": 61, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 8, - "endLine": 63, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 12, - "endLine": 67, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 29, - "endLine": 67, - "endColumn": 30, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 12, - "endLine": 68, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 9, - "endLine": 71, - "endColumn": 10, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 12, - "endLine": 72, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 27, - "endLine": 72, - "endColumn": 28, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 77, - "column": 10, - "endLine": 77, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 11, - "endLine": 78, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 79, + "line": 186, "column": 5, - "endLine": 79, - "endColumn": 24, + "endLine": 186, + "endColumn": 60, "problem": "DefiniteAssignment", "suggest": "", "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "WARNING" }, { - "line": 79, - "column": 11, - "endLine": 79, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 11, - "endLine": 80, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 10, - "endLine": 81, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 21, - "endLine": 81, - "endColumn": 22, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 84, - "column": 17, - "endLine": 84, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 85, - "column": 17, - "endLine": 85, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 90, - "column": 22, - "endLine": 90, - "endColumn": 23, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 91, + "line": 202, "column": 19, - "endLine": 91, + "endLine": 202, "endColumn": 42, "problem": "DestructuringParameter", "suggest": "", @@ -315,9 +55,9 @@ "severity": "ERROR" }, { - "line": 91, + "line": 202, "column": 28, - "endLine": 91, + "endLine": 202, "endColumn": 29, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -325,69 +65,9 @@ "severity": "ERROR" }, { - "line": 95, - "column": 13, - "endLine": 95, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 13, - "endLine": 96, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 99, - "column": 17, - "endLine": 99, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 13, - "endLine": 102, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 27, - "endLine": 102, - "endColumn": 28, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 41, - "endLine": 102, - "endColumn": 42, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 105, + "line": 240, "column": 12, - "endLine": 105, + "endLine": 240, "endColumn": 13, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -395,9 +75,9 @@ "severity": "ERROR" }, { - "line": 105, + "line": 240, "column": 14, - "endLine": 105, + "endLine": 240, "endColumn": 15, "problem": "LiteralAsPropertyName", "suggest": "", @@ -405,9 +85,9 @@ "severity": "ERROR" }, { - "line": 106, + "line": 241, "column": 13, - "endLine": 106, + "endLine": 241, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -415,9 +95,9 @@ "severity": "ERROR" }, { - "line": 106, + "line": 241, "column": 15, - "endLine": 106, + "endLine": 241, "endColumn": 18, "problem": "ComputedPropertyName", "suggest": "", @@ -425,9 +105,9 @@ "severity": "ERROR" }, { - "line": 107, + "line": 242, "column": 13, - "endLine": 107, + "endLine": 242, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -435,9 +115,9 @@ "severity": "ERROR" }, { - "line": 107, + "line": 242, "column": 15, - "endLine": 107, + "endLine": 242, "endColumn": 25, "problem": "ComputedPropertyName", "suggest": "", @@ -445,9 +125,9 @@ "severity": "ERROR" }, { - "line": 109, + "line": 244, "column": 15, - "endLine": 109, + "endLine": 244, "endColumn": 18, "problem": "AnyType", "suggest": "", @@ -455,9 +135,9 @@ "severity": "ERROR" }, { - "line": 110, + "line": 245, "column": 13, - "endLine": 110, + "endLine": 245, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -465,9 +145,9 @@ "severity": "ERROR" }, { - "line": 113, + "line": 248, "column": 13, - "endLine": 113, + "endLine": 248, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -475,9 +155,9 @@ "severity": "ERROR" }, { - "line": 114, + "line": 249, "column": 13, - "endLine": 114, + "endLine": 249, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -485,9 +165,9 @@ "severity": "ERROR" }, { - "line": 114, + "line": 249, "column": 15, - "endLine": 114, + "endLine": 249, "endColumn": 20, "problem": "SpreadOperator", "suggest": "", @@ -495,9 +175,9 @@ "severity": "ERROR" }, { - "line": 115, + "line": 256, "column": 13, - "endLine": 115, + "endLine": 256, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -505,19 +185,9 @@ "severity": "ERROR" }, { - "line": 117, - "column": 13, - "endLine": 117, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 120, + "line": 259, "column": 8, - "endLine": 120, + "endLine": 259, "endColumn": 9, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -525,9 +195,9 @@ "severity": "ERROR" }, { - "line": 130, + "line": 269, "column": 14, - "endLine": 130, + "endLine": 269, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -535,9 +205,9 @@ "severity": "ERROR" }, { - "line": 131, + "line": 270, "column": 14, - "endLine": 131, + "endLine": 270, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -545,9 +215,9 @@ "severity": "ERROR" }, { - "line": 132, + "line": 271, "column": 14, - "endLine": 132, + "endLine": 271, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -555,29 +225,9 @@ "severity": "ERROR" }, { - "line": 134, - "column": 22, - "endLine": 134, - "endColumn": 23, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 135, - "column": 35, - "endLine": 135, - "endColumn": 36, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 136, + "line": 278, "column": 14, - "endLine": 136, + "endLine": 278, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -585,9 +235,9 @@ "severity": "ERROR" }, { - "line": 139, + "line": 281, "column": 14, - "endLine": 139, + "endLine": 281, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -595,9 +245,9 @@ "severity": "ERROR" }, { - "line": 141, + "line": 283, "column": 14, - "endLine": 141, + "endLine": 283, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -605,9 +255,9 @@ "severity": "ERROR" }, { - "line": 141, + "line": 283, "column": 19, - "endLine": 141, + "endLine": 283, "endColumn": 29, "problem": "ClassAsObject", "suggest": "", @@ -615,9 +265,9 @@ "severity": "WARNING" }, { - "line": 145, + "line": 287, "column": 26, - "endLine": 145, + "endLine": 287, "endColumn": 29, "problem": "AnyType", "suggest": "", @@ -625,19 +275,9 @@ "severity": "ERROR" }, { - "line": 145, - "column": 33, - "endLine": 145, - "endColumn": 34, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 151, + "line": 293, "column": 35, - "endLine": 151, + "endLine": 293, "endColumn": 38, "problem": "AnyType", "suggest": "", @@ -645,19 +285,9 @@ "severity": "ERROR" }, { - "line": 151, - "column": 42, - "endLine": 151, - "endColumn": 43, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 160, + "line": 302, "column": 35, - "endLine": 160, + "endLine": 302, "endColumn": 38, "problem": "AnyType", "suggest": "", @@ -665,9 +295,9 @@ "severity": "ERROR" }, { - "line": 160, + "line": 302, "column": 42, - "endLine": 160, + "endLine": 302, "endColumn": 43, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -675,34 +305,14 @@ "severity": "ERROR" }, { - "line": 164, + "line": 306, "column": 5, - "endLine": 164, + "endLine": 306, "endColumn": 10, "problem": "ComputedPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" - }, - { - "line": 170, - "column": 28, - "endLine": 170, - "endColumn": 29, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 171, - "column": 13, - "endLine": 171, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.args.json b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d1901e50e01e4fb1463cdbfacc8798aa0f672bb4 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.ets @@ -0,0 +1,54 @@ +/* + * 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. + */ + +type F = () => void; +interface FuncInterface { + (x: number): string + f?: number; +} + +class A { + a: F; + b: Function; + c: () => void; + d: FuncInterface; +} + +let a: A = { + a: () => { console.log('Hello'); }, + b: () => { console.log('Bye'); }, + c: () => { console.log('Apple'); }, + d: (x: number) => x.toString(), +} + +let q: F = () => {}; +let w: Function = (x: number) => x * x; +let e = () => { console.log('Orange'); }; +let r: FuncInterface = (x: number) => x.toString(); + +a = { + a: q, + b: w, + c: e, + d: r, +} + +// #14569 - initialize field with 'Function' object +class B { + f: Function = () => {}; +} +let b: B = { + f: Function +}; \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.json b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8c06a808b0b1241a3206f1b11d66841c5335c971 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.json @@ -0,0 +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": 18, + "column": 3, + "endLine": 18, + "endColumn": 22, + "problem": "CallSignature", + "suggest": "", + "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 6, + "endLine": 53, + "endColumn": 14, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'c' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'c' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'd' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'd' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_properties.ets b/ets2panda/linter/test/main/object_literals_properties.ets index e6956798332d731b6f0b637b84e97f85b8eb769a..da4dacf6b6e45689b60d2deefe303a22360543ac 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets +++ b/ets2panda/linter/test/main/object_literals_properties.ets @@ -13,32 +13,233 @@ * limitations under the License. */ -class MyClass { - a: string = "" - b: number = 0 -} +// Untyped object literals +let method = { + m() { console.log(1); } // Error, fixable +}; + +let getMethod = { + get property() { return 2; } // Error, fixable +}; + +let setMethod = { + set property(value: number) { // Error, fixable + console.log(value); + } +}; + +let x = 1, y = '2', z = true; + +let shorthand = { + x, // Error, fixable + y, // Error, fixable + z // Error, fixable +}; + +let spread = { + ...shorthand // Error, not fixable +}; -let c: MyClass = {a: "a", b: 3} +let mixed = { // Fixable + a: "foo", + b: 42, + c: [1, 2, 3], + x, // Error + y, // Error -let b: MyClass = { - a: "Alice", - "c", // Error - c, // Error - b: "num", - method() { // Error + method() { // Error console.log(42) }, + + get property() { // Error + return 0; + }, + + set property(value: number) { // Error + if (value < 0) { + throw new Error('Bad value'); + } + } +}; + +let x2 = 1, y2 = 2, z2 = 3; +let mixedBad = { // Not fixable + a: 1, + b: 2, + x2, // Error, fixable + y2, // Error, fixable + z2, // Error, fixable + m() {}, + ...shorthand // Error, not fixable } -let o: MyClass = { - a: "foo", - b: 42, - c: {}, - 1: "number literal property", // Error - "foo:bar": "string literal property", // Error +// Typed object literals +interface I { + m(): void; +} +let i: I = { + m() { // Fixable + console.log(100); + } +}; + +class C { + m(): void { + console.log(200); + } +} +let c: C = { + m(): void { // Fixable + console.log(300); + } +}; + +function foo(c: C) {} +foo({ + m() { console.log(300); } // Fixable +}); - get property() {}, // Error - set property(value) {}, // Error +class C2 { + x2 = 10; + y2 = 20; + z2 = 30; + + m() {} +} +let c2: C2 = { + x2, // Fixable + y2, // Fixable + z2, // Fixable + m() { console.log(1); } // Fixable +}; - [expression]: "computed property", // Error +let c22: C2 = { + x2, // Fixable + y2, // Fixable + z2, // Fixable + m() { console.log(1); }, // Not fixable, object has spread property + ...shorthand // Not fixable }; + +class C3 { + x2 = 10; + y2 = 20; + z2 = 30; + + m() {} + + constructor(a: number) {} +} +let c3: C3 = { + x2, // Fixable + y2, // Fixable + z2, // Fixable + m() { console.log(1); } // Not fixable, class type has constructor with parameters +}; + +function capturesFromLocalScope() { + let a = 1, b = 2; + let captureLocalVal = { + m() { // Not fixable, captures local values 'a' and 'b' + console.log(a, b); + } + }; + + let captureLocalVal2: C = { + m(): void { // Not fixable, captures local values 'a' and 'b' + console.log(a, b); + } + }; + + type LocalType = {a: number, b: string}; + let localTypeVar: LocalType = { a: 1, b: '2' }; + let captureLocalType = { + m() { // Not fixable, captures value of type `LocalType` declared in local scope + console.log(localTypeVar); + } + }; + let captureLocalType2 = { + m(x: LocalType) { // Not fixable, `x` references type `LocalType` declared in local scope + console.log(x); + } + }; + + class LocalClass { x: number = 1 }; + let captureLocalType3 = { + m() { // Not fixable, references type `LocalClass` declared in local scope + console.log(new LocalClass()); + } + }; +} + +// Method overriding field +class C4 { + a: number = 0; + b() {}; +} +let c4: C4 = { // Not fixable, overrides class method with property of functional type + a: 1, + b: () => {} +}; + +class C5 { + a: number = 0; + b: () => void; +} +let c5: C5 = { // Not fixable, overrides class property with method + a: 1, + b() {} +}; + +interface I2 { + a: number; + b(): void; +} +let i2: I2 = { // Not fixable, implements method as functional-type property + a: 1, + b: () => {} +}; + +interface I3 { + a: number; + b: () => void; +} +let ii: I3 = { // Not fixable, implements functional-type property as a method + a: 1, + b() {} +}; + +// Inheritance +class Base { + constructor() {} +} +class Derived extends Base { + m() {} +} +let b: Derived = { // Fixable + m() { console.log(2); } +}; + +class Base2 { + constructor(a: number) {} +} +class Derived2 extends Base2 { + m() {} +} +let b2: Derived2 = { // Not fixable, derived class inherits a constructor with parameters from base class + m() { console.log(2); } +}; + +class Base3 { + constructor(a: number) {} +} +class Derived3 extends Base3 { + m() {} + + constructor() { + super(1); + } +} +let b3: Derived3 = { // Fixable + m() { console.log(2); } +}; \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.args.json b/ets2panda/linter/test/main/object_literals_properties.ets.args.json index 720715a55cfe7d0e9847cee28d64d03e7888416e..f9fc1047e86a36642e6e262c41779a581f640a7f 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "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", @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } 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 d22a34564890885fbeb7121dfe5683cd0dd568fc..8f19012800d443c8de18d3cf18e2da365f0defb2 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json @@ -15,59 +15,89 @@ ], "result": [ { - "line": 23, - "column": 18, - "endLine": 23, - "endColumn": 19, + "line": 17, + "column": 14, + "endLine": 17, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 25, + "line": 18, "column": 3, - "endLine": 25, - "endColumn": 6, + "endLine": 18, + "endColumn": 26, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 26, + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 22, "column": 3, - "endLine": 26, - "endColumn": 4, + "endLine": 22, + "endColumn": 31, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 28, + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 26, "column": 3, - "endLine": 30, + "endLine": 28, "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 33, - "column": 18, + "column": 17, "endLine": 33, - "endColumn": 19, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 37, + "line": 34, "column": 3, - "endLine": 37, + "endLine": 34, "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", @@ -75,39 +105,199 @@ "severity": "ERROR" }, { - "line": 38, + "line": 35, "column": 3, - "endLine": 38, - "endColumn": 12, + "endLine": 35, + "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, { "line": 40, "column": 3, "endLine": 40, - "endColumn": 20, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 3, + "endLine": 47, + "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 41, + "line": 48, "column": 3, - "endLine": 41, - "endColumn": 25, + "endLine": 48, + "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 43, + "line": 50, "column": 3, - "endLine": 43, + "endLine": 52, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 56, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 62, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 13, + "endLine": 65, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 21, + "endLine": 65, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 3, + "endLine": 69, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 3, + "endLine": 70, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 3, + "endLine": 71, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 3, + "endLine": 73, "endColumn": 15, "problem": "ObjectLiteralProperty", "suggest": "", @@ -115,33 +305,553 @@ "severity": "ERROR" }, { - "line": 36, - "column": 6, - "endLine": 36, - "endColumn": 7, + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 12, + "endLine": 80, + "endColumn": 13, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 37, + "line": 81, "column": 3, - "endLine": 37, + "endLine": 83, "endColumn": 4, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 43, + "line": 91, + "column": 12, + "endLine": 91, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 92, "column": 3, - "endLine": 43, + "endLine": 94, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 5, + "endLine": 98, + "endColumn": 6, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 28, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 3, + "endLine": 105, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 14, + "endLine": 109, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 3, + "endLine": 110, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 3, + "endLine": 111, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 3, + "endLine": 112, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 3, + "endLine": 113, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 15, + "endLine": 116, + "endColumn": 16, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 3, + "endLine": 117, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 3, + "endLine": 118, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 3, + "endLine": 119, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 3, + "endLine": 120, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 3, + "endLine": 127, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 14, + "endLine": 133, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 3, + "endLine": 134, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 3, + "endLine": 135, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 3, + "endLine": 136, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 3, + "endLine": 137, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 7, + "endLine": 141, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 14, + "endLine": 141, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 25, + "endLine": 142, + "endColumn": 26, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 5, + "endLine": 145, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 29, + "endLine": 148, + "endColumn": 30, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 5, + "endLine": 151, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 20, + "endLine": 154, + "endColumn": 21, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 33, + "endLine": 155, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 156, + "column": 26, + "endLine": 156, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 5, + "endLine": 159, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 27, + "endLine": 161, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 5, + "endLine": 164, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 27, + "endLine": 168, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 5, + "endLine": 171, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 14, + "endLine": 180, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 191, + "column": 3, + "endLine": 191, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 14, + "endLine": 198, "endColumn": 15, - "problem": "ComputedPropertyName", + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 3, + "endLine": 209, + "endColumn": 9, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 219, + "column": 18, + "endLine": 219, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 3, + "endLine": 220, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 229, + "column": 20, + "endLine": 229, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 3, + "endLine": 230, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 20, + "endLine": 243, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 3, + "endLine": 244, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 3, + "endLine": 187, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.migrate.json b/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json similarity index 30% rename from ets2panda/linter/test/migrate/object_literals_autofixes.ts.migrate.json rename to ets2panda/linter/test/main/object_literals_properties.ets.autofix.json index 8757f86ed2a8cf7900b5451b1ebb13a44b2e64a4..de865a4411fa65c6c9208d8f2c65af44f481e221 100644 --- a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.migrate.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json @@ -1,519 +1,827 @@ { + "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": 29, + "line": 17, "column": 14, - "endLine": 29, + "endLine": 17, "endColumn": 15, - "problem": "AnyType", + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 637, + "end": 637, + "replacementText": "class GeneratedObjectLiteralClass_1 {\n m() { console.log(1); } // Error, fixable\n}\n\n" + }, + { + "start": 650, + "end": 697, + "replacementText": "new GeneratedObjectLiteralClass_1()" + } + ], "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 33, - "column": 12, - "endLine": 33, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 26, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 34, - "column": 12, - "endLine": 34, - "endColumn": 13, + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 700, + "end": 700, + "replacementText": "class GeneratedObjectLiteralClass_2 {\n get property() { return 2; } // Error, fixable\n}\n\n" + }, + { + "start": 716, + "end": 768, + "replacementText": "new GeneratedObjectLiteralClass_2()" + } + ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 25, - "problem": "DefiniteAssignment", + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 31, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", - "severity": "WARNING" + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" }, { - "line": 35, - "column": 13, - "endLine": 35, - "endColumn": 14, + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 771, + "end": 771, + "replacementText": "class GeneratedObjectLiteralClass_3 {\n set property(value: number) {\n console.log(value);\n }\n}\n\n" + }, + { + "start": 787, + "end": 868, + "replacementText": "new GeneratedObjectLiteralClass_3()" + } + ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 36, - "column": 12, - "endLine": 36, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 26, + "column": 3, + "endLine": 28, + "endColumn": 4, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 46, - "column": 12, - "endLine": 46, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 875, + "end": 880, + "replacementText": "x: number = 1" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 51, - "column": 8, - "endLine": 51, - "endColumn": 9, + "line": 33, + "column": 17, + "endLine": 33, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 52, - "column": 8, - "endLine": 52, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 922, + "end": 923, + "replacementText": "x: x" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 53, - "column": 8, - "endLine": 53, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 945, + "end": 946, + "replacementText": "y: y" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 58, - "column": 12, - "endLine": 58, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 968, + "end": 969, + "replacementText": "z: z" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 61, - "column": 8, - "endLine": 61, - "endColumn": 9, + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 63, - "column": 8, - "endLine": 63, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 15, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 67, - "column": 12, - "endLine": 67, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 15, + "problem": "SpreadOperator", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", "severity": "ERROR" }, { - "line": 67, - "column": 29, - "endLine": 67, - "endColumn": 30, + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 14, "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 1048, + "end": 1048, + "replacementText": "class GeneratedObjectLiteralClass_4 {\n a: string;\n b: number;\n c: number[];\n x: number;\n y: string;\n constructor(init: GeneratedObjectLiteralInitInterface_4) {\n this.a = init.a;\n this.b = init.b;\n this.c = init.c;\n this.x = init.x;\n this.y = init.y;\n }\n method() {\n console.log(42);\n }\n get property() {\n return 0;\n }\n set property(value: number) {\n if (value < 0) {\n throw new Error('Bad value');\n }\n }\n}\n\ninterface GeneratedObjectLiteralInitInterface_4 {\n a: string;\n b: number;\n c: number[];\n x: number;\n y: string;\n}\n\n" + }, + { + "start": 1060, + "end": 1344, + "replacementText": "new GeneratedObjectLiteralClass_4({\n a: \"foo\",\n b: 42,\n c: [1, 2, 3],\n x: x,\n y: y\n})" + } + ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 68, - "column": 12, - "endLine": 68, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 47, + "column": 3, + "endLine": 47, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1112, + "end": 1113, + "replacementText": "x: x" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 71, - "column": 9, - "endLine": 71, - "endColumn": 10, - "problem": "ObjectLiteralNoContextType", + "line": 48, + "column": 3, + "endLine": 48, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1126, + "end": 1127, + "replacementText": "y: y" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 72, - "column": 12, - "endLine": 72, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 50, + "column": 3, + "endLine": 52, + "endColumn": 4, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 72, - "column": 27, - "endLine": 72, - "endColumn": 28, - "problem": "ObjectLiteralNoContextType", + "line": 54, + "column": 3, + "endLine": 56, + "endColumn": 4, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 77, - "column": 10, - "endLine": 77, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", + "line": 58, + "column": 3, + "endLine": 62, + "endColumn": 4, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 78, - "column": 11, - "endLine": 78, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1351, + "end": 1357, + "replacementText": "x2: number = 1" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 79, - "column": 5, - "endLine": 79, - "endColumn": 24, - "problem": "DefiniteAssignment", + "line": 65, + "column": 13, + "endLine": 65, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1359, + "end": 1365, + "replacementText": "y2: number = 2" + } + ], "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", - "severity": "WARNING" + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" }, { - "line": 79, - "column": 11, - "endLine": 79, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", + "line": 65, + "column": 21, + "endLine": 65, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1367, + "end": 1373, + "replacementText": "z2: number = 3" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 80, - "column": 11, - "endLine": 80, - "endColumn": 12, + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 17, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 81, - "column": 10, - "endLine": 81, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", + "line": 69, + "column": 3, + "endLine": 69, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1425, + "end": 1427, + "replacementText": "x2: x2" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 81, - "column": 21, - "endLine": 81, - "endColumn": 22, - "problem": "ObjectLiteralNoContextType", + "line": 70, + "column": 3, + "endLine": 70, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1449, + "end": 1451, + "replacementText": "y2: y2" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 84, - "column": 17, - "endLine": 84, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", + "line": 71, + "column": 3, + "endLine": 71, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1473, + "end": 1475, + "replacementText": "z2: z2" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 85, - "column": 17, - "endLine": 85, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 9, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 90, - "column": 22, - "endLine": 90, - "endColumn": 23, - "problem": "ObjectLiteralNoContextType", + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 91, - "column": 19, - "endLine": 91, - "endColumn": 42, - "problem": "DestructuringParameter", + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "SpreadOperator", "suggest": "", - "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", "severity": "ERROR" }, { - "line": 91, - "column": 28, - "endLine": 91, - "endColumn": 29, + "line": 80, + "column": 12, + "endLine": 80, + "endColumn": 13, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 95, - "column": 13, - "endLine": 95, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "line": 81, + "column": 3, + "endLine": 83, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1599, + "end": 1599, + "replacementText": "class GeneratedObjectLiteralClass_5 implements I {\n m() {\n console.log(100);\n }\n}\n\n" + }, + { + "start": 1610, + "end": 1658, + "replacementText": "new GeneratedObjectLiteralClass_5()" + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 96, - "column": 13, - "endLine": 96, - "endColumn": 14, + "line": 91, + "column": 12, + "endLine": 91, + "endColumn": 13, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 99, - "column": 17, - "endLine": 99, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", + "line": 92, + "column": 3, + "endLine": 94, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1713, + "end": 1713, + "replacementText": "class GeneratedObjectLiteralClass_6 extends C {\n m(): void {\n console.log(300);\n }\n}\n\n" + }, + { + "start": 1724, + "end": 1778, + "replacementText": "new GeneratedObjectLiteralClass_6()" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 102, - "column": 13, - "endLine": 102, - "endColumn": 14, + "line": 98, + "column": 5, + "endLine": 98, + "endColumn": 6, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 102, - "column": 27, - "endLine": 102, + "line": 99, + "column": 3, + "endLine": 99, "endColumn": 28, - "problem": "ObjectLiteralNoContextType", + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1803, + "end": 1803, + "replacementText": "class GeneratedObjectLiteralClass_7 extends C {\n m() { console.log(300); } // Fixable\n}\n\n" + }, + { + "start": 1807, + "end": 1849, + "replacementText": "new GeneratedObjectLiteralClass_7()" + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1866, + "end": 1874, + "replacementText": "x2: number = 10;" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 102, - "column": 41, - "endLine": 102, - "endColumn": 42, - "problem": "ObjectLiteralNoContextType", + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1877, + "end": 1885, + "replacementText": "y2: number = 20;" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 105, - "column": 12, + "column": 3, "endLine": 105, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1888, + "end": 1896, + "replacementText": "z2: number = 30;" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 105, + "line": 109, "column": 14, - "endLine": 105, + "endLine": 109, "endColumn": 15, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 106, - "column": 13, - "endLine": 106, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 110, + "column": 3, + "endLine": 110, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1926, + "end": 1928, + "replacementText": "x2: x2" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 106, - "column": 15, - "endLine": 106, - "endColumn": 18, - "problem": "ComputedPropertyName", + "line": 111, + "column": 3, + "endLine": 111, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1943, + "end": 1945, + "replacementText": "y2: y2" + } + ], "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 107, - "column": 13, - "endLine": 107, - "endColumn": 14, + "line": 112, + "column": 3, + "endLine": 112, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1960, + "end": 1962, + "replacementText": "z2: z2" + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 3, + "endLine": 113, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1909, + "end": 1909, + "replacementText": "class GeneratedObjectLiteralClass_8 extends C2 {\n x2: number;\n y2: number;\n z2: number;\n constructor(init: GeneratedObjectLiteralInitInterface_8) {\n super();\n this.x2 = init.x2;\n this.y2 = init.y2;\n this.z2 = init.z2;\n }\n m() { console.log(1); } // Fixable\n}\n\ninterface GeneratedObjectLiteralInitInterface_8 {\n x2: number;\n y2: number;\n z2: number;\n}\n\n" + }, + { + "start": 1922, + "end": 2013, + "replacementText": "new GeneratedObjectLiteralClass_8({\n x2: x2,\n y2: y2,\n z2: z2\n})" + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 15, + "endLine": 116, + "endColumn": 16, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 107, - "column": 15, - "endLine": 107, - "endColumn": 25, - "problem": "ComputedPropertyName", + "line": 117, + "column": 3, + "endLine": 117, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 2034, + "end": 2036, + "replacementText": "x2: x2" + } + ], "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 109, - "column": 15, - "endLine": 109, - "endColumn": 18, - "problem": "AnyType", + "line": 118, + "column": 3, + "endLine": 118, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 2051, + "end": 2053, + "replacementText": "y2: y2" + } + ], "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 110, - "column": 13, - "endLine": 110, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 119, + "column": 3, + "endLine": 119, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 2068, + "end": 2070, + "replacementText": "z2: z2" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 113, - "column": 13, - "endLine": 113, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 120, + "column": 3, + "endLine": 120, + "endColumn": 26, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 114, - "column": 13, - "endLine": 114, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 114, - "column": 15, - "endLine": 114, - "endColumn": 20, + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, "problem": "SpreadOperator", "suggest": "", "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", "severity": "ERROR" }, { - "line": 115, - "column": 13, - "endLine": 115, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2200, + "end": 2208, + "replacementText": "x2: number = 10;" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 117, - "column": 13, - "endLine": 117, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2211, + "end": 2219, + "replacementText": "y2: number = 20;" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 120, - "column": 8, - "endLine": 120, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", + "line": 127, + "column": 3, + "endLine": 127, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2222, + "end": 2230, + "replacementText": "z2: number = 30;" + } + ], "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 130, + "line": 133, "column": 14, - "endLine": 130, + "endLine": 133, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -521,174 +829,360 @@ "severity": "ERROR" }, { - "line": 131, + "line": 134, + "column": 3, + "endLine": 134, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 2289, + "end": 2291, + "replacementText": "x2: x2" + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 3, + "endLine": 135, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 2306, + "end": 2308, + "replacementText": "y2: y2" + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 3, + "endLine": 136, + "endColumn": 5, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 2323, + "end": 2325, + "replacementText": "z2: z2" + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 3, + "endLine": 137, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 7, + "endLine": 141, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2469, + "end": 2474, + "replacementText": "a: number = 1" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, "column": 14, - "endLine": 131, - "endColumn": 15, + "endLine": 141, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2476, + "end": 2481, + "replacementText": "b: number = 2" + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 25, + "endLine": 142, + "endColumn": 26, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 132, - "column": 14, - "endLine": 132, - "endColumn": 15, + "line": 143, + "column": 5, + "endLine": 145, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 29, + "endLine": 148, + "endColumn": 30, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 134, - "column": 22, - "endLine": 134, - "endColumn": 23, + "line": 149, + "column": 5, + "endLine": 151, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 20, + "endLine": 154, + "endColumn": 21, "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 2741, + "end": 2781, + "replacementText": "interface LocalType {\n a: number;\n b: string;\n}" + } + ], "suggest": "", "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 135, - "column": 35, - "endLine": 135, - "endColumn": 36, + "line": 155, + "column": 33, + "endLine": 155, + "endColumn": 34, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 136, - "column": 14, - "endLine": 136, - "endColumn": 15, + "line": 156, + "column": 26, + "endLine": 156, + "endColumn": 27, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 139, - "column": 14, - "endLine": 139, - "endColumn": 15, - "problem": "ObjectLiteralNoContextType", + "line": 157, + "column": 5, + "endLine": 159, + "endColumn": 6, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 141, - "column": 14, - "endLine": 141, - "endColumn": 15, + "line": 161, + "column": 27, + "endLine": 161, + "endColumn": 28, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 141, - "column": 19, - "endLine": 141, - "endColumn": 29, - "problem": "ClassAsObject", + "line": 162, + "column": 5, + "endLine": 164, + "endColumn": 6, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "WARNING" + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" }, { - "line": 145, - "column": 26, - "endLine": 145, - "endColumn": 29, - "problem": "AnyType", + "line": 168, + "column": 27, + "endLine": 168, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 145, - "column": 33, - "endLine": 145, - "endColumn": 34, + "line": 169, + "column": 5, + "endLine": 171, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 14, + "endLine": 180, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 151, - "column": 35, - "endLine": 151, - "endColumn": 38, - "problem": "AnyType", + "line": 191, + "column": 3, + "endLine": 191, + "endColumn": 9, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 151, - "column": 42, - "endLine": 151, - "endColumn": 43, + "line": 198, + "column": 14, + "endLine": 198, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 160, - "column": 35, - "endLine": 160, - "endColumn": 38, - "problem": "AnyType", + "line": 209, + "column": 3, + "endLine": 209, + "endColumn": 9, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 160, - "column": 42, - "endLine": 160, - "endColumn": 43, + "line": 219, + "column": 18, + "endLine": 219, + "endColumn": 19, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 164, - "column": 5, - "endLine": 164, - "endColumn": 10, - "problem": "ComputedPropertyName", + "line": 220, + "column": 3, + "endLine": 220, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 4038, + "end": 4038, + "replacementText": "class GeneratedObjectLiteralClass_9 extends Derived {\n m() { console.log(2); }\n}\n\n" + }, + { + "start": 4055, + "end": 4095, + "replacementText": "new GeneratedObjectLiteralClass_9()" + } + ], "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 170, - "column": 28, - "endLine": 170, - "endColumn": 29, + "line": 229, + "column": 20, + "endLine": 229, + "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 171, - "column": 13, - "endLine": 171, - "endColumn": 14, + "line": 230, + "column": 3, + "endLine": 230, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 20, + "endLine": 243, + "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" + }, + { + "line": 244, + "column": 3, + "endLine": 244, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 4443, + "end": 4443, + "replacementText": "class GeneratedObjectLiteralClass_10 extends Derived3 {\n m() { console.log(2); }\n}\n\n" + }, + { + "start": 4462, + "end": 4502, + "replacementText": "new GeneratedObjectLiteralClass_10()" + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 3, + "endLine": 187, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.json b/ets2panda/linter/test/main/object_literals_properties.ets.json index f49a2e6be91dd6343b7307145784ad7f89c9aaf7..c8d9bf18dc81b732a67d5bb6570894fd796d4f76 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.json @@ -15,10 +15,30 @@ ], "result": [ { - "line": 23, - "column": 18, - "endLine": 23, - "endColumn": 19, + "line": 17, + "column": 14, + "endLine": 17, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", @@ -26,42 +46,262 @@ }, { "line": 33, - "column": 18, + "column": 17, "endLine": 33, - "endColumn": 19, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 36, - "column": 6, - "endLine": 36, - "endColumn": 7, + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 37, + "line": 40, "column": 3, - "endLine": 37, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "endLine": 40, + "endColumn": 15, + "problem": "SpreadOperator", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", "severity": "ERROR" }, { "line": 43, - "column": 3, + "column": 13, "endLine": 43, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 3, + "endLine": 73, "endColumn": 15, - "problem": "ComputedPropertyName", + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 12, + "endLine": 80, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 12, + "endLine": 91, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 5, + "endLine": 98, + "endColumn": 6, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 14, + "endLine": 109, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 15, + "endLine": 116, + "endColumn": 16, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 14, + "endLine": 133, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 25, + "endLine": 142, + "endColumn": 26, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 29, + "endLine": 148, + "endColumn": 30, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 20, + "endLine": 154, + "endColumn": 21, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 33, + "endLine": 155, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 156, + "column": 26, + "endLine": 156, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 27, + "endLine": 161, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 27, + "endLine": 168, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 14, + "endLine": 180, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 14, + "endLine": 198, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 219, + "column": 18, + "endLine": 219, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 229, + "column": 20, + "endLine": 229, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 20, + "endLine": 243, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 3, + "endLine": 187, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bbf9dbf43596f87971f1cbfc2187a676fbcb27c --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets @@ -0,0 +1,307 @@ +/* + * 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. + */ + +// Untyped object literals +class GeneratedObjectLiteralClass_1 { + m() { console.log(1); } // Error, fixable +} + +let method = new GeneratedObjectLiteralClass_1(); + +class GeneratedObjectLiteralClass_2 { + get property() { return 2; } // Error, fixable +} + +let getMethod = new GeneratedObjectLiteralClass_2(); + +class GeneratedObjectLiteralClass_3 { + set property(value: number) { + console.log(value); + } +} + +let setMethod = new GeneratedObjectLiteralClass_3(); + +let x: number = 1, y = '2', z = true; + +interface GeneratedObjectLiteralInterface_1 { + x: number; + y: string; + z: boolean; +} +let shorthand: GeneratedObjectLiteralInterface_1 = { + x: x, // Error, fixable + y: y, // Error, fixable + z: z // Error, fixable +}; + +let spread = { + ...shorthand // Error, not fixable +}; + +class GeneratedObjectLiteralClass_4 { + a: string; + b: number; + c: number[]; + x: number; + y: string; + constructor(init: GeneratedObjectLiteralInitInterface_4) { + this.a = init.a; + this.b = init.b; + this.c = init.c; + this.x = init.x; + this.y = init.y; + } + method() { + console.log(42); + } + get property() { + return 0; + } + set property(value: number) { + if (value < 0) { + throw new Error('Bad value'); + } + } +} + +interface GeneratedObjectLiteralInitInterface_4 { + a: string; + b: number; + c: number[]; + x: number; + y: string; +} + +let mixed = new GeneratedObjectLiteralClass_4({ + a: "foo", + b: 42, + c: [1, 2, 3], + x: x, + y: y +}); + +let x2: number = 1, y2: number = 2, z2: number = 3; +let mixedBad = { // Not fixable + a: 1, + b: 2, + x2: x2, // Error, fixable + y2: y2, // Error, fixable + z2: z2, // Error, fixable + m() {}, + ...shorthand // Error, not fixable +} + +// Typed object literals +interface I { + m(): void; +} +class GeneratedObjectLiteralClass_5 implements I { + m() { + console.log(100); + } +} + +let i: I = new GeneratedObjectLiteralClass_5(); + +class C { + m(): void { + console.log(200); + } +} +class GeneratedObjectLiteralClass_6 extends C { + m(): void { + console.log(300); + } +} + +let c: C = new GeneratedObjectLiteralClass_6(); + +function foo(c: C) {} +class GeneratedObjectLiteralClass_7 extends C { + m() { console.log(300); } // Fixable +} + +foo(new GeneratedObjectLiteralClass_7()); + +class C2 { + x2: number = 10; + y2: number = 20; + z2: number = 30; + + m() {} +} +class GeneratedObjectLiteralClass_8 extends C2 { + x2: number; + y2: number; + z2: number; + constructor(init: GeneratedObjectLiteralInitInterface_1) { + super(); + this.x2 = init.x2; + this.y2 = init.y2; + this.z2 = init.z2; + } + m() { console.log(1); } // Fixable +} + +interface GeneratedObjectLiteralInitInterface_1 { + x2: number; + y2: number; + z2: number; +} + +let c2: C2 = new GeneratedObjectLiteralClass_8({ + x2: x2, + y2: y2, + z2: z2 +}); + +let c22: C2 = { + x2: x2, // Fixable + y2: y2, // Fixable + z2: z2, // Fixable + m() { console.log(1); }, // Not fixable, object has spread property + ...shorthand // Not fixable +}; + +class C3 { + x2: number = 10; + y2: number = 20; + z2: number = 30; + + m() {} + + constructor(a: number) {} +} +let c3: C3 = { + x2: x2, // Fixable + y2: y2, // Fixable + z2: z2, // Fixable + m() { console.log(1); } // Not fixable, class type has constructor with parameters +}; + +function capturesFromLocalScope() { + let a: number = 1, b: number = 2; + let captureLocalVal = { + m() { // Not fixable, captures local values 'a' and 'b' + console.log(a, b); + } + }; + + let captureLocalVal2: C = { + m(): void { // Not fixable, captures local values 'a' and 'b' + console.log(a, b); + } + }; + + interface LocalType { + a: number; + b: string; +} + let localTypeVar: LocalType = { a: 1, b: '2' }; + let captureLocalType = { + m() { // Not fixable, captures value of type `LocalType` declared in local scope + console.log(localTypeVar); + } + }; + let captureLocalType2 = { + m(x: LocalType) { // Not fixable, `x` references type `LocalType` declared in local scope + console.log(x); + } + }; + + class LocalClass { x: number = 1 }; + let captureLocalType3 = { + m() { // Not fixable, references type `LocalClass` declared in local scope + console.log(new LocalClass()); + } + }; +} + +// Method overriding field +class C4 { + a: number = 0; + b() {}; +} +let c4: C4 = { // Not fixable, overrides class method with property of functional type + a: 1, + b: () => {} +}; + +class C5 { + a: number = 0; + b: () => void; +} +let c5: C5 = { // Not fixable, overrides class property with method + a: 1, + b() {} +}; + +interface I2 { + a: number; + b(): void; +} +let i2: I2 = { // Not fixable, implements method as functional-type property + a: 1, + b: () => {} +}; + +interface I3 { + a: number; + b: () => void; +} +let ii: I3 = { // Not fixable, implements functional-type property as a method + a: 1, + b() {} +}; + +// Inheritance +class Base { + constructor() {} +} +class Derived extends Base { + m() {} +} +class GeneratedObjectLiteralClass_9 extends Derived { + m() { console.log(2); } +} + +let b: Derived = new GeneratedObjectLiteralClass_9(); + +class Base2 { + constructor(a: number) {} +} +class Derived2 extends Base2 { + m() {} +} +let b2: Derived2 = { // Not fixable, derived class inherits a constructor with parameters from base class + m() { console.log(2); } +}; + +class Base3 { + constructor(a: number) {} +} +class Derived3 extends Base3 { + m() {} + + constructor() { + super(1); + } +} +class GeneratedObjectLiteralClass_10 extends Derived3 { + m() { console.log(2); } +} + +let b3: Derived3 = new GeneratedObjectLiteralClass_10(); \ 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 new file mode 100644 index 0000000000000000000000000000000000000000..05c3a0ea0afabb5997a61e67a3313ab008a370a8 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json @@ -0,0 +1,318 @@ +{ + "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": 50, + "column": 14, + "endLine": 50, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 3, + "endLine": 51, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 3, + "endLine": 51, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 16, + "endLine": 97, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 15, + "endLine": 171, + "endColumn": 16, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 3, + "endLine": 175, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 3, + "endLine": 176, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 3, + "endLine": 176, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 188, + "column": 14, + "endLine": 188, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 192, + "column": 3, + "endLine": 192, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 25, + "endLine": 197, + "endColumn": 26, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 5, + "endLine": 200, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 29, + "endLine": 203, + "endColumn": 30, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 204, + "column": 5, + "endLine": 206, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 214, + "column": 26, + "endLine": 214, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 215, + "column": 5, + "endLine": 217, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 219, + "column": 27, + "endLine": 219, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 5, + "endLine": 222, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 226, + "column": 27, + "endLine": 226, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 227, + "column": 5, + "endLine": 229, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 238, + "column": 14, + "endLine": 238, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 249, + "column": 3, + "endLine": 249, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 256, + "column": 14, + "endLine": 256, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 267, + "column": 3, + "endLine": 267, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 289, + "column": 20, + "endLine": 289, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 290, + "column": 3, + "endLine": 290, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 245, + "column": 3, + "endLine": 245, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_spread.ets.args.json b/ets2panda/linter/test/main/object_spread.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_spread.ets.args.json +++ b/ets2panda/linter/test/main/object_spread.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/test/parser/ets/user_defined_2.ets b/ets2panda/linter/test/main/object_spread.ets.migrate.ets similarity index 68% rename from ets2panda/test/parser/ets/user_defined_2.ets rename to ets2panda/linter/test/main/object_spread.ets.migrate.ets index a85d431332a89622fb6f092d47499538ddf539d0..0925345ec75f9e3f93949e9a4753fcfcdd9d9c0c 100644 --- a/ets2panda/test/parser/ets/user_defined_2.ets +++ b/ets2panda/linter/test/main/object_spread.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * 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 @@ -13,13 +13,14 @@ * limitations under the License. */ -function main() { - let float : float; - let boolean : boolean; - let double : double; - let byte : byte; - let short : short; - let int : int; - let char : char; - let long : long; +interface GeneratedObjectLiteralInterface_1 { + x: number; + y: number; } +const pt2D: GeneratedObjectLiteralInterface_1 = { x: 1, y: 2 }; + +console.log(pt2D); + +const pt3D = { ...pt2D, z: 3 }; + +console.log(pt3D); diff --git a/ets2panda/linter/test/main/object_spread.ets.migrate.json b/ets2panda/linter/test/main/object_spread.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..b1bad3882fd487054e27edcac38ef174bb8b4684 --- /dev/null +++ b/ets2panda/linter/test/main/object_spread.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 24, + "column": 14, + "endLine": 24, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 23, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@arkts.collections.d.ets b/ets2panda/linter/test/main/oh_modules/@arkts.collections.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..f54a1fd4d6e9776e65d68aeb141b9e54d5163559 --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@arkts.collections.d.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +export namespace collections { + export class Array implements ConcatArray { + constructor(); + } + + export class Map { + constructor(entries?: readonly (readonly [K, V])[] | null); + } + + export interface ConcatArray { + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets b/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..df9184137493b52f8f3387f4c5518985c9d24e5a --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +export namespace utils { + namespace ASON { + function stringify(value: Object | null | undefined): string; + } +} + +export default utils; \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets b/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd994ead622471b25a9e0e8a233865d567fac6b4 --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ + +export { worker } from '../oh_modules/@ohos.worker'; +export { collections } from '../oh_modules/@arkts.collections'; +export { utils } from '../oh_modules/@arkts.utils'; +export { taskpool } from '../oh_modules/@ohos.taskpool'; \ No newline at end of file diff --git a/ets2panda/linter/test/interop/oh_modules/reflect_export_safe.ets b/ets2panda/linter/test/main/oh_modules/@ohos.taskpool.d.ets similarity index 80% rename from ets2panda/linter/test/interop/oh_modules/reflect_export_safe.ets rename to ets2panda/linter/test/main/oh_modules/@ohos.taskpool.d.ets index 64ac6ea76a5f674eb375505d74e6a7f8f19c2322..f727b78f7a23e2d0c034d02fe71aef9d9c045d36 100644 --- a/ets2panda/linter/test/interop/oh_modules/reflect_export_safe.ets +++ b/ets2panda/linter/test/main/oh_modules/@ohos.taskpool.d.ets @@ -13,8 +13,6 @@ * limitations under the License. */ -export function safeVersion(prx: Object) { - Reflect.get(prx, 'a') // 'hello' - Reflect.set(prx, 'a', 'world') // true - Reflect.ownKeys(prx) // ['a'] +export namespace taskpool { + export const isConcurrent: () => boolean; } \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@ohos.worker.d.ets b/ets2panda/linter/test/main/oh_modules/@ohos.worker.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..74748df41d8516a3b623e9d1778fc7e7690787cd --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@ohos.worker.d.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +export namespace worker { + export class ThreadWorker { + constructor(scriptURL: string, options?: WorkerOptions); + postMessage(message: any, transfer?: Transferable[]): void; + terminate(): void; + on(type: string, listener: (data: any) => void): void; + } + + export interface WorkerOptions { + type?: "classic" | "module"; + name?: string; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/parameter_properties.ets.args.json b/ets2panda/linter/test/main/parameter_properties.ets.args.json index 4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100644 --- a/ets2panda/linter/test/main/parameter_properties.ets.args.json +++ b/ets2panda/linter/test/main/parameter_properties.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/parameter_properties.ets.migrate.ets b/ets2panda/linter/test/main/parameter_properties.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6a79a113c46ed75c70c35b4dd9736eed54fd0979 --- /dev/null +++ b/ets2panda/linter/test/main/parameter_properties.ets.migrate.ets @@ -0,0 +1,147 @@ +/* + * 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. + */ + +class A { + public readonly x: number; +protected y: number; +private z: number; +constructor( + x: number, + y: number, + z: number + ) { + this.x = x; + this.y = y; + this.z = z; +} + + foo(): void { + console.log(this.x + this.y + this.z); + } +} + +const a = new A(1, 2, 3); +console.log(a.x); + +class B { + public f: number = 10; + + public w: string; +private readonly r: number[]; +constructor(q: number, w = 'default', e: boolean, r: number[] = [1, 2, 3]) { + this.w = w; + this.r = r; + console.log(q, this.w, e, this.r, this.f); +} +} + +const b = new B(1, '2', true, []); +console.log(b.w); + +class C { + constructor(public a: any) {} // not fixable +} + +interface GeneratedTypeLiteralInterface_1 { + x: string; +} +class D { + public a: number; +private b: GeneratedTypeLiteralInterface_1; +constructor(a: number, b: GeneratedTypeLiteralInterface_1) { + this.a = a; + this.b = b; +} // not fixable +} + +class E { + b: number = 0; + c: number = 0; + + readonly a: number; +constructor(a: number) { + this.a = a; +} +} + +class F extends E { + readonly aa: number; +b: number; +public c: number; +constructor( + aa: number, + b: number, + c: number + ){ + super(aa); + this.aa = aa; + this.b = b; + this.c = c; +} +} + +class F2 extends E { + readonly aa: number; +constructor(aa: number) { + let f2: number = 1; + console.log('before super() call'); + super(aa); + this.aa = aa; +} +} + +class F3 extends E { + readonly aa: number; +constructor(aa: number) { + super(aa); + this.aa = aa; + let f3: number = 1; + console.log('after super() call'); +} +} + +class F4 extends E { + readonly aa: number; +constructor(aa: number) { + let f4: number = 1; + console.log('before super() call'); + super(aa); + this.aa = aa; + console.log('after super() call'); + let f5: number = 1; +} +} + +class G { + constructor(a?: number) {} +} + +class G1 { + public a?: number; +public b: number; +constructor(a?: number, b: number) { + this.a = a; + this.b = b; +} +} + +class G2 { + public a?: number; +public b?: number; +constructor(a?: number, b?: number) { + this.a = a; + this.b = b; +} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/parameter_properties.ets.migrate.json b/ets2panda/linter/test/main/parameter_properties.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..03cac9f4e47f0a3b2f7cc5966991917f603ee4d0 --- /dev/null +++ b/ets2panda/linter/test/main/parameter_properties.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 54, + "column": 15, + "endLine": 54, + "endColumn": 21, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 25, + "endLine": 54, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/private_identifiers.ets.args.json b/ets2panda/linter/test/main/private_identifiers.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/private_identifiers.ets.args.json +++ b/ets2panda/linter/test/main/private_identifiers.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/private_identifiers.ets.migrate.ets b/ets2panda/linter/test/main/private_identifiers.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..001beccf210eebba407f1d00bc14b8846391f25f --- /dev/null +++ b/ets2panda/linter/test/main/private_identifiers.ets.migrate.ets @@ -0,0 +1,78 @@ +/* + * 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. + */ + +class C { + private p: number; + + p2: number; + #p2: string; // not fixable + + private q?: string; + private e!: string; + private static s = 0; + private readonly r = 20; + private static readonly sr = 0; + private static readonly srq?: string; + + private m(x: number): void { } + + m2(x: number): void {} + #m2(x: number): void {} // not fixable + + m3: boolean; + #m3(x: number): void {} // not fixable + + private get g1(): number { return 10; } + private set s1(x: number) { } + + private static get g2(): number { return 10; } + private static set s2(x: number) { } + + test() { + console.log(this.p + this.#p2 + this.q + this.e + C.s + this.r + C.sr + C.srq); // '#p2' is not fixable + this.m(10); + this.#m2(20); // not fixable + this.#m3(30); // not fixable + let x = this.g1; + this.s1 = x; + let y = C.g2; + C.s2 = y; + } +} + +class D extends C { + private a: string; + #p: number; // not fixable + + #m(): string { return 'foo'; } // not fixable + + private bar(): string { return 'baz'; } + + test() { + console.log(this.#p + this.a); // '#p' is not fixable + let x = this.#m(); // not fixable + let y = this.bar(); + } +} + +class E { + private a: number; + #b: string; // not fixable + + public b: number; +constructor(b: number) { + this.b = b; +} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/private_identifiers.ets.migrate.json b/ets2panda/linter/test/main/private_identifiers.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4b6bcee72005fd48c5985cc177fe2dad249d7a20 --- /dev/null +++ b/ets2panda/linter/test/main/private_identifiers.ets.migrate.json @@ -0,0 +1,318 @@ +{ + "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": 3, + "endLine": 19, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 6, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 6, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 6, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 6, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 22, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 6, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 6, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 31, + "endLine": 44, + "endColumn": 34, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 13, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 10, + "endLine": 47, + "endColumn": 13, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 5, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 22, + "endLine": 64, + "endColumn": 24, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 18, + "endLine": 65, + "endColumn": 20, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 10, + "endLine": 74, + "endColumn": 11, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 5, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 11, + "endLine": 17, + "endColumn": 12, + "problem": "StrictDiagnostic", + "suggest": "Property 'p' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'p' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'p2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'p2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property '#p2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '#p2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'm3' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'm3' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 56, + "column": 11, + "endLine": 56, + "endColumn": 12, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property '#p' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '#p' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 71, + "column": 11, + "endLine": 71, + "endColumn": 12, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property '#b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '#b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f83645b5e8aa5d4df1227701293a81aa80a7897 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class User { + name: string = "" + age: number = 0 +} + +@Entry +@Component +struct FatherComponent { + @Prop user1: User = new User() + @StorageLink("user2") user2: User = new User() + @LocalStorageLink("user3") user3: User = new User() + + build() { + } +} + +@Component +struct ChildComponent { + @StorageProp("user2") user2: User = new User() + @LocalStorageProp("user3") user3: User = new User() + + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.args.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.arkts2.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..eda4a3c782419fa3f42038746047f40637c8b8ec --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.arkts2.json @@ -0,0 +1,128 @@ +{ + "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": 24, + "column": 3, + "endLine": 24, + "endColumn": 33, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 49, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 54, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 4, + "endLine": 24, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 4, + "endLine": 25, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 20, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 4, + "endLine": 34, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 4, + "endLine": 35, + "endColumn": 20, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..f218bde1db65360c1d8e33e6bebc75814dded0a9 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets @@ -0,0 +1,49 @@ +/* + * 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. + */ + +class MyClassA { + +} + +let para: Record = { 'PropA': 47 } +let storage: LocalStorage = new LocalStorage(para) +let prop1 = storage.prop('PropA') +let prop2 = storage.prop('PropA') +let prop3 = storage.prop('PropA') +let prop4: SubscribedAbstractProperty = storage.prop('PropA') +let prop5: SubscribedAbstractProperty = storage.prop('PropA') +let prop6: SubscribedAbstractProperty = storage.prop('PropA') + +AppStorage.SetOrCreate('PropB', 46) +let prop7 = AppStorage.prop('PropB') +let prop8 = AppStorage.prop('PropB') +let prop9 = AppStorage.prop('PropB') +let prop10: SubscribedAbstractProperty = AppStorage.prop('PropB') +let prop11: SubscribedAbstractProperty = AppStorage.prop('PropB') +let prop12: SubscribedAbstractProperty = AppStorage.prop('PropB') + +@Entry +@Component +struct MyComponent { + + aboutToAppear(): void { + let storage = LocalStorage.getShared() + let prop1 = storage.prop('PropA') + let prop2: SubscribedAbstractProperty = storage.prop('PropA') + } + + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.args.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.arkts2.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..a34c53714857c59f1233360467e425e46bc04227 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.arkts2.json @@ -0,0 +1,448 @@ +{ + "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": 21, + "column": 33, + "endLine": 21, + "endColumn": 45, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 42, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 42, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 44, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 53, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 70, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 72, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 81, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 45, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 45, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 45, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 47, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 56, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 74, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 76, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 85, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 52, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 13, + "endLine": 44, + "endColumn": 80, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 14, + "endLine": 21, + "endColumn": 26, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 33, + "endLine": 21, + "endColumn": 45, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 12, + "endLine": 25, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 12, + "endLine": 26, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 13, + "endLine": 31, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 13, + "endLine": 33, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 50, + "endLine": 33, + "endColumn": 60, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 13, + "endLine": 34, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 52, + "endLine": 34, + "endColumn": 62, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 61, + "endLine": 35, + "endColumn": 71, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 2, + "endLine": 37, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 2, + "endLine": 38, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 23, + "endLine": 42, + "endColumn": 35, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 20, + "endLine": 44, + "endColumn": 46, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..897276b6ebb2bfcd6175508d9288d7154b6a58a1 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.json @@ -0,0 +1,98 @@ +{ + "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": 22, + "column": 5, + "endLine": 22, + "endColumn": 42, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 45, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..5a75d8e00d8979f2a84a8fd4ec69e4e3899dfff0 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets @@ -0,0 +1,59 @@ +/* + * 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. + */1q + +class MyClassA { + +} + +class MyClassB { + +} + +function getClass1 { + let a = new MyClassA() + + if (1 > 0) { + return new MyClassB() + } else { + return a + } +} + +function getClass2 { + if (1 > 0) { + return 1 + } else { + return new MyClassA() + } +} + +let para: Record = { 'PropA': 47 } +let storage: LocalStorage = new LocalStorage(para) +let prop1 = storage.setAndProp('PropA', getClass1()) +let prop2 = storage.setAndProp('PropA', getClass2()) +let prop3 = storage.setAndProp('PropA', {name: "jack", age: 2}) +let prop4 = storage.setAndProp('PropA', 1 > 0 ? 1 : getClass1()) +let prop5 = storage.setAndProp('PropA', 1 > 0 ? {name: "jack"} : "test") +let prop6 = storage.setAndProp('PropA', new MyClassA()) +let prop7 = storage.setAndProp('PropA', 1) +let prop8 = storage.setAndProp('PropA', "test") +let prop9 = storage.setAndProp('PropA', true) + +@Entry +@Component +struct MyComponent { + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.args.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.arkts2.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..aae50874a93b096af39198a74ec4c1311c7aeb9e --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.arkts2.json @@ -0,0 +1,248 @@ +{ + "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": 43, + "column": 33, + "endLine": 43, + "endColumn": 45, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 53, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 53, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 64, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 64, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 65, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 65, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 73, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 73, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 56, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 43, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 48, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 48, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 46, + "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "suggest": "", + "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 46, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 14, + "endLine": 43, + "endColumn": 26, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 33, + "endLine": 43, + "endColumn": 45, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 2, + "endLine": 54, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 2, + "endLine": 55, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..de7a4258a1f6b8da812a9b2a4c008c68ffd109f1 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.json @@ -0,0 +1,108 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 64, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 65, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 73, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 48, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 46, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_name_from_value.ets b/ets2panda/linter/test/main/prop_name_from_value.ets new file mode 100644 index 0000000000000000000000000000000000000000..bdfdc1a80d5529ad17bdec94f11f1a0e7e493de8 --- /dev/null +++ b/ets2panda/linter/test/main/prop_name_from_value.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +enum TEST { + A, + B, + C +} +const arr = ['a', 'b', 'c']; + +const val = TEST[1]; +const value: number = TEST.A; //legal +const arrVal = arr[1]; //legal \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_name_from_value.ets.args.json b/ets2panda/linter/test/main/prop_name_from_value.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/prop_name_from_value.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/migrate/class_static_block.ts.json b/ets2panda/linter/test/main/prop_name_from_value.ets.arkts2.json similarity index 73% rename from ets2panda/linter/test/migrate/class_static_block.ts.json rename to ets2panda/linter/test/main/prop_name_from_value.ets.arkts2.json index 487f1000c4583c3b0507ec169649e62827b942cb..4218268d314b5d23e17b0cb47ab709da3f410059 100644 --- a/ets2panda/linter/test/migrate/class_static_block.ts.json +++ b/ets2panda/linter/test/main/prop_name_from_value.ets.arkts2.json @@ -1,10 +1,12 @@ { "copyright": [ - "Copyright (c) 2022-2024 Huawei Device Co., Ltd.", + "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.", @@ -14,12 +16,12 @@ "result": [ { "line": 23, - "column": 3, + "column": 13, "endLine": 23, - "endColumn": 9, - "problem": "MultipleStaticBlocks", + "endColumn": 20, + "problem": "UnsupportPropNameFromValue", "suggest": "", - "rule": "Only one static block is supported (arkts-no-multiple-static-blocks)", + "rule": "Enum cannot get member name by member value (arkts-unsupport-prop-name-from-value)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/prop_name_from_value.ets.json b/ets2panda/linter/test/main/prop_name_from_value.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/prop_name_from_value.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/property_access_by_index.ets.args.json b/ets2panda/linter/test/main/property_access_by_index.ets.args.json index a830284339c398efecc87cc656cada022d6db5c4..7341e330faa243cfdd4795226601488b62c2f729 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets.args.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -15,6 +15,7 @@ ], "mode": { "autofix": "", - "arkts2": "" + "arkts2": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/property_access_by_index.ets.arkts2.json b/ets2panda/linter/test/main/property_access_by_index.ets.arkts2.json index 7fd2c9eac2ad5e1904127c7f0332f01322fcde8a..ea96b93ba8af3b0c1fad7546875a92aea9916318 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets.arkts2.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.arkts2.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, { "line": 22, "column": 3, @@ -134,6 +144,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 107, + "column": 24, + "endLine": 107, + "endColumn": 39, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, { "line": 108, "column": 5, @@ -174,6 +194,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 117, + "column": 20, + "endLine": 117, + "endColumn": 35, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, { "line": 118, "column": 5, @@ -204,6 +234,16 @@ "rule": "Avoid using union types (arkts-common-union-member-access)", "severity": "ERROR" }, + { + "line": 139, + "column": 12, + "endLine": 139, + "endColumn": 31, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, { "line": 159, "column": 3, @@ -245,13 +285,13 @@ "severity": "ERROR" }, { - "line": 176, - "column": 1, - "endLine": 176, - "endColumn": 10, - "problem": "LimitedStdLibApi", + "line": 177, + "column": 23, + "endLine": 177, + "endColumn": 34, + "problem": "NoNeedStdLibSendableContainer", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", "severity": "ERROR" }, { @@ -265,4 +305,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a19d0154802a6a02c685d077909c66a95a19c687 --- /dev/null +++ b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets @@ -0,0 +1,184 @@ +/* + * 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. + */ +import {OhosInterface} from './oh_modules/ohos_lib'; +import { collections } from './@arkts.collections'; +// #14071 +class A { + v: string = ''; +} +function SetProperty(oldObj: T, str: string, obj: Object): void { + oldObj[str] = obj; // Should report error +} +function GetProperty(oldObj: T, str: string): U { + return oldObj[str]; // Should report error +} +function test() { + let a: A = { v: 'abc' }; + SetProperty(a, 'u', 'def'); + return GetProperty(a, 'v') + GetProperty(a, 'u'); +} + +let ar1 = [1, 2, 3, 4]; +let ar2 = [1, '2', 3, 4]; +let ar3: number[] = []; + +ar1[2]; +ar2[2]; +ar3[2]; + +const r0 = [1, 2, 3][1]; +let r1 = [1, 2, 3, 4][0] +let r2 = [1, '2', 3, 4][0] + +function fobject1(o: object) { + o['j'] +} + +function fobject2(o: Object) { + o['k'] +} + +let array1 = [0,1] +let array2 = [1,2,3,4,5] +let array3: number[] = [1,2,3,4,5] +let array4: Array = [1,2,3,4,5] +let array5 = new Array(10) +let array6 = new Int8Array(10) +let array7 = new Uint8Array(10) +let array8 = new Uint8ClampedArray(10) +let array9 = new Int16Array(10) +let array10 = new Uint16Array(10) +let array11 = new Int32Array(10) +let array12 = new Uint32Array(10) +let array13 = new Float32Array(10) +let array14 = new Float64Array(10) +let array15 = new BigInt64Array(10) +let array16 = new BigUint64Array(10) + +array1[0]; +array2[0]; +array3[0]; +array4[0]; +array5[0]; +array6[0]; +array7[0]; +array8[0]; +array9[0]; +array10[0]; +array11[0]; +array12[0]; +array13[0]; +array14[0]; +array15[0]; +array16[0]; + +function fff1(r: Record) { + r['bob'] +} + +enum CCCCCCCCC { + KATE, + BOB, + ROB, +} + +CCCCCCCCC['KATE'] +CCCCCCCCC['BOB'] +CCCCCCCCC['ROB'] + +CCCCCCCCC[CCCCCCCCC.KATE] +CCCCCCCCC[CCCCCCCCC.BOB] +CCCCCCCCC[CCCCCCCCC.ROB] + +let arr32 = new Float32Array([1,2,3]) + +let iter_arr32 = arr32[Symbol.iterator]() +let tmp_arr32 = iter_arr32.next().value; +while (!!tmp_arr32) { + console.log(tmp_arr32[0]) + + tmp_arr32 = iter_arr32.next().value +} + +let arr = new Array() +arr = ['a','f','g'] +let iter_arr = arr[Symbol.iterator]() +let tmp_arr = iter_arr.next().value; +while (!!tmp_arr) { + console.log(tmp_arr[0]) + tmp_arr = iter_arr.next().value +} + +// #14415 +class ArrayContainer { + numbers: number[] = []; +} +class NullableArray { + container: ArrayContainer | null = null; + + print() { + console.log(this.container?.numbers[0]); + } +} + +let str1 = 'sssss' +let str2 = "aaaaa" +let str3 = `sssss` +let str4 = new String('sssss') +let str5 = str1 +let str6 = str2 + +str1[1] +str2[1] +str3[1] +str4[1] +str5[1] +str6[1] + +class AString extends String {} +let str7 = new AString('dwdd') +str7[1] + +type IndexableUnion = string[] | (number | string)[] | Uint8Array; +type NonIndexableUnion = string[] | number[] | Uint8Array | number; + +function indexUnion(iu: IndexableUnion, niu: NonIndexableUnion) { + iu[0]; + niu[0]; +} + +function testLibraryUnnamedType(a: OhosInterface) { + a['kek']; +} + +class MMap extends Map {} + +let mmap1 = new Map(); +let mmap2 = new Map(); +let mmap3 = new MMap(); + +mmap1[1]; +mmap2['222']; +mmap3["kkr"]; + +@Sendable +class MyClass extends collections.BitVector { + constructor() { + super(0); + for (let i = 0; i < this.length; i++) { + this[i] = 1; + } + } +} diff --git a/ets2panda/linter/test/main/property_access_by_index.ts.arkts2.json b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.json similarity index 68% rename from ets2panda/linter/test/main/property_access_by_index.ts.arkts2.json rename to ets2panda/linter/test/main/property_access_by_index.ets.migrate.json index 610499fd9a153ebf2958618031d833763770078d..e700885404cdb3909d85aea7ff974569658ce43f 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ts.arkts2.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -34,16 +34,6 @@ "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, - { - "line": 46, - "column": 3, - "endLine": 46, - "endColumn": 9, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, { "line": 50, "column": 3, @@ -93,36 +83,6 @@ "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" - }, - { - "line": 172, - "column": 1, - "endLine": 172, - "endColumn": 9, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 173, - "column": 1, - "endLine": 173, - "endColumn": 13, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 174, - "column": 1, - "endLine": 174, - "endColumn": 13, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/property_decl_on_function.ets.arkts2.json b/ets2panda/linter/test/main/property_decl_on_function.ets.arkts2.json index f7836beb5261edcd119bbac7caa60111c4a6d4ec..4f28f1e680d44222a9f7e780440b1c69f6cb6254 100644 --- a/ets2panda/linter/test/main/property_decl_on_function.ets.arkts2.json +++ b/ets2panda/linter/test/main/property_decl_on_function.ets.arkts2.json @@ -184,16 +184,6 @@ "rule": "Declaring properties on functions is not supported (arkts-no-func-props)", "severity": "ERROR" }, - { - "line": 48, - "column": 16, - "endLine": 48, - "endColumn": 24, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 52, "column": 13, diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets b/ets2panda/linter/test/main/provide_annotation_1.ets index 6eebfb8e65070fb47748dcf873d292edaf8068c4..6ef3ea67563dac6af76c8baffbfb64cc69395a02 100644 --- a/ets2panda/linter/test/main/provide_annotation_1.ets +++ b/ets2panda/linter/test/main/provide_annotation_1.ets @@ -1,44 +1,44 @@ -/* - * 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. - */ - -@Component -struct Index { - @Provide - value: number; - build() { - Column() { - } - } -} - -@Component -struct Index { - @Provide("value") - value: number; - build() { - Column() { - } - } -} - -@Component -struct Index { - @Provide({allowOverride: "value"}) - value: number; - build() { - Column() { - } - } +/* + * 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. + */ + +@Component +struct Index { + @Provide + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide("value") + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({allowOverride: "value"}) + value: number; + build() { + Column() { + } + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.args.json b/ets2panda/linter/test/main/provide_annotation_1.ets.args.json index 40bac500e37ee9b8de610a9bd90a1128e2bec858..b023016d6bc3b2713d4e02b6f765940828db476b 100644 --- a/ets2panda/linter/test/main/provide_annotation_1.ets.args.json +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json b/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json index 73e8de4b45dd65e8cdf506562286dfbbb0329dae..499fa5b2964077f05d7b44e759e4cc617cc850c0 100644 --- a/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json @@ -22,8 +22,8 @@ "problem": "ProvideAnnotation", "autofix": [ { - "start": 754, - "end": 771, + "start": 727, + "end": 744, "replacementText": "@Provide({ alias: \"value\" })" } ], @@ -39,8 +39,8 @@ "problem": "ProvideAnnotation", "autofix": [ { - "start": 867, - "end": 901, + "start": 830, + "end": 864, "replacementText": "@Provide({ alias: \"value\", allowOverride: true })" } ], @@ -56,8 +56,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -73,8 +73,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -90,8 +90,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -107,8 +107,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -124,8 +124,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -141,8 +141,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -158,8 +158,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -175,8 +175,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -192,8 +192,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba3e7877529a70f08c4e368f72f937afb629de7e --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, Provide, Column } from '@kit.ArkUI'; + +@Component +struct Index { + @Provide + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value" }) + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value", allowOverride: true }) + value: number; + build() { + Column() { + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..2817e72894d499711b29674c52d22fb304b2bd01 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json @@ -0,0 +1,48 @@ +{ + "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": 21, + "column": 3, + "endLine": 21, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 41, + "column": 3, + "endLine": 41, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets b/ets2panda/linter/test/main/provide_annotation_2.ets index a3d3e3bb355cbb5fd0b1e88ec4915dc5a352e0c5..bddf1e72c0a37b914608dab6842cfdb253adba23 100644 --- a/ets2panda/linter/test/main/provide_annotation_2.ets +++ b/ets2panda/linter/test/main/provide_annotation_2.ets @@ -1,44 +1,44 @@ -/* - * 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. - */ - -@Component -struct Index { - @Provide - value: number; - build() { - Column() { - } - } -} - -@Component -struct Index { - @Provide({ alias: "value" }) - value: number; - build() { - Column() { - } - } -} - -@Component -struct Index { - @Provide({ alias: "value", allowOverride: true }) - value: number; - build() { - Column() { - } - } +/* + * 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. + */ + +@Component +struct Index { + @Provide + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value" }) + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value", allowOverride: true }) + value: number; + build() { + Column() { + } + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.args.json b/ets2panda/linter/test/main/provide_annotation_2.ets.args.json index 40bac500e37ee9b8de610a9bd90a1128e2bec858..b023016d6bc3b2713d4e02b6f765940828db476b 100644 --- a/ets2panda/linter/test/main/provide_annotation_2.ets.args.json +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json b/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json index 4db8f1e8f2998968cc37a0f0226e259e91d4ca01..f828839e124ace4ad3d38b7f2893c16b7f4d09d7 100644 --- a/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json @@ -22,8 +22,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -39,8 +39,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -56,8 +56,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -73,8 +73,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -90,8 +90,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -107,8 +107,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -124,8 +124,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -141,8 +141,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], @@ -158,8 +158,8 @@ "problem": "UIInterfaceImport", "autofix": [ { - "start": 616, - "end": 616, + "start": 603, + "end": 603, "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" } ], diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba3e7877529a70f08c4e368f72f937afb629de7e --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, Provide, Column } from '@kit.ArkUI'; + +@Component +struct Index { + @Provide + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value" }) + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value", allowOverride: true }) + value: number; + build() { + Column() { + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..2817e72894d499711b29674c52d22fb304b2bd01 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json @@ -0,0 +1,48 @@ +{ + "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": 21, + "column": 3, + "endLine": 21, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 41, + "column": 3, + "endLine": 41, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "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 new file mode 100644 index 0000000000000000000000000000000000000000..435c6ac0e6817708630365cdac50f50fdb0b8e78 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.ets @@ -0,0 +1,90 @@ +/* + * 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. + */ +'use static' + +const arr: int[] = [1, 2, 3, 4]; + +for (let i = 0; i < arr.length; i++) { + arr[i]; //legal +} + +for (let i = 0; i < 100; i++) { + console.log(i); //legal +} + +const arr2: int[] = [1, 2, 3, 4]; +for (let i = 0; i < 100; i++) { + arr2[10] //should report +} + +const arr3: int[] = [1, 2, 3, 4]; +for (let i = 0; i < arr3.length; i++) { + arr3[10] //should report +} + +const arr4: int[] = [1, 2, 3, 4]; +let x: int = 3; +for (let i = 0; i < arr4.length; i++) { + arr4[x]; //should report +} + +const arr5: int[] = [1, 2, 3, 4]; +for (let i = 0; i < 10; i++) { + arr5[i]; //should report +} + + +const arr6: int[] = [1, 2, 3, 4]; +if (arr6.length > 10) { + arr6[10] +} + +const arr7: int[] = [1, 2, 3, 4]; +if (arr7.length > 10) { + return; +} + +arr7[10] + +const arr8: int[] = [1, 2, 3, 4]; +const index: int = 9; +if (arr8.length > 10 && index > 0) { + return; +} + +arr8[index]; + +const arr9: int[] = [1, 2, 3, 4]; +if (arr9.length > 10 && index > 0) { + arr9[index]; +} + +const arr10: int[] = [1, 2, 3, 4]; +if (index > 0) { + arr10[index]; +} + +const arr10: int[] = [1, 2, 3, 4]; +let newIndex = 10; +if (arr10.length > newIndex) { + return; +} + +newIndex = 22; + +arr10[newIndex]; + + + diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.args.json b/ets2panda/linter/test/main/runtime_array_bound.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..8a4be28991e8164c0366b8b3ad0dffbc04910a27 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.args.json @@ -0,0 +1,20 @@ +{ + "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": "", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json b/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..134de695ab064c209275b6d0d13585cd29425c75 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.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": 19, + "column": 10, + "endLine": 19, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 10, + "endLine": 23, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 10, + "endLine": 28, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 10, + "endLine": 39, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 5, + "endLine": 76, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.json b/ets2panda/linter/test/main/runtime_array_bound.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd1b7140ca95b67336908f5fca6dec77fb46b2c0 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.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/runtime_array_bound.ets.migrate.ets b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..261214843c9393f03bfda1d5d7f9dcb868660b31 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets @@ -0,0 +1,90 @@ +/* + * 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. + */ +'use static' + +const arr: int[] = [1, 2, 3, 4]; + +for (let i: number = 0; i < arr.length; i++) { + arr[i]; //legal +} + +for (let i: number = 0; i < 100; i++) { + console.log(i); //legal +} + +const arr2: int[] = [1, 2, 3, 4]; +for (let i: number = 0; i < 100; i++) { + arr2[10] //should report +} + +const arr3: int[] = [1, 2, 3, 4]; +for (let i: number = 0; i < arr3.length; i++) { + arr3[10] //should report +} + +const arr4: int[] = [1, 2, 3, 4]; +let x: int = 3; +for (let i: number = 0; i < arr4.length; i++) { + arr4[x]; //should report +} + +const arr5: int[] = [1, 2, 3, 4]; +for (let i: number = 0; i < 10; i++) { + arr5[i]; //should report +} + + +const arr6: int[] = [1, 2, 3, 4]; +if (arr6.length > 10) { + arr6[10] +} + +const arr7: int[] = [1, 2, 3, 4]; +if (arr7.length > 10) { + return; +} + +arr7[10] + +const arr8: int[] = [1, 2, 3, 4]; +const index: int = 9; +if (arr8.length > 10 && index > 0) { + return; +} + +arr8[index]; + +const arr9: int[] = [1, 2, 3, 4]; +if (arr9.length > 10 && index > 0) { + arr9[index]; +} + +const arr10: int[] = [1, 2, 3, 4]; +if (index > 0) { + arr10[index]; +} + +const arr10: int[] = [1, 2, 3, 4]; +let newIndex: number = 10; +if (arr10.length > newIndex) { + return; +} + +newIndex = 22; + +arr10[newIndex]; + + + diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d472b1c6cc9d61f69619525ff8267eee0e555d22 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json @@ -0,0 +1,98 @@ +{ + "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": 29, + "column": 5, + "endLine": 29, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 5, + "endLine": 76, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/sendable_class_inheritance.ets.args.json b/ets2panda/linter/test/main/sendable_class_inheritance.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_class_inheritance.ets.args.json +++ b/ets2panda/linter/test/main/sendable_class_inheritance.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.ets b/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..34b7339258a705bb7d30797ea73f4547782e7591 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.ets @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + sendableClassA, + sendableVar, + nonSendableClassB, + nonSendableVar, + sendableInterface, + nonSendableInterface, + lang, +} from './@arkts.lang'; + +// sendable class +@Sendable +class localSendableClassA {} + +// sendable class var +let localSendableVar = localSendableClassA + + +// non-sendable class +class localNonSendableClassB {} + +// non-sendable class var +let localNonSendableVar = localNonSendableClassB + +// sendable interface +interface localSendableInterface extends lang.ISendable {} + +// non-sendable interface +interface localNonSendableInterface {} + +// sendable interface type alias +type localSendableInterfaceAlias = localSendableInterface + +// non-sendable interface type alias +type localNonSendableInterfaceAlias = localNonSendableInterface + +// left: sendable class + +// class + class + +// case1: extends import var +// == case1.1: extends sendable +@Sendable +class sendableClass1 extends sendableVar {} // ERROR + +// == case1.2: extends non-sendable +@Sendable +class sendableClass2 extends nonSendableVar {} // ERROR + +// case2: extends local var +// == case2.1: extends sendable +@Sendable +class sendableClass3 extends localSendableVar {} // ERROR + +// == case2.2: extends non-sendable +@Sendable +class sendableClass4 extends localNonSendableVar {} // ERROR + +// case3: extends import class +// == case3.1: extends sendable +@Sendable +class sendableClass5 extends sendableClassA {} // OK + +// == case3.2: extends non-sendable +@Sendable +class sendableClass6 extends nonSendableClassB {} // ERROR + +// case4: extends local class +// == case4.1: extends sendable +@Sendable +class sendableClass7 extends localSendableClassA {} // OK + +// == case4.2: extends non-sendable +@Sendable +class sendableClass8 extends localNonSendableClassB {} // ERROR + +// class + interface + +// case1: implements local interface +// == case1.1: implements sendable +@Sendable +class sendableClass9 implements localSendableInterface {} // OK + +// == case1.2: implements non-sendable +@Sendable +class sendableClass10 implements localNonSendableInterface {} // OK + +// case2: implements import interface +// == case2.1: implements sendable +@Sendable +class sendableClass11 implements sendableInterface {} // OK + +// == case2.2: implements non-sendable +@Sendable +class sendableClass12 implements nonSendableInterface {} // OK + +// case3: implements type alias +// == case3.1: implements sendable +@Sendable +class sendableClass13 implements localSendableInterfaceAlias {} // OK + +// == case3.2: implements non-sendable +@Sendable +class sendableClass14 implements localNonSendableInterfaceAlias {} // OK + +// left: non sendable class + +// case1: extends import var +// == case1.1: extends sendable +class sendableClass15 extends sendableVar {} // ERROR + +// == case1.2: extends non-sendable +class sendableClass16 extends nonSendableVar {} // OK + +// case2: extends local var +// == case2.1: extends sendable +class sendableClass17 extends localSendableVar {} // ERROR + +// == case2.2: extends non-sendable +class sendableClass18 extends localNonSendableVar {} // OK + +// case3: extends import class +// == case3.1: extends sendable +@Sendable +class sendableClass19 extends sendableClassA {} // ERROR + +// == case3.2: extends non-sendable +class sendableClass20 extends nonSendableClassB {} // OK + +// case4: extends local class +// == case4.1: extends sendable +@Sendable +class sendableClass21 extends localSendableClassA {} // ERROR + +// == case4.2: extends non-sendable +class sendableClass22 extends localNonSendableClassB {} // OK + +// class + interface + +// case1: implements local interface +// == case1.1: implements sendable +@Sendable +class sendableClass23 implements localSendableInterface {} // ERROR + +// == case1.2: implements non-sendable +class sendableClass24 implements localNonSendableInterface {} // OK + +// case2: implements import interface +// == case2.1: implements sendable +@Sendable +class sendableClass25 implements sendableInterface {} // ERROR + +// == case2.2: implements non-sendable +class sendableClass26 implements nonSendableInterface {} // OK + +// case3: implements type alias +// == case4.1: implements sendable +@Sendable +class sendableClass27 implements localSendableInterfaceAlias {} // ERROR + +// == case4.2: implements non-sendable +class sendableClass28 implements localNonSendableInterfaceAlias {} // OK + +// ISendable created by developer is not a sendable interface + +interface ISendable {} + +interface fakeSendableInterface extends ISendable {} + +// fake sendable interface type alias +type fakeSendableInterfaceAlias = fakeSendableInterface + +class sendableClass29 implements fakeSendableInterface {} // OK + +class sendableClass30 implements fakeSendableInterfaceAlias {} // OK \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets.json b/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.json similarity index 43% rename from ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets.json rename to ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.json index d16c4619dbba158fe71ea20bf13d004a62f85552..1b1edbb0f96d0f628ef1f7765111f8ee495443b8 100644 --- a/ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets.json +++ b/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.json @@ -15,94 +15,104 @@ ], "result": [ { - "line": 62, + "line": 31, "column": 24, - "endLine": 62, - "endColumn": 35, - "problem": "ConstructorFuncs", + "endLine": 31, + "endColumn": 43, + "problem": "ClassAsObject", "suggest": "", - "rule": "Constructor function type is not supported (arkts-no-ctor-signatures-funcs)", - "severity": "ERROR" + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 38, + "column": 27, + "endLine": 38, + "endColumn": 49, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" }, { - "line": 64, - "column": 28, - "endLine": 64, - "endColumn": 39, - "problem": "ConstructorFuncs", + "line": 59, + "column": 30, + "endLine": 59, + "endColumn": 41, + "problem": "SendableClassInheritance", "suggest": "", - "rule": "Constructor function type is not supported (arkts-no-ctor-signatures-funcs)", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", "severity": "ERROR" }, { - "line": 74, - "column": 12, - "endLine": 74, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 63, + "column": 30, + "endLine": 63, + "endColumn": 44, + "problem": "SendableClassInheritance", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", "severity": "ERROR" }, { - "line": 74, - "column": 13, - "endLine": 74, - "endColumn": 22, - "problem": "SpreadOperator", + "line": 68, + "column": 30, + "endLine": 68, + "endColumn": 46, + "problem": "SendableClassInheritance", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", "severity": "ERROR" }, { - "line": 82, - "column": 12, - "endLine": 82, - "endColumn": 32, - "problem": "ArrayLiteralNoContextType", + "line": 72, + "column": 30, + "endLine": 72, + "endColumn": 49, + "problem": "SendableClassInheritance", "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", "severity": "ERROR" }, { - "line": 82, - "column": 13, - "endLine": 82, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 81, + "column": 30, + "endLine": 81, + "endColumn": 47, + "problem": "SendableClassInheritance", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", "severity": "ERROR" }, { - "line": 82, - "column": 14, - "endLine": 82, - "endColumn": 23, - "problem": "SpreadOperator", + "line": 90, + "column": 30, + "endLine": 90, + "endColumn": 52, + "problem": "SendableClassInheritance", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", "severity": "ERROR" }, { - "line": 89, - "column": 37, - "endLine": 89, - "endColumn": 41, - "problem": "ClassAsObject", + "line": 125, + "column": 31, + "endLine": 125, + "endColumn": 42, + "problem": "SendableClassInheritance", "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "WARNING" + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" }, { - "line": 104, - "column": 42, - "endLine": 104, - "endColumn": 49, - "problem": "ClassAsObject", + "line": 132, + "column": 31, + "endLine": 132, + "endColumn": 47, + "problem": "SendableClassInheritance", "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "WARNING" + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.args.json b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.args.json +++ b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.ets b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..42ff9e372ca8b0b2d3fcbabacdde227b81437ca7 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.ets @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { lang } from './@arkts.lang'; + +@Sendable +class GoodA implements lang.ISendable {} + +@Sendable +class BadA implements lang.ISendable {} // Fixable + +interface B extends lang.ISendable {} + +@Sendable +class GoodB implements B {} + +@Sendable +class BadB implements B {} // Fixable + +@Sendable +class C {} + +@Sendable +class GoodC extends C {} + +@Sendable +class BadC extends C {} // Fixable + +@Sendable +class BadC2 extends C implements lang.ISendable {} // Fixable + +class D {} + +@Sendable +class BadD extends D {} // Not fixable + +class GoodD extends D {} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.json b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..6cc01d31bc0a8e4bcff67bd288847a52525a0967 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 47, + "column": 20, + "endLine": 47, + "endColumn": 21, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets index 604e2aadb360b91099eb1219065061150bd097e5..ad7642039b2fb9f41631f91b9e8a6876e2258a70 100644 --- a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' @Sendable // ERROR class SendableClass { diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.args.json b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.args.json index 4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100644 --- a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.args.json +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.arkts2.json b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.arkts2.json index 9a72d0f98a6f7f384e37fb2e02f4362ba216c519..84cf5f2ee31640facc568576a4300a791e76078a 100644 --- a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.arkts2.json @@ -1,28 +1,14 @@ { - "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, + "line": 17, "column": 1, - "endLine": 16, + "endLine": 17, "endColumn": 10, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoSendableDecorator", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.autofix.json b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.autofix.json index 4c8d17a17a59846281654444569726255232e24d..713f44e680df8e8ee976ff1d7ffb58711f2fc498 100644 --- a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.autofix.json @@ -15,20 +15,20 @@ ], "result": [ { - "line": 16, + "line": 17, "column": 1, - "endLine": 16, + "endLine": 17, "endColumn": 10, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoSendableDecorator", "autofix": [ { - "start": 610, - "end": 619, + "start": 623, + "end": 632, "replacementText": "" } ], "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", "severity": "ERROR" } ] diff --git a/ets2panda/test/parser/ets/user_defined_6.ets b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.ets similarity index 93% rename from ets2panda/test/parser/ets/user_defined_6.ets rename to ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.ets index 8e3f4782f0551cfbb0f546e1717361181b3f9007..32a1cd22fac0d4d421315e744b06b8b6cbe6c8d1 100644 --- a/ets2panda/test/parser/ets/user_defined_6.ets +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.ets @@ -12,6 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' -function float() { + // ERROR +class SendableClass { } diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.json b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_decorator_limited.ets.args.json b/ets2panda/linter/test/main/sendable_decorator_limited.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/sendable_decorator_limited.ets.args.json +++ b/ets2panda/linter/test/main/sendable_decorator_limited.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/test/parser/ets/user_defined_3.ets b/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.ets similarity index 59% rename from ets2panda/test/parser/ets/user_defined_3.ets rename to ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.ets index a058258ea3247b6812e73600fe8fbc13a0927ba5..7b27a36af23bb3774a09df40af4eefeda6f101bb 100644 --- a/ets2panda/test/parser/ets/user_defined_3.ets +++ b/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.ets @@ -13,22 +13,41 @@ * limitations under the License. */ - let float : float; - let boolean : boolean; - let double : double; - let byte : byte; - let short : short; - let int : int; - let char : char; - let long : long; - -function main() { - let float : float; - let boolean : boolean; - let double : double; - let byte : byte; - let short : short; - let int : int; - let char : char; - let long : long; +@Sendable // OK +class SendableClass { +} + +@Sendable // OK +function sendableFunction(): void { +}; + +@Sendable // OK +type SendableType = () => void; + + // ERROR +struct SendableStruct { +}; + + +class NormalClass { + // ERROR + name: string = 'name'; + + // ERROR + handle() { + + }; + + handle2( param: string) { // ERROR + + } + + // ERROR + get age(): number { + return 1; + } + + // ERROR + set age(value: number) { + } } diff --git a/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.json b/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.args.json b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.args.json +++ b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.autofix.json b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.autofix.json index ca304dd6c5151064dd79af5775651fa379dc337a..4431346a560958da8ac5ba18547d9074c9d8de0f 100644 --- a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.autofix.json +++ b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.autofix.json @@ -542,9 +542,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3320, - "end": 3447, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp4: boolean = true;" + "start": 3439, + "end": 3439, + "replacementText": ": boolean" } ], "suggest": "", @@ -559,9 +559,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3447, - "end": 3469, - "replacementText": "numberProp4: number = 42;" + "start": 3463, + "end": 3463, + "replacementText": ": number" } ], "suggest": "", @@ -576,9 +576,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3469, - "end": 3496, - "replacementText": "stringProp4: string = \"Hello\";" + "start": 3485, + "end": 3485, + "replacementText": ": string" } ], "suggest": "", @@ -593,9 +593,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3496, - "end": 3524, - "replacementText": "arrayProp4: number[] = [1, 2, 3];" + "start": 3511, + "end": 3511, + "replacementText": ": number[]" } ], "suggest": "", @@ -610,9 +610,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3524, - "end": 3560, - "replacementText": "tupleProp4: (string | number)[] = [\"typescript\", 4];" + "start": 3539, + "end": 3539, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -627,9 +627,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3560, - "end": 3589, - "replacementText": "enumProp4: Color = Color.Green;" + "start": 3574, + "end": 3574, + "replacementText": ": Color" } ], "suggest": "", @@ -676,9 +676,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3622, - "end": 3649, - "replacementText": "voidProp4: undefined = undefined;" + "start": 3636, + "end": 3636, + "replacementText": ": undefined" } ], "suggest": "", @@ -693,9 +693,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3649, - "end": 3671, - "replacementText": "nullProp4: null = null;" + "start": 3663, + "end": 3663, + "replacementText": ": null" } ], "suggest": "", @@ -710,9 +710,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3671, - "end": 3703, - "replacementText": "undefinedProp4: undefined = undefined;" + "start": 3690, + "end": 3690, + "replacementText": ": undefined" } ], "suggest": "", @@ -759,9 +759,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3748, - "end": 3790, - "replacementText": "sendableClass4: SendableClass = new SendableClass();" + "start": 3767, + "end": 3767, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -776,9 +776,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3790, - "end": 3836, - "replacementText": "noSendableClass4: NoSendableClass = new NoSendableClass();" + "start": 3811, + "end": 3811, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -793,9 +793,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3836, - "end": 3964, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp5?: boolean | undefined = true;" + "start": 3956, + "end": 3956, + "replacementText": ": boolean | undefined" } ], "suggest": "", @@ -810,9 +810,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3964, - "end": 3987, - "replacementText": "numberProp5?: number | undefined = 42;" + "start": 3981, + "end": 3981, + "replacementText": ": number | undefined" } ], "suggest": "", @@ -827,9 +827,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3987, - "end": 4015, - "replacementText": "stringProp5?: string | undefined = \"Hello\";" + "start": 4004, + "end": 4004, + "replacementText": ": string | undefined" } ], "suggest": "", @@ -844,9 +844,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4015, - "end": 4044, - "replacementText": "arrayProp5?: number[] | undefined = [1, 2, 3];" + "start": 4031, + "end": 4031, + "replacementText": ": number[] | undefined" } ], "suggest": "", @@ -861,9 +861,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4044, - "end": 4081, - "replacementText": "tupleProp5?: (string | number)[] | undefined = [\"typescript\", 4];" + "start": 4060, + "end": 4060, + "replacementText": ": (string | number)[] | undefined" } ], "suggest": "", @@ -878,9 +878,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4081, - "end": 4111, - "replacementText": "enumProp5?: Color | undefined = Color.Green;" + "start": 4096, + "end": 4096, + "replacementText": ": Color | undefined" } ], "suggest": "", @@ -927,9 +927,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4145, - "end": 4173, - "replacementText": "voidProp5?: undefined = undefined;" + "start": 4160, + "end": 4160, + "replacementText": ": undefined" } ], "suggest": "", @@ -944,9 +944,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4173, - "end": 4196, - "replacementText": "nullProp5?: null | undefined = null;" + "start": 4188, + "end": 4188, + "replacementText": ": null | undefined" } ], "suggest": "", @@ -961,9 +961,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4196, - "end": 4229, - "replacementText": "undefinedProp5?: undefined = undefined;" + "start": 4216, + "end": 4216, + "replacementText": ": undefined" } ], "suggest": "", @@ -1010,9 +1010,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4275, - "end": 4318, - "replacementText": "sendableClass5?: SendableClass | undefined = new SendableClass();" + "start": 4295, + "end": 4295, + "replacementText": ": SendableClass | undefined" } ], "suggest": "", @@ -1027,9 +1027,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4318, - "end": 4365, - "replacementText": "noSendableClass5?: NoSendableClass | undefined = new NoSendableClass();" + "start": 4340, + "end": 4340, + "replacementText": ": NoSendableClass | undefined" } ], "suggest": "", @@ -1044,9 +1044,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4365, - "end": 4502, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\npublic optBooleanProp6: boolean = true;" + "start": 4494, + "end": 4494, + "replacementText": ": boolean" } ], "suggest": "", @@ -1061,9 +1061,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4502, - "end": 4534, - "replacementText": "public optNumberProp6: number = 42;" + "start": 4528, + "end": 4528, + "replacementText": ": number" } ], "suggest": "", @@ -1078,9 +1078,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4534, - "end": 4571, - "replacementText": "public optStringProp6: string = \"Hello\";" + "start": 4560, + "end": 4560, + "replacementText": ": string" } ], "suggest": "", @@ -1095,9 +1095,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4571, - "end": 4609, - "replacementText": "public optArrayProp6: number[] = [1, 2, 3];" + "start": 4596, + "end": 4596, + "replacementText": ": number[]" } ], "suggest": "", @@ -1112,9 +1112,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4609, - "end": 4655, - "replacementText": "public optTupleProp6: (string | number)[] = [\"typescript\", 4];" + "start": 4634, + "end": 4634, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -1129,9 +1129,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4655, - "end": 4694, - "replacementText": "public optEnumProp6: Color = Color.Green;" + "start": 4679, + "end": 4679, + "replacementText": ": Color" } ], "suggest": "", @@ -1178,9 +1178,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4737, - "end": 4774, - "replacementText": "public optVoidProp6: undefined = undefined;" + "start": 4761, + "end": 4761, + "replacementText": ": undefined" } ], "suggest": "", @@ -1195,9 +1195,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4774, - "end": 4806, - "replacementText": "public optNullProp6: null = null;" + "start": 4798, + "end": 4798, + "replacementText": ": null" } ], "suggest": "", @@ -1212,9 +1212,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4806, - "end": 4848, - "replacementText": "public optUndefinedProp6: undefined = undefined;" + "start": 4835, + "end": 4835, + "replacementText": ": undefined" } ], "suggest": "", @@ -1261,9 +1261,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4903, - "end": 4955, - "replacementText": "public optSendableClass6: SendableClass = new SendableClass();" + "start": 4932, + "end": 4932, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -1278,9 +1278,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4955, - "end": 5011, - "replacementText": "public optNoSendableClass6: NoSendableClass = new NoSendableClass();" + "start": 4986, + "end": 4986, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -1295,9 +1295,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5011, - "end": 5150, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nreadonly optBooleanProp7: true = true;" + "start": 5142, + "end": 5142, + "replacementText": ": true" } ], "suggest": "", @@ -1312,9 +1312,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5150, - "end": 5184, - "replacementText": "readonly optNumberProp7: 42 = 42;" + "start": 5178, + "end": 5178, + "replacementText": ": 42" } ], "suggest": "", @@ -1329,9 +1329,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5184, - "end": 5223, - "replacementText": "readonly optStringProp7: \"Hello\" = \"Hello\";" + "start": 5212, + "end": 5212, + "replacementText": ": \"Hello\"" } ], "suggest": "", @@ -1346,9 +1346,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5223, - "end": 5263, - "replacementText": "readonly optArrayProp7: number[] = [1, 2, 3];" + "start": 5250, + "end": 5250, + "replacementText": ": number[]" } ], "suggest": "", @@ -1363,9 +1363,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5263, - "end": 5311, - "replacementText": "readonly optTupleProp7: (string | number)[] = [\"typescript\", 4];" + "start": 5290, + "end": 5290, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -1380,9 +1380,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5311, - "end": 5352, - "replacementText": "readonly optEnumProp7: Color.Green = Color.Green;" + "start": 5337, + "end": 5337, + "replacementText": ": Color.Green" } ], "suggest": "", @@ -1429,9 +1429,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5397, - "end": 5436, - "replacementText": "readonly optVoidProp7: undefined = undefined;" + "start": 5423, + "end": 5423, + "replacementText": ": undefined" } ], "suggest": "", @@ -1446,9 +1446,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5436, - "end": 5470, - "replacementText": "readonly optNullProp7: null = null;" + "start": 5462, + "end": 5462, + "replacementText": ": null" } ], "suggest": "", @@ -1463,9 +1463,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5470, - "end": 5514, - "replacementText": "readonly optUndefinedProp7: undefined = undefined;" + "start": 5501, + "end": 5501, + "replacementText": ": undefined" } ], "suggest": "", @@ -1512,9 +1512,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5571, - "end": 5625, - "replacementText": "readonly optSendableClass7: SendableClass = new SendableClass();" + "start": 5602, + "end": 5602, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -1529,9 +1529,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5625, - "end": 5683, - "replacementText": "readonly optNoSendableClass7: NoSendableClass = new NoSendableClass();" + "start": 5658, + "end": 5658, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -2066,9 +2066,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8256, - "end": 8383, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp4: boolean = true;" + "start": 8375, + "end": 8375, + "replacementText": ": boolean" } ], "suggest": "", @@ -2083,9 +2083,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8383, - "end": 8405, - "replacementText": "numberProp4: number = 42;" + "start": 8399, + "end": 8399, + "replacementText": ": number" } ], "suggest": "", @@ -2100,9 +2100,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8405, - "end": 8432, - "replacementText": "stringProp4: string = \"Hello\";" + "start": 8421, + "end": 8421, + "replacementText": ": string" } ], "suggest": "", @@ -2117,9 +2117,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8432, - "end": 8460, - "replacementText": "arrayProp4: number[] = [1, 2, 3];" + "start": 8447, + "end": 8447, + "replacementText": ": number[]" } ], "suggest": "", @@ -2134,9 +2134,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8460, - "end": 8496, - "replacementText": "tupleProp4: (string | number)[] = [\"typescript\", 4];" + "start": 8475, + "end": 8475, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -2151,9 +2151,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8496, - "end": 8525, - "replacementText": "enumProp4: Color = Color.Green;" + "start": 8510, + "end": 8510, + "replacementText": ": Color" } ], "suggest": "", @@ -2200,9 +2200,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8558, - "end": 8585, - "replacementText": "voidProp4: undefined = undefined;" + "start": 8572, + "end": 8572, + "replacementText": ": undefined" } ], "suggest": "", @@ -2217,9 +2217,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8585, - "end": 8607, - "replacementText": "nullProp4: null = null;" + "start": 8599, + "end": 8599, + "replacementText": ": null" } ], "suggest": "", @@ -2234,9 +2234,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8607, - "end": 8639, - "replacementText": "undefinedProp4: undefined = undefined;" + "start": 8626, + "end": 8626, + "replacementText": ": undefined" } ], "suggest": "", @@ -2283,9 +2283,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8684, - "end": 8726, - "replacementText": "sendableClass4: SendableClass = new SendableClass();" + "start": 8703, + "end": 8703, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -2300,9 +2300,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8726, - "end": 8772, - "replacementText": "noSendableClass4: NoSendableClass = new NoSendableClass();" + "start": 8747, + "end": 8747, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -2317,9 +2317,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8772, - "end": 8900, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp5?: boolean | undefined = true;" + "start": 8892, + "end": 8892, + "replacementText": ": boolean | undefined" } ], "suggest": "", @@ -2334,9 +2334,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8900, - "end": 8923, - "replacementText": "numberProp5?: number | undefined = 42;" + "start": 8917, + "end": 8917, + "replacementText": ": number | undefined" } ], "suggest": "", @@ -2351,9 +2351,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8923, - "end": 8951, - "replacementText": "stringProp5?: string | undefined = \"Hello\";" + "start": 8940, + "end": 8940, + "replacementText": ": string | undefined" } ], "suggest": "", @@ -2368,9 +2368,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8951, - "end": 8980, - "replacementText": "arrayProp5?: number[] | undefined = [1, 2, 3];" + "start": 8967, + "end": 8967, + "replacementText": ": number[] | undefined" } ], "suggest": "", @@ -2385,9 +2385,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8980, - "end": 9017, - "replacementText": "tupleProp5?: (string | number)[] | undefined = [\"typescript\", 4];" + "start": 8996, + "end": 8996, + "replacementText": ": (string | number)[] | undefined" } ], "suggest": "", @@ -2402,9 +2402,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9017, - "end": 9047, - "replacementText": "enumProp5?: Color | undefined = Color.Green;" + "start": 9032, + "end": 9032, + "replacementText": ": Color | undefined" } ], "suggest": "", @@ -2451,9 +2451,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9081, - "end": 9109, - "replacementText": "voidProp5?: undefined = undefined;" + "start": 9096, + "end": 9096, + "replacementText": ": undefined" } ], "suggest": "", @@ -2468,9 +2468,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9109, - "end": 9132, - "replacementText": "nullProp5?: null | undefined = null;" + "start": 9124, + "end": 9124, + "replacementText": ": null | undefined" } ], "suggest": "", @@ -2485,9 +2485,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9132, - "end": 9165, - "replacementText": "undefinedProp5?: undefined = undefined;" + "start": 9152, + "end": 9152, + "replacementText": ": undefined" } ], "suggest": "", @@ -2534,9 +2534,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9211, - "end": 9254, - "replacementText": "sendableClass5?: SendableClass | undefined = new SendableClass();" + "start": 9231, + "end": 9231, + "replacementText": ": SendableClass | undefined" } ], "suggest": "", @@ -2551,9 +2551,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9254, - "end": 9301, - "replacementText": "noSendableClass5?: NoSendableClass | undefined = new NoSendableClass();" + "start": 9276, + "end": 9276, + "replacementText": ": NoSendableClass | undefined" } ], "suggest": "", @@ -2568,9 +2568,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9301, - "end": 9438, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\npublic optBooleanProp6: boolean = true;" + "start": 9430, + "end": 9430, + "replacementText": ": boolean" } ], "suggest": "", @@ -2585,9 +2585,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9438, - "end": 9470, - "replacementText": "public optNumberProp6: number = 42;" + "start": 9464, + "end": 9464, + "replacementText": ": number" } ], "suggest": "", @@ -2602,9 +2602,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9470, - "end": 9507, - "replacementText": "public optStringProp6: string = \"Hello\";" + "start": 9496, + "end": 9496, + "replacementText": ": string" } ], "suggest": "", @@ -2619,9 +2619,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9507, - "end": 9545, - "replacementText": "public optArrayProp6: number[] = [1, 2, 3];" + "start": 9532, + "end": 9532, + "replacementText": ": number[]" } ], "suggest": "", @@ -2636,9 +2636,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9545, - "end": 9591, - "replacementText": "public optTupleProp6: (string | number)[] = [\"typescript\", 4];" + "start": 9570, + "end": 9570, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -2653,9 +2653,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9591, - "end": 9630, - "replacementText": "public optEnumProp6: Color = Color.Green;" + "start": 9615, + "end": 9615, + "replacementText": ": Color" } ], "suggest": "", @@ -2702,9 +2702,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9673, - "end": 9710, - "replacementText": "public optVoidProp6: undefined = undefined;" + "start": 9697, + "end": 9697, + "replacementText": ": undefined" } ], "suggest": "", @@ -2719,9 +2719,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9710, - "end": 9742, - "replacementText": "public optNullProp6: null = null;" + "start": 9734, + "end": 9734, + "replacementText": ": null" } ], "suggest": "", @@ -2736,9 +2736,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9742, - "end": 9784, - "replacementText": "public optUndefinedProp6: undefined = undefined;" + "start": 9771, + "end": 9771, + "replacementText": ": undefined" } ], "suggest": "", @@ -2785,9 +2785,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9839, - "end": 9891, - "replacementText": "public optSendableClass6: SendableClass = new SendableClass();" + "start": 9868, + "end": 9868, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -2802,9 +2802,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9891, - "end": 9947, - "replacementText": "public optNoSendableClass6: NoSendableClass = new NoSendableClass();" + "start": 9922, + "end": 9922, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -2819,9 +2819,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9947, - "end": 10086, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nreadonly optBooleanProp7: true = true;" + "start": 10078, + "end": 10078, + "replacementText": ": true" } ], "suggest": "", @@ -2836,9 +2836,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10086, - "end": 10120, - "replacementText": "readonly optNumberProp7: 42 = 42;" + "start": 10114, + "end": 10114, + "replacementText": ": 42" } ], "suggest": "", @@ -2853,9 +2853,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10120, - "end": 10159, - "replacementText": "readonly optStringProp7: \"Hello\" = \"Hello\";" + "start": 10148, + "end": 10148, + "replacementText": ": \"Hello\"" } ], "suggest": "", @@ -2870,9 +2870,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10159, - "end": 10199, - "replacementText": "readonly optArrayProp7: number[] = [1, 2, 3];" + "start": 10186, + "end": 10186, + "replacementText": ": number[]" } ], "suggest": "", @@ -2887,9 +2887,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10199, - "end": 10247, - "replacementText": "readonly optTupleProp7: (string | number)[] = [\"typescript\", 4];" + "start": 10226, + "end": 10226, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -2904,9 +2904,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10247, - "end": 10288, - "replacementText": "readonly optEnumProp7: Color.Green = Color.Green;" + "start": 10273, + "end": 10273, + "replacementText": ": Color.Green" } ], "suggest": "", @@ -2953,9 +2953,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10333, - "end": 10372, - "replacementText": "readonly optVoidProp7: undefined = undefined;" + "start": 10359, + "end": 10359, + "replacementText": ": undefined" } ], "suggest": "", @@ -2970,9 +2970,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10372, - "end": 10406, - "replacementText": "readonly optNullProp7: null = null;" + "start": 10398, + "end": 10398, + "replacementText": ": null" } ], "suggest": "", @@ -2987,9 +2987,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10406, - "end": 10450, - "replacementText": "readonly optUndefinedProp7: undefined = undefined;" + "start": 10437, + "end": 10437, + "replacementText": ": undefined" } ], "suggest": "", @@ -3036,9 +3036,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10507, - "end": 10561, - "replacementText": "readonly optSendableClass7: SendableClass = new SendableClass();" + "start": 10538, + "end": 10538, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -3053,9 +3053,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10561, - "end": 10619, - "replacementText": "readonly optNoSendableClass7: NoSendableClass = new NoSendableClass();" + "start": 10594, + "end": 10594, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -3590,9 +3590,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13165, - "end": 13292, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp4: boolean = true;" + "start": 13284, + "end": 13284, + "replacementText": ": boolean" } ], "suggest": "", @@ -3607,9 +3607,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13292, - "end": 13314, - "replacementText": "numberProp4: number = 42;" + "start": 13308, + "end": 13308, + "replacementText": ": number" } ], "suggest": "", @@ -3624,9 +3624,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13314, - "end": 13341, - "replacementText": "stringProp4: string = \"Hello\";" + "start": 13330, + "end": 13330, + "replacementText": ": string" } ], "suggest": "", @@ -3641,9 +3641,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13341, - "end": 13369, - "replacementText": "arrayProp4: number[] = [1, 2, 3];" + "start": 13356, + "end": 13356, + "replacementText": ": number[]" } ], "suggest": "", @@ -3658,9 +3658,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13369, - "end": 13405, - "replacementText": "tupleProp4: (string | number)[] = [\"typescript\", 4];" + "start": 13384, + "end": 13384, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -3675,9 +3675,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13405, - "end": 13434, - "replacementText": "enumProp4: Color = Color.Green;" + "start": 13419, + "end": 13419, + "replacementText": ": Color" } ], "suggest": "", @@ -3724,9 +3724,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13467, - "end": 13494, - "replacementText": "voidProp4: undefined = undefined;" + "start": 13481, + "end": 13481, + "replacementText": ": undefined" } ], "suggest": "", @@ -3741,9 +3741,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13494, - "end": 13516, - "replacementText": "nullProp4: null = null;" + "start": 13508, + "end": 13508, + "replacementText": ": null" } ], "suggest": "", @@ -3758,9 +3758,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13516, - "end": 13548, - "replacementText": "undefinedProp4: undefined = undefined;" + "start": 13535, + "end": 13535, + "replacementText": ": undefined" } ], "suggest": "", @@ -3807,9 +3807,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13593, - "end": 13635, - "replacementText": "sendableClass4: SendableClass = new SendableClass();" + "start": 13612, + "end": 13612, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -3824,9 +3824,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13635, - "end": 13681, - "replacementText": "noSendableClass4: NoSendableClass = new NoSendableClass();" + "start": 13656, + "end": 13656, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -3841,9 +3841,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13681, - "end": 13809, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp5?: boolean | undefined = true;" + "start": 13801, + "end": 13801, + "replacementText": ": boolean | undefined" } ], "suggest": "", @@ -3858,9 +3858,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13809, - "end": 13832, - "replacementText": "numberProp5?: number | undefined = 42;" + "start": 13826, + "end": 13826, + "replacementText": ": number | undefined" } ], "suggest": "", @@ -3875,9 +3875,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13832, - "end": 13860, - "replacementText": "stringProp5?: string | undefined = \"Hello\";" + "start": 13849, + "end": 13849, + "replacementText": ": string | undefined" } ], "suggest": "", @@ -3892,9 +3892,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13860, - "end": 13889, - "replacementText": "arrayProp5?: number[] | undefined = [1, 2, 3];" + "start": 13876, + "end": 13876, + "replacementText": ": number[] | undefined" } ], "suggest": "", @@ -3909,9 +3909,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13889, - "end": 13926, - "replacementText": "tupleProp5?: (string | number)[] | undefined = [\"typescript\", 4];" + "start": 13905, + "end": 13905, + "replacementText": ": (string | number)[] | undefined" } ], "suggest": "", @@ -3926,9 +3926,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13926, - "end": 13956, - "replacementText": "enumProp5?: Color | undefined = Color.Green;" + "start": 13941, + "end": 13941, + "replacementText": ": Color | undefined" } ], "suggest": "", @@ -3975,9 +3975,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13990, - "end": 14018, - "replacementText": "voidProp5?: undefined = undefined;" + "start": 14005, + "end": 14005, + "replacementText": ": undefined" } ], "suggest": "", @@ -3992,9 +3992,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14018, - "end": 14041, - "replacementText": "nullProp5?: null | undefined = null;" + "start": 14033, + "end": 14033, + "replacementText": ": null | undefined" } ], "suggest": "", @@ -4009,9 +4009,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14041, - "end": 14074, - "replacementText": "undefinedProp5?: undefined = undefined;" + "start": 14061, + "end": 14061, + "replacementText": ": undefined" } ], "suggest": "", @@ -4058,9 +4058,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14120, - "end": 14163, - "replacementText": "sendableClass5?: SendableClass | undefined = new SendableClass();" + "start": 14140, + "end": 14140, + "replacementText": ": SendableClass | undefined" } ], "suggest": "", @@ -4075,9 +4075,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14163, - "end": 14210, - "replacementText": "noSendableClass5?: NoSendableClass | undefined = new NoSendableClass();" + "start": 14185, + "end": 14185, + "replacementText": ": NoSendableClass | undefined" } ], "suggest": "", @@ -4092,9 +4092,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14210, - "end": 14347, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\npublic optBooleanProp6: boolean = true;" + "start": 14339, + "end": 14339, + "replacementText": ": boolean" } ], "suggest": "", @@ -4109,9 +4109,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14347, - "end": 14379, - "replacementText": "public optNumberProp6: number = 42;" + "start": 14373, + "end": 14373, + "replacementText": ": number" } ], "suggest": "", @@ -4126,9 +4126,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14379, - "end": 14416, - "replacementText": "public optStringProp6: string = \"Hello\";" + "start": 14405, + "end": 14405, + "replacementText": ": string" } ], "suggest": "", @@ -4143,9 +4143,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14416, - "end": 14454, - "replacementText": "public optArrayProp6: number[] = [1, 2, 3];" + "start": 14441, + "end": 14441, + "replacementText": ": number[]" } ], "suggest": "", @@ -4160,9 +4160,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14454, - "end": 14500, - "replacementText": "public optTupleProp6: (string | number)[] = [\"typescript\", 4];" + "start": 14479, + "end": 14479, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -4177,9 +4177,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14500, - "end": 14539, - "replacementText": "public optEnumProp6: Color = Color.Green;" + "start": 14524, + "end": 14524, + "replacementText": ": Color" } ], "suggest": "", @@ -4226,9 +4226,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14582, - "end": 14619, - "replacementText": "public optVoidProp6: undefined = undefined;" + "start": 14606, + "end": 14606, + "replacementText": ": undefined" } ], "suggest": "", @@ -4243,9 +4243,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14619, - "end": 14651, - "replacementText": "public optNullProp6: null = null;" + "start": 14643, + "end": 14643, + "replacementText": ": null" } ], "suggest": "", @@ -4260,9 +4260,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14651, - "end": 14693, - "replacementText": "public optUndefinedProp6: undefined = undefined;" + "start": 14680, + "end": 14680, + "replacementText": ": undefined" } ], "suggest": "", @@ -4309,9 +4309,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14748, - "end": 14800, - "replacementText": "public optSendableClass6: SendableClass = new SendableClass();" + "start": 14777, + "end": 14777, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -4326,9 +4326,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14800, - "end": 14856, - "replacementText": "public optNoSendableClass6: NoSendableClass = new NoSendableClass();" + "start": 14831, + "end": 14831, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -4343,9 +4343,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14856, - "end": 14995, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nreadonly optBooleanProp7: true = true;" + "start": 14987, + "end": 14987, + "replacementText": ": true" } ], "suggest": "", @@ -4360,9 +4360,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14995, - "end": 15029, - "replacementText": "readonly optNumberProp7: 42 = 42;" + "start": 15023, + "end": 15023, + "replacementText": ": 42" } ], "suggest": "", @@ -4377,9 +4377,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15029, - "end": 15068, - "replacementText": "readonly optStringProp7: \"Hello\" = \"Hello\";" + "start": 15057, + "end": 15057, + "replacementText": ": \"Hello\"" } ], "suggest": "", @@ -4394,9 +4394,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15068, - "end": 15108, - "replacementText": "readonly optArrayProp7: number[] = [1, 2, 3];" + "start": 15095, + "end": 15095, + "replacementText": ": number[]" } ], "suggest": "", @@ -4411,9 +4411,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15108, - "end": 15156, - "replacementText": "readonly optTupleProp7: (string | number)[] = [\"typescript\", 4];" + "start": 15135, + "end": 15135, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -4428,9 +4428,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15156, - "end": 15197, - "replacementText": "readonly optEnumProp7: Color.Green = Color.Green;" + "start": 15182, + "end": 15182, + "replacementText": ": Color.Green" } ], "suggest": "", @@ -4477,9 +4477,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15242, - "end": 15281, - "replacementText": "readonly optVoidProp7: undefined = undefined;" + "start": 15268, + "end": 15268, + "replacementText": ": undefined" } ], "suggest": "", @@ -4494,9 +4494,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15281, - "end": 15315, - "replacementText": "readonly optNullProp7: null = null;" + "start": 15307, + "end": 15307, + "replacementText": ": null" } ], "suggest": "", @@ -4511,9 +4511,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15315, - "end": 15359, - "replacementText": "readonly optUndefinedProp7: undefined = undefined;" + "start": 15346, + "end": 15346, + "replacementText": ": undefined" } ], "suggest": "", @@ -4560,9 +4560,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15416, - "end": 15470, - "replacementText": "readonly optSendableClass7: SendableClass = new SendableClass();" + "start": 15447, + "end": 15447, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -4577,9 +4577,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15470, - "end": 15528, - "replacementText": "readonly optNoSendableClass7: NoSendableClass = new NoSendableClass();" + "start": 15503, + "end": 15503, + "replacementText": ": NoSendableClass" } ], "suggest": "", diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.ets b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..8bcbd308819d074fadbfa76b621642921619ca53 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.ets @@ -0,0 +1,659 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare namespace lang { + interface ISendable {} +} + +enum Color {Red, Green, Blue} + +@Sendable +class SendableClass { + public a: number = 1; +} + +class NoSendableClass { + public b: number = 1; +} + +interface GeneratedObjectLiteralInterface_1 { + key: string; +} +interface GeneratedObjectLiteralInterface_2 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_3 { + key: string; +} +interface GeneratedObjectLiteralInterface_4 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_5 { + key: string; +} +interface GeneratedObjectLiteralInterface_6 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_7 { + key: string; +} +interface GeneratedObjectLiteralInterface_8 { + name: string; + age: number; +} +@Sendable +class A { + booleanProp: boolean = true; + numberProp: number = 42; + stringProp: string = "Hello"; + arrayProp: number[] = [1, 2, 3]; + tupleProp: [string, number] = ["typescript", 4]; + enumProp: Color = Color.Green; + anyProp: any = { key: "value" }; + voidProp: void = undefined; + nullProp: null = null; + undefinedProp: undefined = undefined; + objectProp: object = { name: "John", age: 30 }; + sendableClass: SendableClass = new SendableClass(); + noSendableClass: NoSendableClass = new NoSendableClass(); + + optBooleanProp1?: boolean = true; + optNumberProp1?: number = 42; + optStringProp1?: string = "Hello"; + optArrayProp1?: number[] = [1, 2, 3]; + optTupleProp1?: [string, number] = ["typescript", 4]; + optEnumProp1?: Color = Color.Green; + optAnyProp1?: any = { key: "value" }; + optVoidProp1?: void = undefined; + optNullProp1?: null = null; + optUndefinedProp1?: undefined = undefined; + optObjectProp1?: object = { name: "John", age: 30 }; + optSendableClass1?: SendableClass = new SendableClass(); + optNoSendableClass1?: NoSendableClass = new NoSendableClass(); + + public optBooleanProp2: boolean = true; + public optNumberProp2: number = 42; + public optStringProp2: string = "Hello"; + public optArrayProp2: number[] = [1, 2, 3]; + public optTupleProp2: [string, number] = ["typescript", 4]; + public optEnumProp2: Color = Color.Green; + public optAnyProp2: any = { key: "value" }; + public optVoidProp2: void = undefined; + public optNullProp2: null = null; + public optUndefinedProp2: undefined = undefined; + public optObjectProp2: object = { name: "John", age: 30 }; + public optSendableClass2: SendableClass = new SendableClass(); + public optNoSendableClass2: NoSendableClass = new NoSendableClass(); + + readonly optBooleanProp3: boolean = true; + readonly optNumberProp3: number = 42; + readonly optStringProp3: string = "Hello"; + readonly optArrayProp3: number[] = [1, 2, 3]; + readonly optTupleProp3: [string, number] = ["typescript", 4]; + readonly optEnumProp3: Color = Color.Green; + readonly optAnyProp3: any = { key: "value" }; + readonly optVoidProp3: void = undefined; + readonly optNullProp3: null = null; + readonly optUndefinedProp3: undefined = undefined; + readonly optObjectProp3: object = { name: "John", age: 30 }; + readonly optSendableClass3: SendableClass = new SendableClass(); + readonly optNoSendableClass3: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp4: boolean = true; + numberProp4: number = 42; + stringProp4: string = "Hello"; + arrayProp4: number[] = [1, 2, 3]; + tupleProp4: (string | number)[] = ["typescript", 4]; + enumProp4: Color = Color.Green; + anyProp4: GeneratedObjectLiteralInterface_1 = { key: "value" }; + voidProp4: undefined = undefined; + nullProp4: null = null; + undefinedProp4: undefined = undefined; + objectProp4: GeneratedObjectLiteralInterface_2 = { name: "John", age: 30 }; + sendableClass4: SendableClass = new SendableClass(); + noSendableClass4: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp5?: boolean | undefined = true; + numberProp5?: number | undefined = 42; + stringProp5?: string | undefined = "Hello"; + arrayProp5?: number[] | undefined = [1, 2, 3]; + tupleProp5?: (string | number)[] | undefined = ["typescript", 4]; + enumProp5?: Color | undefined = Color.Green; + anyProp5?: GeneratedObjectLiteralInterface_3 = { key: "value" }; + voidProp5?: undefined = undefined; + nullProp5?: null | undefined = null; + undefinedProp5?: undefined = undefined; + objectProp5?: GeneratedObjectLiteralInterface_4 = { name: "John", age: 30 }; + sendableClass5?: SendableClass | undefined = new SendableClass(); + noSendableClass5?: NoSendableClass | undefined = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + public optBooleanProp6: boolean = true; + public optNumberProp6: number = 42; + public optStringProp6: string = "Hello"; + public optArrayProp6: number[] = [1, 2, 3]; + public optTupleProp6: (string | number)[] = ["typescript", 4]; + public optEnumProp6: Color = Color.Green; + public optAnyProp6: GeneratedObjectLiteralInterface_5 = { key: "value" }; + public optVoidProp6: undefined = undefined; + public optNullProp6: null = null; + public optUndefinedProp6: undefined = undefined; + public optObjectProp6: GeneratedObjectLiteralInterface_6 = { name: "John", age: 30 }; + public optSendableClass6: SendableClass = new SendableClass(); + public optNoSendableClass6: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + readonly optBooleanProp7: true = true; + readonly optNumberProp7: 42 = 42; + readonly optStringProp7: "Hello" = "Hello"; + readonly optArrayProp7: number[] = [1, 2, 3]; + readonly optTupleProp7: (string | number)[] = ["typescript", 4]; + readonly optEnumProp7: Color.Green = Color.Green; + readonly optAnyProp7: GeneratedObjectLiteralInterface_7 = { key: "value" }; + readonly optVoidProp7: undefined = undefined; + readonly optNullProp7: null = null; + readonly optUndefinedProp7: undefined = undefined; + readonly optObjectProp7: GeneratedObjectLiteralInterface_8 = { name: "John", age: 30 }; + readonly optSendableClass7: SendableClass = new SendableClass(); + readonly optNoSendableClass7: NoSendableClass = new NoSendableClass(); +} + +interface GeneratedObjectLiteralInterface_9 { + key: string; +} +interface GeneratedObjectLiteralInterface_10 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_11 { + key: string; +} +interface GeneratedObjectLiteralInterface_12 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_13 { + key: string; +} +interface GeneratedObjectLiteralInterface_14 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_15 { + key: string; +} +interface GeneratedObjectLiteralInterface_16 { + name: string; + age: number; +} +@Sendable +class A1 extends A { + constructor() { + super(); + } + booleanProp: boolean = true; + numberProp: number = 42; + stringProp: string = "Hello"; + arrayProp: number[] = [1, 2, 3]; + tupleProp: [string, number] = ["typescript", 4]; + enumProp: Color = Color.Green; + anyProp: any = { key: "value" }; + voidProp: void = undefined; + nullProp: null = null; + undefinedProp: undefined = undefined; + objectProp: object = { name: "John", age: 30 }; + sendableClass: SendableClass = new SendableClass(); + noSendableClass: NoSendableClass = new NoSendableClass(); + + optBooleanProp1?: boolean = true; + optNumberProp1?: number = 42; + optStringProp1?: string = "Hello"; + optArrayProp1?: number[] = [1, 2, 3]; + optTupleProp1?: [string, number] = ["typescript", 4]; + optEnumProp1?: Color = Color.Green; + optAnyProp1?: any = { key: "value" }; + optVoidProp1?: void = undefined; + optNullProp1?: null = null; + optUndefinedProp1?: undefined = undefined; + optObjectProp1?: object = { name: "John", age: 30 }; + optSendableClass1?: SendableClass = new SendableClass(); + optNoSendableClass1?: NoSendableClass = new NoSendableClass(); + + public optBooleanProp2: boolean = true; + public optNumberProp2: number = 42; + public optStringProp2: string = "Hello"; + public optArrayProp2: number[] = [1, 2, 3]; + public optTupleProp2: [string, number] = ["typescript", 4]; + public optEnumProp2: Color = Color.Green; + public optAnyProp2: any = { key: "value" }; + public optVoidProp2: void = undefined; + public optNullProp2: null = null; + public optUndefinedProp2: undefined = undefined; + public optObjectProp2: object = { name: "John", age: 30 }; + public optSendableClass2: SendableClass = new SendableClass(); + public optNoSendableClass2: NoSendableClass = new NoSendableClass(); + + readonly optBooleanProp3: boolean = true; + readonly optNumberProp3: number = 42; + readonly optStringProp3: string = "Hello"; + readonly optArrayProp3: number[] = [1, 2, 3]; + readonly optTupleProp3: [string, number] = ["typescript", 4]; + readonly optEnumProp3: Color = Color.Green; + readonly optAnyProp3: any = { key: "value" }; + readonly optVoidProp3: void = undefined; + readonly optNullProp3: null = null; + readonly optUndefinedProp3: undefined = undefined; + readonly optObjectProp3: object = { name: "John", age: 30 }; + readonly optSendableClass3: SendableClass = new SendableClass(); + readonly optNoSendableClass3: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp4: boolean = true; + numberProp4: number = 42; + stringProp4: string = "Hello"; + arrayProp4: number[] = [1, 2, 3]; + tupleProp4: (string | number)[] = ["typescript", 4]; + enumProp4: Color = Color.Green; + anyProp4: GeneratedObjectLiteralInterface_9 = { key: "value" }; + voidProp4: undefined = undefined; + nullProp4: null = null; + undefinedProp4: undefined = undefined; + objectProp4: GeneratedObjectLiteralInterface_10 = { name: "John", age: 30 }; + sendableClass4: SendableClass = new SendableClass(); + noSendableClass4: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp5?: boolean | undefined = true; + numberProp5?: number | undefined = 42; + stringProp5?: string | undefined = "Hello"; + arrayProp5?: number[] | undefined = [1, 2, 3]; + tupleProp5?: (string | number)[] | undefined = ["typescript", 4]; + enumProp5?: Color | undefined = Color.Green; + anyProp5?: GeneratedObjectLiteralInterface_11 = { key: "value" }; + voidProp5?: undefined = undefined; + nullProp5?: null | undefined = null; + undefinedProp5?: undefined = undefined; + objectProp5?: GeneratedObjectLiteralInterface_12 = { name: "John", age: 30 }; + sendableClass5?: SendableClass | undefined = new SendableClass(); + noSendableClass5?: NoSendableClass | undefined = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + public optBooleanProp6: boolean = true; + public optNumberProp6: number = 42; + public optStringProp6: string = "Hello"; + public optArrayProp6: number[] = [1, 2, 3]; + public optTupleProp6: (string | number)[] = ["typescript", 4]; + public optEnumProp6: Color = Color.Green; + public optAnyProp6: GeneratedObjectLiteralInterface_13 = { key: "value" }; + public optVoidProp6: undefined = undefined; + public optNullProp6: null = null; + public optUndefinedProp6: undefined = undefined; + public optObjectProp6: GeneratedObjectLiteralInterface_14 = { name: "John", age: 30 }; + public optSendableClass6: SendableClass = new SendableClass(); + public optNoSendableClass6: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + readonly optBooleanProp7: true = true; + readonly optNumberProp7: 42 = 42; + readonly optStringProp7: "Hello" = "Hello"; + readonly optArrayProp7: number[] = [1, 2, 3]; + readonly optTupleProp7: (string | number)[] = ["typescript", 4]; + readonly optEnumProp7: Color.Green = Color.Green; + readonly optAnyProp7: GeneratedObjectLiteralInterface_15 = { key: "value" }; + readonly optVoidProp7: undefined = undefined; + readonly optNullProp7: null = null; + readonly optUndefinedProp7: undefined = undefined; + readonly optObjectProp7: GeneratedObjectLiteralInterface_16 = { name: "John", age: 30 }; + readonly optSendableClass7: SendableClass = new SendableClass(); + readonly optNoSendableClass7: NoSendableClass = new NoSendableClass(); +} + +interface GeneratedObjectLiteralInterface_17 { + key: string; +} +interface GeneratedObjectLiteralInterface_18 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_19 { + key: string; +} +interface GeneratedObjectLiteralInterface_20 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_21 { + key: string; +} +interface GeneratedObjectLiteralInterface_22 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_23 { + key: string; +} +interface GeneratedObjectLiteralInterface_24 { + name: string; + age: number; +} +@Sendable +class A2 implements lang.ISendable { + booleanProp: boolean = true; + numberProp: number = 42; + stringProp: string = "Hello"; + arrayProp: number[] = [1, 2, 3]; + tupleProp: [string, number] = ["typescript", 4]; + enumProp: Color = Color.Green; + anyProp: any = { key: "value" }; + voidProp: void = undefined; + nullProp: null = null; + undefinedProp: undefined = undefined; + objectProp: object = { name: "John", age: 30 }; + sendableClass: SendableClass = new SendableClass(); + noSendableClass: NoSendableClass = new NoSendableClass(); + + optBooleanProp1?: boolean = true; + optNumberProp1?: number = 42; + optStringProp1?: string = "Hello"; + optArrayProp1?: number[] = [1, 2, 3]; + optTupleProp1?: [string, number] = ["typescript", 4]; + optEnumProp1?: Color = Color.Green; + optAnyProp1?: any = { key: "value" }; + optVoidProp1?: void = undefined; + optNullProp1?: null = null; + optUndefinedProp1?: undefined = undefined; + optObjectProp1?: object = { name: "John", age: 30 }; + optSendableClass1?: SendableClass = new SendableClass(); + optNoSendableClass1?: NoSendableClass = new NoSendableClass(); + + public optBooleanProp2: boolean = true; + public optNumberProp2: number = 42; + public optStringProp2: string = "Hello"; + public optArrayProp2: number[] = [1, 2, 3]; + public optTupleProp2: [string, number] = ["typescript", 4]; + public optEnumProp2: Color = Color.Green; + public optAnyProp2: any = { key: "value" }; + public optVoidProp2: void = undefined; + public optNullProp2: null = null; + public optUndefinedProp2: undefined = undefined; + public optObjectProp2: object = { name: "John", age: 30 }; + public optSendableClass2: SendableClass = new SendableClass(); + public optNoSendableClass2: NoSendableClass = new NoSendableClass(); + + readonly optBooleanProp3: boolean = true; + readonly optNumberProp3: number = 42; + readonly optStringProp3: string = "Hello"; + readonly optArrayProp3: number[] = [1, 2, 3]; + readonly optTupleProp3: [string, number] = ["typescript", 4]; + readonly optEnumProp3: Color = Color.Green; + readonly optAnyProp3: any = { key: "value" }; + readonly optVoidProp3: void = undefined; + readonly optNullProp3: null = null; + readonly optUndefinedProp3: undefined = undefined; + readonly optObjectProp3: object = { name: "John", age: 30 }; + readonly optSendableClass3: SendableClass = new SendableClass(); + readonly optNoSendableClass3: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp4: boolean = true; + numberProp4: number = 42; + stringProp4: string = "Hello"; + arrayProp4: number[] = [1, 2, 3]; + tupleProp4: (string | number)[] = ["typescript", 4]; + enumProp4: Color = Color.Green; + anyProp4: GeneratedObjectLiteralInterface_17 = { key: "value" }; + voidProp4: undefined = undefined; + nullProp4: null = null; + undefinedProp4: undefined = undefined; + objectProp4: GeneratedObjectLiteralInterface_18 = { name: "John", age: 30 }; + sendableClass4: SendableClass = new SendableClass(); + noSendableClass4: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp5?: boolean | undefined = true; + numberProp5?: number | undefined = 42; + stringProp5?: string | undefined = "Hello"; + arrayProp5?: number[] | undefined = [1, 2, 3]; + tupleProp5?: (string | number)[] | undefined = ["typescript", 4]; + enumProp5?: Color | undefined = Color.Green; + anyProp5?: GeneratedObjectLiteralInterface_19 = { key: "value" }; + voidProp5?: undefined = undefined; + nullProp5?: null | undefined = null; + undefinedProp5?: undefined = undefined; + objectProp5?: GeneratedObjectLiteralInterface_20 = { name: "John", age: 30 }; + sendableClass5?: SendableClass | undefined = new SendableClass(); + noSendableClass5?: NoSendableClass | undefined = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + public optBooleanProp6: boolean = true; + public optNumberProp6: number = 42; + public optStringProp6: string = "Hello"; + public optArrayProp6: number[] = [1, 2, 3]; + public optTupleProp6: (string | number)[] = ["typescript", 4]; + public optEnumProp6: Color = Color.Green; + public optAnyProp6: GeneratedObjectLiteralInterface_21 = { key: "value" }; + public optVoidProp6: undefined = undefined; + public optNullProp6: null = null; + public optUndefinedProp6: undefined = undefined; + public optObjectProp6: GeneratedObjectLiteralInterface_22 = { name: "John", age: 30 }; + public optSendableClass6: SendableClass = new SendableClass(); + public optNoSendableClass6: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + readonly optBooleanProp7: true = true; + readonly optNumberProp7: 42 = 42; + readonly optStringProp7: "Hello" = "Hello"; + readonly optArrayProp7: number[] = [1, 2, 3]; + readonly optTupleProp7: (string | number)[] = ["typescript", 4]; + readonly optEnumProp7: Color.Green = Color.Green; + readonly optAnyProp7: GeneratedObjectLiteralInterface_23 = { key: "value" }; + readonly optVoidProp7: undefined = undefined; + readonly optNullProp7: null = null; + readonly optUndefinedProp7: undefined = undefined; + readonly optObjectProp7: GeneratedObjectLiteralInterface_24 = { name: "John", age: 30 }; + readonly optSendableClass7: SendableClass = new SendableClass(); + readonly optNoSendableClass7: NoSendableClass = new NoSendableClass(); +} + +interface GeneratedObjectLiteralInterface_25 { + key: string; +} +interface GeneratedObjectLiteralInterface_26 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_27 { + key: string; +} +interface GeneratedObjectLiteralInterface_28 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_29 { + key: string; +} +interface GeneratedObjectLiteralInterface_30 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_31 { + key: string; +} +interface GeneratedObjectLiteralInterface_32 { + name: string; + age: number; +} +class A3 { + booleanProp: boolean = true; + numberProp: number = 42; + stringProp: string = "Hello"; + arrayProp: number[] = [1, 2, 3]; + tupleProp: [string, number] = ["typescript", 4]; + enumProp: Color = Color.Green; + anyProp: any = { key: "value" }; + voidProp: void = undefined; + nullProp: null = null; + undefinedProp: undefined = undefined; + objectProp: object = { name: "John", age: 30 }; + sendableClass: SendableClass = new SendableClass(); + noSendableClass: NoSendableClass = new NoSendableClass(); + + optBooleanProp1?: boolean = true; + optNumberProp1?: number = 42; + optStringProp1?: string = "Hello"; + optArrayProp1?: number[] = [1, 2, 3]; + optTupleProp1?: [string, number] = ["typescript", 4]; + optEnumProp1?: Color = Color.Green; + optAnyProp1?: any = { key: "value" }; + optVoidProp1?: void = undefined; + optNullProp1?: null = null; + optUndefinedProp1?: undefined = undefined; + optObjectProp1?: object = { name: "John", age: 30 }; + optSendableClass1?: SendableClass = new SendableClass(); + optNoSendableClass1?: NoSendableClass = new NoSendableClass(); + + public optBooleanProp2: boolean = true; + public optNumberProp2: number = 42; + public optStringProp2: string = "Hello"; + public optArrayProp2: number[] = [1, 2, 3]; + public optTupleProp2: [string, number] = ["typescript", 4]; + public optEnumProp2: Color = Color.Green; + public optAnyProp2: any = { key: "value" }; + public optVoidProp2: void = undefined; + public optNullProp2: null = null; + public optUndefinedProp2: undefined = undefined; + public optObjectProp2: object = { name: "John", age: 30 }; + public optSendableClass2: SendableClass = new SendableClass(); + public optNoSendableClass2: NoSendableClass = new NoSendableClass(); + + readonly optBooleanProp3: boolean = true; + readonly optNumberProp3: number = 42; + readonly optStringProp3: string = "Hello"; + readonly optArrayProp3: number[] = [1, 2, 3]; + readonly optTupleProp3: [string, number] = ["typescript", 4]; + readonly optEnumProp3: Color = Color.Green; + readonly optAnyProp3: any = { key: "value" }; + readonly optVoidProp3: void = undefined; + readonly optNullProp3: null = null; + readonly optUndefinedProp3: undefined = undefined; + readonly optObjectProp3: object = { name: "John", age: 30 }; + readonly optSendableClass3: SendableClass = new SendableClass(); + readonly optNoSendableClass3: NoSendableClass = new NoSendableClass(); + + booleanProp4 = true; + numberProp4 = 42; + stringProp4 = "Hello"; + arrayProp4 = [1, 2, 3]; + tupleProp4 = ["typescript", 4]; + enumProp4 = Color.Green; + anyProp4: GeneratedObjectLiteralInterface_25 = { key: "value" }; + voidProp4 = undefined; + nullProp4 = null; + undefinedProp4 = undefined; + objectProp4: GeneratedObjectLiteralInterface_26 = { name: "John", age: 30 }; + sendableClass4 = new SendableClass(); + noSendableClass4 = new NoSendableClass(); + + booleanProp5? = true; + numberProp5? = 42; + stringProp5? = "Hello"; + arrayProp5? = [1, 2, 3]; + tupleProp5? = ["typescript", 4]; + enumProp5? = Color.Green; + anyProp5?: GeneratedObjectLiteralInterface_27 = { key: "value" }; + voidProp5? = undefined; + nullProp5? = null; + undefinedProp5? = undefined; + objectProp5?: GeneratedObjectLiteralInterface_28 = { name: "John", age: 30 }; + sendableClass5? = new SendableClass(); + noSendableClass5? = new NoSendableClass(); + + public optBooleanProp6 = true; + public optNumberProp6 = 42; + public optStringProp6 = "Hello"; + public optArrayProp6 = [1, 2, 3]; + public optTupleProp6 = ["typescript", 4]; + public optEnumProp6 = Color.Green; + public optAnyProp6: GeneratedObjectLiteralInterface_29 = { key: "value" }; + public optVoidProp6 = undefined; + public optNullProp6 = null; + public optUndefinedProp6 = undefined; + public optObjectProp6: GeneratedObjectLiteralInterface_30 = { name: "John", age: 30 }; + public optSendableClass6 = new SendableClass(); + public optNoSendableClass6 = new NoSendableClass(); + + readonly optBooleanProp7 = true; + readonly optNumberProp7 = 42; + readonly optStringProp7 = "Hello"; + readonly optArrayProp7 = [1, 2, 3]; + readonly optTupleProp7 = ["typescript", 4]; + readonly optEnumProp7 = Color.Green; + readonly optAnyProp7: GeneratedObjectLiteralInterface_31 = { key: "value" }; + readonly optVoidProp7 = undefined; + readonly optNullProp7 = null; + readonly optUndefinedProp7 = undefined; + readonly optObjectProp7: GeneratedObjectLiteralInterface_32 = { name: "John", age: 30 }; + readonly optSendableClass7 = new SendableClass(); + readonly optNoSendableClass7 = new NoSendableClass(); +} + +interface I extends lang.ISendable { + booleanProp: boolean; + numberProp: number; + stringProp: string; + arrayProp: number[]; + tupleProp: [string, number]; + enumProp: Color; + anyProp: any; + voidProp: void; + nullProp: null; + undefinedProp: undefined; + objectProp: object; + sendableClass: SendableClass; + noSendableClass: NoSendableClass; + + optBooleanProp1?: boolean; + optNumberProp1?: number; + optStringProp1?: string; + optArrayProp1?: number[]; + optTupleProp1?: [string, number]; + optEnumProp1?: Color; + optAnyProp1?: any; + optVoidProp1?: void; + optNullProp1?: null; + optUndefinedProp1?: undefined; + optObjectProp1?: object; + optSendableClass1?: SendableClass; + optNoSendableClass1?: NoSendableClass; + + readonly optBooleanProp3: boolean; + readonly optNumberProp3: number; + readonly optStringProp3: string; + readonly optArrayProp3: number[]; + readonly optTupleProp3: [string, number]; + readonly optEnumProp3: Color; + readonly optAnyProp3: any; + readonly optVoidProp3: void; + readonly optNullProp3: null; + readonly optUndefinedProp3: undefined; + readonly optObjectProp3: object; + readonly optSendableClass3: SendableClass; + readonly optNoSendableClass3: NoSendableClass; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.json b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..b8c6d94da97f3dde594b2f0e940b89889bbcdc23 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.json @@ -0,0 +1,2498 @@ +{ + "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": 66, + "column": 23, + "endLine": 66, + "endColumn": 28, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 44, + "endLine": 73, + "endColumn": 59, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 28, + "endLine": 80, + "endColumn": 33, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 49, + "endLine": 87, + "endColumn": 64, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 34, + "endLine": 94, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 55, + "endLine": 101, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 36, + "endLine": 108, + "endColumn": 41, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 57, + "endLine": 115, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 24, + "endLine": 123, + "endColumn": 29, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 45, + "endLine": 130, + "endColumn": 60, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 37, + "endLine": 138, + "endColumn": 42, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 58, + "endLine": 145, + "endColumn": 73, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 34, + "endLine": 153, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 55, + "endLine": 160, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 42, + "endLine": 168, + "endColumn": 47, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 57, + "endLine": 175, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 53, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 35, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 14, + "endLine": 67, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 5, + "endLine": 68, + "endColumn": 32, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 52, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 26, + "endLine": 71, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 62, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 5, + "endLine": 78, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 58, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 40, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 19, + "endLine": 81, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 31, + "endLine": 85, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 5, + "endLine": 92, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 5, + "endLine": 93, + "endColumn": 64, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 5, + "endLine": 94, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 5, + "endLine": 95, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 25, + "endLine": 95, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 5, + "endLine": 96, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 5, + "endLine": 99, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 37, + "endLine": 99, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 5, + "endLine": 101, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 5, + "endLine": 106, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 5, + "endLine": 107, + "endColumn": 66, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 5, + "endLine": 108, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 5, + "endLine": 109, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 27, + "endLine": 109, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 5, + "endLine": 110, + "endColumn": 45, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 5, + "endLine": 113, + "endColumn": 65, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 39, + "endLine": 113, + "endColumn": 40, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 5, + "endLine": 115, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 5, + "endLine": 121, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 5, + "endLine": 122, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 5, + "endLine": 123, + "endColumn": 36, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 5, + "endLine": 124, + "endColumn": 68, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 5, + "endLine": 128, + "endColumn": 80, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 5, + "endLine": 130, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 5, + "endLine": 136, + "endColumn": 51, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 5, + "endLine": 137, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 5, + "endLine": 138, + "endColumn": 49, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 5, + "endLine": 139, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 5, + "endLine": 143, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 5, + "endLine": 145, + "endColumn": 76, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 5, + "endLine": 151, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 5, + "endLine": 153, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 5, + "endLine": 154, + "endColumn": 78, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 5, + "endLine": 158, + "endColumn": 90, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 5, + "endLine": 160, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 5, + "endLine": 163, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 5, + "endLine": 164, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 165, + "column": 5, + "endLine": 165, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 5, + "endLine": 166, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 5, + "endLine": 167, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 5, + "endLine": 168, + "endColumn": 54, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 5, + "endLine": 169, + "endColumn": 80, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 5, + "endLine": 173, + "endColumn": 92, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 5, + "endLine": 175, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 216, + "column": 23, + "endLine": 216, + "endColumn": 28, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 223, + "column": 44, + "endLine": 223, + "endColumn": 59, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 28, + "endLine": 230, + "endColumn": 33, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 237, + "column": 49, + "endLine": 237, + "endColumn": 64, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 34, + "endLine": 244, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 251, + "column": 55, + "endLine": 251, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 36, + "endLine": 258, + "endColumn": 41, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 265, + "column": 57, + "endLine": 265, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 24, + "endLine": 273, + "endColumn": 29, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 45, + "endLine": 280, + "endColumn": 60, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 288, + "column": 37, + "endLine": 288, + "endColumn": 42, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 295, + "column": 58, + "endLine": 295, + "endColumn": 73, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 303, + "column": 34, + "endLine": 303, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 310, + "column": 55, + "endLine": 310, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 42, + "endLine": 318, + "endColumn": 47, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 325, + "column": 57, + "endLine": 325, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 214, + "column": 5, + "endLine": 214, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 215, + "column": 5, + "endLine": 215, + "endColumn": 53, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 216, + "column": 5, + "endLine": 216, + "endColumn": 35, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 5, + "endLine": 217, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 14, + "endLine": 217, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 218, + "column": 5, + "endLine": 218, + "endColumn": 32, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 221, + "column": 5, + "endLine": 221, + "endColumn": 52, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 221, + "column": 26, + "endLine": 221, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 223, + "column": 5, + "endLine": 223, + "endColumn": 62, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 5, + "endLine": 228, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 229, + "column": 5, + "endLine": 229, + "endColumn": 58, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 5, + "endLine": 230, + "endColumn": 40, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 231, + "column": 5, + "endLine": 231, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 231, + "column": 19, + "endLine": 231, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 232, + "column": 5, + "endLine": 232, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 235, + "column": 5, + "endLine": 235, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 235, + "column": 31, + "endLine": 235, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 237, + "column": 5, + "endLine": 237, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 242, + "column": 5, + "endLine": 242, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 5, + "endLine": 243, + "endColumn": 64, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 5, + "endLine": 244, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 245, + "column": 5, + "endLine": 245, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 245, + "column": 25, + "endLine": 245, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 246, + "column": 5, + "endLine": 246, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 249, + "column": 5, + "endLine": 249, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 249, + "column": 37, + "endLine": 249, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 251, + "column": 5, + "endLine": 251, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 256, + "column": 5, + "endLine": 256, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 257, + "column": 5, + "endLine": 257, + "endColumn": 66, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 5, + "endLine": 258, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 259, + "column": 5, + "endLine": 259, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 259, + "column": 27, + "endLine": 259, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 260, + "column": 5, + "endLine": 260, + "endColumn": 45, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 5, + "endLine": 263, + "endColumn": 65, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 39, + "endLine": 263, + "endColumn": 40, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 265, + "column": 5, + "endLine": 265, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 5, + "endLine": 271, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 272, + "column": 5, + "endLine": 272, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 5, + "endLine": 273, + "endColumn": 36, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 274, + "column": 5, + "endLine": 274, + "endColumn": 68, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 278, + "column": 5, + "endLine": 278, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 5, + "endLine": 280, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 286, + "column": 5, + "endLine": 286, + "endColumn": 51, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 5, + "endLine": 287, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 288, + "column": 5, + "endLine": 288, + "endColumn": 49, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 289, + "column": 5, + "endLine": 289, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 293, + "column": 5, + "endLine": 293, + "endColumn": 82, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 295, + "column": 5, + "endLine": 295, + "endColumn": 76, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 301, + "column": 5, + "endLine": 301, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 302, + "column": 5, + "endLine": 302, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 303, + "column": 5, + "endLine": 303, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 304, + "column": 5, + "endLine": 304, + "endColumn": 79, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 308, + "column": 5, + "endLine": 308, + "endColumn": 91, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 310, + "column": 5, + "endLine": 310, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 5, + "endLine": 313, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 314, + "column": 5, + "endLine": 314, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 315, + "column": 5, + "endLine": 315, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 5, + "endLine": 316, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 317, + "column": 5, + "endLine": 317, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 5, + "endLine": 318, + "endColumn": 54, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 319, + "column": 5, + "endLine": 319, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 323, + "column": 5, + "endLine": 323, + "endColumn": 93, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 325, + "column": 5, + "endLine": 325, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 363, + "column": 23, + "endLine": 363, + "endColumn": 28, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 370, + "column": 44, + "endLine": 370, + "endColumn": 59, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 377, + "column": 28, + "endLine": 377, + "endColumn": 33, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 384, + "column": 49, + "endLine": 384, + "endColumn": 64, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 391, + "column": 34, + "endLine": 391, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 398, + "column": 55, + "endLine": 398, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 405, + "column": 36, + "endLine": 405, + "endColumn": 41, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 412, + "column": 57, + "endLine": 412, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 420, + "column": 24, + "endLine": 420, + "endColumn": 29, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 427, + "column": 45, + "endLine": 427, + "endColumn": 60, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 435, + "column": 37, + "endLine": 435, + "endColumn": 42, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 442, + "column": 58, + "endLine": 442, + "endColumn": 73, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 450, + "column": 34, + "endLine": 450, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 457, + "column": 55, + "endLine": 457, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 465, + "column": 42, + "endLine": 465, + "endColumn": 47, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 472, + "column": 57, + "endLine": 472, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 361, + "column": 5, + "endLine": 361, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 362, + "column": 5, + "endLine": 362, + "endColumn": 53, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 363, + "column": 5, + "endLine": 363, + "endColumn": 35, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 364, + "column": 5, + "endLine": 364, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 364, + "column": 14, + "endLine": 364, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 365, + "column": 5, + "endLine": 365, + "endColumn": 32, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 368, + "column": 5, + "endLine": 368, + "endColumn": 52, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 368, + "column": 26, + "endLine": 368, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 370, + "column": 5, + "endLine": 370, + "endColumn": 62, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 375, + "column": 5, + "endLine": 375, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 376, + "column": 5, + "endLine": 376, + "endColumn": 58, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 377, + "column": 5, + "endLine": 377, + "endColumn": 40, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 378, + "column": 5, + "endLine": 378, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 378, + "column": 19, + "endLine": 378, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 379, + "column": 5, + "endLine": 379, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 382, + "column": 5, + "endLine": 382, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 382, + "column": 31, + "endLine": 382, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 384, + "column": 5, + "endLine": 384, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 389, + "column": 5, + "endLine": 389, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 390, + "column": 5, + "endLine": 390, + "endColumn": 64, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 391, + "column": 5, + "endLine": 391, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 392, + "column": 5, + "endLine": 392, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 392, + "column": 25, + "endLine": 392, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 393, + "column": 5, + "endLine": 393, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 396, + "column": 5, + "endLine": 396, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 396, + "column": 37, + "endLine": 396, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 398, + "column": 5, + "endLine": 398, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 403, + "column": 5, + "endLine": 403, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 404, + "column": 5, + "endLine": 404, + "endColumn": 66, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 405, + "column": 5, + "endLine": 405, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 406, + "column": 5, + "endLine": 406, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 406, + "column": 27, + "endLine": 406, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 407, + "column": 5, + "endLine": 407, + "endColumn": 45, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 410, + "column": 5, + "endLine": 410, + "endColumn": 65, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 410, + "column": 39, + "endLine": 410, + "endColumn": 40, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 412, + "column": 5, + "endLine": 412, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 418, + "column": 5, + "endLine": 418, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 419, + "column": 5, + "endLine": 419, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 420, + "column": 5, + "endLine": 420, + "endColumn": 36, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 421, + "column": 5, + "endLine": 421, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 425, + "column": 5, + "endLine": 425, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 427, + "column": 5, + "endLine": 427, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 433, + "column": 5, + "endLine": 433, + "endColumn": 51, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 434, + "column": 5, + "endLine": 434, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 435, + "column": 5, + "endLine": 435, + "endColumn": 49, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 436, + "column": 5, + "endLine": 436, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 440, + "column": 5, + "endLine": 440, + "endColumn": 82, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 442, + "column": 5, + "endLine": 442, + "endColumn": 76, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 448, + "column": 5, + "endLine": 448, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 449, + "column": 5, + "endLine": 449, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 450, + "column": 5, + "endLine": 450, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 451, + "column": 5, + "endLine": 451, + "endColumn": 79, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 455, + "column": 5, + "endLine": 455, + "endColumn": 91, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 457, + "column": 5, + "endLine": 457, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 460, + "column": 5, + "endLine": 460, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 461, + "column": 5, + "endLine": 461, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 462, + "column": 5, + "endLine": 462, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 463, + "column": 5, + "endLine": 463, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 464, + "column": 5, + "endLine": 464, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 465, + "column": 5, + "endLine": 465, + "endColumn": 54, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 466, + "column": 5, + "endLine": 466, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 470, + "column": 5, + "endLine": 470, + "endColumn": 93, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 472, + "column": 5, + "endLine": 472, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 510, + "column": 14, + "endLine": 510, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 514, + "column": 26, + "endLine": 514, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 524, + "column": 19, + "endLine": 524, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 528, + "column": 31, + "endLine": 528, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 538, + "column": 25, + "endLine": 538, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 542, + "column": 37, + "endLine": 542, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 552, + "column": 27, + "endLine": 552, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 556, + "column": 39, + "endLine": 556, + "endColumn": 40, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 624, + "column": 14, + "endLine": 624, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 638, + "column": 19, + "endLine": 638, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 652, + "column": 27, + "endLine": 652, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.args.json b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.args.json +++ b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.autofix.json b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.autofix.json index 4debe785776201f8b8a308d021e0af56b941e5e0..210cf70cd25cd718ae339791a7815e4ecc5966dd 100644 --- a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.autofix.json +++ b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.autofix.json @@ -22,9 +22,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 647, - "end": 673, - "replacementText": "// fixable\na: number = 0;" + "start": 668, + "end": 668, + "replacementText": ": number" } ], "suggest": "", @@ -39,9 +39,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 673, - "end": 693, - "replacementText": "static b: string = ' ';" + "start": 686, + "end": 686, + "replacementText": ": string" } ], "suggest": "", @@ -56,9 +56,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 693, - "end": 720, - "replacementText": "private c: undefined = undefined;" + "start": 707, + "end": 707, + "replacementText": ": undefined" } ], "suggest": "", @@ -73,9 +73,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 720, - "end": 751, - "replacementText": "public static d: A = new A();" + "start": 740, + "end": 740, + "replacementText": ": A" } ], "suggest": "", @@ -90,9 +90,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 751, - "end": 764, - "replacementText": "e?: number | undefined = 10;" + "start": 758, + "end": 758, + "replacementText": ": number | undefined" } ], "suggest": "", @@ -107,9 +107,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 764, - "end": 783, - "replacementText": "f: number[] = [1, 2, 3];" + "start": 770, + "end": 770, + "replacementText": ": number[]" } ], "suggest": "", diff --git a/ets2panda/linter/test/migrate/parameter_properties.sts b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.ets similarity index 52% rename from ets2panda/linter/test/migrate/parameter_properties.sts rename to ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.ets index d6878228fd421a282f65636dece4d068fc28604b..75be1fcd7712126eb96e0d736a8c144f55114080 100644 --- a/ets2panda/linter/test/migrate/parameter_properties.sts +++ b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.ets @@ -13,36 +13,35 @@ * limitations under the License. */ +@Sendable class A { - constructor( - public readonly x: number, - protected y: number, - private z: number - ) {} - - foo(): void { - console.log(this.x + this.y + this.z); - } } -const a = new A(1, 2, 3); -console.log(a.x); - -class B { - public f: number = 10; - - constructor(q: number, public w = 'default', e: boolean, private readonly r: number[] = [1, 2, 3]) { - console.log(q, this.w, e, this.r, this.f); - } +interface GeneratedObjectLiteralInterface_1 { + e1: number; + e2: string; } - -const b = new B(1, '2', true, []); -console.log(b.w); - -class C { - constructor(public a: any) {} // not fixable +@Sendable +class B { + // fixable + a: number = 0; + static b: string = ' '; + private c: undefined = undefined; + public static d: A = new A(); + e?: number | undefined = 10; + f: number[] = [1, 2, 3]; + + // not fixable + bad; + + ehelper1: number = 4; + ehelper2: string = 'abc'; + public bad3: GeneratedObjectLiteralInterface_1 = { + e1: this.ehelper1, + e2: this.ehelper2 + }; + + constructor(x: boolean) { + this.bad = x; + } } - -class D { - constructor(public a: number, private b: {x: string}) {} // not fixable -} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.json b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ab1db740e7d949840de01758ecef958cd5a438bb --- /dev/null +++ b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 5, + "endLine": 32, + "endColumn": 29, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 9, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 9, + "problem": "SendableExplicitFieldType", + "suggest": "", + "rule": "Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 42, + "endColumn": 7, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_function.ets.args.json b/ets2panda/linter/test/main/sendable_function.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_function.ets.args.json +++ b/ets2panda/linter/test/main/sendable_function.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_function.ets.migrate.ets b/ets2panda/linter/test/main/sendable_function.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..2c4a30f42de8bd637c7ddf7af21fa85c383a376a --- /dev/null +++ b/ets2panda/linter/test/main/sendable_function.ets.migrate.ets @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { D_Sft, D_Nft } from './sendable_function_dependencie'; +import { + D_sf, Dv_sf, D_nf, Dv_nf, Dv_Sft, Dv_Nft, D_Sc, D_Nc, + D_sf as AS_D_sf, Dv_sf as AS_Dv_sf, D_nf as AS_D_nf, Dv_nf as AS_Dv_nf, + D_Sft as AS_D_Sft, Dv_Sft as AS_Dv_Sft, D_Nft as AS_D_Nft, Dv_Nft as AS_Dv_Nft, + D_Sc as AS_D_Sc, D_Nc as AS_D_Nc +} from './sendable_function_dependencie'; + +// -------------------- check sendable-function declaration -------------------- // +@Sendable +function sf():void {} // OK +@Sendable +function stf(p:T):T { + return p; +} // OK +@Sendable +@Other // ERROR +function sf2():void {} + + +// check overloading +@Sendable +function sf3():void; // OK +@Sendable +function sf3():void; + +@Sendable +function sf3():void {} + +@Sendable +function sf4():void; +@Sendable +function sf4():void; // ERROR +@Sendable +function sf4():void {} + +@Sendable +function sf5():void; + +@Sendable +@Other // ERROR +function sf5():void; + +@Sendable +function sf5():void {} + +function nf():void {} + +// -------------------- check sendable-typealias declaration -------------------- // +@Sendable +type Sft = () => void; // OK +@Sendable +type Sft2 = () => void; // OK +@Sendable +type Sft3 = (p:T) => T; // OK +@Sendable +@Other // ERROR +type Sft4 = () => void; +@Sendable +type Sft5 = number; // ERROR +@Sendable +type Sft6 = Sft; // ERROR +type Sft7 = () => void; + +@Sendable +type Sft8 = Sft4; // ERROR + +type Nft = ()=>void; + +// -------------------- check sendable-function closure -------------------- // +@Sendable +class Sc {} +class Nc {} + +@Sendable +class SendableClassClosure { + constructor() { + const a1:Sft = sf; // OK + const a2:Nft = nf; // ERROR + const a3:Sc = new Sc(); // OK + const a4:Nc = new Nc(); // ERROR + + const b1:D_Sft = D_sf; // OK + const b2:D_Nft = D_nf; // OK + const b3:D_Sc = new D_Sc(); // OK + const b4:D_Nc = new D_Nc(); // OK + } + + @nf + handle() {} +} + +@Sendable +@nf +function SendableFunctionClosure() { + const a1:Sft = sf; // OK + const a2:Nft = nf; // ERROR + const a3:Sc = new Sc(); // OK + const a4:Nc = new Nc(); // ERROR + const b1:D_Sft = D_sf; // OK + const b2:D_Nft = D_nf; // OK + const b3:D_Sc = new D_Sc(); // OK + const b4:D_Nc = new D_Nc(); // OK +} + +namespace ns { + @Sendable + function sf():void; + @Sendable + function sf():void {} +} + + + +// -------------------- check sendable-typealias is sendaboe-data-type -------------------- // + + +// check property +@Sendable +class Sc2 { + p1: Sft = sf; // OK + p2: D_Nft = sf; // ERROR +} +// check genericity +new Sc2(); +new Sc2(); // ERROR + +// -------------------- check sendable-function cannot operation property --------------------// +sf.prop = 1; // ERROR +D_nf.prop = 1; // OK +D_sf.prop = 1; // ERROR +AS_D_sf.prop = 1;// ERROR + +// -------------------- check sendable-function assignment --------------------// + +@Sendable +function stf1(p:T):T {return p;}; +function ntf1(p:T):T {return p}; +// +const of1 = ()=>{}; +// +@Sendable +type Stft1 = (p:T)=>T; +@Sendable +type Stft2 = ()=>void; +// +type Nft1 = ()=>void; +type Nft2 = ()=>number; +type Ntft1 = (p:T)=>T; +type Ntft2 = ()=>void; +// +type U_Sft1 = Sft | D_Sft; +type U_Sft2 = Sft | Stft1; +type U_Nft1 = Nft1 | Nft2; +type U_Nft2 = Nft1 | Ntft1; +type U_ft1 = Sft | Nft1; +type U_ft2 = Sft | Stft1| Nft1 | Ntft1; +// +type TU_Sft1 = Sft | D_Sft; +type TU_Sft2 = Sft | Stft1 | Stft1 ; +type TU_Nft1 = Nft1 | Nft2; +type TU_Nft2 = Nft1 | Ntft1| Ntft2; +type TU_ft1 = Sft | Stft1 | Nft1 | Ntft1; +// +type DU_Sft1 = U_Sft1 | U_Sft2; +type DU_Sft2 = DU_Sft1 | TU_Sft1; +type DU_Sft3 = DU_Sft2 | TU_Sft2; +type DU_Nft = DU_Sft3 | TU_Nft2; +// normal +const a1: Sft = sf; // OK +const a2: Sft = nf; // ERROR +const a3: Sft = of1; // ERROR +const a4: Nft1 = nf; // OK +const a5: Sft = a1; // OK +const a6: Sft = a4; // ERROR +// generic +const b1: Stft1 = stf1; // OK +const b2: Stft1 = ntf1; // ERROR +const b3: Ntft1 = ntf1; // OK +const b4: Stft1 = b1; // OK +const b5: Stft1 = b3; // ERROR +// unite +const f1: U_ft1 = sf; // OK +const f2: U_ft2 = stf1; // OK +const f3: U_ft1 = nf; // ERROR +const f4: U_ft2 = ntf1; // ERROR +const d1: U_Sft1 = sf; // OK +const d2: U_Sft1 = nf; // ERROR +const d3: U_Sft1 = of1; // ERROR +const d4: U_Nft1 = sf; // OK +const d5: U_Nft1 = nf; // OK +const d6: U_Nft1 = of1; // OK +const d7: U_Sft1 = d1; // OK +const d18: U_Sft1 = d4; // ERROR +const d9: U_Sft1 = f1; // ERROR +// const d10: U_Sft1 = f2; // ERROR +const e1: U_Sft2 = stf1; // OK +const e2: U_Sft2 = ntf1; // ERROR +const e3: U_Nft2 = ntf1; // OK +const e4: U_Sft2 = e1; // OK +const e5: U_Sft2 = e3; // ERROR +const e6: U_Sft2 = f1; // ERROR +const e7: U_Sft2 = f2; // ERROR +// unite & generic +const g1: TU_ft1 = sf; // OK +const g2: TU_ft1 = stf1; // OK +const g3: TU_ft1 = nf; // ERROR +const h1: TU_Sft1 = sf; // OK +const h2: TU_Sft1 = nf; // ERROR +const h3: TU_Sft1 = of1; // ERROR +const h4: TU_Nft1 = nf; // OK +const h5: TU_Sft1 = h1; // OK +const h6: TU_Sft1 = h4; // ERROR +const h7: TU_Sft2 = stf1; // OK +const h8: TU_Sft2 = ntf1; // ERROR diff --git a/ets2panda/linter/test/main/sendable_function.ets.migrate.json b/ets2panda/linter/test/main/sendable_function.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..405511857491108238c01607fa2232a95dbd0fa5 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_function.ets.migrate.json @@ -0,0 +1,388 @@ +{ + "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": 1, + "endLine": 32, + "endColumn": 7, + "problem": "SendableFunctionDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" function (arkts-sendable-function-decorator)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 1, + "endLine": 56, + "endColumn": 7, + "problem": "SendableFunctionDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" function (arkts-sendable-function-decorator)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 7, + "problem": "SendableTypeAliasDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" typeAlias (arkts-sendable-typealias-decorator)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 13, + "endLine": 75, + "endColumn": 19, + "problem": "SendableTypeAliasDeclaration", + "suggest": "", + "rule": "Only \"FunctionType\" can declare \"Sendable\" typeAlias (arkts-sendable-typeAlias-declaration)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 13, + "endLine": 77, + "endColumn": 16, + "problem": "SendableTypeAliasDeclaration", + "suggest": "", + "rule": "Only \"FunctionType\" can declare \"Sendable\" typeAlias (arkts-sendable-typeAlias-declaration)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 13, + "endLine": 81, + "endColumn": 17, + "problem": "SendableTypeAliasDeclaration", + "suggest": "", + "rule": "Only \"FunctionType\" can declare \"Sendable\" typeAlias (arkts-sendable-typeAlias-declaration)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 20, + "endLine": 94, + "endColumn": 22, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 23, + "endLine": 96, + "endColumn": 25, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 6, + "problem": "SendableClassDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" class (arkts-sendable-class-decorator)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 1, + "endLine": 109, + "endColumn": 4, + "problem": "SendableFunctionDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" function (arkts-sendable-function-decorator)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 18, + "endLine": 112, + "endColumn": 20, + "problem": "SendableFunctionImportedVariables", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" function (arkts-sendable-function-imported-variables)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 21, + "endLine": 114, + "endColumn": 23, + "problem": "SendableFunctionImportedVariables", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" function (arkts-sendable-function-imported-variables)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 3, + "endLine": 137, + "endColumn": 18, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 9, + "endLine": 141, + "endColumn": 14, + "problem": "SendableGenericTypes", + "suggest": "", + "rule": "Type arguments of generic \"Sendable\" type must be a \"Sendable\" data type (arkts-sendable-generic-types)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 1, + "endLine": 144, + "endColumn": 8, + "problem": "SendableFunctionProperty", + "suggest": "", + "rule": "The property of \"Sendable\" function is limited (arkts-sendable-function-property)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 1, + "endLine": 146, + "endColumn": 10, + "problem": "SendableFunctionProperty", + "suggest": "", + "rule": "The property of \"Sendable\" function is limited (arkts-sendable-function-property)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 1, + "endLine": 147, + "endColumn": 13, + "problem": "SendableFunctionProperty", + "suggest": "", + "rule": "The property of \"Sendable\" function is limited (arkts-sendable-function-property)", + "severity": "ERROR" + }, + { + "line": 186, + "column": 7, + "endLine": 186, + "endColumn": 19, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 7, + "endLine": 187, + "endColumn": 20, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 190, + "column": 7, + "endLine": 190, + "endColumn": 19, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 7, + "endLine": 193, + "endColumn": 23, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 196, + "column": 7, + "endLine": 196, + "endColumn": 21, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 7, + "endLine": 200, + "endColumn": 21, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 7, + "endLine": 201, + "endColumn": 23, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 7, + "endLine": 203, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 204, + "column": 7, + "endLine": 204, + "endColumn": 23, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 7, + "endLine": 209, + "endColumn": 23, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 210, + "column": 7, + "endLine": 210, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 213, + "column": 7, + "endLine": 213, + "endColumn": 24, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 216, + "column": 7, + "endLine": 216, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 7, + "endLine": 217, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 218, + "column": 7, + "endLine": 218, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 222, + "column": 7, + "endLine": 222, + "endColumn": 30, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 7, + "endLine": 224, + "endColumn": 31, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 7, + "endLine": 225, + "endColumn": 32, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 7, + "endLine": 228, + "endColumn": 31, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 7, + "endLine": 230, + "endColumn": 33, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_function_2.ets.args.json b/ets2panda/linter/test/main/sendable_function_2.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_function_2.ets.args.json +++ b/ets2panda/linter/test/main/sendable_function_2.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_function_2.ets.migrate.ets b/ets2panda/linter/test/main/sendable_function_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..db2a902510a9c6414d2012845baabb3e4eafba5f --- /dev/null +++ b/ets2panda/linter/test/main/sendable_function_2.ets.migrate.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +@Sendable +function foo(name: string): void; +@Sendable +function foo(age: number): void; // Fixable +@Sendable +function foo(...args: Object[]): void {} // Fixable + +@Sendable +function bar(name: string): void; // Fixable +@Sendable +function bar(age: number): void; // Fixable +@Sendable +function bar(...args: Object[]): void {} diff --git a/ets2panda/linter/test/main/sendable_function_2.ets.migrate.json b/ets2panda/linter/test/main/sendable_function_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_function_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/static_class.ets b/ets2panda/linter/test/main/static_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..3316c3afad05c8a0fda1c2720b05810e896a190e --- /dev/null +++ b/ets2panda/linter/test/main/static_class.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ +'use static' + +class A { + static { + console.log("Shouldn't be here"); + } +} diff --git a/ets2panda/linter/test/main/static_class.ets.args.json b/ets2panda/linter/test/main/static_class.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..8a4be28991e8164c0366b8b3ad0dffbc04910a27 --- /dev/null +++ b/ets2panda/linter/test/main/static_class.ets.args.json @@ -0,0 +1,20 @@ +{ + "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": "", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/main/static_class.ets.arkts2.json b/ets2panda/linter/test/main/static_class.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..614cb2e9da0d7473cfd9fc84d6da43667358ccc4 --- /dev/null +++ b/ets2panda/linter/test/main/static_class.ets.arkts2.json @@ -0,0 +1,28 @@ +{ + "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": 5, + "endLine": 20, + "endColumn": 6, + "problem": "NoStaticOnClass", + "suggest": "", + "rule": "Class cannot have static codeblocks. (arkts-class-lazy-import)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/static_class.ets.json b/ets2panda/linter/test/main/static_class.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd1b7140ca95b67336908f5fca6dec77fb46b2c0 --- /dev/null +++ b/ets2panda/linter/test/main/static_class.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/static_class.ets.migrate.ets b/ets2panda/linter/test/main/static_class.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3316c3afad05c8a0fda1c2720b05810e896a190e --- /dev/null +++ b/ets2panda/linter/test/main/static_class.ets.migrate.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ +'use static' + +class A { + static { + console.log("Shouldn't be here"); + } +} diff --git a/ets2panda/linter/test/main/static_class.ets.migrate.json b/ets2panda/linter/test/main/static_class.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..614cb2e9da0d7473cfd9fc84d6da43667358ccc4 --- /dev/null +++ b/ets2panda/linter/test/main/static_class.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 5, + "endLine": 20, + "endColumn": 6, + "problem": "NoStaticOnClass", + "suggest": "", + "rule": "Class cannot have static codeblocks. (arkts-class-lazy-import)", + "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 2546e534df7bc2c559cc498d384d9ac2ae666388..a3b9b0c1a18acbcb484dd177dbc136b68056466c 100644 --- a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json +++ b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json @@ -974,26 +974,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 480, - "column": 1, - "endLine": 480, - "endColumn": 10, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", - "severity": "ERROR" - }, - { - "line": 485, - "column": 1, - "endLine": 485, - "endColumn": 10, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", - "severity": "ERROR" - }, { "line": 502, "column": 7, @@ -1344,16 +1324,6 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, - { - "line": 622, - "column": 50, - "endLine": 622, - "endColumn": 58, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 626, "column": 5, @@ -1575,4 +1545,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.args.json b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..df6e67a5c9292c4c7e7aa5e976a3b8d1104fa082 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.args.json @@ -1,20 +1,21 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "mode": { - "arkts2": "", - "autofix": "--arkts-2" - } + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.arkts2.json index ff8b6e8a6e4c49d1c23a7a078547243f61adf83c..1bf55e2d4c97c0d7db9df4c1ae69dad934df5d31 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.arkts2.json @@ -16,9 +16,9 @@ "result": [ { "line": 27, - "column": 6, + "column": 18, "endLine": 40, - "endColumn": 7, + "endColumn": 6, "problem": "StylesDecoratorNotSupported", "suggest": "", "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.autofix.json index bbf6e8f769202d557312c4fba405acee1fca4352..d6ed03103fd54f9bb04c15856abb4d54290c9a0c 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.autofix.json @@ -16,9 +16,9 @@ "result": [ { "line": 27, - "column": 6, + "column": 18, "endLine": 40, - "endColumn": 7, + "endColumn": 6, "problem": "StylesDecoratorNotSupported", "autofix": [ { diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..26b949ad3751a102e09f12b6e79ffb87396fb64e --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI'; + +@Entry +@Component +struct TestStateStyle { + @BuilderParam + @Require + content: () => void; + + build() { + Button() { + this.content + } + .stateStyles({ + normal: (instance: CommonMethod): void => { + instance.backgroundColor("#00ffff"); + instance.borderWidth(8); + }, + pressed: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + instance.backgroundImagePosition({ + x: 0, + y: 0 + }); + instance.backgroundColor("#ffff00"); + } + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.args.json b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0888e5b74cd5c44c475b4f91aefe12e0cbd5d8b --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI'; + +@Entry +@Component +struct TestStateStyle { + @BuilderParam + @Require + content: () => void; + + build() { + Button() { + this.content + } + .stateStyles({ + normal: (instance: CommonMethod): void => { + instance.backgroundColor("#00ffff"); + instance.borderWidth(8); + }, + pressed: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + instance.backgroundImagePosition({ + x: 0, + y: 0 + }); + instance.backgroundColor("#ffff00"); + } + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets b/ets2panda/linter/test/main/styles_decorator_global_1.ets index e7ebe0041b60903801359902091a1c030ba1b925..0c7853382e20805550eb2507a6138c19791e1d46 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets @@ -32,9 +32,10 @@ function cardStyle1() struct MyCard1 { build() { Column() { - + Text("TestStyles").cardStyle1() } .cardStyle1() + .backgroundColor(Color.Red) } } diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.args.json b/ets2panda/linter/test/main/styles_decorator_global_1.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_global_1.ets.arkts2.json index 58303d7e15646cb449b19cf618a9323fed7a2b5c..775283b08efecf00adb1b66e1f9ce188f305b031 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.arkts2.json @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 42, "column": 1, - "endLine": 44, + "endLine": 45, "endColumn": 2, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 46, + "line": 47, "column": 1, - "endLine": 49, + "endLine": 50, "endColumn": 2, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -75,9 +75,29 @@ "severity": "ERROR" }, { - "line": 51, + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 26, + "endLine": 38, + "endColumn": 31, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, "column": 2, - "endLine": 51, + "endLine": 52, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -85,9 +105,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 54, "column": 6, - "endLine": 53, + "endLine": 54, "endColumn": 18, "problem": "UIInterfaceImport", "suggest": "", @@ -95,9 +115,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 55, "column": 6, - "endLine": 54, + "endLine": 55, "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", @@ -105,9 +125,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 59, "column": 9, - "endLine": 58, + "endLine": 59, "endColumn": 15, "problem": "UIInterfaceImport", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_global_1.ets.autofix.json index e385b5de1708603bdad9ff8438e7ef2ec1e524b3..e7bb004c0391b3b8e3aa2fcf6f52b5518e8b9664 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.autofix.json @@ -27,8 +27,13 @@ "replacementText": "function cardStyle1(instance: CommonMethod): void {\n instance.backgroundColor(mycolor);\n instance.borderColor(Color.Red);\n instance.borderRadius(8);\n instance.padding(8);\n instance.backgroundImagePosition({\n x: 0,\n y: 0\n });\n}" }, { - "start": 918, - "end": 930, + "start": 929, + "end": 941, + "replacementText": "applyStyles(cardStyle1)" + }, + { + "start": 961, + "end": 973, "replacementText": "applyStyles(cardStyle1)" } ], @@ -37,15 +42,15 @@ "severity": "ERROR" }, { - "line": 41, + "line": 42, "column": 1, - "endLine": 44, + "endLine": 45, "endColumn": 2, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 940, - "end": 1007, + "start": 1019, + "end": 1086, "replacementText": "function NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}" } ], @@ -54,15 +59,15 @@ "severity": "ERROR" }, { - "line": 46, + "line": 47, "column": 1, - "endLine": 49, + "endLine": 50, "endColumn": 2, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 1009, - "end": 1077, + "start": 1088, + "end": 1156, "replacementText": "function PressedStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}" } ], @@ -80,7 +85,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" } ], "suggest": "", @@ -97,7 +102,7 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" } ], "suggest": "", @@ -114,7 +119,24 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 17, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" } ], "suggest": "", @@ -122,16 +144,33 @@ "severity": "ERROR" }, { - "line": 51, + "line": 38, + "column": 26, + "endLine": 38, + "endColumn": 31, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, "column": 2, - "endLine": 51, + "endLine": 52, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" } ], "suggest": "", @@ -139,16 +178,16 @@ "severity": "ERROR" }, { - "line": 53, + "line": 54, "column": 6, - "endLine": 53, + "endLine": 54, "endColumn": 18, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" } ], "suggest": "", @@ -156,16 +195,16 @@ "severity": "ERROR" }, { - "line": 54, + "line": 55, "column": 6, - "endLine": 54, + "endLine": 55, "endColumn": 13, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" } ], "suggest": "", @@ -173,16 +212,16 @@ "severity": "ERROR" }, { - "line": 58, + "line": 59, "column": 9, - "endLine": 58, + "endLine": 59, "endColumn": 15, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" } ], "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..fd272fd000da58d98840d17fbb58c3de7fc89e21 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.ets @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; + +const mycolor: string = "#ffff00" + +function cardStyle1(instance: CommonMethod): void { + instance.backgroundColor(mycolor); + instance.borderColor(Color.Red); + instance.borderRadius(8); + instance.padding(8); + instance.backgroundImagePosition({ + x: 0, + y: 0 + }); +} + +@Component +struct MyCard1 { + build() { + Column() { + Text("TestStyles").applyStyles(cardStyle1) + } + .applyStyles(cardStyle1) + .backgroundColor(Color.Red) + } +} + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor("#ffffff"); +} + +function PressedStyles(instance: CommonMethod): void { + instance.backgroundColor("#ffffff"); +} + +@Component +struct MyButton { + @BuilderParam + @Require + content: () => void; + + build() { + Button() { + this.content() + } + .stateStyles({ + normal: NormalStyles, + pressed: PressedStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets b/ets2panda/linter/test/main/styles_decorator_global_2.ets index a3f4363eb4e87f081db895b3a7c9d3eb19326ce8..fd272fd000da58d98840d17fbb58c3de7fc89e21 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kit.ArkUI'; +import { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; const mycolor: string = "#ffff00" @@ -32,9 +32,10 @@ function cardStyle1(instance: CommonMethod): void { struct MyCard1 { build() { Column() { - + Text("TestStyles").applyStyles(cardStyle1) } - applyStyles.cardStyle1() + .applyStyles(cardStyle1) + .backgroundColor(Color.Red) } } diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets.args.json b/ets2panda/linter/test/main/styles_decorator_global_2.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_2.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..fd272fd000da58d98840d17fbb58c3de7fc89e21 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.ets @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; + +const mycolor: string = "#ffff00" + +function cardStyle1(instance: CommonMethod): void { + instance.backgroundColor(mycolor); + instance.borderColor(Color.Red); + instance.borderRadius(8); + instance.padding(8); + instance.backgroundImagePosition({ + x: 0, + y: 0 + }); +} + +@Component +struct MyCard1 { + build() { + Column() { + Text("TestStyles").applyStyles(cardStyle1) + } + .applyStyles(cardStyle1) + .backgroundColor(Color.Red) + } +} + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor("#ffffff"); +} + +function PressedStyles(instance: CommonMethod): void { + instance.backgroundColor("#ffffff"); +} + +@Component +struct MyButton { + @BuilderParam + @Require + content: () => void; + + build() { + Button() { + this.content() + } + .stateStyles({ + normal: NormalStyles, + pressed: PressedStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets b/ets2panda/linter/test/main/styles_decorator_mix_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..040d2154f7bdae6d19d54cf1e0c4256c2824a71a --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets @@ -0,0 +1,92 @@ +/* + * 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. + */ + +@Styles +function NormalStyles() { + .backgroundColor(Color.Blue) +} + +@Entry +@Component +struct MyButton1 { + @BuilderParam + @Require + content: () => void; + + @Styles + PressedStyles() { + .backgroundColor(Color.Green) + } + + build() { + Button("MyButton1") { + this.content + } + .stateStyles({ + pressed: this.PressedStyles, + selected: { + .backgroundColor(Color.Red) + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton2 { + @BuilderParam + @Require + content: () => void; + + build() { + Button("MyButton2") { + this.content + } + .stateStyles({ + selected: { + .backgroundColor(Color.Red) + }, + normal: NormalStyles, + }) + } +} + +@Component +struct MyButton3 { + + build() { + Button("MyButton3") + .stateStyles({ + normal: NormalStyles, + selected: { + .backgroundColor(Color.Red) + } + }) + } +} + +@Component +struct MyButton4 { + + build() { + Button("MyButton4") + .stateStyles({ + selected: { + .backgroundColor(Color.Red) + }, + normal: NormalStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.args.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/func_return_type.ts.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json similarity index 33% rename from ets2panda/linter/test/migrate/func_return_type.ts.json rename to ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json index 00be5f244b8ce3b6ab16fa954aa0368a9bc39cf2..b0c53b4c8e59d1cb200b077428a1b0c7d7cf5173 100644 --- a/ets2panda/linter/test/migrate/func_return_type.ts.json +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "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", @@ -16,262 +16,252 @@ "result": [ { "line": 16, - "column": 10, - "endLine": 16, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 10, - "endLine": 23, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "column": 1, + "endLine": 19, + "endColumn": 2, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 33, - "column": 10, - "endLine": 33, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "line": 28, + "column": 3, + "endLine": 31, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 40, - "column": 10, - "endLine": 40, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "line": 37, + "column": 18, + "endLine": 43, + "endColumn": 6, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 46, - "column": 10, - "endLine": 46, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "line": 57, + "column": 18, + "endLine": 62, + "endColumn": 6, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 54, - "column": 10, - "endLine": 54, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "line": 71, + "column": 20, + "endLine": 76, + "endColumn": 8, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 57, - "column": 10, - "endLine": 57, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", + "line": 85, + "column": 20, + "endLine": 90, + "endColumn": 8, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 57, - "column": 15, - "endLine": 57, - "endColumn": 18, - "problem": "AnyType", + "line": 18, + "column": 22, + "endLine": 18, + "endColumn": 27, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 62, - "column": 12, - "endLine": 64, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 7, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 65, - "column": 12, - "endLine": 67, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 69, - "column": 12, - "endLine": 71, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 24, + "column": 4, + "endLine": 24, + "endColumn": 16, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 73, - "column": 12, - "endLine": 75, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 25, + "column": 4, + "endLine": 25, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 76, - "column": 12, - "endLine": 78, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 30, + "column": 22, + "endLine": 30, + "endColumn": 27, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 80, - "column": 12, - "endLine": 82, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 80, - "column": 12, - "endLine": 82, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 40, + "column": 26, + "endLine": 40, + "endColumn": 31, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 86, - "column": 12, - "endLine": 88, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 47, + "column": 2, + "endLine": 47, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 97, - "column": 12, - "endLine": 99, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 16, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 104, - "column": 12, - "endLine": 106, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 50, + "column": 4, + "endLine": 50, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 114, - "column": 3, - "endLine": 114, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", + "line": 59, + "column": 26, + "endLine": 59, + "endColumn": 31, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", + "line": 66, + "column": 2, + "endLine": 66, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 126, - "column": 3, - "endLine": 126, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 131, - "column": 10, - "endLine": 131, - "endColumn": 30, - "problem": "LimitedReturnTypeInference", + "line": 74, + "column": 28, + "endLine": 74, + "endColumn": 33, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 135, - "column": 18, - "endLine": 135, - "endColumn": 40, - "problem": "LimitedReturnTypeInference", + "line": 80, + "column": 2, + "endLine": 80, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 139, - "column": 3, - "endLine": 139, - "endColumn": 10, - "problem": "LimitedReturnTypeInference", + "line": 84, + "column": 5, + "endLine": 84, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 144, - "column": 3, - "endLine": 144, - "endColumn": 7, - "problem": "LimitedReturnTypeInference", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..a84810a9e76f91e0a4988d7bb703da2ca2631e99 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.autofix.json @@ -0,0 +1,443 @@ +{ + "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": 1, + "endLine": 19, + "endColumn": 2, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 605, + "end": 673, + "replacementText": "function NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(Color.Blue);\n}" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 3, + "endLine": 31, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 765, + "end": 830, + "replacementText": "PressedStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n };" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 18, + "endLine": 43, + "endColumn": 6, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 912, + "end": 1044, + "replacementText": "{\n pressed: this.PressedStyles,\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 18, + "endLine": 62, + "endColumn": 6, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 1214, + "end": 1312, + "replacementText": "{\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 20, + "endLine": 76, + "endColumn": 8, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 1407, + "end": 1514, + "replacementText": "{\n normal: NormalStyles,\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n }\n }" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 20, + "endLine": 90, + "endColumn": 8, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 1609, + "end": 1716, + "replacementText": "{\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 22, + "endLine": 18, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 4, + "endLine": 24, + "endColumn": 16, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 4, + "endLine": 25, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 22, + "endLine": 30, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 26, + "endLine": 40, + "endColumn": 31, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 2, + "endLine": 47, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 16, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 4, + "endLine": 50, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 26, + "endLine": 59, + "endColumn": 31, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 2, + "endLine": 66, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 28, + "endLine": 74, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 2, + "endLine": 80, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 5, + "endLine": 84, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_2.ets b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.ets similarity index 31% rename from ets2panda/linter/test/main/data_observation_2.ets rename to ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.ets index 7a9160706720ace81bccd778b4f898706cdad034..4e9c2b35e023074c8d1813a6a7c22a487bd97e25 100644 --- a/ets2panda/linter/test/main/data_observation_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.ets @@ -13,82 +13,80 @@ * limitations under the License. */ -import { Observed, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kit.ArkUI'; +import { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; -@Observed -class MyClassA {} - -@Observed -class MyClassB { - name: string = '' +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor(Color.Blue); } -@Observed -class MyClassC1 {} - -@Observed -class MyClassC2 extends MyClassC1 {} - -@Observed -class MyClassC3 extends MyClassC2 {} - -@Observed -class MyClassD extends MyClassC3 {} - -class MyClassC4 extends MyClassD {} - -interface IntfA {} - -@Observed -class MyClassE implements IntfA {} - -@Observed -class MyClassF {} - -@Observed -class MyClassG {} +@Entry +@Component +struct MyButton1 { + @BuilderParam + @Require + content: () => void; -@Observed -class MyClassH {} + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; -@Observed -class MyClassI {} + build() { + Button("MyButton1") { + this.content + } + .stateStyles({ + pressed: this.PressedStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} -@Observed -class MyClassJ extends MyClassI {} +@Component +struct MyButton2 { + @BuilderParam + @Require + content: () => void; -@Observed -class MyClassK extends MyClassJ {} + build() { + Button("MyButton2") { + this.content + } + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} -@Entry @Component -struct Test { - @State data1: number = 0 - @State data2: MyClassA = new MyClassA() - @State data3: MyClassB = { name: "jack" } - @State data4: MyClassC2 = new MyClassD() - @State data5: IntfA = new MyClassE() - @Prop data6: MyClassE = new MyClassE() - @Prop data7: MyClassF = new MyClassF() - @Prop data8: MyClassG | MyClassH | number = 0 - @Prop data9: MyClassJ = new MyClassK() - @Provide selectedDate: Date = new Date('2021-08-08') - @StorageLink('PropB') storageLink: MyClassA = new MyClassA() - @LocalStorageLink('LinkB') localStorageLink: MyClassB = new MyClassB() - @StorageProp('test') test1: MyClassC2 = new MyClassC3() - @LocalStorageProp('test') test2: MyClassD = new MyClassD() +struct MyButton3 { build() { - + Button("MyButton3") + .stateStyles({ + normal: NormalStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + } + }) } } @Component -struct MyComponent { - @Link data2: MyClassA - @Consume selectedDate: Date +struct MyButton4 { build() { - + Button("MyButton4") + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets b/ets2panda/linter/test/main/styles_decorator_mix_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e9c2b35e023074c8d1813a6a7c22a487bd97e25 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor(Color.Blue); +} + +@Entry +@Component +struct MyButton1 { + @BuilderParam + @Require + content: () => void; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button("MyButton1") { + this.content + } + .stateStyles({ + pressed: this.PressedStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton2 { + @BuilderParam + @Require + content: () => void; + + build() { + Button("MyButton2") { + this.content + } + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton3 { + + build() { + Button("MyButton3") + .stateStyles({ + normal: NormalStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + } + }) + } +} + +@Component +struct MyButton4 { + + build() { + Button("MyButton4") + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.args.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.arkts2.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.autofix.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e9c2b35e023074c8d1813a6a7c22a487bd97e25 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.ets @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor(Color.Blue); +} + +@Entry +@Component +struct MyButton1 { + @BuilderParam + @Require + content: () => void; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button("MyButton1") { + this.content + } + .stateStyles({ + pressed: this.PressedStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton2 { + @BuilderParam + @Require + content: () => void; + + build() { + Button("MyButton2") { + this.content + } + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton3 { + + build() { + Button("MyButton3") + .stateStyles({ + normal: NormalStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + } + }) + } +} + +@Component +struct MyButton4 { + + build() { + Button("MyButton4") + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets b/ets2panda/linter/test/main/styles_decorator_struct_1.ets index f757e64088b7094e7077cfff802789c8bc7e2f00..d6be55373484396d021fdc85e09448c25cdab905 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets @@ -23,9 +23,10 @@ struct MyCard1 { build() { Column() { - Text('Card') + Text('Card').cardStyle1() } .cardStyle1() + .backgroundColor(Color.Red) } } @@ -50,9 +51,10 @@ struct MyCard2 { build() { Column() { - Text('Card') + Text('Card').cardStyle2() } .cardStyle2() + .backgroundColor(Color.Red) } } @@ -77,8 +79,8 @@ struct MyButton { this.content } .stateStyles({ - normal: this.NormalStyles(), - pressed: this.PressedStyles() + normal: this.NormalStyles, + pressed: this.PressedStyles }) } } diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.args.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json index a1342457933cab440fe7eff7da4b977ad19ad9d4..7c09951b771c9d6b27fd76b5762aa06dd34596ed 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 34, + "line": 35, "column": 3, - "endLine": 41, + "endLine": 42, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 65, + "line": 67, "column": 3, - "endLine": 68, + "endLine": 70, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 72, "column": 3, - "endLine": 73, + "endLine": 75, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -55,29 +55,9 @@ "severity": "ERROR" }, { - "line": 80, - "column": 15, - "endLine": 80, - "endColumn": 34, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 16, - "endLine": 81, - "endColumn": 36, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 103, + "line": 105, "column": 3, - "endLine": 116, + "endLine": 118, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -85,9 +65,9 @@ "severity": "ERROR" }, { - "line": 106, + "line": 108, "column": 18, - "endLine": 114, + "endLine": 116, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -125,9 +105,19 @@ "severity": "ERROR" }, { - "line": 32, + "line": 29, + "column": 22, + "endLine": 29, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, "column": 2, - "endLine": 32, + "endLine": 33, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -135,9 +125,9 @@ "severity": "ERROR" }, { - "line": 43, + "line": 44, "column": 23, - "endLine": 43, + "endLine": 44, "endColumn": 28, "problem": "UIInterfaceImport", "suggest": "", @@ -145,9 +135,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 45, "column": 12, - "endLine": 44, + "endLine": 45, "endColumn": 17, "problem": "UIInterfaceImport", "suggest": "", @@ -155,9 +145,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 53, "column": 5, - "endLine": 52, + "endLine": 53, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -165,9 +155,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 54, "column": 7, - "endLine": 53, + "endLine": 54, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -175,9 +165,19 @@ "severity": "ERROR" }, { - "line": 59, + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 61, "column": 2, - "endLine": 59, + "endLine": 61, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -185,9 +185,9 @@ "severity": "ERROR" }, { - "line": 61, + "line": 63, "column": 4, - "endLine": 61, + "endLine": 63, "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", @@ -195,9 +195,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 64, "column": 4, - "endLine": 62, + "endLine": 64, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -205,9 +205,9 @@ "severity": "ERROR" }, { - "line": 67, + "line": 69, "column": 22, - "endLine": 67, + "endLine": 69, "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", @@ -215,9 +215,9 @@ "severity": "ERROR" }, { - "line": 72, + "line": 74, "column": 22, - "endLine": 72, + "endLine": 74, "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", @@ -225,9 +225,9 @@ "severity": "ERROR" }, { - "line": 76, + "line": 78, "column": 5, - "endLine": 76, + "endLine": 78, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -235,9 +235,9 @@ "severity": "ERROR" }, { - "line": 97, + "line": 99, "column": 2, - "endLine": 97, + "endLine": 99, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -245,9 +245,9 @@ "severity": "ERROR" }, { - "line": 101, + "line": 103, "column": 24, - "endLine": 101, + "endLine": 103, "endColumn": 37, "problem": "UIInterfaceImport", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json index 778dc5b85f0a49d047603565553cdc3410f3c167..aeedca2d7d6aaf5a377682d2d3c52cded5b91662 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json @@ -27,8 +27,13 @@ "replacementText": "cardStyle1 = (instance: CommonMethod): void => {\n instance.backgroundColor('#ffffff');\n instance.borderRadius(8);\n };" }, { - "start": 775, - "end": 787, + "start": 764, + "end": 776, + "replacementText": "applyStyles(this.cardStyle1)" + }, + { + "start": 788, + "end": 800, "replacementText": "applyStyles(this.cardStyle1)" } ], @@ -37,20 +42,25 @@ "severity": "ERROR" }, { - "line": 34, + "line": 35, "column": 3, - "endLine": 41, + "endLine": 42, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 825, - "end": 965, + "start": 870, + "end": 1010, "replacementText": "cardStyle2 = (instance: CommonMethod): void => {\n instance.border({\n color: this.getColor(),\n width: this.getWidth()\n });\n instance.backgroundColor('#ffffff');\n };" }, { - "start": 1134, - "end": 1146, + "start": 1168, + "end": 1180, + "replacementText": "applyStyles(this.cardStyle2)" + }, + { + "start": 1192, + "end": 1204, "replacementText": "applyStyles(this.cardStyle2)" } ], @@ -59,15 +69,15 @@ "severity": "ERROR" }, { - "line": 65, + "line": 67, "column": 3, - "endLine": 68, + "endLine": 70, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 1236, - "end": 1298, + "start": 1326, + "end": 1388, "replacementText": "NormalStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n };" } ], @@ -76,15 +86,15 @@ "severity": "ERROR" }, { - "line": 70, + "line": 72, "column": 3, - "endLine": 73, + "endLine": 75, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 1302, - "end": 1367, + "start": 1392, + "end": 1457, "replacementText": "PressedStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n };" } ], @@ -93,35 +103,15 @@ "severity": "ERROR" }, { - "line": 80, - "column": 15, - "endLine": 80, - "endColumn": 34, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 16, - "endLine": 81, - "endColumn": 36, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 103, + "line": 105, "column": 3, - "endLine": 116, + "endLine": 118, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 1867, - "end": 2363, + "start": 1953, + "end": 2449, "replacementText": "imageStyle = (instance: CommonMethod): void => {\n instance.draggable(this.isShowLongPressMenu() && this.isPC());\n instance.onDragStart(() => {\n console.info(TAG, 'onDragStart');\n this.touchVibrate(VibrateType.DRAG);\n if (this.mediaItem?.path) {\n this.previewUri =\n this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true);\n }\n return this.DragBuilder;\n });\n instance.accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : '');\n };" } ], @@ -130,9 +120,9 @@ "severity": "ERROR" }, { - "line": 106, + "line": 108, "column": 18, - "endLine": 114, + "endLine": 116, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -191,9 +181,26 @@ "severity": "ERROR" }, { - "line": 32, + "line": 29, + "column": 22, + "endLine": 29, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, "column": 2, - "endLine": 32, + "endLine": 33, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -208,9 +215,9 @@ "severity": "ERROR" }, { - "line": 43, + "line": 44, "column": 23, - "endLine": 43, + "endLine": 44, "endColumn": 28, "problem": "UIInterfaceImport", "autofix": [ @@ -225,9 +232,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 45, "column": 12, - "endLine": 44, + "endLine": 45, "endColumn": 17, "problem": "UIInterfaceImport", "autofix": [ @@ -242,9 +249,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 53, "column": 5, - "endLine": 52, + "endLine": 53, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -259,9 +266,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 54, "column": 7, - "endLine": 53, + "endLine": 54, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -276,9 +283,26 @@ "severity": "ERROR" }, { - "line": 59, + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 61, "column": 2, - "endLine": 59, + "endLine": 61, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -293,9 +317,9 @@ "severity": "ERROR" }, { - "line": 61, + "line": 63, "column": 4, - "endLine": 61, + "endLine": 63, "endColumn": 16, "problem": "UIInterfaceImport", "autofix": [ @@ -310,9 +334,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 64, "column": 4, - "endLine": 62, + "endLine": 64, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -327,9 +351,9 @@ "severity": "ERROR" }, { - "line": 67, + "line": 69, "column": 22, - "endLine": 67, + "endLine": 69, "endColumn": 27, "problem": "UIInterfaceImport", "autofix": [ @@ -344,9 +368,9 @@ "severity": "ERROR" }, { - "line": 72, + "line": 74, "column": 22, - "endLine": 72, + "endLine": 74, "endColumn": 27, "problem": "UIInterfaceImport", "autofix": [ @@ -361,9 +385,9 @@ "severity": "ERROR" }, { - "line": 76, + "line": 78, "column": 5, - "endLine": 76, + "endLine": 78, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -378,9 +402,9 @@ "severity": "ERROR" }, { - "line": 97, + "line": 99, "column": 2, - "endLine": 97, + "endLine": 99, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ @@ -395,9 +419,9 @@ "severity": "ERROR" }, { - "line": 101, + "line": 103, "column": 24, - "endLine": 101, + "endLine": 103, "endColumn": 37, "problem": "UIInterfaceImport", "autofix": [ diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.json index 3b43bc06e5c2374556829587ae98991a426fc956..967418d91151ac7a883ceec1516bb396845937e8 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 106, + "line": 108, "column": 18, - "endLine": 114, + "endLine": 116, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..31fb825cee110c0a92e0531cd375c90a965e6ec2 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.ets @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI'; + +@Component +struct MyCard1 { + cardStyle1 = (instance: CommonMethod): void => { + instance.backgroundColor('#ffffff'); + instance.borderRadius(8); + }; + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle1) + } + .applyStyles(this.cardStyle1) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyCard2 { + cardStyle2 = (instance: CommonMethod): void => { + instance.border({ + color: this.getColor(), + width: this.getWidth() + }); + instance.backgroundColor('#ffffff'); + }; + + private getColor(): Color { + return Color.Red + } + + private getWidth(): number { + return 10 + } + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle2) + } + .applyStyles(this.cardStyle2) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyButton { + @BuilderParam + @Require + content: () => void; + + NormalStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button() { + this.content + } + .stateStyles({ + normal: this.NormalStyles, + pressed: this.PressedStyles + }) + } +} + +const TAG: string = 'common_ImageTest'; + +class MediaItem { + public path: string = ''; + public uri: string = ''; + + public getDateModified(): string { + return '' + } +} + +@Component +struct imageTest { + private mediaItem: MediaItem | undefined; + private previewUri: string | undefined; + private DragBuilder: CustomBuilder | undefined; + + imageStyle = (instance: CommonMethod): void => { + instance.draggable(this.isShowLongPressMenu() && this.isPC()); + instance.onDragStart(() => { + console.info(TAG, 'onDragStart'); + this.touchVibrate(VibrateType.DRAG); + if (this.mediaItem?.path) { + this.previewUri = + this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true); + } + return this.DragBuilder; + }); + instance.accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : ''); + }; + + private isShowLongPressMenu(): boolean { + return true; + } + + private isPC(): boolean { + return true; + } + + private touchVibrate(type: VibrateType): void { + + } + + private isOpenTouchGuide: boolean = true; + + private getImageItemGridAccessibilityText(): string { + return '' + } + + private getPreviewUri(path: string, date: string, isOk: boolean, ready: boolean): string { + return '' + } + + build() { + + } +} + +enum VibrateType { + DRAG +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0e17a7dad5ec718d7915c535975cf8c692eecda6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 105, + "column": 26, + "endLine": 113, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets b/ets2panda/linter/test/main/styles_decorator_struct_2.ets index 82fe4ba1fedd0db5c562315a1925078b4f07f061..31fb825cee110c0a92e0531cd375c90a965e6ec2 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets @@ -24,9 +24,10 @@ struct MyCard1 { build() { Column() { - Text('Card') + Text('Card').applyStyles(this.cardStyle1) } - applyStyles.cardStyle1() + .applyStyles(this.cardStyle1) + .backgroundColor(Color.Red) } } @@ -34,9 +35,10 @@ struct MyCard1 { struct MyCard2 { cardStyle2 = (instance: CommonMethod): void => { instance.border({ - color: this.getColor(), - width: this.getWidth() + color: this.getColor(), + width: this.getWidth() }); + instance.backgroundColor('#ffffff'); }; private getColor(): Color { @@ -49,9 +51,10 @@ struct MyCard2 { build() { Column() { - Text('Card') + Text('Card').applyStyles(this.cardStyle2) } - .cardStyle2() + .applyStyles(this.cardStyle2) + .backgroundColor(Color.Red) } } @@ -63,19 +66,19 @@ struct MyButton { NormalStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Red); - } + }; PressedStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Green); - } + }; build() { Button() { this.content } .stateStyles({ - normal: this.NormalStyles(), - pressed: this.PressedStyles() + normal: this.NormalStyles, + pressed: this.PressedStyles }) } } @@ -100,13 +103,13 @@ struct imageTest { imageStyle = (instance: CommonMethod): void => { instance.draggable(this.isShowLongPressMenu() && this.isPC()); instance.onDragStart(() => { - console.info(TAG, 'onDragStart'); - this.touchVibrate(VibrateType.DRAG); - if (this.mediaItem?.path) { - this.previewUri = - this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true); - } - return this.DragBuilder; + console.info(TAG, 'onDragStart'); + this.touchVibrate(VibrateType.DRAG); + if (this.mediaItem?.path) { + this.previewUri = + this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true); + } + return this.DragBuilder; }); instance.accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : ''); }; diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.args.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json index 13eb52986b98db69515349797d9854342e51f483..0e17a7dad5ec718d7915c535975cf8c692eecda6 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json @@ -15,29 +15,9 @@ ], "result": [ { - "line": 77, - "column": 15, - "endLine": 77, - "endColumn": 34, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 16, - "endLine": 78, - "endColumn": 36, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 102, + "line": 105, "column": 26, - "endLine": 110, + "endLine": 113, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json index 13eb52986b98db69515349797d9854342e51f483..0e17a7dad5ec718d7915c535975cf8c692eecda6 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json @@ -15,29 +15,9 @@ ], "result": [ { - "line": 77, - "column": 15, - "endLine": 77, - "endColumn": 34, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 16, - "endLine": 78, - "endColumn": 36, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 102, + "line": 105, "column": 26, - "endLine": 110, + "endLine": 113, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json index ce898503c69ba29eb07c0796d24f68ee19c64d16..0e17a7dad5ec718d7915c535975cf8c692eecda6 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 102, + "line": 105, "column": 26, - "endLine": 110, + "endLine": 113, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..31fb825cee110c0a92e0531cd375c90a965e6ec2 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.ets @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI'; + +@Component +struct MyCard1 { + cardStyle1 = (instance: CommonMethod): void => { + instance.backgroundColor('#ffffff'); + instance.borderRadius(8); + }; + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle1) + } + .applyStyles(this.cardStyle1) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyCard2 { + cardStyle2 = (instance: CommonMethod): void => { + instance.border({ + color: this.getColor(), + width: this.getWidth() + }); + instance.backgroundColor('#ffffff'); + }; + + private getColor(): Color { + return Color.Red + } + + private getWidth(): number { + return 10 + } + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle2) + } + .applyStyles(this.cardStyle2) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyButton { + @BuilderParam + @Require + content: () => void; + + NormalStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button() { + this.content + } + .stateStyles({ + normal: this.NormalStyles, + pressed: this.PressedStyles + }) + } +} + +const TAG: string = 'common_ImageTest'; + +class MediaItem { + public path: string = ''; + public uri: string = ''; + + public getDateModified(): string { + return '' + } +} + +@Component +struct imageTest { + private mediaItem: MediaItem | undefined; + private previewUri: string | undefined; + private DragBuilder: CustomBuilder | undefined; + + imageStyle = (instance: CommonMethod): void => { + instance.draggable(this.isShowLongPressMenu() && this.isPC()); + instance.onDragStart(() => { + console.info(TAG, 'onDragStart'); + this.touchVibrate(VibrateType.DRAG); + if (this.mediaItem?.path) { + this.previewUri = + this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true); + } + return this.DragBuilder; + }); + instance.accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : ''); + }; + + private isShowLongPressMenu(): boolean { + return true; + } + + private isPC(): boolean { + return true; + } + + private touchVibrate(type: VibrateType): void { + + } + + private isOpenTouchGuide: boolean = true; + + private getImageItemGridAccessibilityText(): string { + return '' + } + + private getPreviewUri(path: string, date: string, isOk: boolean, ready: boolean): string { + return '' + } + + build() { + + } +} + +enum VibrateType { + DRAG +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0e17a7dad5ec718d7915c535975cf8c692eecda6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 105, + "column": 26, + "endLine": 113, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/subclass_super_call.ets b/ets2panda/linter/test/main/subclass_super_call.ets new file mode 100644 index 0000000000000000000000000000000000000000..d275725c9ced20f3df8eb301562897c1f14e3845 --- /dev/null +++ b/ets2panda/linter/test/main/subclass_super_call.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use static' + +class A { + constructor(a: number) { + } +} + +class B { + constructor() { + } +} + +class C extends A {} // ERROR + +class D extends A { // ERROR super is not called + constructor(a: number) {} +} + +class E extends A { // NO ERROR constructor is called + constructor(a: number) { + super(a); + } +} + +class F extends B {} // NO ERROR diff --git a/ets2panda/linter/test/sdkwhite/OptionalMethod1.ets.args.json b/ets2panda/linter/test/main/subclass_super_call.ets.args.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/OptionalMethod1.ets.args.json rename to ets2panda/linter/test/main/subclass_super_call.ets.args.json diff --git a/ets2panda/linter/test/main/subclass_super_call.ets.arkts2.json b/ets2panda/linter/test/main/subclass_super_call.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..289a83337b8aabfabe08c43a0ade753e39dfbf7b --- /dev/null +++ b/ets2panda/linter/test/main/subclass_super_call.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 27, + "column": 9, + "endLine": 27, + "endColumn": 18, + "problem": "MissingSuperCall", + "suggest": "", + "rule": "The subclass constructor must call the parent class's parametered constructor (arkts-subclass-must-call-super-constructor-with-args)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 9, + "endLine": 29, + "endColumn": 18, + "problem": "MissingSuperCall", + "suggest": "", + "rule": "The subclass constructor must call the parent class's parametered constructor (arkts-subclass-must-call-super-constructor-with-args)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/subclass_super_call.ets.json b/ets2panda/linter/test/main/subclass_super_call.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/main/subclass_super_call.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/swicth_expr.ets b/ets2panda/linter/test/main/swicth_expr.ets index 6cb0b9550ecd91cbaea82210f40fd01c818a35af..bdef6cc461c22f0c2d47d00bab87ad647f132bf4 100755 --- a/ets2panda/linter/test/main/swicth_expr.ets +++ b/ets2panda/linter/test/main/swicth_expr.ets @@ -31,7 +31,7 @@ switch (objValue) { break; default: console.log("Non-matching object"); - +} let arrayValue = [1, 2, 3]; @@ -220,4 +220,162 @@ switch (str11) { break case "world": console.log("Default Case") +} + +let isnum1: string | number = 1; +switch (isnum1) { + case 1.1: + console.log('It's num'); + break; + default: + console.log('F'); +} +// 整型 5.2fail +type sw1 = number + +function FunSw4(): sw1 { + return 1 +} + +switch (FunSw4()) { + case 1: + console.log('A'); + break; + default: + console.log('F'); +} + +// 浮点 5.2fail +type sw2 = number | string + +function FunSw5(): sw2 { + return 1.11 +} + +switch (FunSw5()) { + case 1.11: + console.log('A'); + break; + default: + console.log('F'); +} + +let number7 = Math.floor(1.5); +switch (number7) { + case Math.floor(1.5): + console.log("Case 1"); + break; + default: + console.log("Default case"); +} +switch (85 + 5.5) { + case 90.5: + console.log('A'); + break; + default: + console.log('F'); +} +const add = (a: number, b: number): number => a + b; +const result1 = add(10, 5); +switch (result1) { + case 15: + console.log('A'); + break; + case 14: + console.log('B'); + break; + default: + console.log('F'); +} +function FunSw2(): number { + return 1.1 +} + +switch (FunSw2()) { + case 1.1: + console.log('A'); + break; + default: + console.log('F'); +} + +// 正无穷 +let number4 = Infinity; +switch (number4) { + case Infinity: + console.log("Case 1"); + break; + default: + console.log("Default case"); +} + +// 负无穷 +let number5 = -Infinity; +switch (number5) { + case -Infinity: + console.log("Case 1"); + break; + default: + console.log("Default case"); +} + +// NaN +let number6 = NaN; +switch (number6) { + case NaN: + console.log("Case 1"); + break; + default: + console.log("Default case"); +} +// 1.0 +let num111 = 1.0; +switch (num111) { + case 1.0: + console.log('One'); + break; + case 2.0: + console.log('Other number'); +} + +// let声明整型,case浮点 +let number33: number = 1; +switch (number33) { + case 1.1: + console.log("Case 1"); + break; + case 2: + console.log("Case 2"); + break; + case 3: + console.log("Case 3"); + break; + default: + console.log("Default case"); +} + +// const声明,整型number,有类型 +const num11: number = 2; +switch (num11) { + case 1: { + console.log('One'); + break; + } + case 2: { + console.log('Two'); + break; + } +} + +// let声明,整型number,有类型 +let num00: number = 2; +switch (num00) { + case 1: { + console.log('One'); + break; + } + case 2: { + console.log('Two'); + break; + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json b/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json index 641b2b4be7cbca1ef684c86254c9bd5397c0d6a4..bd61cc7b008e4b7ac18bb2d6dc0cc53e732449fe 100755 --- a/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json +++ b/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json @@ -13,196 +13,446 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - { - "line": 17, - "column": 9, - "endLine": 17, - "endColumn": 15, - "problem": "SwitchExpression", - "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 16, - "endLine": 26, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 9, - "endLine": 28, - "endColumn": 17, - "problem": "SwitchExpression", - "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", - "severity": "ERROR" - }, - { - "line": 29, - "column": 8, - "endLine": 29, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 5, - "endLine": 36, - "endColumn": 27, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 9, - "endLine": 38, - "endColumn": 19, - "problem": "SwitchExpression", - "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 7, - "endLine": 56, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 7, - "endLine": 70, - "endColumn": 20, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 7, - "endLine": 80, - "endColumn": 21, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 9, - "endLine": 81, - "endColumn": 16, - "problem": "SwitchExpression", - "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", - "severity": "ERROR" - }, - { - "line": 90, - "column": 7, - "endLine": 90, - "endColumn": 27, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 9, - "endLine": 91, - "endColumn": 16, - "problem": "SwitchExpression", - "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", - "severity": "ERROR" - }, - { - "line": 100, - "column": 7, - "endLine": 100, - "endColumn": 33, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 9, - "endLine": 101, - "endColumn": 16, - "problem": "SwitchExpression", - "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", - "severity": "ERROR" - }, - { - "line": 139, - "column": 1, - "endLine": 139, - "endColumn": 9, - "problem": "LocalFunction", - "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", - "severity": "ERROR" - }, - { - "line": 163, - "column": 5, - "endLine": 163, - "endColumn": 13, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 187, - "column": 5, - "endLine": 187, - "endColumn": 13, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 197, - "column": 5, - "endLine": 197, - "endColumn": 17, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 206, - "column": 7, - "endLine": 206, - "endColumn": 22, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - } - ] + "result": [ + { + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 15, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 16, + "endLine": 26, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 9, + "endLine": 28, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 9, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 9, + "endLine": 38, + "endColumn": 19, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 7, + "endLine": 56, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 7, + "endLine": 70, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 7, + "endLine": 80, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 9, + "endLine": 81, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 7, + "endLine": 90, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 9, + "endLine": 91, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 7, + "endLine": 100, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 9, + "endLine": 101, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 9, + "endLine": 112, + "endColumn": 12, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 11, + "endLine": 140, + "endColumn": 19, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 14, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 5, + "endLine": 163, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 9, + "endLine": 176, + "endColumn": 14, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 5, + "endLine": 187, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 5, + "endLine": 197, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 9, + "endLine": 198, + "endColumn": 15, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 7, + "endLine": 206, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 216, + "column": 13, + "endLine": 216, + "endColumn": 32, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 226, + "column": 9, + "endLine": 226, + "endColumn": 15, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 240, + "column": 9, + "endLine": 240, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 255, + "column": 9, + "endLine": 255, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 5, + "endLine": 263, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 264, + "column": 9, + "endLine": 264, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 9, + "endLine": 271, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 279, + "column": 7, + "endLine": 279, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 9, + "endLine": 280, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 294, + "column": 9, + "endLine": 294, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 303, + "column": 5, + "endLine": 303, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 304, + "column": 9, + "endLine": 304, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 5, + "endLine": 313, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 314, + "column": 9, + "endLine": 314, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 323, + "column": 5, + "endLine": 323, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 324, + "column": 9, + "endLine": 324, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 332, + "column": 5, + "endLine": 332, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 333, + "column": 9, + "endLine": 333, + "endColumn": 15, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 343, + "column": 9, + "endLine": 343, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 359, + "column": 9, + "endLine": 359, + "endColumn": 14, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 372, + "column": 9, + "endLine": 372, + "endColumn": 14, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + } +] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/swicth_expr.ets.json b/ets2panda/linter/test/main/swicth_expr.ets.json index f4aef6866196e2385a9879da8c595e369bb399f4..9dda12ea9c2e9a4268ae2c72029296496f86eb06 100755 --- a/ets2panda/linter/test/main/swicth_expr.ets.json +++ b/ets2panda/linter/test/main/swicth_expr.ets.json @@ -15,33 +15,23 @@ ], "result": [ { - "line": 26, - "column": 16, - "endLine": 26, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 29, - "column": 8, - "endLine": 29, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" + "line": 26, + "column": 16, + "endLine": 26, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" }, { - "line": 139, - "column": 1, - "endLine": 139, + "line": 29, + "column": 8, + "endLine": 29, "endColumn": 9, - "problem": "LocalFunction", + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets new file mode 100644 index 0000000000000000000000000000000000000000..05ec4e2f14809d6685c63f0ff9c89f60bb817001 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ +'use static' + +let baseInstance1: BaseClass = new BaseClass(); +let array1 = new Array(); +array1.push(baseInstance1); +let task1 = new taskpool.Task(testFunc, array1, 10); +task1.setCloneList(array1); +task1.setTransferList(array1); diff --git a/ets2panda/linter/test/migrate/class_static_block.ts.args.json b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.args.json similarity index 90% rename from ets2panda/linter/test/migrate/class_static_block.ts.args.json rename to ets2panda/linter/test/main/taskpool_deprecated_usages.ets.args.json index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..3ef4496a819a201892114d1c90f78ae32053c334 100644 --- a/ets2panda/linter/test/migrate/class_static_block.ts.args.json +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..f2b6fbc104278c5a2db8b9a60b4bc29891c48fea --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.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": 17, + "column": 36, + "endLine": 17, + "endColumn": 45, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 30, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 28, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 31, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.json b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..1c17b59df7a1612ee61e9a9368eed3b136b9bcfc --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.json @@ -0,0 +1,28 @@ +{ + "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": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets b/ets2panda/linter/test/main/ts-like-catch-type.ets new file mode 100644 index 0000000000000000000000000000000000000000..76d4be8122a044cab26465f3b6e83eb567e024a6 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets @@ -0,0 +1,30 @@ +/* + * 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. +*/ + +function test() { + try { + let a: number = 1; + } catch (e) { + console.log('catch') + } +} + +function test2() { + try { + let a: number = 1; + } catch (e: any) { + console.log('catch') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets.args.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..e2b903f0aa82e6ca4108ff67d5272bf49d6c2a5b --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..c42a19087434140d6ec2b18122a7038c5c5622f5 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 5, + "endLine": 21, + "endColumn": 4, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 18, + "problem": "CatchWithUnsupportedType", + "suggest": "", + "rule": "Type annotation in catch clause is not supported (arkts-no-types-in-catch)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 29, + "endColumn": 4, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 15, + "endLine": 27, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd65f7efbe5b1a14b6001506f9a8511cd080d1d1 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets.json @@ -0,0 +1,38 @@ +{ + "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": 27, + "column": 12, + "endLine": 27, + "endColumn": 18, + "problem": "CatchWithUnsupportedType", + "suggest": "", + "rule": "Type annotation in catch clause is not supported (arkts-no-types-in-catch)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 15, + "endLine": 27, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/type_literals.ets.args.json b/ets2panda/linter/test/main/type_literals.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/type_literals.ets.args.json +++ b/ets2panda/linter/test/main/type_literals.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/migrate/type_literals.sts b/ets2panda/linter/test/main/type_literals.ets.migrate.ets similarity index 34% rename from ets2panda/linter/test/migrate/type_literals.sts rename to ets2panda/linter/test/main/type_literals.ets.migrate.ets index b3ec3eea0ff269d03622697328dee1e7a6527f62..a8a0de8970f1123b38e3892c9593a46b77fc34bb 100644 --- a/ets2panda/linter/test/migrate/type_literals.sts +++ b/ets2panda/linter/test/main/type_literals.ets.migrate.ets @@ -13,36 +13,83 @@ * limitations under the License. */ -type Type1 = {}; -type Type2 = {a: number; b: string;}; -type Type3 = {a: number, b: number,}[]; -type Type4 = Type1 | {a: number, b: string} | {c: number, d: string}; -type Type5 = {a: T, b: K, c: number}; -type Type6 = { - a: number - b: string - c: { - x: number - y: string - z: Type1 - } -}; -export type Type7 = {a: number}; - -let var1: {} = {}; -let var2: {a: number, b: string} = {a:1, b:'2'}; -let var3: {a: number, b: number,}[]; -let var4: Type1 | {a: number, b: string} | {c: number, d: string}; -let var5 = var1 as {a: number, b: string}; -let var6: { - a: number - b: string - c: { - x: number - y: string - z: Type2 - } -} = { +interface Type1 { +} +interface Type2 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_1 { + a: number; + b: number; +} +type Type3 = GeneratedTypeLiteralInterface_1[]; +interface GeneratedTypeLiteralInterface_2 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_3 { + c: number; + d: string; +} +type Type4 = Type1 | GeneratedTypeLiteralInterface_2 | GeneratedTypeLiteralInterface_3; +interface Type5 { + a: T; + b: K; + c: number; +} +interface GeneratedTypeLiteralInterface_4 { + x: number; + y: string; + z: Type1; +} +interface Type6 { + a: number; + b: string; + c: GeneratedTypeLiteralInterface_4; +} +export interface Type7 { + a: number; +} + +interface GeneratedTypeLiteralInterface_5 { +} +let var1: GeneratedTypeLiteralInterface_5 = {}; +interface GeneratedTypeLiteralInterface_6 { + a: number; + b: string; +} +let var2: GeneratedTypeLiteralInterface_6 = {a:1, b:'2'}; +interface GeneratedTypeLiteralInterface_7 { + a: number; + b: number; +} +let var3: GeneratedTypeLiteralInterface_7[]; +interface GeneratedTypeLiteralInterface_8 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_9 { + c: number; + d: string; +} +let var4: Type1 | GeneratedTypeLiteralInterface_8 | GeneratedTypeLiteralInterface_9; +interface GeneratedTypeLiteralInterface_10 { + a: number; + b: string; +} +let var5 = var1 as GeneratedTypeLiteralInterface_10; +interface GeneratedTypeLiteralInterface_12 { + x: number; + y: string; + z: Type2; +} +interface GeneratedTypeLiteralInterface_11 { + a: number; + b: string; + c: GeneratedTypeLiteralInterface_12; +} +let var6: GeneratedTypeLiteralInterface_11 = { a: 1, b: '2', c: { @@ -55,67 +102,100 @@ let var6: { } }; -function f(p: {x: number, y: string}): {z: boolean} { +interface GeneratedTypeLiteralInterface_13 { + x: number; + y: string; +} +interface GeneratedTypeLiteralInterface_14 { + z: boolean; +} +function f(p: GeneratedTypeLiteralInterface_13): GeneratedTypeLiteralInterface_14 { return {z: true}; } +interface GeneratedTypeLiteralInterface_15 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_16 { + c: number; + d: string; +} +interface GeneratedTypeLiteralInterface_17 { + e: boolean; +} class C { - f: {a: number, b: string} = {a: 1, b:'2'}; + f: GeneratedTypeLiteralInterface_15 = {a: 1, b:'2'}; - m(p: {c: number, d: string}): {e: boolean} { + m(p: GeneratedTypeLiteralInterface_16): GeneratedTypeLiteralInterface_17 { return {e: true}; } } // Generic types class GC {} -class GC2 extends GC<{ x: 10 }> {} -const gc: GC<{ y: string }> = new GC<{ y: '20' }>(); +interface GeneratedTypeLiteralInterface_18 { + x: 10; +} +class GC2 extends GC {} +interface GeneratedTypeLiteralInterface_19 { + y: string; +} +interface GeneratedTypeLiteralInterface_20 { + y: '20'; +} +const gc: GC = new GC(); -type GType = GC; +interface GeneratedTypeLiteralInterface_21 { + z: number; +} +type GType = GC; function g(t: T): number { return 10; } -g<{ z: boolean }>({ z: true }); - -type TypeMembers = { - a: number; - 'b': string; - 3: boolean; - ['x']: number; - - m: (p: string) => number; - n(p: number): void; - get val(): number; - set val(p: number); - - (p: number): string; - new (p: string): C; - [key: string]: unknown; +interface GeneratedTypeLiteralInterface_22 { + z: boolean; +} +g({ z: true }); + +interface TypeMembers { + a: number; + 'b': string; + __3: boolean; + ['x']: number; + m: (p: string) => number; + n(p: number): void; + get val(): number; + set val(p: number); + (p: number): string; + new (p: string): C; + [key: string]: unknown; } -let typeMembers: { - a: number; - 'b': string; - 3: boolean; - ['x']: number; - - m: (p: string) => number; - n(p: number): void; - get val(): number; - set val(p: number); - - (p: number): string; - new (p: string): C; - [key: string]: unknown; -}; +interface GeneratedTypeLiteralInterface_23 { + a: number; + 'b': string; + __3: boolean; + ['x']: number; + m: (p: string) => number; + n(p: number): void; + get val(): number; + set val(p: number); + (p: number): string; + new (p: string): C; + [key: string]: unknown; +} +let typeMembers: GeneratedTypeLiteralInterface_23; // Capture type from enclosing local scope export function captureFromLocalScope(t: T): {ret: T} { // Non-fixable, type captures type parameter from enclosing declaration let v1: {local: T}; // Non-fixable, type captures type parameter from enclosing declaration - type LocalType = {a: number, b: string}; + interface LocalType { + a: number; + b: string; +} let v2: { x: LocalType } = {x: {a: 1, b: '2'}}; // Non-fixable, type captures another type declared in local scope type LocalType2 = ({k: K}); // Non-fixable, type captures type parameter from enclosing declaration diff --git a/ets2panda/linter/test/migrate/types.ts.migrate.json b/ets2panda/linter/test/main/type_literals.ets.migrate.json similarity index 31% rename from ets2panda/linter/test/migrate/types.ts.migrate.json rename to ets2panda/linter/test/main/type_literals.ets.migrate.json index 58dcba3064bfe3da860676abdf6ee444eb2b924c..f132876e4826418ec254d0a0e0df92ccca9a3f78 100644 --- a/ets2panda/linter/test/migrate/types.ts.migrate.json +++ b/ets2panda/linter/test/main/type_literals.ets.migrate.json @@ -1,454 +1,238 @@ { + "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": 15, - "endLine": 17, - "endColumn": 18, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 15, - "endLine": 18, - "endColumn": 21, - "problem": "SymbolType", - "suggest": "", - "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 20, - "endLine": 19, - "endColumn": 27, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 18, - "endLine": 26, - "endColumn": 19, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 17, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 15, - "endLine": 34, + "line": 171, + "column": 5, + "endLine": 171, "endColumn": 25, - "problem": "IndexedAccessType", - "suggest": "", - "rule": "Indexed access types are not supported (arkts-no-aliases-by-index)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 24, - "endLine": 36, - "endColumn": 31, - "problem": "UnknownType", + "problem": "CallSignature", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", "severity": "ERROR" }, { - "line": 37, - "column": 20, - "endLine": 37, - "endColumn": 23, - "problem": "AnyType", + "line": 172, + "column": 5, + "endLine": 172, + "endColumn": 24, + "problem": "ConstructorIface", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", "severity": "ERROR" }, { - "line": 43, - "column": 3, - "endLine": 43, - "endColumn": 11, - "problem": "LocalFunction", + "line": 173, + "column": 5, + "endLine": 173, + "endColumn": 28, + "problem": "IndexMember", "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", "severity": "ERROR" }, { - "line": 43, - "column": 24, - "endLine": 43, + "line": 173, + "column": 20, + "endLine": 173, "endColumn": 27, - "problem": "AnyType", + "problem": "UnknownType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 43, - "column": 30, - "endLine": 43, - "endColumn": 41, - "problem": "IsOperator", - "suggest": "", - "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 26, - "endLine": 54, - "endColumn": 27, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 3, - "endLine": 56, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 3, - "endLine": 57, - "endColumn": 6, - "problem": "ComputedPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 3, - "endLine": 58, - "endColumn": 6, - "problem": "ComputedPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 62, - "column": 3, - "endLine": 62, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 3, - "endLine": 67, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 185, + "column": 5, + "endLine": 185, + "endColumn": 25, + "problem": "CallSignature", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", "severity": "ERROR" }, { - "line": 71, - "column": 19, - "endLine": 71, - "endColumn": 20, - "problem": "ObjectTypeLiteral", + "line": 186, + "column": 5, + "endLine": 186, + "endColumn": 24, + "problem": "ConstructorIface", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", "severity": "ERROR" }, { - "line": 72, - "column": 3, - "endLine": 72, - "endColumn": 26, + "line": 187, + "column": 5, + "endLine": 187, + "endColumn": 28, "problem": "IndexMember", "suggest": "", "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", "severity": "ERROR" }, { - "line": 72, - "column": 18, - "endLine": 72, - "endColumn": 25, + "line": 187, + "column": 20, + "endLine": 187, + "endColumn": 27, "problem": "UnknownType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 76, - "column": 32, - "endLine": 76, - "endColumn": 35, - "problem": "AnyType", + "line": 192, + "column": 49, + "endLine": 192, + "endColumn": 50, + "problem": "ObjectTypeLiteral", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 77, + "line": 193, "column": 11, - "endLine": 77, - "endColumn": 13, - "problem": "InOperator", - "suggest": "", - "rule": "\"in\" operator is not supported (arkts-no-in)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 5, - "endLine": 78, - "endColumn": 14, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 92, - "column": 22, - "endLine": 92, - "endColumn": 29, - "problem": "IntersectionType", + "endLine": 193, + "endColumn": 12, + "problem": "ObjectTypeLiteral", "suggest": "", - "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 94, - "column": 28, - "endLine": 94, - "endColumn": 29, + "line": 199, + "column": 11, + "endLine": 199, + "endColumn": 12, "problem": "ObjectTypeLiteral", "suggest": "", "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 96, - "column": 3, - "endLine": 96, - "endColumn": 30, - "problem": "CallSignature", + "line": 199, + "column": 30, + "endLine": 199, + "endColumn": 31, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 111, - "column": 19, - "endLine": 111, - "endColumn": 20, + "line": 201, + "column": 25, + "endLine": 201, + "endColumn": 26, "problem": "ObjectTypeLiteral", "suggest": "", "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 112, - "column": 12, - "endLine": 112, - "endColumn": 13, + "line": 204, + "column": 11, + "endLine": 204, + "endColumn": 12, "problem": "ObjectTypeLiteral", "suggest": "", "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 112, - "column": 35, - "endLine": 112, - "endColumn": 36, - "problem": "ObjectTypeLiteral", + "line": 204, + "column": 12, + "endLine": 204, + "endColumn": 17, + "problem": "ComputedPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 116, - "column": 9, - "endLine": 116, - "endColumn": 10, + "line": 207, + "column": 11, + "endLine": 207, + "endColumn": 12, "problem": "ObjectTypeLiteral", "suggest": "", "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 116, - "column": 25, - "endLine": 116, - "endColumn": 26, + "line": 207, + "column": 31, + "endLine": 207, + "endColumn": 32, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 119, - "column": 9, - "endLine": 119, - "endColumn": 21, - "problem": "AnyType", + "line": 209, + "column": 11, + "endLine": 209, + "endColumn": 12, + "problem": "ObjectTypeLiteral", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 119, - "column": 15, - "endLine": 119, - "endColumn": 21, - "problem": "TypeAssertion", + "line": 209, + "column": 17, + "endLine": 209, + "endColumn": 23, + "problem": "TypeQuery", "suggest": "", - "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", "severity": "ERROR" }, { - "line": 119, - "column": 16, - "endLine": 119, - "endColumn": 19, - "problem": "AnyType", + "line": 211, + "column": 11, + "endLine": 211, + "endColumn": 12, + "problem": "ObjectTypeLiteral", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, { - "line": 120, - "column": 20, - "endLine": 120, - "endColumn": 77, - "problem": "TypeAssertion", + "line": 211, + "column": 17, + "endLine": 211, + "endColumn": 23, + "problem": "TypeQuery", "suggest": "", - "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", "severity": "ERROR" }, { - "line": 124, - "column": 13, - "endLine": 124, - "endColumn": 14, + "line": 213, + "column": 10, + "endLine": 213, + "endColumn": 11, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" - }, - { - "line": 125, - "column": 3, - "endLine": 125, - "endColumn": 9, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 126, - "column": 15, - "endLine": 126, - "endColumn": 21, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 12, - "endLine": 128, - "endColumn": 15, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 138, - "column": 3, - "endLine": 138, - "endColumn": 11, - "problem": "LocalFunction", - "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", - "severity": "ERROR" - }, - { - "line": 157, - "column": 5, - "endLine": 157, - "endColumn": 23, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 106, - "column": 3, - "endLine": 106, - "endColumn": 6, - "problem": "StrictDiagnostic", - "suggest": "Property 'val' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property 'val' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 148, - "column": 3, - "endLine": 148, - "endColumn": 4, - "problem": "StrictDiagnostic", - "suggest": "Type 'undefined' is not assignable to type 'string'.", - "rule": "Type 'undefined' is not assignable to type 'string'.", - "severity": "ERROR" - }, - { - "line": 149, - "column": 18, - "endLine": 149, - "endColumn": 27, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'undefined' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'undefined' is not assignable to parameter of type 'string'.", - "severity": "ERROR" - }, - { - "line": 150, - "column": 17, - "endLine": 150, - "endColumn": 26, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'undefined' is not assignable to parameter of type 'number'.", - "rule": "Argument of type 'undefined' is not assignable to parameter of type 'number'.", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/types.ets.args.json b/ets2panda/linter/test/main/types.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/types.ets.args.json +++ b/ets2panda/linter/test/main/types.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/migrate/types.sts b/ets2panda/linter/test/main/types.ets.migrate.ets similarity index 67% rename from ets2panda/linter/test/migrate/types.sts rename to ets2panda/linter/test/main/types.ets.migrate.ets index 3e6cffadf2f02b790daa1352f657b51b0f3574df..07bcd2036971da481f8dc8867af57126a0f474f2 100644 --- a/ets2panda/linter/test/migrate/types.sts +++ b/ets2panda/linter/test/main/types.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,6 +13,11 @@ * limitations under the License. */ +interface GeneratedObjectLiteralInterface_1 { + name: string; + idx: number; + handler: string; +} export function animations() { let anyvar: any = undefined; let symvar: symbol; @@ -23,13 +28,16 @@ export function animations() { const flag = false; - const status = { name: 'A', idx: 0, handler: 'foo' }; + const status: GeneratedObjectLiteralInterface_1 = { name: 'A', idx: 0, handler: 'foo' }; type Person = [string, number]; const user: Person = ['John', 32]; const age = user[1]; - type Point = { x: number; y: number }; + interface Point { + x: number; + y: number; +} type P = keyof Point; type AxeX = Point['x']; type P_NULL = P | null; @@ -40,9 +48,9 @@ export function animations() { const typeU = typeof user; - function isNumber(x: any): x is number { + let isNumber: (x: any) => x is number = (x: any): x is number => { return typeof x === 'number'; - } +}; const regex = /go*d/; @@ -51,26 +59,26 @@ export function animations() { const c = 'c'; const d = 10; -type ComputedPropertyT = { - a: string; // String-like name - 5: string; // Number-like name - [c]: string; // String-like name - [d]: string; // Number-like name -}; +interface ComputedPropertyT { + a: string; // String-like name + __5: string; // Number-like name + [c]: string; // String-like name + [d]: string; // Number-like name +} class LiteralAsPropertyName { - 2: string; + __2: string; 'Two': number; } const litAsPropName: LiteralAsPropertyName = { - 2: 'two', + __2: 'two', 'Two': 2, }; -type Dictionary = { - [key: string]: unknown; -}; +interface Dictionary { + [key: string]: unknown; +} let dict: Dictionary; function bar(key: string, val: any) { @@ -91,10 +99,10 @@ interface I2 { type IntersectionT = I1 & I2; -type DescribableFunction = { - description: string; - (someArg: number): boolean; -}; +interface DescribableFunction { + description: string; + (someArg: number): boolean; +} function callFunctionObject(fn: DescribableFunction) { console.log(fn.description + ' returned ' + fn(5)); } @@ -108,20 +116,36 @@ class G { return this.val; } } -class H extends G<{ x: 2 }> {} -const g: G<{ y: string }> = new G<{ y: 'constant' }>(); +interface GeneratedTypeLiteralInterface_1 { + x: 2; +} +class H extends G {} +interface GeneratedTypeLiteralInterface_2 { + y: string; +} +interface GeneratedTypeLiteralInterface_3 { + y: 'constant'; +} +const g: G = new G(); function generic(t: T): number { return 10; } -generic<{ z: boolean }>({ z: true }); +interface GeneratedTypeLiteralInterface_4 { + z: boolean; +} +generic({ z: true }); function typeAssertions(): void { - const num = 1; - const myCanvas = document.getElementById('main_canvas'); + const num = 1 as any; + const myCanvas = document.getElementById('main_canvas') as HTMLCanvasElement; } +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: string; +} function dynamicProperties(): void { - const x = { a: 5, b: 'text' }; + const x: GeneratedObjectLiteralInterface_2 = { a: 5, b: 'text' }; x['c'] = 100200; console.log(x['c']); @@ -135,9 +159,9 @@ function genericArrayType(): void { const y: Array = new Array(1, 2, 3); const z: number[] = [1, 2, 3]; - function arrayFunc(array: Array): Array { + let arrayFunc: (array: Array) => Array = (array: Array): Array => { return array.map((x) => x.toString()); - } +}; } class C { diff --git a/ets2panda/linter/test/migrate/types.ts.json b/ets2panda/linter/test/main/types.ets.migrate.json similarity index 51% rename from ets2panda/linter/test/migrate/types.ts.json rename to ets2panda/linter/test/main/types.ets.migrate.json index 69500549d0b9d123e719cb8a48d61c03b61fcacd..9235d4235cf4c7aca6585e704998c63f0030b9a0 100644 --- a/ets2panda/linter/test/migrate/types.ts.json +++ b/ets2panda/linter/test/main/types.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2022-2024 Huawei Device Co., Ltd.", + "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", @@ -15,9 +15,9 @@ ], "result": [ { - "line": 17, + "line": 22, "column": 15, - "endLine": 17, + "endLine": 22, "endColumn": 18, "problem": "AnyType", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 23, "column": 15, - "endLine": 18, + "endLine": 23, "endColumn": 21, "problem": "SymbolType", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 24, "column": 20, - "endLine": 19, + "endLine": 24, "endColumn": 27, "problem": "UnknownType", "suggest": "", @@ -45,29 +45,9 @@ "severity": "ERROR" }, { - "line": 26, - "column": 18, - "endLine": 26, - "endColumn": 19, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 17, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 34, + "line": 42, "column": 15, - "endLine": 34, + "endLine": 42, "endColumn": 25, "problem": "IndexedAccessType", "suggest": "", @@ -75,9 +55,9 @@ "severity": "ERROR" }, { - "line": 36, + "line": 44, "column": 24, - "endLine": 36, + "endLine": 44, "endColumn": 31, "problem": "UnknownType", "suggest": "", @@ -85,9 +65,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 45, "column": 20, - "endLine": 37, + "endLine": 45, "endColumn": 23, "problem": "AnyType", "suggest": "", @@ -95,129 +75,89 @@ "severity": "ERROR" }, { - "line": 43, - "column": 3, - "endLine": 43, - "endColumn": 11, - "problem": "LocalFunction", - "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 24, - "endLine": 43, - "endColumn": 27, + "line": 51, + "column": 21, + "endLine": 51, + "endColumn": 24, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 43, - "column": 30, - "endLine": 43, - "endColumn": 41, + "line": 51, + "column": 29, + "endLine": 51, + "endColumn": 40, "problem": "IsOperator", "suggest": "", "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", "severity": "ERROR" }, { - "line": 54, - "column": 26, - "endLine": 54, - "endColumn": 27, - "problem": "ObjectTypeLiteral", + "line": 51, + "column": 47, + "endLine": 51, + "endColumn": 50, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 56, - "column": 3, - "endLine": 56, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 51, + "column": 53, + "endLine": 51, + "endColumn": 64, + "problem": "IsOperator", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", "severity": "ERROR" }, { - "line": 57, - "column": 3, - "endLine": 57, - "endColumn": 6, + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 8, "problem": "ComputedPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 58, - "column": 3, - "endLine": 58, - "endColumn": 6, + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 8, "problem": "ComputedPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 62, - "column": 3, - "endLine": 62, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 3, - "endLine": 67, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 19, - "endLine": 71, - "endColumn": 20, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 3, - "endLine": 72, - "endColumn": 26, + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 28, "problem": "IndexMember", "suggest": "", "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", "severity": "ERROR" }, { - "line": 72, - "column": 18, - "endLine": 72, - "endColumn": 25, + "line": 80, + "column": 20, + "endLine": 80, + "endColumn": 27, "problem": "UnknownType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 76, + "line": 84, "column": 32, - "endLine": 76, + "endLine": 84, "endColumn": 35, "problem": "AnyType", "suggest": "", @@ -225,9 +165,9 @@ "severity": "ERROR" }, { - "line": 77, + "line": 85, "column": 11, - "endLine": 77, + "endLine": 85, "endColumn": 13, "problem": "InOperator", "suggest": "", @@ -235,9 +175,9 @@ "severity": "ERROR" }, { - "line": 78, + "line": 86, "column": 5, - "endLine": 78, + "endLine": 86, "endColumn": 14, "problem": "PropertyAccessByIndex", "suggest": "", @@ -245,9 +185,9 @@ "severity": "ERROR" }, { - "line": 92, + "line": 100, "column": 22, - "endLine": 92, + "endLine": 100, "endColumn": 29, "problem": "IntersectionType", "suggest": "", @@ -255,129 +195,39 @@ "severity": "ERROR" }, { - "line": 94, - "column": 28, - "endLine": 94, - "endColumn": 29, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 3, - "endLine": 96, - "endColumn": 30, + "line": 104, + "column": 5, + "endLine": 104, + "endColumn": 32, "problem": "CallSignature", "suggest": "", "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", "severity": "ERROR" }, { - "line": 111, - "column": 19, - "endLine": 111, - "endColumn": 20, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 112, - "column": 12, - "endLine": 112, - "endColumn": 13, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 112, - "column": 35, - "endLine": 112, - "endColumn": 36, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 116, + "line": 139, "column": 9, - "endLine": 116, - "endColumn": 10, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 116, - "column": 25, - "endLine": 116, - "endColumn": 26, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 9, - "endLine": 119, - "endColumn": 21, + "endLine": 139, + "endColumn": 23, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 119, - "column": 15, - "endLine": 119, - "endColumn": 21, - "problem": "TypeAssertion", - "suggest": "", - "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 16, - "endLine": 119, - "endColumn": 19, + "line": 139, + "column": 20, + "endLine": 139, + "endColumn": 23, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 120, - "column": 20, - "endLine": 120, - "endColumn": 77, - "problem": "TypeAssertion", - "suggest": "", - "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", - "severity": "ERROR" - }, - { - "line": 124, - "column": 13, - "endLine": 124, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 125, + "line": 149, "column": 3, - "endLine": 125, + "endLine": 149, "endColumn": 9, "problem": "PropertyAccessByIndex", "suggest": "", @@ -385,9 +235,9 @@ "severity": "ERROR" }, { - "line": 126, + "line": 150, "column": 15, - "endLine": 126, + "endLine": 150, "endColumn": 21, "problem": "PropertyAccessByIndex", "suggest": "", @@ -395,9 +245,9 @@ "severity": "ERROR" }, { - "line": 128, + "line": 152, "column": 12, - "endLine": 128, + "endLine": 152, "endColumn": 15, "problem": "AnyType", "suggest": "", @@ -405,19 +255,9 @@ "severity": "ERROR" }, { - "line": 138, - "column": 3, - "endLine": 138, - "endColumn": 11, - "problem": "LocalFunction", - "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", - "severity": "ERROR" - }, - { - "line": 157, + "line": 181, "column": 5, - "endLine": 157, + "endLine": 181, "endColumn": 23, "problem": "AnyType", "suggest": "", @@ -425,9 +265,19 @@ "severity": "ERROR" }, { - "line": 106, + "line": 70, "column": 3, - "endLine": 106, + "endLine": 70, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property '__2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '__2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, "endColumn": 6, "problem": "StrictDiagnostic", "suggest": "Property 'val' has no initializer and is not definitely assigned in the constructor.", @@ -435,9 +285,9 @@ "severity": "ERROR" }, { - "line": 148, + "line": 172, "column": 3, - "endLine": 148, + "endLine": 172, "endColumn": 4, "problem": "StrictDiagnostic", "suggest": "Type 'undefined' is not assignable to type 'string'.", @@ -445,9 +295,9 @@ "severity": "ERROR" }, { - "line": 149, + "line": 173, "column": 18, - "endLine": 149, + "endLine": 173, "endColumn": 27, "problem": "StrictDiagnostic", "suggest": "Argument of type 'undefined' is not assignable to parameter of type 'string'.", @@ -455,9 +305,9 @@ "severity": "ERROR" }, { - "line": 150, + "line": 174, "column": 17, - "endLine": 150, + "endLine": 174, "endColumn": 26, "problem": "StrictDiagnostic", "suggest": "Argument of type 'undefined' is not assignable to parameter of type 'number'.", diff --git a/ets2panda/linter/test/main/void_operator.ets.args.json b/ets2panda/linter/test/main/void_operator.ets.args.json index aaabef1e0a30f23f303a3fcf12ad9bd1973f6aa0..8186a08902bd23b8298befe95fff67730ddf50ab 100644 --- a/ets2panda/linter/test/main/void_operator.ets.args.json +++ b/ets2panda/linter/test/main/void_operator.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/void_operator.ets.migrate.ets b/ets2panda/linter/test/main/void_operator.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a81c570d54801e19685e158703a94fcd6dea8d5 --- /dev/null +++ b/ets2panda/linter/test/main/void_operator.ets.migrate.ets @@ -0,0 +1,149 @@ +/* + * 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. + */ + +(() => { + 0; + return undefined; +})(); + +(() => { + 'hello'; + return undefined; +})(); + +(() => { + (1 + 2); + return undefined; +})(); + +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: number; +} +(() => { + ({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1); + return undefined; +})(); + +(() => { + [1, 2, 3]; + return undefined; +})(); + +(() => { + console.log('expression evaluated'); + return undefined; +})(); + +const undefined_value = (() => { + 1; + return undefined; +})(); + +const undefined_value2: undefined = (() => { + 2; + return undefined; +})(); + +const undefined_value3: number | undefined = (() => { + 3; + return undefined; +})(); + +(() => { + (() => { + 1; + return undefined; +})(); + return undefined; +})(); + +(() => { + (() => { + console.log('foo'); +}); + return undefined; +})(); + +(() => { + (() => { + console.log("bar!"); +})(); + return undefined; +})(); + +(() => { + (() => { + console.log('baz!'); +})(); + return undefined; +})(); + +(() => { + (class { + }); + return undefined; +})(); + +(() => { + (class { + }); + return undefined; +})(); + +(() => { + (() => { }); + return undefined; +})(); + +function foo() { + let a: number = 1; + (() => { + a++; + return undefined; +})(); + + let b: number[] = [1, 2, 3]; + (() => { + console.log(b.filter(x => x % 2 !== 0)); + return undefined; +})(); + + (() => { + (() => { + console.log('foo'); +}); + return undefined; +})(); + + (() => { + (() => { + console.log('foo'); +}); + return undefined; +})(); + + (() => { + (class { + }); + return undefined; +})(); + + (() => { + (class localClass { + }); + return undefined; +})(); +} diff --git a/ets2panda/linter/test/main/void_operator.ets.migrate.json b/ets2panda/linter/test/main/void_operator.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..12de68ea372eb83f2257518b738f63f6fa6fa397 --- /dev/null +++ b/ets2panda/linter/test/main/void_operator.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 95, + "column": 6, + "endLine": 95, + "endColumn": 11, + "problem": "ClassExpression", + "suggest": "", + "rule": "Class literals are not supported (arkts-no-class-literals)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 6, + "endLine": 101, + "endColumn": 11, + "problem": "ClassExpression", + "suggest": "", + "rule": "Class literals are not supported (arkts-no-class-literals)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 6, + "endLine": 139, + "endColumn": 11, + "problem": "ClassExpression", + "suggest": "", + "rule": "Class literals are not supported (arkts-no-class-literals)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 6, + "endLine": 145, + "endColumn": 11, + "problem": "ClassExpression", + "suggest": "", + "rule": "Class literals are not supported (arkts-no-class-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/worker_module.ets b/ets2panda/linter/test/main/worker_module.ets index 5eb608bafe76650ab5e4debef32650b664bffed6..dc6f082a9f8010cf7e3aefc2307d793ac59f1459 100644 --- a/ets2panda/linter/test/main/worker_module.ets +++ b/ets2panda/linter/test/main/worker_module.ets @@ -13,12 +13,28 @@ * limitations under the License. */ -import { worker, MessageEvents } from '@kit.ArkTS'; +import { worker } from './oh_modules/@ohos.worker'; -import { process } from '@kit.ArkTS'; //legal +import { worker as workerAlias } from './oh_modules/@ohos.worker'; -import { worker as workerAlias } from '@ohos.worker'; - -import { worker as kitWorker } from '@kit.ArkTS'; +import { worker as kitWorker } from './oh_modules/@kit.ArkTS'; import { worker as definedWorker } from 'user_defined_worker'; //legal + +export { worker } from './oh_modules/@ohos.worker'; + +function testWorkerUsage() { + + const worker1: worker.ThreadWorker = new worker.ThreadWorker('script.js'); + + const worker2 = new workerAlias.ThreadWorker('script.js'); + + const worker3 = new kitWorker.ThreadWorker('script.js'); + + let worker4: workerAlias.ThreadWorker('script.js'); + + const worker5: workerAlias.ThreadWorker = new workerAlias.ThreadWorker('script.js'); + + let worker6: definedWorker.ThreadWorker('script.js'); // legal + +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/worker_module.ets.arkts2.json b/ets2panda/linter/test/main/worker_module.ets.arkts2.json index 9dea915ba6f1c7da12230d06a5bee5fdb8b09516..535d022afdc58f18c353c35b8ca2d43213f138e0 100644 --- a/ets2panda/linter/test/main/worker_module.ets.arkts2.json +++ b/ets2panda/linter/test/main/worker_module.ets.arkts2.json @@ -16,32 +16,132 @@ "result": [ { "line": 16, - "column": 1, + "column": 10, "endLine": 16, - "endColumn": 52, - "problem": "LimitedStdLibApi", + "endColumn": 16, + "problem": "NoNeedStdlibWorker", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 16, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 20, + "endLine": 18, + "endColumn": 31, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", "severity": "ERROR" }, { "line": 20, - "column": 1, + "column": 10, "endLine": 20, - "endColumn": 54, - "problem": "LimitedStdLibApi", + "endColumn": 16, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 29, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 16, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 18, + "endLine": 28, + "endColumn": 24, + "problem": "NoNeedStdlibWorker", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", "severity": "ERROR" }, { - "line": 22, - "column": 1, - "endLine": 22, + "line": 28, + "column": 44, + "endLine": 28, "endColumn": 50, - "problem": "LimitedStdLibApi", + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 23, + "endLine": 30, + "endColumn": 34, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 23, + "endLine": 32, + "endColumn": 32, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 16, + "endLine": 34, + "endColumn": 27, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 18, + "endLine": 36, + "endColumn": 29, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 49, + "endLine": 36, + "endColumn": 60, + "problem": "NoNeedStdlibWorker", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/migrate/class_static_block.ts.migrate.json b/ets2panda/linter/test/migrate/class_static_block.ts.migrate.json deleted file mode 100644 index ed0f91dab0cfef35674166dfa5b99734f4d08549..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/class_static_block.ts.migrate.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "result": [ - { - "line": 23, - "column": 3, - "endLine": 23, - "endColumn": 9, - "problem": "MultipleStaticBlocks", - "suggest": "", - "rule": "Only one static block is supported (arkts-no-multiple-static-blocks)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/destructuring_assignments.ts.migrate.json b/ets2panda/linter/test/migrate/destructuring_assignments.ts.migrate.json deleted file mode 100644 index 05a9b858c91e689b4354c0ced816adf6e9be7843..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/destructuring_assignments.ts.migrate.json +++ /dev/null @@ -1,624 +0,0 @@ -{ - "result": [ - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 9, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 11, - "endLine": 18, - "endColumn": 16, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 2, - "endLine": 19, - "endColumn": 44, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 16, - "endLine": 19, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 2, - "endLine": 20, - "endColumn": 18, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 16, - "endLine": 20, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 2, - "endLine": 21, - "endColumn": 33, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 7, - "endLine": 21, - "endColumn": 14, - "problem": "SpreadOperator", - "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 2, - "endLine": 22, - "endColumn": 56, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 26, - "endLine": 22, - "endColumn": 27, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 37, - "endLine": 22, - "endColumn": 38, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 2, - "endLine": 23, - "endColumn": 56, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 12, - "endLine": 23, - "endColumn": 19, - "problem": "SpreadOperator", - "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 26, - "endLine": 23, - "endColumn": 27, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 10, - "endLine": 26, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 2, - "endLine": 28, - "endColumn": 24, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 1, - "endLine": 31, - "endColumn": 25, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 1, - "endLine": 32, - "endColumn": 15, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 1, - "endLine": 33, - "endColumn": 58, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 16, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 1, - "endLine": 35, - "endColumn": 39, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 8, - "endLine": 35, - "endColumn": 15, - "problem": "SpreadOperator", - "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 1, - "endLine": 36, - "endColumn": 42, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 1, - "endLine": 37, - "endColumn": 46, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 12, - "endLine": 37, - "endColumn": 19, - "problem": "SpreadOperator", - "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 17, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 1, - "endLine": 41, - "endColumn": 21, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 5, - "endLine": 41, - "endColumn": 12, - "problem": "SpreadOperator", - "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", - "severity": "ERROR" - }, - { - "line": 44, - "column": 1, - "endLine": 44, - "endColumn": 20, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 1, - "endLine": 47, - "endColumn": 16, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 50, - "column": 1, - "endLine": 50, - "endColumn": 23, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 30, - "endLine": 53, - "endColumn": 31, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 45, - "endLine": 53, - "endColumn": 46, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 1, - "endLine": 54, - "endColumn": 51, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 29, - "endLine": 54, - "endColumn": 50, - "problem": "ArrayLiteralNoContextType", - "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 30, - "endLine": 54, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 41, - "endLine": 54, - "endColumn": 42, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 55, - "column": 1, - "endLine": 55, - "endColumn": 42, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 55, - "column": 18, - "endLine": 55, - "endColumn": 22, - "problem": "SpreadOperator", - "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 1, - "endLine": 56, - "endColumn": 38, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 8, - "endLine": 56, - "endColumn": 19, - "problem": "SpreadOperator", - "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 23, - "endLine": 56, - "endColumn": 38, - "problem": "ArrayLiteralNoContextType", - "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 30, - "endLine": 56, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 2, - "endLine": 58, - "endColumn": 41, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 22, - "endLine": 58, - "endColumn": 23, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 2, - "endLine": 65, - "endColumn": 44, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 5, - "endLine": 65, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 17, - "endLine": 65, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 2, - "endLine": 68, - "endColumn": 48, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 20, - "endLine": 68, - "endColumn": 21, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 2, - "endLine": 69, - "endColumn": 60, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 30, - "endLine": 69, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 41, - "endLine": 69, - "endColumn": 42, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 2, - "endLine": 70, - "endColumn": 45, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 26, - "endLine": 70, - "endColumn": 27, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 2, - "endLine": 77, - "endColumn": 44, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 77, - "column": 5, - "endLine": 77, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 77, - "column": 17, - "endLine": 77, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 87, - "column": 2, - "endLine": 87, - "endColumn": 23, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 2, - "endLine": 32, - "endColumn": 3, - "problem": "StrictDiagnostic", - "suggest": "Type 'undefined' is not assignable to type 'number'.", - "rule": "Type 'undefined' is not assignable to type 'number'.", - "severity": "ERROR" - }, - { - "line": 32, - "column": 5, - "endLine": 32, - "endColumn": 6, - "problem": "StrictDiagnostic", - "suggest": "Type 'undefined' is not assignable to type 'number'.", - "rule": "Type 'undefined' is not assignable to type 'number'.", - "severity": "ERROR" - }, - { - "line": 32, - "column": 8, - "endLine": 32, - "endColumn": 9, - "problem": "StrictDiagnostic", - "suggest": "Type 'undefined' is not assignable to type 'number'.", - "rule": "Type 'undefined' is not assignable to type 'number'.", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/destructuring_declarations.ts.migrate.json b/ets2panda/linter/test/migrate/destructuring_declarations.ts.migrate.json deleted file mode 100644 index 0729d4936cb374f8b43bd73043faa9da2d2cc6c0..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/destructuring_declarations.ts.migrate.json +++ /dev/null @@ -1,494 +0,0 @@ -{ - "result": [ - { - "line": 17, - "column": 5, - "endLine": 17, - "endColumn": 47, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 19, - "endLine": 17, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 40, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 24, - "endLine": 18, - "endColumn": 25, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 68, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 34, - "endLine": 19, - "endColumn": 35, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 47, - "endLine": 19, - "endColumn": 48, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 66, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 32, - "endLine": 20, - "endColumn": 33, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 45, - "endLine": 20, - "endColumn": 46, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 5, - "endLine": 22, - "endColumn": 21, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 19, - "endLine": 22, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 10, - "endLine": 25, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 27, - "column": 5, - "endLine": 27, - "endColumn": 29, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 7, - "endLine": 30, - "endColumn": 34, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 7, - "endLine": 31, - "endColumn": 48, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 7, - "endLine": 32, - "endColumn": 52, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 7, - "endLine": 33, - "endColumn": 56, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 64, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 7, - "endLine": 36, - "endColumn": 85, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 39, - "column": 5, - "endLine": 39, - "endColumn": 25, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 5, - "endLine": 40, - "endColumn": 29, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 5, - "endLine": 43, - "endColumn": 28, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 5, - "endLine": 46, - "endColumn": 26, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 49, - "column": 5, - "endLine": 49, - "endColumn": 35, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 5, - "endLine": 52, - "endColumn": 67, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 41, - "endLine": 52, - "endColumn": 66, - "problem": "ArrayLiteralNoContextType", - "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 55, - "endLine": 52, - "endColumn": 56, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 5, - "endLine": 53, - "endColumn": 60, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 43, - "endLine": 53, - "endColumn": 60, - "problem": "ArrayLiteralNoContextType", - "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 50, - "endLine": 53, - "endColumn": 51, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 7, - "endLine": 54, - "endColumn": 45, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 5, - "endLine": 56, - "endColumn": 55, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 32, - "endLine": 56, - "endColumn": 33, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 5, - "endLine": 63, - "endColumn": 52, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 5, - "endLine": 63, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 21, - "endLine": 63, - "endColumn": 22, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 66, - "column": 5, - "endLine": 66, - "endColumn": 51, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 66, - "column": 23, - "endLine": 66, - "endColumn": 24, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 5, - "endLine": 67, - "endColumn": 73, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 39, - "endLine": 67, - "endColumn": 40, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 52, - "endLine": 67, - "endColumn": 53, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 5, - "endLine": 68, - "endColumn": 33, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 5, - "endLine": 69, - "endColumn": 60, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 37, - "endLine": 69, - "endColumn": 38, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 5, - "endLine": 76, - "endColumn": 52, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 76, - "column": 5, - "endLine": 76, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 76, - "column": 21, - "endLine": 76, - "endColumn": 22, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 85, - "column": 5, - "endLine": 85, - "endColumn": 26, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/function_expression.ts.args.json b/ets2panda/linter/test/migrate/function_expression.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/function_expression.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "mode": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/function_expression.ts.migrate.json b/ets2panda/linter/test/migrate/function_expression.ts.migrate.json deleted file mode 100644 index 7d294016f97ab9956de77d29efc4a7dab1474c1d..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/function_expression.ts.migrate.json +++ /dev/null @@ -1,334 +0,0 @@ -{ - "result": [ - { - "line": 16, - "column": 15, - "endLine": 16, - "endColumn": 29, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 18, - "endLine": 20, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 39, - "endLine": 18, - "endColumn": 40, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 10, - "endLine": 25, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 17, - "endLine": 30, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 2, - "endLine": 34, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 7, - "endLine": 38, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 26, - "endLine": 43, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 44, - "column": 27, - "endLine": 46, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 48, - "column": 22, - "endLine": 50, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 48, - "column": 22, - "endLine": 50, - "endColumn": 2, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 48, - "column": 35, - "endLine": 48, - "endColumn": 38, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 19, - "endLine": 54, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 19, - "endLine": 54, - "endColumn": 2, - "problem": "GeneratorFunction", - "suggest": "", - "rule": "Generator functions are not supported (arkts-no-generators)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 3, - "endLine": 53, - "endColumn": 10, - "problem": "YieldExpression", - "suggest": "", - "rule": "Generator functions are not supported (arkts-no-generators)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 17, - "endLine": 58, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 60, - "column": 18, - "endLine": 62, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 64, - "column": 19, - "endLine": 66, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 25, - "endLine": 76, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 12, - "endLine": 80, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 82, - "column": 5, - "endLine": 84, - "endColumn": 5, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 82, - "column": 19, - "endLine": 84, - "endColumn": 5, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 82, - "column": 19, - "endLine": 84, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 86, - "column": 6, - "endLine": 88, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 9, - "endLine": 93, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 25, - "endLine": 98, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 9, - "endLine": 104, - "endColumn": 17, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 104, - "column": 7, - "endLine": 104, - "endColumn": 17, - "problem": "FunctionBind", - "suggest": "", - "rule": "'Function.bind' is not supported (arkts-no-func-bind)", - "severity": "WARNING" - }, - { - "line": 102, - "column": 15, - "endLine": 104, - "endColumn": 6, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 108, - "column": 16, - "endLine": 108, - "endColumn": 55, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 109, - "column": 24, - "endLine": 109, - "endColumn": 75, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 112, - "column": 5, - "endLine": 112, - "endColumn": 45, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 113, - "column": 10, - "endLine": 113, - "endColumn": 50, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.args.json b/ets2panda/linter/test/migrate/literals_as_prop_names.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "mode": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.args.json b/ets2panda/linter/test/migrate/object_literals_autofixes.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "mode": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/parameter_properties.ts.args.json b/ets2panda/linter/test/migrate/parameter_properties.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/parameter_properties.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "mode": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/parameter_properties.ts.migrate.json b/ets2panda/linter/test/migrate/parameter_properties.ts.migrate.json deleted file mode 100644 index ea6dab7c47ca3563e1141bb5d9375d46fa8b6c47..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/parameter_properties.ts.migrate.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "result": [ - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 11, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 14, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 12, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 26, - "endLine": 34, - "endColumn": 32, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 60, - "endLine": 34, - "endColumn": 67, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 15, - "endLine": 43, - "endColumn": 21, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 25, - "endLine": 43, - "endColumn": 28, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 15, - "endLine": 47, - "endColumn": 21, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 33, - "endLine": 47, - "endColumn": 40, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 44, - "endLine": 47, - "endColumn": 45, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/type_literals.ts.args.json b/ets2panda/linter/test/migrate/type_literals.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/type_literals.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "mode": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/type_literals.ts.migrate.json b/ets2panda/linter/test/migrate/type_literals.ts.migrate.json deleted file mode 100644 index bae2bb21043ca18828307c6d95970411b576e409..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/type_literals.ts.migrate.json +++ /dev/null @@ -1,644 +0,0 @@ -{ - "result": [ - { - "line": 16, - "column": 14, - "endLine": 16, - "endColumn": 15, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 14, - "endLine": 17, - "endColumn": 15, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 14, - "endLine": 18, - "endColumn": 15, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 22, - "endLine": 19, - "endColumn": 23, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 47, - "endLine": 19, - "endColumn": 48, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 20, - "endLine": 20, - "endColumn": 21, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 14, - "endLine": 21, - "endColumn": 15, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 6, - "endLine": 24, - "endColumn": 7, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 21, - "endLine": 30, - "endColumn": 22, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 11, - "endLine": 32, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 11, - "endLine": 33, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 36, - "endLine": 33, - "endColumn": 37, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 11, - "endLine": 34, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 19, - "endLine": 35, - "endColumn": 20, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 44, - "endLine": 35, - "endColumn": 45, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 20, - "endLine": 36, - "endColumn": 21, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 11, - "endLine": 37, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 6, - "endLine": 40, - "endColumn": 7, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 48, - "column": 6, - "endLine": 48, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 8, - "endLine": 51, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 15, - "endLine": 58, - "endColumn": 16, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 40, - "endLine": 58, - "endColumn": 41, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 10, - "endLine": 59, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 6, - "endLine": 63, - "endColumn": 7, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 31, - "endLine": 63, - "endColumn": 32, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 8, - "endLine": 65, - "endColumn": 9, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 33, - "endLine": 65, - "endColumn": 34, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 66, - "column": 12, - "endLine": 66, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 22, - "endLine": 72, - "endColumn": 23, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 14, - "endLine": 73, - "endColumn": 15, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 38, - "endLine": 73, - "endColumn": 39, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 75, - "column": 16, - "endLine": 75, - "endColumn": 17, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 3, - "endLine": 80, - "endColumn": 4, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 19, - "endLine": 80, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 82, - "column": 20, - "endLine": 82, - "endColumn": 21, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 85, - "column": 3, - "endLine": 85, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 93, - "column": 3, - "endLine": 93, - "endColumn": 23, - "problem": "CallSignature", - "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", - "severity": "ERROR" - }, - { - "line": 94, - "column": 3, - "endLine": 94, - "endColumn": 22, - "problem": "ConstructorType", - "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", - "severity": "ERROR" - }, - { - "line": 95, - "column": 3, - "endLine": 95, - "endColumn": 26, - "problem": "IndexMember", - "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", - "severity": "ERROR" - }, - { - "line": 95, - "column": 18, - "endLine": 95, - "endColumn": 25, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 98, - "column": 18, - "endLine": 98, - "endColumn": 19, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 3, - "endLine": 101, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 109, - "column": 3, - "endLine": 109, - "endColumn": 23, - "problem": "CallSignature", - "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", - "severity": "ERROR" - }, - { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 22, - "problem": "ConstructorType", - "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", - "severity": "ERROR" - }, - { - "line": 111, - "column": 3, - "endLine": 111, - "endColumn": 26, - "problem": "IndexMember", - "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", - "severity": "ERROR" - }, - { - "line": 111, - "column": 18, - "endLine": 111, - "endColumn": 25, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 115, - "column": 49, - "endLine": 115, - "endColumn": 50, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 116, - "column": 11, - "endLine": 116, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 20, - "endLine": 118, - "endColumn": 21, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 11, - "endLine": 119, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 30, - "endLine": 119, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 34, - "endLine": 119, - "endColumn": 35, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 121, - "column": 25, - "endLine": 121, - "endColumn": 26, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 124, - "column": 11, - "endLine": 124, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 124, - "column": 12, - "endLine": 124, - "endColumn": 17, - "problem": "ComputedPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 127, - "column": 11, - "endLine": 127, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 127, - "column": 31, - "endLine": 127, - "endColumn": 32, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 129, - "column": 11, - "endLine": 129, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 129, - "column": 17, - "endLine": 129, - "endColumn": 23, - "problem": "TypeQuery", - "suggest": "", - "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", - "severity": "ERROR" - }, - { - "line": 131, - "column": 11, - "endLine": 131, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 131, - "column": 17, - "endLine": 131, - "endColumn": 23, - "problem": "TypeQuery", - "suggest": "", - "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", - "severity": "ERROR" - }, - { - "line": 133, - "column": 10, - "endLine": 133, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/types.ts.args.json b/ets2panda/linter/test/migrate/types.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/types.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "mode": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/void_operator.ts.migrate.json b/ets2panda/linter/test/migrate/void_operator.ts.migrate.json deleted file mode 100644 index e1644e2d8d5f78ed1b06f5be8b157586408ce8fd..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/void_operator.ts.migrate.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "result": [ - { - "line": 22, - "column": 6, - "endLine": 22, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 6, - "endLine": 38, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 6, - "endLine": 42, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 44, - "column": 7, - "endLine": 46, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 48, - "column": 6, - "endLine": 48, - "endColumn": 11, - "problem": "ClassExpression", - "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", - "severity": "ERROR" - }, - { - "line": 50, - "column": 7, - "endLine": 50, - "endColumn": 12, - "problem": "ClassExpression", - "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 8, - "endLine": 63, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 8, - "endLine": 67, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 8, - "endLine": 69, - "endColumn": 13, - "problem": "ClassExpression", - "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 8, - "endLine": 71, - "endColumn": 13, - "problem": "ClassExpression", - "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets b/ets2panda/linter/test/migration/mixed_problems.ets new file mode 100644 index 0000000000000000000000000000000000000000..617d37acf69f2724ad293882a5b967e7062b6e28 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets @@ -0,0 +1,54 @@ +/* + * 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. + */ + +// destructuring declaration + untyped object literal +let { a, b } = { a: 1, b: 2 }; + +// destructuring declaration + untyped object literal + type literal +let { a2, b2 } = { + a2: 1, + b2: { + c2: 1, + d2: '2' + } as { c2: number, d2: string } +}; + +// untyped object literal + 'in' operator +console.log('a' in { a: 1, b: 2 }); + +// untyped object literal + var declaration + literal as property name + function expression +var fun = function() { + var o = { + 'a': 1, + 'b': 2 + }; + + var o2 = { + 'c': 3, + 'd': 4, + 5: { + x1: 10, + x2: 20 + } + }; +}; + +// private identifier + definite assignment +class A { + #a!: number; +} + +// type assertion + as 'const' +const t = 'hello'; \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.args.json b/ets2panda/linter/test/migration/mixed_problems.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..65eb728b5df03fbf77be432348751a6c1518904c --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.args.json @@ -0,0 +1,20 @@ +{ + "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": { + "autofix": "", + "migrate": "" + } +} diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json b/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..57f25df2f307782186bdc847598ce6a21d60dae0 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json @@ -0,0 +1,303 @@ +{ + "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": 30, + "problem": "DestructuringDeclaration", + "autofix": [ + { + "replacementText": "GeneratedDestructObj_1", + "start": 663, + "end": 671 + }, + { + "replacementText": "\nlet a = GeneratedDestructObj_1.a;\nlet b = GeneratedDestructObj_1.b;\n", + "start": 689, + "end": 689 + } + ], + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 26, + "endColumn": 2, + "problem": "DestructuringDeclaration", + "autofix": [ + { + "replacementText": "GeneratedDestructObj_2", + "start": 764, + "end": 774 + }, + { + "replacementText": "\nlet a2 = GeneratedDestructObj_2.a2;\nlet b2 = GeneratedDestructObj_2.b2;\n", + "start": 869, + "end": 869 + } + ], + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 18, + "endLine": 20, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 9, + "endLine": 22, + "endColumn": 10, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 11, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 760, + "end": 760, + "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n c2: number;\n d2: string;\n}\n" + }, + { + "start": 840, + "end": 866, + "replacementText": "GeneratedTypeLiteralInterface_1" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 17, + "endLine": 29, + "endColumn": 19, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 20, + "endLine": 29, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 913, + "end": 913, + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n a: number;\n b: number;\n}\n" + }, + { + "start": 932, + "end": 946, + "replacementText": "({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1)" + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 4, + "problem": "VarDeclaration", + "autofix": [ + { + "start": 1043, + "end": 1238, + "replacementText": "let fun = function () {\n var o = {\n 'a': 1,\n 'b': 2\n };\n var o2 = {\n 'c': 3,\n 'd': 4,\n 5: {\n x1: 10,\n x2: 20\n }\n };\n}" + } + ], + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 11, + "endLine": 46, + "endColumn": 2, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 1053, + "end": 1238, + "replacementText": "() => {\n var o = {\n 'a': 1,\n 'b': 2\n };\n var o2 = {\n 'c': 3,\n 'd': 4,\n 5: {\n x1: 10,\n x2: 20\n }\n };\n}" + } + ], + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 8, + "problem": "VarDeclaration", + "autofix": [ + { + "start": 1071, + "end": 1117, + "replacementText": "let o = {\n 'a': 1,\n 'b': 2\n}" + } + ], + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 13, + "endLine": 33, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 8, + "problem": "VarDeclaration", + "autofix": [ + { + "start": 1124, + "end": 1235, + "replacementText": "let o2 = {\n 'c': 3,\n 'd': 4,\n 5: {\n x1: 10,\n x2: 20\n }\n}" + } + ], + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 9, + "endLine": 41, + "endColumn": 10, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 1043, + "end": 1043, + "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n x1: number;\n x2: number;\n}\n" + }, + { + "start": 1178, + "end": 1228, + "replacementText": "({ x1: 10,\n x2: 20 } as GeneratedObjectLiteralInterface_2)" + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 17, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 7, + "problem": "PrivateIdentifier", + "autofix": [ + { + "start": 1299, + "end": 1311, + "replacementText": "private a!: number;" + } + ], + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 27, + "endLine": 54, + "endColumn": 18, + "problem": "ConstAssertion", + "suggest": "", + "rule": "\"as const\" assertions are not supported (arkts-no-as-const)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.json b/ets2panda/linter/test/migration/mixed_problems.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dbb09ef3dc5bcac13242fb8caaa6b0e6f809b349 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.json @@ -0,0 +1,208 @@ +{ + "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": 30, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 26, + "endColumn": 2, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 18, + "endLine": 20, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 9, + "endLine": 22, + "endColumn": 10, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 11, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 17, + "endLine": 29, + "endColumn": 19, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 20, + "endLine": 29, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 4, + "problem": "VarDeclaration", + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 11, + "endLine": 46, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 8, + "problem": "VarDeclaration", + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 13, + "endLine": 33, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 8, + "problem": "VarDeclaration", + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 9, + "endLine": 41, + "endColumn": 10, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 17, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 7, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 27, + "endLine": 54, + "endColumn": 18, + "problem": "ConstAssertion", + "suggest": "", + "rule": "\"as const\" assertions are not supported (arkts-no-as-const)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.migrate.ets b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1ffb82d2ebf46615bb1be1ef8704f1e58d5e95c7 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.ets @@ -0,0 +1,77 @@ +/* + * 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. + */ + +// destructuring declaration + untyped object literal +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: number; +} +let GeneratedDestructObj_1: GeneratedObjectLiteralInterface_2 = { a: 1, b: 2 }; +let a = GeneratedDestructObj_1.a; +let b = GeneratedDestructObj_1.b; + + +// destructuring declaration + untyped object literal + type literal +interface GeneratedTypeLiteralInterface_1 { + c2: number; + d2: string; +} +interface GeneratedObjectLiteralInterface_3 { + a2: number; + b2: GeneratedTypeLiteralInterface_1; +} +let GeneratedDestructObj_2: GeneratedObjectLiteralInterface_3 = { + a2: 1, + b2: { + c2: 1, + d2: '2' + } as GeneratedTypeLiteralInterface_1 +}; +let a2 = GeneratedDestructObj_2.a2; +let b2 = GeneratedDestructObj_2.b2; + + +// untyped object literal + 'in' operator +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: number; +} +console.log('a' in ({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1)); + +// untyped object literal + var declaration + literal as property name + function expression +interface GeneratedObjectLiteralInterface_4 { + x1: number; + x2: number; +} +let fun = () => { + let o = { + 'a': 1, + 'b': 2 +}; + let o2 = { + 'c': 3, + 'd': 4, + 5: ({ x1: 10, + x2: 20 } as GeneratedObjectLiteralInterface_4) +}; +}; + +// private identifier + definite assignment +class A { + private a!: number; +} + +// type assertion + as 'const' +const t = 'hello'; \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..bfb7a82f089b08ec604a536fff2ac426e2896312 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json @@ -0,0 +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": 51, + "column": 17, + "endLine": 51, + "endColumn": 19, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 13, + "endLine": 59, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 14, + "endLine": 63, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 6, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 24, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 77, + "column": 27, + "endLine": 77, + "endColumn": 18, + "problem": "ConstAssertion", + "suggest": "", + "rule": "\"as const\" assertions are not supported (arkts-no-as-const)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.args.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.args.json index db044a3dff705d84beabaa2d833b7cf1b2debd01..a89d885810708ad03d96e3e14bb6590efd1a7547 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.args.json +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.ets b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1d67bf9461153ad005437a1f1c5c0e0454039bc6 --- /dev/null +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + import { MainPage } from 'library/src/main/ets/components/MainPage' // Should fail on ArkTS 1.2 + import { Something1 } from "library/src/main/ets/components/Something1" // Valid + import { Something2 } from 'entry/src/main/ets/components/Something2' // Should Fail + import { Valid } from "normal/path/to/import/MainPage" // Valid + import { RelativeImport } from "../components/MainPage" // Valid + import { Something } from 'entry/src/main/ets/pages/test1' //should fail + import { SomethingElse } from 'entry/src/main/ets/pages/testing'; //should fail + import { Test } from 'module/src/main/ets/random/test'; //should fail diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule1.ets.args.json b/ets2panda/linter/test/rules/rule1.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule1.ets.args.json +++ b/ets2panda/linter/test/rules/rule1.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule1.ets.autofix.json b/ets2panda/linter/test/rules/rule1.ets.autofix.json index 7a9e068c21ccc994a440185452e32954b1e35a3a..4418693726fc8d2fee1ef9a555ecaf70b8925a1e 100644 --- a/ets2panda/linter/test/rules/rule1.ets.autofix.json +++ b/ets2panda/linter/test/rules/rule1.ets.autofix.json @@ -37,18 +37,6 @@ "endLine": 16, "endColumn": 10, "problem": "ObjectLiteralNoContextType", - "autofix": [ - { - "start": 610, - "end": 610, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n \"name\": number;\n 2: number;\n}\n" - }, - { - "start": 615, - "end": 615, - "replacementText": ": GeneratedObjectLiteralInterface_1" - } - ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" @@ -93,12 +81,12 @@ { "start": 719, "end": 719, - "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n name: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n name: number;\n}\n" }, { "start": 724, "end": 724, - "replacementText": ": GeneratedObjectLiteralInterface_2" + "replacementText": ": GeneratedObjectLiteralInterface_1" } ], "suggest": "", diff --git a/ets2panda/linter/test/rules/rule1.ets.migrate.ets b/ets2panda/linter/test/rules/rule1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e78c2703ba999713c90ccdb16243c99e39005aa9 --- /dev/null +++ b/ets2panda/linter/test/rules/rule1.ets.migrate.ets @@ -0,0 +1,58 @@ +/* + * 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. + */ + +let x = { "name": 1, 2: 3 } + +console.log(x["name"]) +console.log(x[2]) + +class X { + public name: number = 0 +} +interface GeneratedObjectLiteralInterface_1 { + name: number; +} +let y: GeneratedObjectLiteralInterface_1 = {name: 1} +console.log(x.name) + +let z = [1, 2, 3] +console.log(y[2]) + +enum S1 { + s1 = "qwqwq", +} + +enum S2 { + s2 = 123, +} + +interface A1 { + [S1.s1]: string; +} + +interface A2 { + [S2.s2]: string; +} + +const a1: A1 = { + [S1.s1]: "fld1", +}; + +const a2: A2 = { + [S2.s2]: "fld2", +}; + +S1["s1"]; +S2["s2"]; diff --git a/ets2panda/linter/test/rules/rule1.ets.migrate.json b/ets2panda/linter/test/rules/rule1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a6b59e880c252dc5f29c2e55d97ff6242a0ba012 --- /dev/null +++ b/ets2panda/linter/test/rules/rule1.ets.migrate.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": 16, + "column": 9, + "endLine": 16, + "endColumn": 10, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 22, + "endLine": 16, + "endColumn": 23, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 13, + "endLine": 18, + "endColumn": 22, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 13, + "endLine": 19, + "endColumn": 17, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 13, + "endLine": 31, + "endColumn": 17, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 3, + "endLine": 46, + "endColumn": 10, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 10, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule113.ets.args.json b/ets2panda/linter/test/rules/rule113.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule113.ets.args.json +++ b/ets2panda/linter/test/rules/rule113.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule113.ets.migrate.ets b/ets2panda/linter/test/rules/rule113.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..67b6f18276903ddc39b27de96765f0cd3e2a9457 --- /dev/null +++ b/ets2panda/linter/test/rules/rule113.ets.migrate.ets @@ -0,0 +1,69 @@ +/* + * 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. + */ + + +// fixable +enum Color { + RED, + GREEN, + YELLOW = 2, + BLACK = 3, + BLUE +} + + +// ------ + +// not fixable +enum C { + A = 1 +} + +const x = 6 +let y = C.A + +enum C{ + B = x +} +// ------ + +// not fixable +const d = 6 + +enum D { + A = 1 +} + +enum D{ + B = d +} +// ------ + +// fixable +enum Str { + A = 1, + B = "abc", + C = 2, + D, + E = "qwerty" +} + + +// ------ + +enum Empty { +} + + diff --git a/ets2panda/linter/test/rules/rule113.ets.migrate.json b/ets2panda/linter/test/rules/rule113.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..93a274b2575f7986b4bbce5dd4a3747b711da618 --- /dev/null +++ b/ets2panda/linter/test/rules/rule113.ets.migrate.json @@ -0,0 +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": 30, + "column": 1, + "endLine": 32, + "endColumn": 2, + "problem": "EnumMerging", + "suggest": "", + "rule": "\"enum\" declaration merging is not supported (arkts-no-enum-merging)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 1, + "endLine": 39, + "endColumn": 2, + "problem": "EnumMerging", + "suggest": "", + "rule": "\"enum\" declaration merging is not supported (arkts-no-enum-merging)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 1, + "endLine": 47, + "endColumn": 2, + "problem": "EnumMerging", + "suggest": "", + "rule": "\"enum\" declaration merging is not supported (arkts-no-enum-merging)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 1, + "endLine": 51, + "endColumn": 2, + "problem": "EnumMerging", + "suggest": "", + "rule": "\"enum\" declaration merging is not supported (arkts-no-enum-merging)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 5, + "endLine": 57, + "endColumn": 14, + "problem": "EnumMemberNonConstInit", + "suggest": "", + "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 17, + "problem": "EnumMemberNonConstInit", + "suggest": "", + "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule140.ets.args.json b/ets2panda/linter/test/rules/rule140.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule140.ets.args.json +++ b/ets2panda/linter/test/rules/rule140.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule140.ets.migrate.ets b/ets2panda/linter/test/rules/rule140.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..eee3cc75c5d5cc8811cc1c44d6de9b1ed04a0b26 --- /dev/null +++ b/ets2panda/linter/test/rules/rule140.ets.migrate.ets @@ -0,0 +1,30 @@ +/* + * 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. + */ + +const person = { + firstName: "aa", + fullName: function (): string { + return this.firstName + } +} +interface GeneratedObjectLiteralInterface_1 { + firstName: string; +} +const person1: GeneratedObjectLiteralInterface_1 = { + firstName: "Mary" +} +// This will log "Mary": +const boundFullName = person.fullName.bind(person1) +console.log(boundFullName()) \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule140.ets.migrate.json b/ets2panda/linter/test/rules/rule140.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c2f9a120a54037ab14e5ff490ccf9af0d9472296 --- /dev/null +++ b/ets2panda/linter/test/rules/rule140.ets.migrate.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": 16, + "column": 16, + "endLine": 16, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 15, + "endLine": 20, + "endColumn": 6, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 16, + "endLine": 19, + "endColumn": 20, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 39, + "endLine": 29, + "endColumn": 52, + "problem": "FunctionBind", + "suggest": "", + "rule": "'Function.bind' is not supported (arkts-no-func-bind)", + "severity": "WARNING" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule16.ets.args.json b/ets2panda/linter/test/rules/rule16.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule16.ets.args.json +++ b/ets2panda/linter/test/rules/rule16.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule16.ets.migrate.ets b/ets2panda/linter/test/rules/rule16.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7b8bdd8a50341aeb624686942f19223e7a8961a5 --- /dev/null +++ b/ets2panda/linter/test/rules/rule16.ets.migrate.ets @@ -0,0 +1,33 @@ +/* + * 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. + */ + +class C { + static s: string + + static { + C.s = "aa"; + C.s = C.s + "bb"; +} + +} + +class D { + static s: string + + static { + D.s = "aa" + D.s = D.s + "bb" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule16.ets.migrate.json b/ets2panda/linter/test/rules/rule16.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule16.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule25.ets.args.json b/ets2panda/linter/test/rules/rule25.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule25.ets.args.json +++ b/ets2panda/linter/test/rules/rule25.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule25.ets.migrate.ets b/ets2panda/linter/test/rules/rule25.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..51395c45d2fd17fb4b93446dd019fe53e7c5d985 --- /dev/null +++ b/ets2panda/linter/test/rules/rule25.ets.migrate.ets @@ -0,0 +1,59 @@ +/* + * 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. + */ + +class Person { + protected ssn: string; +private firstName: string; +private lastName: string; +constructor( + ssn: string, + firstName: string, + lastName: string + ) { + this.ssn = ssn; + this.firstName = firstName; + this.lastName = lastName; + this.ssn = ssn; + this.firstName = firstName; + this.lastName = lastName; +} + + getFullName(): string { + return this.firstName + " " + this.lastName + } +} + +class Person2{ + protected ssn: string + private firstName: string + private lastName: string + + constructor(ssn: string, firstName: string, lastName: string) { + this.ssn = ssn + this.firstName = firstName + this.lastName = lastName + } + + getFullName(): string { + return this.firstName + " " + this.lastName + } +} + +class A { + constructor(readonly a: A) { + this.a = a; + } +} + \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule25.ets.migrate.json b/ets2panda/linter/test/rules/rule25.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule25.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule29.ets.args.json b/ets2panda/linter/test/rules/rule29.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule29.ets.args.json +++ b/ets2panda/linter/test/rules/rule29.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule29.ets.migrate.ets b/ets2panda/linter/test/rules/rule29.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..284d21dac74036aef884a94888814edf8c49bd7e --- /dev/null +++ b/ets2panda/linter/test/rules/rule29.ets.migrate.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +class Point {x: number = 0; y: number = 0} +let p: Point = {x: 1, y: 2} +let x = p.x + +class Point2 {x: number = 0; y: number = 0} +let p2: Point2 = {x: 1, y: 2} +let x2 = p.x \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule29.ets.migrate.json b/ets2panda/linter/test/rules/rule29.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule29.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule3.ets.args.json b/ets2panda/linter/test/rules/rule3.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule3.ets.args.json +++ b/ets2panda/linter/test/rules/rule3.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule3.ets.migrate.ets b/ets2panda/linter/test/rules/rule3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d67266f1810625c091a72beb0990d974dd841f3a --- /dev/null +++ b/ets2panda/linter/test/rules/rule3.ets.migrate.ets @@ -0,0 +1,36 @@ +/* + * 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. + */ + + +class C { + private foo: number = 42; +} + +class X { + private foo: number = 42 +} + +class D { + private a: number = 1; + private b: number = 2; + + foo(): number { + return this.a + this.b + } + + bar(): number { + return this.a + this.b - this.a - this.b + } +} diff --git a/ets2panda/linter/test/rules/rule3.ets.migrate.json b/ets2panda/linter/test/rules/rule3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule3.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule37.ets b/ets2panda/linter/test/rules/rule37.ets index 4839a90823344ca855c20957a7cf21e585590b4e..a1d8a329aca0978ea0b86998c6902c4ae37580e0 100644 --- a/ets2panda/linter/test/rules/rule37.ets +++ b/ets2panda/linter/test/rules/rule37.ets @@ -64,4 +64,12 @@ let regex12: RegExp = RegExp("ab*c") - let regex13: RegExp = RegExp("ab*c","i") \ No newline at end of file + let regex13: RegExp = RegExp("ab*c","i") + + let a27: RegExp = RegExp('dawfgr'+'12345') + + let a25: RegExp = RegExp('.∗?(?:(?:元宵|三八|妇女|母亲|父亲|七夕|重阳|情人|儿童|六一'+'|愚人|复活|青年|护士|建军|教师|建党|万圣|感恩|秘书|七一|五四|八一|腊八|光棍|植树|中元)节|除夕|大年三十|大年30|七夕'+'|平安夜|六一|七一|五四|八一|三八|腊八|双十一|双十二).∗'); + + let regex20: RegExp = RegExp('dawfgr'.concat('12345')) + + let a28: RegExp = RegExp('dawfgr'+'12345' + '789') diff --git a/ets2panda/linter/test/rules/rule37.ets.args.json b/ets2panda/linter/test/rules/rule37.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/rules/rule37.ets.args.json +++ b/ets2panda/linter/test/rules/rule37.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule37.ets.arkts2.json b/ets2panda/linter/test/rules/rule37.ets.arkts2.json index ffad898af941561a93cd16e6bcca3574f1cf8fc4..e07b57d6dfb8725687fadcdc4937e02927228535 100644 --- a/ets2panda/linter/test/rules/rule37.ets.arkts2.json +++ b/ets2panda/linter/test/rules/rule37.ets.arkts2.json @@ -143,6 +143,46 @@ "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" + }, + { + "line": 69, + "column": 20, + "endLine": 69, + "endColumn": 44, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 20, + "endLine": 71, + "endColumn": 176, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 24, + "endLine": 73, + "endColumn": 56, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 21, + "endLine": 75, + "endColumn": 53, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule37.ets.autofix.json b/ets2panda/linter/test/rules/rule37.ets.autofix.json index bd396f0bda1a03374e4ff9887af2dcd32898e0ee..3cad91ca09415031931a0886e1e44b09b2ec7132 100644 --- a/ets2panda/linter/test/rules/rule37.ets.autofix.json +++ b/ets2panda/linter/test/rules/rule37.ets.autofix.json @@ -234,6 +234,74 @@ "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" + }, + { + "line": 69, + "column": 20, + "endLine": 69, + "endColumn": 44, + "problem": "RegularExpressionLiteral", + "autofix": [ + { + "start": 1968, + "end": 1992, + "replacementText": "new RegExp('dawfgr' + '12345')" + } + ], + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 20, + "endLine": 71, + "endColumn": 176, + "problem": "RegularExpressionLiteral", + "autofix": [ + { + "start": 2013, + "end": 2169, + "replacementText": "new RegExp('.∗?(?:(?:元宵|三八|妇女|母亲|父亲|七夕|重阳|情人|儿童|六一' + '|愚人|复活|青年|护士|建军|教师|建党|万圣|感恩|秘书|七一|五四|八一|腊八|光棍|植树|中元)节|除夕|大年三十|大年30|七夕' + '|平安夜|六一|七一|五四|八一|三八|腊八|双十一|双十二).∗')" + } + ], + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 24, + "endLine": 73, + "endColumn": 56, + "problem": "RegularExpressionLiteral", + "autofix": [ + { + "start": 2195, + "end": 2227, + "replacementText": "new RegExp('dawfgr'.concat('12345'))" + } + ], + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 21, + "endLine": 75, + "endColumn": 53, + "problem": "RegularExpressionLiteral", + "autofix": [ + { + "start": 2250, + "end": 2282, + "replacementText": "new RegExp('dawfgr' + '12345' + '789')" + } + ], + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule37.ets.migrate.ets b/ets2panda/linter/test/rules/rule37.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6cd09a1b8bd06b035a6b8a1d47df9bf984d2ab76 --- /dev/null +++ b/ets2panda/linter/test/rules/rule37.ets.migrate.ets @@ -0,0 +1,75 @@ +/* + * 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. + */ + + let regex: RegExp = new RegExp("bc*d"); + + let regex2: RegExp = new RegExp("bc*d"); + + const regex3 = new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$"); + const regex4: RegExp = new RegExp('^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$'); + + let regex5: RegExp = new RegExp("bc*d", "ig"); + + let regex6: RegExp = new RegExp("bc*d", "ig"); + + let regex7: RegExp = new RegExp(new RegExp("bc*d", "i"), "g"); + + let regex8: RegExp = new RegExp(new RegExp("bc*d", "i"), "g"); + + let regex9: RegExp = new RegExp("a\\\\"); + + let regex10: RegExp = new RegExp("a\\\\"); + + class A { + static readonly classregex0: RegExp = new RegExp("bc*d") + + static readonly classregex2 = new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$"); + + classregex3: RegExp = new RegExp("bc*d"); + + static staticMethodOne() { + let regex = new RegExp("bc*d") + } + + static staticMethodTwo() { + let regex: RegExp = new RegExp("/bc*d/"); + } + + methodOne() { + let regex = new RegExp("bc*d") + } + + methodTwo() { + let regex: RegExp = new RegExp("/bc*d/"); + } + + methodRet(): RegExp { + return new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$"); + } + } + + const regexLambda = () => new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$"); + + let regex12: RegExp = new RegExp("ab*c") + + let regex13: RegExp = new RegExp("ab*c", "i") + + let a27: RegExp = new RegExp('dawfgr' + '12345') + + let a25: RegExp = new RegExp('.∗?(?:(?:元宵|三八|妇女|母亲|父亲|七夕|重阳|情人|儿童|六一' + '|愚人|复活|青年|护士|建军|教师|建党|万圣|感恩|秘书|七一|五四|八一|腊八|光棍|植树|中元)节|除夕|大年三十|大年30|七夕' + '|平安夜|六一|七一|五四|八一|三八|腊八|双十一|双十二).∗'); + + let regex20: RegExp = new RegExp('dawfgr'.concat('12345')) + + let a28: RegExp = new RegExp('dawfgr' + '12345' + '789') diff --git a/ets2panda/linter/test/rules/rule37.ets.migrate.json b/ets2panda/linter/test/rules/rule37.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule37.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule38.ets.args.json b/ets2panda/linter/test/rules/rule38.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule38.ets.args.json +++ b/ets2panda/linter/test/rules/rule38.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule38.ets.migrate.ets b/ets2panda/linter/test/rules/rule38.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..59cb4761aa50e3cf26d9a7fbff2c633157a32584 --- /dev/null +++ b/ets2panda/linter/test/rules/rule38.ets.migrate.ets @@ -0,0 +1,69 @@ +/* + * 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. + */ + +interface GeneratedObjectLiteralInterface_1 { + n: number; + s: string; +} +let o1: GeneratedObjectLiteralInterface_1 = {n: 42, s: "foo"} +let o2: Object = {n: 42, s: "foo"} +let o3: object = {n: 42, s: "foo"} + +let oo: Object[] = [{n: 1, s: "1"}, {n: 2, s: "2"}] + +class C2 { + s: string + constructor(s: string) { + this.s = "s =" + s + } +} +let o4: C2 = {s: "foo"} + +class C3 { + readonly n: number = 0 + readonly s: string = "" +} +let o5: C3 = {n: 42, s: "foo"} + +abstract class A {} +let o6: A = {} + +class C4 { + n: number = 0 + s: string = "" + f() { + console.log("Hello") + } +} +let o7: C4 = {n: 42, s: "foo", f : () => {}} + +class Point { + x: number = 0 + y: number = 0 +} +function id_x_y(o: Point): Point { + return o +} + +// Structural typing is used to deduce that p is Point: +interface GeneratedObjectLiteralInterface_2 { + x: number; + y: number; +} +let p: GeneratedObjectLiteralInterface_2 = {x: 5, y: 10} +id_x_y(p) + +// A literal can be contextually (i.e., implicitly) typed as Point: +id_x_y({x: 5, y: 10}) \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets.json b/ets2panda/linter/test/rules/rule38.ets.migrate.json similarity index 56% rename from ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets.json rename to ets2panda/linter/test/rules/rule38.ets.migrate.json index 4d9df55e45af518b46bea5a4146a106275f37d00..c7161779dac42c50a664c11aaa8a89191afb0a60 100644 --- a/ets2panda/linter/test/sdkwhite/ComputedPropertyName.ets.json +++ b/ets2panda/linter/test/rules/rule38.ets.migrate.json @@ -15,103 +15,103 @@ ], "result": [ { - "line": 17, - "column": 3, - "endLine": 17, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 21, + "column": 18, + "endLine": 21, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 17, - "column": 6, - "endLine": 17, - "endColumn": 7, + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 19, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 20, - "column": 3, - "endLine": 20, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 24, + "column": 20, + "endLine": 24, + "endColumn": 52, + "problem": "ArrayLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", "severity": "ERROR" }, { - "line": 20, - "column": 6, - "endLine": 20, - "endColumn": 7, + "line": 24, + "column": 21, + "endLine": 24, + "endColumn": 22, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 23, - "column": 3, - "endLine": 23, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 24, + "column": 37, + "endLine": 24, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 23, - "column": 6, - "endLine": 23, - "endColumn": 7, + "line": 32, + "column": 14, + "endLine": 32, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 26, - "column": 3, - "endLine": 26, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 26, - "column": 6, - "endLine": 26, - "endColumn": 7, + "line": 41, + "column": 13, + "endLine": 41, + "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 29, - "column": 3, - "endLine": 29, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 50, + "column": 14, + "endLine": 50, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 29, - "column": 6, - "endLine": 29, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", + "line": 66, + "column": 8, + "endLine": 66, + "endColumn": 9, + "problem": "StructuralIdentity", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/rules/rule40.ets.args.json b/ets2panda/linter/test/rules/rule40.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule40.ets.args.json +++ b/ets2panda/linter/test/rules/rule40.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule40.ets.migrate.ets b/ets2panda/linter/test/rules/rule40.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..b98111045312a07ad6278ec84fed06b4621357e3 --- /dev/null +++ b/ets2panda/linter/test/rules/rule40.ets.migrate.ets @@ -0,0 +1,38 @@ +/* + * 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. + */ + +interface GeneratedTypeLiteralInterface_1 { + x: number; + y: number; +} +let o: GeneratedTypeLiteralInterface_1 = { + x: 2, + y: 3 +} + +interface GeneratedTypeLiteralInterface_2 { + x: number; + y: number; +} +type S = Set + +class C { + x: number = 0 + y: number = 0 +} + +let c: C = {x: 2, y: 3} + +type t = Set \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule40.ets.migrate.json b/ets2panda/linter/test/rules/rule40.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule40.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule46.ets.args.json b/ets2panda/linter/test/rules/rule46.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule46.ets.args.json +++ b/ets2panda/linter/test/rules/rule46.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/test/runtime/ets/user_defined_2.ets b/ets2panda/linter/test/rules/rule46.ets.migrate.ets similarity index 84% rename from ets2panda/test/runtime/ets/user_defined_2.ets rename to ets2panda/linter/test/rules/rule46.ets.migrate.ets index e96781534538477c045ec6ed0d589d2b75005ca3..d05a5787397d2bd5447be008301272074c187053 100644 --- a/ets2panda/test/runtime/ets/user_defined_2.ets +++ b/ets2panda/linter/test/rules/rule46.ets.migrate.ets @@ -13,9 +13,10 @@ * limitations under the License. */ -let boolean : boolean = true; - -function main() { - let boolean : boolean = false; - assertEQ(boolean, false) +let f = (s: string) => { + console.log(s); } + +let foo = (s: string) => { + console.log(s) +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule46.ets.migrate.json b/ets2panda/linter/test/rules/rule46.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule46.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule5.ets.args.json b/ets2panda/linter/test/rules/rule5.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule5.ets.args.json +++ b/ets2panda/linter/test/rules/rule5.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule5.ets.migrate.ets b/ets2panda/linter/test/rules/rule5.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..4be90ab7194bb4ce6eb8891a949c6f212b7f508f --- /dev/null +++ b/ets2panda/linter/test/rules/rule5.ets.migrate.ets @@ -0,0 +1,124 @@ +/* + * 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. + */ + +// fixable +let bar1 = 1; +let foo1 = bar1; + +let bar2 = 1; +let most2 = 1; +let foo2 = bar2, toast2 = most2; + +let bar3 = 1; +let most3 = 1; +let foo3 = bar3; let toast3 = most3; + +let b4 = []; +for (let a4 of b4) { console.log(a4); } + +let b5 = []; +for (let a5 in b5) { console.log(a5); } + +let b6 = []; +for (let a6 of b6) { let c6 = 1; console.log(c6); } + +let list7 = []; +for (let i7 = 0; i7 < list7.length; ++i7) { foo(i7) } + +var {a8, b8 = a8} = {} // not fixable + +let a9 = b9; var b9 = 1 + +let foo10 = 1 + +declare let foo11 = 2; + +// not fixable +var fx12 = function (i12 = 0) { if (i12 < 5) { return fx12(i12 + 1); } console.log(i12); }; fx12(); + +var foo13 = () => { foo13(); }; + +var foo14 = () => foo14(); + +// fixable +let bar15 = foo15; var foo15 = () => { foo15(); }; + +let bar16 = () => { foo16(); }; var foo16 = () => { }; + +// not fixable +for (var i17 = 0, i17 = 0; false;); + +var i18 = 0; for (var i18 = 1; false;); console.log(i18); + +var a19, b19, c19; var a19; + +let b20 = 1; +var a20; if (b20) { var a20; } + +let foo21 = 1; +if (foo21) { var a21, b21, c21; } a21; + +for (var i22 = 0; i22 < 10; ++i22) {} i22; + +let obj23 = []; +for (var a23 in obj23) {} a23; + +let list24 = []; +for (var a24 of list24) {} a24; + +let a25 = 1; +switch (a25) { case 0: var b25 = 1 } + +let b26 = []; +let arr26 = []; +for (var a26 of b26) { arr26.push(() => a26); } + +let b27 = []; +for (let a27 of b27) { var c27; console.log(c27); c27 = 'hello'; } + +var a28 = a28 + +var {a29 = a29} = {} + +var {a30 = b30, b30} = {} + +var a31 = b31, b31 = 1 + +function foo32() { a32 } var a32 = 1; foo32() + +let foo33 = 1; +if (foo33) var bar33 = 1; + +// var foo34 = 1 + +// { var foo35 = 1 } + +if (true) { var foo36 = 1 } + +function foo37() { var let; } + +// how to test it, let keyword should stay let keyword +// function foo38() { var { let } = {}; } + +var foo39 = (() => { foo39(); })(); + +let bar40 = (a) => { }; +var foo40 = bar40(() => { foo40(); }); + +var bar41 = foo41, foo41 = () => { foo41(); }; + +var { foo42 = foo42 } = () => { foo42(); }; + +var { bar43 = foo43, foo43 } = () => { foo43(); }; diff --git a/ets2panda/linter/test/migrate/type_literals.ts.json b/ets2panda/linter/test/rules/rule5.ets.migrate.json similarity index 38% rename from ets2panda/linter/test/migrate/type_literals.ts.json rename to ets2panda/linter/test/rules/rule5.ets.migrate.json index 45191b82e30c33c2b17335a0ceec474892e0dc17..d5974e4a39550fafd4da3e905d701096a8416c04 100644 --- a/ets2panda/linter/test/migrate/type_literals.ts.json +++ b/ets2panda/linter/test/rules/rule5.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -15,643 +15,673 @@ ], "result": [ { - "line": 16, - "column": 14, - "endLine": 16, + "line": 32, + "column": 13, + "endLine": 32, "endColumn": 15, - "problem": "ObjectTypeLiteral", + "problem": "ForInStatement", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "\"for .. in\" is not supported (arkts-no-for-in)", "severity": "ERROR" }, { - "line": 17, - "column": 14, - "endLine": 17, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "line": 40, + "column": 1, + "endLine": 40, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 18, - "column": 14, - "endLine": 18, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 23, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { - "line": 19, - "column": 22, - "endLine": 19, - "endColumn": 23, - "problem": "ObjectTypeLiteral", + "line": 40, + "column": 21, + "endLine": 40, + "endColumn": 22, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 19, - "column": 47, - "endLine": 19, - "endColumn": 48, - "problem": "ObjectTypeLiteral", + "line": 42, + "column": 14, + "endLine": 42, + "endColumn": 17, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 20, - "column": 20, - "endLine": 20, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 49, + "column": 1, + "endLine": 49, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 21, - "column": 14, - "endLine": 21, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 91, + "problem": "FunctionExpression", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", "severity": "ERROR" }, { - "line": 24, - "column": 6, - "endLine": 24, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 91, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 30, - "column": 21, - "endLine": 30, - "endColumn": 22, - "problem": "ObjectTypeLiteral", + "line": 51, + "column": 1, + "endLine": 51, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 32, - "column": 11, - "endLine": 32, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 53, + "column": 1, + "endLine": 53, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", + "line": 53, + "column": 13, + "endLine": 53, + "endColumn": 26, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 33, - "column": 11, - "endLine": 33, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 56, + "column": 20, + "endLine": 56, + "endColumn": 23, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 33, - "column": 36, - "endLine": 33, - "endColumn": 37, - "problem": "ObjectLiteralNoContextType", + "line": 58, + "column": 33, + "endLine": 58, + "endColumn": 36, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 34, - "column": 11, - "endLine": 34, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 61, + "column": 6, + "endLine": 61, + "endColumn": 9, + "problem": "VarDeclaration", + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 35, + "line": 63, "column": 19, - "endLine": 35, - "endColumn": 20, - "problem": "ObjectTypeLiteral", + "endLine": 63, + "endColumn": 22, + "problem": "VarDeclaration", + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 1, + "endLine": 65, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 35, - "column": 44, - "endLine": 35, - "endColumn": 45, - "problem": "ObjectTypeLiteral", + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 8, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 36, + "line": 65, + "column": 10, + "endLine": 65, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 15, + "endLine": 65, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 65, "column": 20, - "endLine": 36, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "endLine": 65, + "endColumn": 23, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 37, - "column": 11, - "endLine": 37, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 65, + "column": 24, + "endLine": 65, + "endColumn": 27, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 40, - "column": 6, - "endLine": 40, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 68, + "column": 1, + "endLine": 68, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 45, + "line": 68, "column": 5, - "endLine": 45, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", + "endLine": 68, + "endColumn": 8, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 48, - "column": 6, - "endLine": 48, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", + "line": 68, + "column": 21, + "endLine": 68, + "endColumn": 24, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 51, - "column": 8, - "endLine": 51, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", + "line": 68, + "column": 25, + "endLine": 68, + "endColumn": 28, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 58, - "column": 15, - "endLine": 58, - "endColumn": 16, - "problem": "ObjectTypeLiteral", + "line": 71, + "column": 14, + "endLine": 71, + "endColumn": 17, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 58, - "column": 40, - "endLine": 58, - "endColumn": 41, - "problem": "ObjectTypeLiteral", + "line": 71, + "column": 18, + "endLine": 71, + "endColumn": 21, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 59, - "column": 10, - "endLine": 59, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", + "line": 71, + "column": 23, + "endLine": 71, + "endColumn": 26, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 63, - "column": 6, - "endLine": 63, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 71, + "column": 28, + "endLine": 71, + "endColumn": 31, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 63, - "column": 31, - "endLine": 63, - "endColumn": 32, - "problem": "ObjectLiteralNoContextType", + "line": 73, + "column": 6, + "endLine": 73, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 65, - "column": 8, - "endLine": 65, - "endColumn": 9, - "problem": "ObjectTypeLiteral", + "line": 76, + "column": 14, + "endLine": 76, + "endColumn": 16, + "problem": "ForInStatement", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "\"for .. in\" is not supported (arkts-no-for-in)", "severity": "ERROR" }, { - "line": 65, - "column": 33, - "endLine": 65, - "endColumn": 34, - "problem": "ObjectTypeLiteral", + "line": 76, + "column": 6, + "endLine": 76, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 66, - "column": 12, - "endLine": 66, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 79, + "column": 6, + "endLine": 79, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 72, - "column": 22, - "endLine": 72, - "endColumn": 23, - "problem": "ObjectTypeLiteral", + "line": 82, + "column": 24, + "endLine": 82, + "endColumn": 27, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 73, - "column": 14, - "endLine": 73, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "line": 86, + "column": 6, + "endLine": 86, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 73, - "column": 38, - "endLine": 73, - "endColumn": 39, - "problem": "ObjectTypeLiteral", + "line": 89, + "column": 24, + "endLine": 89, + "endColumn": 27, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 75, - "column": 16, - "endLine": 75, - "endColumn": 17, - "problem": "ObjectTypeLiteral", + "line": 89, + "column": 28, + "endLine": 89, + "endColumn": 31, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 80, - "column": 3, - "endLine": 80, + "line": 91, + "column": 1, + "endLine": 91, "endColumn": 4, - "problem": "ObjectTypeLiteral", + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 80, - "column": 19, - "endLine": 80, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", + "line": 91, + "column": 5, + "endLine": 91, + "endColumn": 14, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 82, - "column": 20, - "endLine": 82, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 93, + "column": 1, + "endLine": 93, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 85, - "column": 3, - "endLine": 85, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 93, + "column": 5, + "endLine": 93, + "endColumn": 21, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { "line": 93, - "column": 3, + "column": 19, "endLine": 93, - "endColumn": 23, - "problem": "CallSignature", + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 94, - "column": 3, - "endLine": 94, - "endColumn": 22, - "problem": "ConstructorType", + "line": 95, + "column": 1, + "endLine": 95, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { "line": 95, - "column": 3, + "column": 5, "endLine": 95, "endColumn": 26, - "problem": "IndexMember", + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { "line": 95, - "column": 18, + "column": 24, "endLine": 95, "endColumn": 25, - "problem": "UnknownType", + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 98, - "column": 18, - "endLine": 98, - "endColumn": 19, - "problem": "ObjectTypeLiteral", + "line": 97, + "column": 1, + "endLine": 97, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 101, - "column": 3, - "endLine": 101, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 99, + "column": 26, + "endLine": 99, + "endColumn": 29, + "problem": "VarDeclaration", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 109, - "column": 3, - "endLine": 109, - "endColumn": 23, - "problem": "CallSignature", + "line": 102, + "column": 12, + "endLine": 102, + "endColumn": 15, + "problem": "VarDeclaration", "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 22, - "problem": "ConstructorType", + "line": 108, + "column": 13, + "endLine": 108, + "endColumn": 16, + "problem": "VarDeclaration", "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 111, - "column": 3, - "endLine": 111, - "endColumn": 26, - "problem": "IndexMember", + "line": 110, + "column": 20, + "endLine": 110, + "endColumn": 23, + "problem": "VarDeclaration", "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 111, - "column": 18, - "endLine": 111, - "endColumn": 25, - "problem": "UnknownType", + "line": 110, + "column": 24, + "endLine": 110, + "endColumn": 27, + "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { "line": 115, - "column": 49, + "column": 1, "endLine": 115, - "endColumn": 50, - "problem": "ObjectTypeLiteral", + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 116, - "column": 11, - "endLine": 116, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 117, + "column": 14, + "endLine": 117, + "endColumn": 15, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { "line": 118, - "column": 20, + "column": 1, "endLine": 118, - "endColumn": 21, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 11, - "endLine": 119, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 119, - "column": 30, - "endLine": 119, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", + "line": 120, + "column": 1, + "endLine": 120, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 119, - "column": 34, - "endLine": 119, - "endColumn": 35, - "problem": "ObjectLiteralNoContextType", + "line": 122, + "column": 1, + "endLine": 122, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 121, - "column": 25, - "endLine": 121, - "endColumn": 26, - "problem": "ObjectTypeLiteral", + "line": 122, + "column": 5, + "endLine": 122, + "endColumn": 43, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { "line": 124, - "column": 11, + "column": 1, "endLine": 124, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { "line": 124, - "column": 12, + "column": 5, "endLine": 124, - "endColumn": 17, - "problem": "ComputedPropertyName", + "endColumn": 50, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { - "line": 127, - "column": 11, - "endLine": 127, + "line": 42, + "column": 10, + "endLine": 42, "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "problem": "StrictDiagnostic", + "suggest": "Variable 'b9' is used before being assigned.", + "rule": "Variable 'b9' is used before being assigned.", "severity": "ERROR" }, { - "line": 127, - "column": 31, - "endLine": 127, - "endColumn": 32, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "line": 56, + "column": 13, + "endLine": 56, + "endColumn": 18, + "problem": "StrictDiagnostic", + "suggest": "Variable 'foo15' is used before being assigned.", + "rule": "Variable 'foo15' is used before being assigned.", "severity": "ERROR" }, { - "line": 129, - "column": 11, - "endLine": 129, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "line": 76, + "column": 27, + "endLine": 76, + "endColumn": 30, + "problem": "StrictDiagnostic", + "suggest": "Variable 'a23' is used before being assigned.", + "rule": "Variable 'a23' is used before being assigned.", "severity": "ERROR" }, { - "line": 129, - "column": 17, - "endLine": 129, - "endColumn": 23, - "problem": "TypeQuery", - "suggest": "", - "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "line": 79, + "column": 28, + "endLine": 79, + "endColumn": 31, + "problem": "StrictDiagnostic", + "suggest": "Variable 'a24' is used before being assigned.", + "rule": "Variable 'a24' is used before being assigned.", "severity": "ERROR" }, { - "line": 131, - "column": 11, - "endLine": 131, - "endColumn": 12, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "line": 86, + "column": 35, + "endLine": 86, + "endColumn": 44, + "problem": "StrictDiagnostic", + "suggest": "Argument of type '() => never' is not assignable to parameter of type 'never'.", + "rule": "Argument of type '() => never' is not assignable to parameter of type 'never'.", "severity": "ERROR" }, { - "line": 131, - "column": 17, - "endLine": 131, - "endColumn": 23, - "problem": "TypeQuery", - "suggest": "", - "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "line": 97, + "column": 11, + "endLine": 97, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'b31' is used before being assigned.", + "rule": "Variable 'b31' is used before being assigned.", "severity": "ERROR" }, { - "line": 133, - "column": 10, - "endLine": 133, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "line": 120, + "column": 13, + "endLine": 120, + "endColumn": 18, + "problem": "StrictDiagnostic", + "suggest": "Variable 'foo41' is used before being assigned.", + "rule": "Variable 'foo41' is used before being assigned.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/rules/rule53.ets.args.json b/ets2panda/linter/test/rules/rule53.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule53.ets.args.json +++ b/ets2panda/linter/test/rules/rule53.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule53.ets.migrate.ets b/ets2panda/linter/test/rules/rule53.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..616623d38749ee75d8c84b784dca402a8bbab2ec --- /dev/null +++ b/ets2panda/linter/test/rules/rule53.ets.migrate.ets @@ -0,0 +1,39 @@ +/* + * 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. + */ + +class Shape {} +class Circle extends Shape {x: number = 5} +class Square extends Shape {y: string = "a"} + +function createShape(): Shape { + return new Circle() +} + +let c1 = createShape() as Circle + +let c2 = createShape() as Circle + +// No report is provided during compilation +// nor during runtime if cast is wrong: +let c3 = createShape() as Square +console.log(c3.y) // undefined + +// Important corner case for casting primitives to the boxed counterparts: +// The left operand is not properly boxed here in in runtime +// because "as" has no runtime effect in TypeScript +let e1 = (5.0 as Number) instanceof Number // false + +// Number object is created and instanceof works as expected: +let e2 = (new Number(5.0)) instanceof Number // true \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule53.ets.migrate.json b/ets2panda/linter/test/rules/rule53.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..e1ec7aa8a9fb6d16b66482200a831120b45860a3 --- /dev/null +++ b/ets2panda/linter/test/rules/rule53.ets.migrate.json @@ -0,0 +1,28 @@ +{ + "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": 36, + "column": 11, + "endLine": 36, + "endColumn": 24, + "problem": "TypeAssertion", + "suggest": "", + "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule71.ets.args.json b/ets2panda/linter/test/rules/rule71.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule71.ets.args.json +++ b/ets2panda/linter/test/rules/rule71.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule71.ets.migrate.ets b/ets2panda/linter/test/rules/rule71.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e7b82ded6d1100b8d02e3be65e833e3bf435ccb3 --- /dev/null +++ b/ets2panda/linter/test/rules/rule71.ets.migrate.ets @@ -0,0 +1,112 @@ +/* + * 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. + */ + +for (let i = 0, j = 0; i < 10; ++i, j += 2) { + console.log(i) + console.log(j) +} + +let x = 0 + +// Error, no autofix +x = (++x, x++) + +// No error +for (let i = 0, j = 0; i < 10; ++i, j += 2) { + console.log(i) + console.log(j) +} + +let x2 = 0 +++x2 +x2 = x2++ + +let c = () => 33; + +// Error, no autofix +const a = (1, b = 2, c()); + +// Error, no autofix +const r = (c(), b, 1) + +class Test { + // Error, no autofix + static readonly sr = (1, c(), 2); + + // Error, no autofix + field1 = (1, 2, c()); + + method() { + // Error, no autofix + this.field1 = (c(), sr, 1); + } +} + +// Error, autofix +x++; + x--; + +// Error, autofix +x++; + x--; + ++x; + --x; + x; + +// Error, no autofix +if (x++, x === 1) { + // Error, autofix + x++; + x--; + ++x; + --x; + x; +} + +// Error, autofix +x++ + x--; + ++x; + --x; + +// Error, autofix +++x; + x-- + x++; + --x; + +// Error, autofix +++x; + --x; + x-- + x++; + +// Error, autofix +x === x; + --x; + x === x; + x++; + x === x; + +// Error, autofix +x instanceof number; + --x; + x instanceof number; + x++; + x instanceof number; + +// Error, autofix +x in x; + --x; + x in x; + x++; + x in x; diff --git a/ets2panda/linter/test/rules/rule71.ets.migrate.json b/ets2panda/linter/test/rules/rule71.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..b3add27cb17b820db267c1c3c1c36a600d729761 --- /dev/null +++ b/ets2panda/linter/test/rules/rule71.ets.migrate.json @@ -0,0 +1,148 @@ +{ + "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": 24, + "column": 6, + "endLine": 24, + "endColumn": 14, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 12, + "endLine": 39, + "endColumn": 25, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 12, + "endLine": 42, + "endColumn": 21, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 27, + "endLine": 46, + "endColumn": 36, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 15, + "endLine": 49, + "endColumn": 24, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 24, + "endLine": 53, + "endColumn": 34, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 17, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 3, + "endLine": 101, + "endColumn": 13, + "problem": "InstanceofUnsupported", + "suggest": "", + "rule": "\"instanceof\" operator is partially supported (arkts-instanceof-ref-types)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 4, + "endLine": 103, + "endColumn": 14, + "problem": "InstanceofUnsupported", + "suggest": "", + "rule": "\"instanceof\" operator is partially supported (arkts-instanceof-ref-types)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 4, + "endLine": 105, + "endColumn": 14, + "problem": "InstanceofUnsupported", + "suggest": "", + "rule": "\"instanceof\" operator is partially supported (arkts-instanceof-ref-types)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 3, + "endLine": 108, + "endColumn": 5, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 4, + "endLine": 110, + "endColumn": 6, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 4, + "endLine": 112, + "endColumn": 6, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule79.ets.args.json b/ets2panda/linter/test/rules/rule79.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule79.ets.args.json +++ b/ets2panda/linter/test/rules/rule79.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule79.ets.migrate.ets b/ets2panda/linter/test/rules/rule79.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e31b555a881d4ddc4858e6654af9f8fb2ca265c8 --- /dev/null +++ b/ets2panda/linter/test/rules/rule79.ets.migrate.ets @@ -0,0 +1,29 @@ +/* + * 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. + */ + +try { + // some code +} +catch (a) { + // handle error +} + + +try { + // some code +} +catch (a) { + // handle error +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule79.ets.migrate.json b/ets2panda/linter/test/rules/rule79.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule79.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule90.ets.args.json b/ets2panda/linter/test/rules/rule90.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90.ets.args.json +++ b/ets2panda/linter/test/rules/rule90.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90.ets.migrate.ets b/ets2panda/linter/test/rules/rule90.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3e97208530afa5e81aa4d0b018c73efacb84c4cd --- /dev/null +++ b/ets2panda/linter/test/rules/rule90.ets.migrate.ets @@ -0,0 +1,52 @@ +/* + * 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. + */ + + // Compile-time error with noImplicitAny + function f(x: number) { + if (x <= 0) { + return x + } + return g(x) + } + + // Compile-time error with noImplicitAny + function g(x: number) { + return f(x - 1) + } + + function doOperation(x: number, y: number) { + return x + y + } + + console.log(f(10)) + console.log(doOperation(2, 3)) + + function f1(x: number) : number { + if (x <= 0) { + return x + } + return g1(x) + } + + function g1(x: number) { + return f1(x - 1) + } + + function doOperation1(x: number, y: number) { + return x + y + } + + console.log(f1(10)) + console.log(doOperation1(2, 3)) diff --git a/ets2panda/linter/test/rules/rule90.ets.migrate.json b/ets2panda/linter/test/rules/rule90.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0ca7cc20930ab46dec04ef3c0545841b97c51cde --- /dev/null +++ b/ets2panda/linter/test/rules/rule90.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 14, + "endLine": 17, + "endColumn": 15, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 14, + "endLine": 25, + "endColumn": 15, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule90_1.ets.args.json b/ets2panda/linter/test/rules/rule90_1.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_1.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_1.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_1.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a4dc9107fc019a7f1d652cda0329307e7920f2b2 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_1.ets.migrate.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + + function f(x: number) { + return 0; + } + + function f1(): number { + return 0; + } + diff --git a/ets2panda/linter/test/rules/rule90_1.ets.migrate.json b/ets2panda/linter/test/rules/rule90_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_1.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule90_2.ets.args.json b/ets2panda/linter/test/rules/rule90_2.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_2.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_2.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_2.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d25831ff19e99082fb5c3f2cdf4a0b741d1d81a7 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_2.ets.migrate.ets @@ -0,0 +1,26 @@ +/* + * 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. + */ + + class A { + public foo: number = 0; + } + + function f() { + return new A; + } + + function f1(): A{ + return new A; + } diff --git a/ets2panda/linter/test/rules/rule90_2.ets.migrate.json b/ets2panda/linter/test/rules/rule90_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_2.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule90_3.ets.args.json b/ets2panda/linter/test/rules/rule90_3.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_3.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_3.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_3.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..168ead9c1e906bf664431fd0902c7010e7bdd6f2 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_3.ets.migrate.ets @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + public foo: number = 0; + + public bar_no_return_def() { + return 0 + } + + public bar_with_return_def() : number { + return 0 + } +} + +function f(): number { + let a = new A(); + return a.bar_no_return_def(); +} + +function f2() { + let a = new A(); + return a.bar_with_return_def(); +} + +function f3(): number{ + let a = new A(); + return a.bar_no_return_def(); +} + +function f2(): number{ + let a = new A(); + return a.bar_with_return_def(); +} diff --git a/ets2panda/linter/test/rules/rule90_3.ets.migrate.json b/ets2panda/linter/test/rules/rule90_3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_3.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule90_4.ets.args.json b/ets2panda/linter/test/rules/rule90_4.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_4.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_4.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_4.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_4.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..cc5ebb1c6073dae1a8d4506b37792888d3df1222 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_4.ets.migrate.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + public foo: number = 0; + + public bar_no_return_def() { + return this.bar_with_return_def(); + } + + public bar_with_return_def() : number { + return (2 + 2) + } +} + +class B { + public foo: number = 0; + + public bar_no_return_def() { + return (2 + 2) + } + + public bar_with_return_def() : number { + return this.bar_with_return_def(); + } +} + diff --git a/ets2panda/linter/test/rules/rule90_4.ets.migrate.json b/ets2panda/linter/test/rules/rule90_4.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_4.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule90_5.ets.args.json b/ets2panda/linter/test/rules/rule90_5.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_5.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_5.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_5.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_5.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c3ac9d3bc2394d9ccc6a972b22ba0f39a0de71b --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_5.ets.migrate.ets @@ -0,0 +1,32 @@ +/* + * 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. + */ + +class Data1 { + public foo: number = 0; +} + +class Data2 extends Data1{ + public foo: number = 0; + +} + + +function dataFactory1() : Data1 { + return new Data2(); +} + +function dataFactory2() : Data2 { + return new Data1(); +} diff --git a/ets2panda/linter/test/rules/rule90_5.ets.migrate.json b/ets2panda/linter/test/rules/rule90_5.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_5.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule92.ets.args.json b/ets2panda/linter/test/rules/rule92.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule92.ets.args.json +++ b/ets2panda/linter/test/rules/rule92.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "Copyright (c) 2024-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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule92.ets.migrate.ets b/ets2panda/linter/test/rules/rule92.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..b50118770b778e5dc925fd5a627de2478cef2cec --- /dev/null +++ b/ets2panda/linter/test/rules/rule92.ets.migrate.ets @@ -0,0 +1,90 @@ +/* + * 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. + */ + +// Fixable + +function addNum(a: number, b: number): void { + let logToConsole: (message: String) => void = (message: String): void => { + console.log(message); +}; + + let result = a + b + + logToConsole("result is " + result) +} + + +function addNum2(a: number, b: number): void { + // Use lambda instead of a nested function: + let logToConsole: (message: string) => void = (message: string): void => { + console.log(message) + } + + let result = a + b + + logToConsole("result is " + result) +} + + +function NestedOne(a: number, b: number): void { + let NestedTwo: (message: String) => void = (message: String): void => { + let NestedThree: (message: String) => void = (message: String): void => { + console.log("NestedThree"); +}; +}; +} + + +function NestedOne1(a: number, b: number): void { + let NestedTwo: (message: String) => void = (message: String): void => { + console.log("NestedTwo"); +}; + + let NestedTooToo: (message: String) => void = (message: String): void => { + console.log("NestedTooToo"); +}; +} + +function NestedOne2(a: number, b: number): void { + let NestedTwo: (message: String) => void = (message: String): void => { + let NestedThree: (message: String) => void = (message: String): void => { + console.log("NestedThree"); +}; + let NestedThreeToo: (message: String) => void = (message: String): void => { + console.log("NestedThreeToo"); +}; +}; +} + +// Not fixable +function decoratorFoo(): void { + @decorator + function decorated(): void { + } + + function* generatorFunction() { + return 3; + } + + function thisFoo() { + return this.what; + } + + notFixable(); + + function notFixable(): void { + } +} + diff --git a/ets2panda/linter/test/rules/rule92.ets.migrate.json b/ets2panda/linter/test/rules/rule92.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4c5918f4ba712a4ef98b04aba13fbf6561f54669 --- /dev/null +++ b/ets2panda/linter/test/rules/rule92.ets.migrate.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": 73, + "column": 5, + "endLine": 73, + "endColumn": 13, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 5, + "endLine": 77, + "endColumn": 13, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 5, + "endLine": 79, + "endColumn": 6, + "problem": "GeneratorFunction", + "suggest": "", + "rule": "Generator functions are not supported (arkts-no-generators)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 14, + "endLine": 81, + "endColumn": 21, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 16, + "endLine": 82, + "endColumn": 20, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 13, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 13, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets b/ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets deleted file mode 100644 index 81cb6eeb8b9723dc0a46616e3380c8fe98eb9612..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/sdkwhite/ConstructorFuncs.ets +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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. - */ - -// 1. First, define the DatabaseObject base class and several entity classes - -// Base database object interface -interface DatabaseObject { - id: number; - save(): Promise; -} - -// User entity class -class User implements DatabaseObject { - id: number; - username: string; - email: string; - - constructor() { - this.id = 0; - this.username = ''; - this.email = ''; - } - - async save(): Promise { - console.log(`Saving user ${this.username}`); - // Actual saving logic... - } -} - -// Product entity class -class Product implements DatabaseObject { - id: number; - name: string; - price: number; - - constructor() { - this.id = 0; - this.name = ''; - this.price = 0; - } - - async save(): Promise { - console.log(`Saving product ${this.name}`); - // Actual saving logic... - } -} - -// 2. Implement the DatabaseQuery class -class DatabaseQuery { - private entityClass: new () => T; - - constructor(entityClass: new () => T) { - this.entityClass = entityClass; - } - - // Example query method - async findById(id: number): Promise { - const entity = new this.entityClass(); - // Simulate database query - console.log(`Querying ${entity.constructor.name} with id ${id}`); - // Actual query logic... - return {...entity, id}; // Return simulated data - } - - // Another example query method - async findAll(): Promise { - const entity = new this.entityClass(); - console.log(`Querying all ${entity.constructor.name} records`); - // Actual query logic... - return [{...entity, id: 1}]; // Return simulated data - } -} - -// 3. Usage example - -// Create a user query instance -const userQuery = new DatabaseQuery(User); // Error occurs - -// Use the query methods -(async () => { - const user = await userQuery.findById(1); - if (user) { - console.log(`Found user: ${user.username}`); - user.username = "newUsername"; - await user.save(); - } - - const allUsers = await userQuery.findAll(); - console.log(`Found ${allUsers.length} users`); - - // Create a product query instance - const productQuery = new DatabaseQuery(Product); // Error occurs - const product = await productQuery.findById(5); - if (product) { - console.log(`Found product: ${product.name} ($${product.price})`); - } -})(); \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/InterfaceExtendsClass.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/InterfaceExtendsClass.ets.arkts2.json deleted file mode 100644 index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/sdkwhite/InterfaceExtendsClass.ets.arkts2.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "result": [ - - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/constructor_types_deprecated_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.args.json old mode 100755 new mode 100644 similarity index 100% rename from ets2panda/linter/test/sdkwhite/constructor_types_deprecated_sdk.ets.args.json rename to ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.args.json diff --git a/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.arkts2.json index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..5d0e2d9cb631c646033d268395725ece2391e0d6 100644 --- a/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.arkts2.json @@ -14,6 +14,105 @@ "limitations under the License." ], "result": [ - + { + "line": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 48, + "endLine": 18, + "endColumn": 52, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 26, + "endLine": 24, + "endColumn": 50, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 54, + "endLine": 24, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 44, + "endLine": 30, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 9, + "endLine": 32, + "endColumn": 10, + "problem": "OptionalMethod", + "suggest": "", + "rule": "Optional methods are not supported (arkts-optional-methods)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 43, + "endLine": 32, + "endColumn": 47, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 28, + "endLine": 37, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 26, + "endLine": 41, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/LiteralAsPropertyName2.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/LiteralAsPropertyName2.ets.arkts2.json deleted file mode 100644 index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/sdkwhite/LiteralAsPropertyName2.ets.arkts2.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "result": [ - - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/SendablePropType.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/SendablePropType.ets.arkts2.json deleted file mode 100644 index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/sdkwhite/SendablePropType.ets.arkts2.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "result": [ - - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets new file mode 100755 index 0000000000000000000000000000000000000000..4584cafa7b4940bab8a405ecae1f87d510783d5a --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets @@ -0,0 +1,60 @@ +/* + * 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. + */ +'use static' + +import { TextStyle } from './sdk/declarations/styled_string' +import { HyperlinkAttribute, HyperlinkInterface } from './sdk/declarations/hyperlink' + +@Entry +@Component +struct Index { + fontStyleAttr1: TextStyle = new TextStyle({fontColor: Color.Blue}); // Error(2) + fontStyleAttr2: TextStyle; // Error + + @State styleList: Array = new Array(); // Error + aboutToAppear() { + for (let i = 15; i < 50; i++) + this.styleList.push(new TextStyle({})); // Error + } + + build() { + List() { + ForEach(this.styleList, (item: TextStyle) => { // Error + ListItem() { + Text("Hello World") + .fontSize(item.fontSize) + } + }) + } + } +} + +class TextStyleDemo2 extends TextStyle { // Error + constructor() { + super(); + } +} + +let hyperlinkAttr1: HyperlinkAttribute = HyperlinkInterface; +let hyperlinkAttr2: HyperlinkAttribute = HyperlinkInterface.color(''); +class HyperlinkTest { + prop1: HyperlinkAttribute = HyperlinkInterface; + prop2: HyperlinkAttribute = HyperlinkInterface.color(''); +} +let hyperlinkAttr3: HyperlinkAttribute; +hyperlinkAttr3 = HyperlinkInterface; +function func(x = HyperlinkInterface) { + +} diff --git a/ets2panda/linter/test/migrate/destructuring_declarations.ts.args.json b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.args.json old mode 100644 new mode 100755 similarity index 90% rename from ets2panda/linter/test/migrate/destructuring_declarations.ts.args.json rename to ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.args.json index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..3ef4496a819a201892114d1c90f78ae32053c334 --- a/ets2panda/linter/test/migrate/destructuring_declarations.ts.args.json +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } 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 new file mode 100644 index 0000000000000000000000000000000000000000..307e9a28a600465c8174974ff51b52c609c700c3 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.arkts2.json @@ -0,0 +1,278 @@ +{ + "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": 1, + "endLine": 17, + "endColumn": 61, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 86, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 19, + "endLine": 23, + "endColumn": 28, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 35, + "endLine": 23, + "endColumn": 44, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 19, + "endLine": 24, + "endColumn": 28, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 27, + "endLine": 26, + "endColumn": 36, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 40, + "endLine": 26, + "endColumn": 51, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 14, + "endLine": 28, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 31, + "endLine": 29, + "endColumn": 40, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 38, + "endLine": 34, + "endColumn": 47, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 30, + "endLine": 44, + "endColumn": 39, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 42, + "endLine": 50, + "endColumn": 60, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 42, + "endLine": 51, + "endColumn": 60, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 31, + "endLine": 53, + "endColumn": 49, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 31, + "endLine": 54, + "endColumn": 49, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 18, + "endLine": 57, + "endColumn": 36, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 19, + "endLine": 58, + "endColumn": 37, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 57, + "endLine": 23, + "endColumn": 62, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 9, + "endLine": 35, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 11, + "endLine": 36, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 17, + "problem": "StrictDiagnostic", + "suggest": "Property 'fontStyleAttr2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'fontStyleAttr2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.json b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..489a1474b5a6f1db71bdf86fbf3b06b773ea21c8 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.json @@ -0,0 +1,48 @@ +{ + "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": 1, + "endLine": 17, + "endColumn": 61, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 86, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 17, + "problem": "StrictDiagnostic", + "suggest": "Property 'fontStyleAttr2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'fontStyleAttr2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets index 82bf1e5c601952cb920461c5b2d5057f5908456d..a2886cecbb321ff0954b2fed4e1aa89181faec9e 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets @@ -13,10 +13,32 @@ * limitations under the License. */ -import {IDataSourcePrefetching} from '@ohos.arkui.Prefetcher' +import { IDataSourcePrefetching } from '@kit.ArkUI'; +import DataSource from './limit_void_type_sdk2'; +import { prefetchTest as preTest } from './limit_void_type_sdk2'; +import { res } from './limit_void_type_sdk2'; +import { LocalDataSource } from './LimitedVoidType3'; +class DS implements IDataSourcePrefetching { + cancel(index: number): void | Promise { //report error + throw new Error('Method not implemented.'); + } -class C implements IDataSourcePrefetching { - prefetch(index: number): void | Promise { + totalCount(): number { + throw new Error('Method not implemented.'); + } + + getData(index: number): number { + throw new Error('Method not implemented.'); + } + + registerDataChangeListener(): void { + throw new Error('Method not implemented.'); + } + + unregisterDataChangeListener(): void { + throw new Error('Method not implemented.'); + } + prefetch(index: number): void | Promise { //report error } @@ -24,3 +46,35 @@ class C implements IDataSourcePrefetching { } } +const ds = new DataSource(); +let num:number=ds.totalCount(); +function testDataSource(){ + console.log(`${num}=num`); + ds.cancel(66); //report error +} +function testPrefetch() { + preTest(); +} + +function testCancel(){ + return res; +} + +class localDemo{ + dataSource:DS|undefined=undefined; + constructor() { + this.dataSource = new DS(); + } + test(){ + this.dataSource?.getData(111); + this.dataSource?.registerDataChangeListener(); + this.dataSource?.unregisterDataChangeListener(); + this.dataSource?.cancel(111); //report error + } +} +function localTest(){ + return ds.cancel(222); //report error +} +const lds = new LocalDataSource(); +lds.prefetch(999); +lds.cancel(222); diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.arkts2.json index f65500d7d1af865c1209f7430aed99d64f9d6329..36517426284632aa6afae10ce61b059b3a06d55d 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.arkts2.json @@ -15,19 +15,49 @@ ], "result": [ { - "line": 19, + "line": 41, "column": 3, - "endLine": 21, + "endLine": 43, "endColumn": 4, "problem": "LimitedVoidTypeFromSdk", "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-sdk-limited-void-type)", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, { - "line": 19, + "line": 22, + "column": 3, + "endLine": 24, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 24, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 26, + "endLine": 22, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 41, "column": 28, - "endLine": 19, + "endLine": 41, "endColumn": 32, "problem": "LimitedVoidType", "suggest": "", @@ -35,14 +65,64 @@ "severity": "ERROR" }, { - "line": 23, + "line": 45, "column": 29, - "endLine": 23, + "endLine": 45, "endColumn": 33, "problem": "LimitedVoidType", "suggest": "", "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 12, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 28, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 10, + "endLine": 76, + "endColumn": 19, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 7, + "endLine": 78, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 17, + "endLine": 78, + "endColumn": 32, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.json index 5e75d5b3e723fd5812f0ab2db7c08ef9f4c44baf..e25d43a0573eae5706cacaa9a08e000fec8b89f1 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.json @@ -14,6 +14,15 @@ "limitations under the License." ], "result": [ - + { + "line": 78, + "column": 7, + "endLine": 78, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets index e768ba911c99c60eaa36617798a898c0533687e9..4592f1a4799a13d1597042fb3e9c3ffc11598285 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { IDataSourcePrefetching } from '@kit.ArkUI'; import { rcp } from '@kit.RemoteCommunicationKit'; class LI implements rcp.WriteFile { write(buffer: ArrayBuffer): Promise { @@ -22,4 +22,40 @@ class LI implements rcp.WriteFile { const sp:rcp.IncomingDataCallback = (incomingData) => { console.log(''); -} \ No newline at end of file +} +export default class MyDataSource implements IDataSourcePrefetching { + constructor() {} + prefetch(index: number): void | Promise { //report error + throw new Error('MyDataSource Method not implemented.'); + } + + cancel(index: number): void | Promise { //report error + throw new Error('MyDataSource Method not implemented.'); + } + + totalCount(): number { + throw new Error('MyDataSource Method not implemented.'); + } + + getData(index: number): number { + throw new Error('MyDataSource Method not implemented.'); + } + + registerDataChangeListener(listener?: DataChangeListener): void { + throw new Error('MyDataSource Method not implemented.'); + } + + unregisterDataChangeListener(listener?: DataChangeListener): void { + throw new Error('MyDataSource Method not implemented.'); + } +} +const ds = new MyDataSource(); +export function prefetchTest(){ + return new MyDataSource().prefetch(666); //report error +} +function prefetchTest2(){ + return ds.prefetch(666); //report error +} + +export const res = new MyDataSource().cancel(222); //report error +export const res2 = ds.cancel(222); //report error \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json index bd91b2508b30b4e09732206523ee89618ddfc92e..2a4a3080f09475df9e522b26254c5f2860f36a2c 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json @@ -21,7 +21,17 @@ "endColumn": 4, "problem": "LimitedVoidTypeFromSdk", "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-sdk-limited-void-type)", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, { @@ -41,7 +51,7 @@ "endColumn": 34, "problem": "LimitedVoidTypeFromSdk", "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-sdk-limited-void-type)", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, { @@ -53,6 +63,116 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 28, + "column": 3, + "endLine": 30, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 34, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 34, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 26, + "endLine": 32, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 10, + "endLine": 54, + "endColumn": 37, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 10, + "endLine": 57, + "endColumn": 21, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 20, + "endLine": 60, + "endColumn": 45, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 21, + "endLine": 61, + "endColumn": 30, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 41, + "endLine": 44, + "endColumn": 59, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 43, + "endLine": 48, + "endColumn": 61, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets similarity index 65% rename from ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets rename to ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets index e3c4c6107c627e23f7acb8d6edf3a9613da682d7..e05617b2ffb84ecbd04c71f0dc7b94f63b0f1138 100644 --- a/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets @@ -24,4 +24,21 @@ class LI implements rcp.WriteFile{ const simpleDataHandler: rcp.IncomingDataCallback = (incomingData) => { console.log(`Received ${incomingData.byteLength} bytes of data`); // Error -}; \ No newline at end of file +}; + +interface IDataSourcePrefetching { + prefetch(index: number): Promise | void; + + cancel?(index: number): Promise | void; +} +export class LocalDataSource implements IDataSourcePrefetching { + constructor() {} + + prefetch(index: number): void | Promise { + throw new Error("LocalDataSource Method not implemented."); + } + + cancel(index: number): void | Promise { + throw new Error("LocalDataSource Method not implemented."); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/void_operator.ts.args.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.args.json similarity index 97% rename from ets2panda/linter/test/migrate/void_operator.ts.args.json rename to ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.args.json index 18bd09a6663ad5c031113d0e9c112c2407277375..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c 100644 --- a/ets2panda/linter/test/migrate/void_operator.ts.args.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.args.json @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } diff --git a/ets2panda/linter/test/migrate/parameter_properties.ts.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.arkts2.json similarity index 43% rename from ets2panda/linter/test/migrate/parameter_properties.ts.json rename to ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.arkts2.json index 52dc9cb7b7b1cab65bfd84efe2784bc7bc8d87b3..5d0e2d9cb631c646033d268395725ece2391e0d6 100644 --- a/ets2panda/linter/test/migrate/parameter_properties.ts.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "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", @@ -16,102 +16,102 @@ "result": [ { "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 11, - "problem": "ParameterProperties", + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 14, - "problem": "ParameterProperties", + "line": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 12, - "problem": "ParameterProperties", + "line": 18, + "column": 48, + "endLine": 18, + "endColumn": 52, + "problem": "LimitedVoidType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, { - "line": 34, + "line": 24, "column": 26, - "endLine": 34, - "endColumn": 32, - "problem": "ParameterProperties", + "endLine": 24, + "endColumn": 50, + "problem": "LimitedVoidTypeFromSdk", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, { - "line": 34, - "column": 60, - "endLine": 34, - "endColumn": 67, - "problem": "ParameterProperties", + "line": 24, + "column": 54, + "endLine": 24, + "endColumn": 66, + "problem": "AnyType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 43, - "column": 15, - "endLine": 43, - "endColumn": 21, - "problem": "ParameterProperties", + "line": 30, + "column": 44, + "endLine": 30, + "endColumn": 48, + "problem": "LimitedVoidType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, { - "line": 43, - "column": 25, - "endLine": 43, - "endColumn": 28, - "problem": "AnyType", + "line": 32, + "column": 9, + "endLine": 32, + "endColumn": 10, + "problem": "OptionalMethod", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Optional methods are not supported (arkts-optional-methods)", "severity": "ERROR" }, { - "line": 47, - "column": 15, - "endLine": 47, - "endColumn": 21, - "problem": "ParameterProperties", + "line": 32, + "column": 43, + "endLine": 32, + "endColumn": 47, + "problem": "LimitedVoidType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, { - "line": 47, - "column": 33, - "endLine": 47, - "endColumn": 40, - "problem": "ParameterProperties", + "line": 37, + "column": 28, + "endLine": 37, + "endColumn": 32, + "problem": "LimitedVoidType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, { - "line": 47, - "column": 44, - "endLine": 47, - "endColumn": 45, - "problem": "ObjectTypeLiteral", + "line": 41, + "column": 26, + "endLine": 41, + "endColumn": 30, + "problem": "LimitedVoidType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.json rename to ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.json diff --git a/ets2panda/linter/test/sdkwhite/LiteralAsPropertyName2.ets b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets similarity index 97% rename from ets2panda/linter/test/sdkwhite/LiteralAsPropertyName2.ets rename to ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets index 3afff7ad6d29ff44a5c8c17957d43f9fdb11dcfc..299f58ac32421b3cfc1a55e78746e097358754a4 100644 --- a/ets2panda/linter/test/sdkwhite/LiteralAsPropertyName2.ets +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets @@ -26,5 +26,4 @@ function createHeaders(authToken?: string): rcp.RequestHeaders { 'cache-control': 'no-cache', // Error 'user-agent': 'MyApp/2.0' // Error }; -} - +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.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/migrate/literals_as_prop_names.ts.migrate.json b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json similarity index 36% rename from ets2panda/linter/test/migrate/literals_as_prop_names.ts.migrate.json rename to ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json index 3d8279213f7e6b6e1cb59d349bda24d65f2af02c..aafa0c6dae965cc263d030a379c4a0c741e7e03a 100644 --- a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.migrate.json +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json @@ -1,174 +1,138 @@ { + "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": 11, - "endLine": 20, - "endColumn": 12, - "problem": "LiteralAsPropertyName", + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 35, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 26, + "line": 18, "column": 3, - "endLine": 26, - "endColumn": 4, + "endLine": 18, + "endColumn": 18, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 33, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 13, - "endLine": 31, - "endColumn": 29, - "problem": "PropertyAccessByIndex", + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 37, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 32, - "column": 13, - "endLine": 32, - "endColumn": 33, - "problem": "PropertyAccessByIndex", + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 17, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 51, - "column": 9, - "endLine": 51, - "endColumn": 10, - "problem": "ObjectLiteralNoContextType", + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 67, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 51, - "column": 22, - "endLine": 51, - "endColumn": 23, + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 20, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 53, - "column": 13, - "endLine": 53, - "endColumn": 22, - "problem": "PropertyAccessByIndex", + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 33, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 54, - "column": 13, - "endLine": 54, - "endColumn": 17, - "problem": "PropertyAccessByIndex", + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 13, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 61, - "column": 13, - "endLine": 61, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 32, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 69, - "column": 3, - "endLine": 69, - "endColumn": 4, + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 20, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 74, - "column": 3, - "endLine": 74, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 30, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 78, - "column": 36, - "endLine": 78, - "endColumn": 37, + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 17, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" - }, - { - "line": 36, - "column": 11, - "endLine": 36, - "endColumn": 13, - "problem": "StrictDiagnostic", - "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '_2' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 37, - "column": 3, - "endLine": 37, - "endColumn": 6, - "problem": "StrictDiagnostic", - "suggest": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 57, - "column": 12, - "endLine": 57, - "endColumn": 16, - "problem": "StrictDiagnostic", - "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property 'name' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 58, - "column": 12, - "endLine": 58, - "endColumn": 14, - "problem": "StrictDiagnostic", - "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '_2' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.json b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets old mode 100755 new mode 100644 index 10ed3b18e17ab61effc02310ed4a2f5f82c924d4..af08caf9520714594a8755e401c1cd47b12d465b --- a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets @@ -1,31 +1,200 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {rcp} from '@kit.RemoteCommunicationKit'; -// case1 -const basicHeaders: rcp.RequestHeaders = { - 'authorization': 'Bearer abc123', // error - 'content-type': 'application/json' // error -} - -// case2 -function createHeaders(): rcp.RequestHeaders { - return { - 'authorization': '', // error - 'accept': 'application/json', // error - 'cache-control': 'no-cache', // error - 'user-agent': 'MyApp/2.0' // error - }; -} \ No newline at end of file +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { rcp } from '@kit.RemoteCommunicationKit'; +import { externalRequestHeaders,externalRequestHeadersInterface } from './quoted_hyphen_props_deprecated_sdk2'; +import { externalResponseHeaders,externalResponseHeadersInterface } from './quoted_hyphen_props_deprecated_sdk2'; +export interface internalRequestHeaders { + rcpHeaders: rcp.RequestHeaders; + additionalHeaders: T; +} +interface AdditionalHeaders { + customHeader: string; +} +type CustomRequestHeaders = internalRequestHeaders; +const cusRequestHeaders: CustomRequestHeaders = { + rcpHeaders: { + 'content-type': 'application/json', // Error + range: 'bytes=0-1023' // Error + }, + additionalHeaders: { + customHeader: 'custom value' + } +}; +const basicHeaders: rcp.RequestHeaders = { + 'authorization': 'Bearer abc123', // Error + 'content-type': 'application/json' // Error +}; +basicHeaders.cookie =''; // Error +function createHeaders(cookie:string,authToken?: string): rcp.RequestHeaders { + return { + 'authorization': authToken ? `Bearer ${authToken}` : undefined, // Error + 'accept': 'application/json', // Error + 'cache-control': 'no-cache', // Error + 'user-agent': 'MyApp/2.0' // Error + }; +} +createHeaders(basicHeaders.cookie); // Error +function getRange(){ + return basicHeaders.range; // Error +} + +export type localRequestHeaders = rcp.RequestHeaders; +let localHeaders:localRequestHeaders = { + 'accept-charset': 'UTF-8', // Error + 'accept-encoding': 'gzip, deflate', // Error + 'accept-language': 'en-US,en;q=0.9', // Error + 'cookie': 'session_id=123456', // Error + 'range': 'bytes=0-1023', // Error + 'upgrade': 'websocket', // Error + 'content-type':'application/json' // Error +} +let externalHeaders:externalRequestHeaders = { + cookie: 'session_id=123456', // Error + range: 'bytes=0-1023', // Error + 'content-type':'application/json' // Error +} +const setRequestHeaders1 = (headers: externalRequestHeaders) => { + headers.authorization =''; // Error +} +class RemoteTest{ + setCookie(cookie:string){ + cookie = 'cookie' + } + createHeaders(cookie:string,authToken?: string): rcp.RequestHeaders { + return { + authorization: authToken ? `Bearer ${authToken}` : undefined, // Error + accept: 'application/json', // Error + "cache-control": 'no-cache', + "user-agent": 'MyApp/2.0', + upgrade:'web', // Error + range:'' // Error + }; + } + constructor() { + createHeaders(basicHeaders.authorization!); // Error + } +} +const exRequestHeadersInterface: externalRequestHeadersInterface = { + authorization: 'Bearer token', //Error + customHeader1: 'value1' +}; +function processHeaders(headers: externalRequestHeadersInterface) { + console.log(headers.authorization); //Error + console.log(headers.customHeader1); +} +function createExHeaders(): externalRequestHeadersInterface { + return { + authorization: 'Bearer token', //Error + customHeader1: 'value1' + }; +} +typeof exRequestHeadersInterface.authorization; //Error +console.log('accept='+exRequestHeadersInterface.accept) //Error +function printHeaders(exheaders: externalRequestHeadersInterface) { + console.log(exheaders.authorization); //Error +} +const headersArray: externalRequestHeadersInterface[] = [ + { + authorization: 'application/json', //Error + customHeader1: 'header1Value1' + }, + { + 'cookie': 'sss', //Error + customHeader1: 'header1Value2' + } +]; +interface RequestConfig { + headers: externalRequestHeadersInterface; + url: string; + method: 'GET' | 'POST'; +} + +const config: RequestConfig = { + headers: { + 'authorization': 'application/json', //Error + customHeader1: 'configHeaderValue' + }, + url: 'https://example.com/api', + method: 'GET' +}; +export const headers:string[]=[ + 'authorization', + 'accept', + 'cache-control', + 'user-agent', + 'accept-charset', + 'accept-encoding', + 'accept-language', + 'cookie', + 'range', + 'upgrade', + 'content-type' +] + +//ResponseHeader part +let externalResponseHeader:externalResponseHeaders = { + 'accept-ranges':'', // Error + 'allow': '', // Error + 'cache-control': '', // Error + 'content-encoding': '' // Error +} +const setResponseHeaders = (headers: externalResponseHeaders) => { + headers.expires =''; // Error +} + +const exResponseHeadersInterface: externalResponseHeadersInterface = { + "www-authenticate": 'Bearer token', + customHeader2: 'value1' +}; +function processResponseHeaders(responseHeaders: externalResponseHeadersInterface) { + console.log(responseHeaders.date); // Error + console.log(responseHeaders.customHeader2); +} +function createExResponseHeaders(): externalResponseHeadersInterface { + return { + date: '2025', //Error + customHeader2: 'value1' + }; +} +typeof exResponseHeadersInterface.authorization; //Error +console.log('accept='+exResponseHeadersInterface.accept) //Error +function printResponseHeaders(exHeaders: externalResponseHeadersInterface) { + console.log(exHeaders.etag); //Error +} +const responseHeadersArray: externalResponseHeadersInterface[] = [ + { + "cache-control": 'application/json', + customHeader2: 'header1Value1' + }, + { + 'server': 'sss', //Error + customHeader2: 'header1Value2' + } +]; +interface ResponseConfig { + headers: externalResponseHeadersInterface; + url: string; + method: 'GET' | 'POST'; +} + +const config2: ResponseConfig = { + headers: { + 'content-encoding': 'application/json', //Error + customHeader2: 'configHeaderValue' + }, + url: 'https://example.com/api', + method: 'GET' +}; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.args.json old mode 100755 new mode 100644 index 3ef4496a819a201892114d1c90f78ae32053c334..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.args.json +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.args.json @@ -1,19 +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": "" - } -} + "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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json old mode 100755 new mode 100644 index 381a73c1da380c7200a1fffe5c4f9f2bf93c6275..3a348d3c8350c18237159008eeb22f282ceceb46 --- a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json @@ -15,123 +15,653 @@ ], "result": [ { - "line": 19, - "column": 3, - "endLine": 19, - "endColumn": 18, + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 39, "problem": "QuotedHyphenPropsDeprecated", "suggest": "", "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 20, + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 19, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 37, "column": 3, - "endLine": 20, - "endColumn": 17, + "endLine": 37, + "endColumn": 35, "problem": "QuotedHyphenPropsDeprecated", "suggest": "", "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 19, + "line": 37, "column": 3, - "endLine": 19, + "endLine": 37, "endColumn": 18, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 37, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 20, + "line": 38, "column": 3, - "endLine": 20, + "endLine": 38, "endColumn": 17, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 26, + "line": 43, "column": 5, - "endLine": 26, + "endLine": 43, + "endColumn": 67, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 5, + "endLine": 43, "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 33, "problem": "QuotedHyphenPropsDeprecated", "suggest": "", "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 27, + "line": 44, "column": 5, - "endLine": 27, + "endLine": 44, "endColumn": 13, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 32, "problem": "QuotedHyphenPropsDeprecated", "suggest": "", "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 28, + "line": 45, "column": 5, - "endLine": 28, + "endLine": 45, "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 30, "problem": "QuotedHyphenPropsDeprecated", "suggest": "", "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 29, + "line": 46, "column": 5, - "endLine": 29, + "endLine": 46, + "endColumn": 17, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 10, + "endLine": 50, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 3, + "endLine": 56, + "endColumn": 28, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 3, + "endLine": 56, + "endColumn": 19, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 37, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 38, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 32, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 11, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 26, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 10, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 3, + "endLine": 61, + "endColumn": 25, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 3, + "endLine": 61, + "endColumn": 12, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 3, + "endLine": 62, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 3, + "endLine": 62, "endColumn": 17, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 36, "problem": "QuotedHyphenPropsDeprecated", "suggest": "", "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 26, + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 17, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 7, + "endLine": 80, + "endColumn": 22, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 7, + "endLine": 81, + "endColumn": 19, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 68, + "endLine": 90, + "endColumn": 69, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 10, + "endLine": 99, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 57, + "endLine": 118, + "endColumn": 2, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 3, + "endLine": 110, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 115, "column": 5, - "endLine": 26, + "endLine": 115, "endColumn": 20, - "problem": "ObjectLiteralProperty", + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 27, + "line": 115, "column": 5, - "endLine": 27, + "endLine": 115, "endColumn": 13, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 31, + "endLine": 125, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 12, + "endLine": 126, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 5, + "endLine": 127, + "endColumn": 40, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 28, + "line": 127, "column": 5, - "endLine": 28, + "endLine": 127, "endColumn": 20, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 29, + "line": 149, + "column": 3, + "endLine": 149, + "endColumn": 21, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 3, + "endLine": 149, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 3, + "endLine": 150, + "endColumn": 14, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 3, + "endLine": 150, + "endColumn": 10, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 3, + "endLine": 151, + "endColumn": 22, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 3, + "endLine": 151, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 3, + "endLine": 152, + "endColumn": 25, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 3, + "endLine": 152, + "endColumn": 21, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 70, + "endLine": 158, + "endColumn": 71, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 3, + "endLine": 159, + "endColumn": 21, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 10, + "endLine": 167, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 66, + "endLine": 186, + "endColumn": 2, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 178, + "column": 3, + "endLine": 178, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 179, "column": 5, - "endLine": 29, - "endColumn": 17, - "problem": "ObjectLiteralProperty", + "endLine": 179, + "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 3, + "endLine": 182, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 183, + "column": 5, + "endLine": 183, + "endColumn": 20, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 183, + "column": 5, + "endLine": 183, + "endColumn": 13, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 33, + "endLine": 193, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 12, + "endLine": 194, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 195, + "column": 5, + "endLine": 195, + "endColumn": 43, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 195, + "column": 5, + "endLine": 195, + "endColumn": 23, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..eaeaa7697684c7a6a6ecffddcb301018911f035e 100755 --- a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json @@ -13,5 +13,156 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 50, + "column": 10, + "endLine": 50, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 68, + "endLine": 90, + "endColumn": 69, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 10, + "endLine": 99, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 57, + "endLine": 118, + "endColumn": 2, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 3, + "endLine": 110, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 31, + "endLine": 125, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 12, + "endLine": 126, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 70, + "endLine": 158, + "endColumn": 71, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 10, + "endLine": 167, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 66, + "endLine": 186, + "endColumn": 2, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 178, + "column": 3, + "endLine": 178, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 3, + "endLine": 182, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 33, + "endLine": 193, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 12, + "endLine": 194, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets new file mode 100755 index 0000000000000000000000000000000000000000..18c729ed2e0d4d28d323d113401ff39648303096 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { rcp } from "@kit.RemoteCommunicationKit"; +export type externalRequestHeaders = rcp.RequestHeaders; +export type externalResponseHeaders = rcp.ResponseHeaders; +export interface externalRequestHeadersInterface extends rcp.RequestHeaders { + customHeader1: string; +} +export interface externalResponseHeadersInterface extends rcp.ResponseHeaders { + customHeader2: string; +} +export const headers:string[]=[ + 'accept-ranges', + 'allow', + 'cache-control', + 'content-encoding', + 'content-range', + 'content-type', + 'date', + 'etag', + 'expires', + 'location', + 'retry-after', + 'set-cookie', + 'server', + 'www-authenticate', +] + +export default function getCookie():string{ + return headers[7]; +} +export const generateRange = () => 'range'; +export let localUpgrade:string = 'upgrade'; +export let localRange:string = generateRange(); +export class Header{ + acceptLanguage = headers[6]; + cookie = 'cookie'; + getUpgrade(){ + return localUpgrade; + } +} + +export interface internalResponseHeaders { + rcpHeaders: rcp.ResponseHeaders; + additionalHeaders: T; +} +interface AdditionalHeaders { + customHeader: string; +} +type CustomResponseHeaders = internalResponseHeaders; +const cusRequestHeaders: CustomResponseHeaders = { + rcpHeaders: { + 'content-range': 'json', // Error + server: 'bytes=0-1023' // Error + }, + additionalHeaders: { + customHeader: 'custom value' + } +}; +const basicHeaders: rcp.ResponseHeaders = { + "set-cookie": 'Bearer abc123', + 'retry-after': 'application/json' // Error +}; +basicHeaders.allow =''; // Error +function createHeaders(cookie:string,authToken?: string): rcp.ResponseHeaders { + return { + server: undefined, + expires: 'application/json', + 'accept-ranges': 'no-cache', // Error + 'www-authenticate': 'MyApp/2.0' // Error + }; +} +createHeaders(basicHeaders.date!); // Error +function getRange(){ + return basicHeaders?.["content-range"]; // Error +} + +export type localResponseHeaders = rcp.ResponseHeaders; +let localHeaders:localResponseHeaders = { + 'content-encoding': 'UTF-8', // Error + 'content-range': 'gzip, deflate', // Error + 'location': 'en-US,en;q=0.9', // Error + 'set-cookie': 'session_id=123456', // Error + 'accept-ranges': 'bytes=0-1023', // Error + 'www-authenticate': 'websocket', // Error + 'content-type':'application/json' // Error +} +class RemoteTest{ + setCookie(cookie:string){ + cookie = 'cookie' + } + createHeaders(cookie:string,authToken?: string): rcp.ResponseHeaders { + return { + 'accept-ranges': undefined, // Error + 'content-encoding': 'application/json', // Error + date: '2025', // Error + "cache-control": 'no', + allow:'web', // Error + 'www-authenticate':'' // Error + }; + } + constructor() { + createHeaders(basicHeaders.date!); // Error + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/func_return_type.ts.args.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.args.json old mode 100644 new mode 100755 similarity index 90% rename from ets2panda/linter/test/migrate/func_return_type.ts.args.json rename to ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.args.json index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..3ef4496a819a201892114d1c90f78ae32053c334 --- a/ets2panda/linter/test/migrate/func_return_type.ts.args.json +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..f2d125c5784100f6d7f32f00cfe38427f50a997b --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.arkts2.json @@ -0,0 +1,328 @@ +{ + "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": 65, + "column": 5, + "endLine": 65, + "endColumn": 28, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 3, + "endLine": 74, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 3, + "endLine": 74, + "endColumn": 16, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 32, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 23, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 10, + "endLine": 86, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 3, + "endLine": 92, + "endColumn": 30, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 3, + "endLine": 92, + "endColumn": 21, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 93, + "endColumn": 35, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 93, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 31, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 13, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 3, + "endLine": 95, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 3, + "endLine": 95, + "endColumn": 15, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 3, + "endLine": 96, + "endColumn": 34, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 3, + "endLine": 96, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 34, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 21, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 3, + "endLine": 98, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 3, + "endLine": 98, + "endColumn": 17, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 7, + "endLine": 106, + "endColumn": 34, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 7, + "endLine": 106, + "endColumn": 22, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 45, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 25, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 22, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 7, + "endLine": 111, + "endColumn": 28, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 7, + "endLine": 111, + "endColumn": 25, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..fe966ab865f8e5a1816ebf8e86731c56e1a9d321 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.json @@ -0,0 +1,28 @@ +{ + "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": 86, + "column": 10, + "endLine": 86, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/return_new_interface.ets b/ets2panda/linter/test/sdkwhite/return_new_interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..3bbb797d6da8522b3b4d9e7f8a0a641eb1fdedd5 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.ets @@ -0,0 +1,31 @@ +/* + * 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. + */ +'use static' + +interface CircleInterface { + config: any; +} + +interface RectInterface { + config: any; +} + +function makeCI(c: CircleInterface) { + return new c({}); // ERROR: using `new` with interface +} + +function makeRe(r: RectInterface) { + return new r({}); // ERROR +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/return_new_interface.ets.args.json b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.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/sdkwhite/return_new_interface.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..92f597960e2eead0bfad0cdde65d9981dff2b182 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 11, + "endLine": 18, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 14, + "endLine": 26, + "endColumn": 15, + "problem": "ConstructorIface", + "suggest": "", + "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 14, + "endLine": 26, + "endColumn": 15, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 10, + "endLine": 29, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 14, + "endLine": 30, + "endColumn": 15, + "problem": "ConstructorIface", + "suggest": "", + "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 14, + "endLine": 30, + "endColumn": 15, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/return_new_interface.ets.json b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..4cc659e3fd9ae63ec5cd793c2863ebdebb471e3c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.json @@ -0,0 +1,58 @@ +{ + "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": 11, + "endLine": 18, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 10, + "endLine": 29, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk/declarations/alert_dialog.d.ts b/ets2panda/linter/test/sdkwhite/sdk/declarations/alert_dialog.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..1093278402c540a6f11290f961cd8fb0f2a6b89c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk/declarations/alert_dialog.d.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export declare interface TextStyle { + wordBreak?: WordBreak; +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk/declarations/hyperlink.d.ts b/ets2panda/linter/test/sdkwhite/sdk/declarations/hyperlink.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..aaf5150b5ec7b2da083865d0208ad8b9a60609f7 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk/declarations/hyperlink.d.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ + +export declare class HyperlinkAttribute { + color(value: Color | number | string | Resource): HyperlinkAttribute; +} +export declare const HyperlinkInterface: HyperlinkAttribute; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk/declarations/styled_string.d.ts b/ets2panda/linter/test/sdkwhite/sdk/declarations/styled_string.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..fbdd125c2fd5088cd96ff46a38a58faf94d6d8bf --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk/declarations/styled_string.d.ts @@ -0,0 +1,23 @@ +/* + * 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. + */ + +export declare class TextStyle { + constructor(value?: TextStyleInterface); + readonly fontColor?: ResourceColor; + readonly fontFamily?: string; + readonly fontSize?: number; + readonly fontWeight?: number; + readonly fontStyle?: FontStyle; +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/constructor_types_deprecated_sdk.ets b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets similarity index 100% rename from ets2panda/linter/test/sdkwhite/constructor_types_deprecated_sdk.ets rename to ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets diff --git a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.args.json b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..9c3d9734324a7b8b9c89fa7f62dce43ac44888ca --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/constructor_types_deprecated_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.arkts2.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/constructor_types_deprecated_sdk.ets.arkts2.json rename to ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.arkts2.json diff --git a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.json b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.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/sdkwhite/ConstructorIface4.ets b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets similarity index 100% rename from ets2panda/linter/test/sdkwhite/ConstructorIface4.ets rename to ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets diff --git a/ets2panda/linter/test/migrate/destructuring_assignments.ts.args.json b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.args.json similarity index 90% rename from ets2panda/linter/test/migrate/destructuring_assignments.ts.args.json rename to ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.args.json index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..3ef4496a819a201892114d1c90f78ae32053c334 100644 --- a/ets2panda/linter/test/migrate/destructuring_assignments.ts.args.json +++ b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } diff --git a/ets2panda/linter/test/sdkwhite/ConstructorIface4.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.arkts2.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/ConstructorIface4.ets.arkts2.json rename to ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.arkts2.json diff --git a/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.json b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/OptionalMethod1.ets b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets similarity index 50% rename from ets2panda/linter/test/sdkwhite/OptionalMethod1.ets rename to ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets index 128f882768c1aace738a395ced0fd8882771d0a4..c7a1a79f36e06a784aa220519b33a7433f8da96e 100644 --- a/ets2panda/linter/test/sdkwhite/OptionalMethod1.ets +++ b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets @@ -14,6 +14,7 @@ */ import { webview } from '@kit.ArkWeb'; +import { AbilityLifecycleCallback, UIAbility } from '@kit.AbilityKit'; class OptionalMethod implements webview.NativeMediaPlayerBridge { updateRect(x: number, y: number, width: number, height: number): void { @@ -65,4 +66,47 @@ class OptionalMethod implements webview.NativeMediaPlayerBridge { } } +class MyAbilityLifecycleCallback extends AbilityLifecycleCallback { + // 用例1: 重写为必选方法 预期报错 用例结果--Error 未识别 + onWillNewWant(ability: UIAbility) { + console.log('AbilityLifecycleCallback onWillNewWant.'); + } + + // 用例2: 重写为可选方法 预期报错 用例结果--Pass + onAbilityWillCreate?(ability: UIAbility) { + console.log('AbilityLifecycleCallback onAbilityWillCreate.'); + } + + // 用例3:使用必选属性重写父类方法 预期无报错 用例结果--Pass + onAbilityWillForeground: (ability: UIAbility) => void = + (ability: UIAbility) => { + console.log('AbilityLifecycleCallback onAbilityWillForeground'); + } + // 用例4:使用可选属性重写父类方法 预期无报错 用例结果--Pass + onAbilityWillBackground?: (ability: UIAbility) => void = + (ability: UIAbility) => { + console.log('AbilityLifecycleCallback onAbilityWillBackground'); + } +} + +// 用例5 类型断言 预期无报错 用例结果--Pass +const callback: AbilityLifecycleCallback = { + onAbilityWillForeground: (ability: UIAbility): void => { + console.log('AbilityLifecycleCallback onAbilityWillForeground'); + } +} as AbilityLifecycleCallback; + +// 用例6 泛型类拓展 +class GenericHandler extends AbilityLifecycleCallback { + // 预期报错 用例结果--Error 未识别 + onAbilityWillCreate(ability: T): void { /*...*/ } + // 预期无报错 用例结果--Pass + onAbilityWillForeground: (ability: T) => void = + (ability: T) => { + console.log('AbilityLifecycleCallback onAbilityWillForeground'); + } +} + +// 接口不能继承类;不能使用交叉类型扩展;不能声明合并 + diff --git a/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.args.json b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.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/sdkwhite/OptionalMethod1.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.arkts2.json similarity index 54% rename from ets2panda/linter/test/sdkwhite/OptionalMethod1.ets.arkts2.json rename to ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.arkts2.json index d7b0f6777ba366f36babc985e9d4db6ca28385e6..bd2e0891ba67adb5782d1b211a72411babec8158 100644 --- a/ets2panda/linter/test/sdkwhite/OptionalMethod1.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.arkts2.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 59, + "line": 60, "column": 3, - "endLine": 61, + "endLine": 62, "endColumn": 4, "problem": "OptionalMethodFromSdk", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 63, + "line": 64, "column": 3, - "endLine": 65, + "endLine": 66, "endColumn": 4, "problem": "OptionalMethodFromSdk", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 60, "column": 15, - "endLine": 59, + "endLine": 60, "endColumn": 16, "problem": "OptionalMethod", "suggest": "", @@ -45,14 +45,54 @@ "severity": "ERROR" }, { - "line": 63, + "line": 64, "column": 16, - "endLine": 63, + "endLine": 64, "endColumn": 17, "problem": "OptionalMethod", "suggest": "", "rule": "Optional methods are not supported (arkts-optional-methods)", "severity": "ERROR" + }, + { + "line": 76, + "column": 3, + "endLine": 78, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 3, + "endLine": 73, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 22, + "endLine": 76, + "endColumn": 23, + "problem": "OptionalMethod", + "suggest": "", + "rule": "Optional methods are not supported (arkts-optional-methods)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 52, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.json b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/IndexedAccessType.ets b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets similarity index 100% rename from ets2panda/linter/test/sdkwhite/IndexedAccessType.ets rename to ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets diff --git a/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.args.json b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.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/sdkwhite/IndexedAccessType.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.arkts2.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/IndexedAccessType.ets.arkts2.json rename to ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.arkts2.json diff --git a/ets2panda/linter/test/sdkwhite/IndexedAccessType.ets.json b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.json similarity index 100% rename from ets2panda/linter/test/sdkwhite/IndexedAccessType.ets.json rename to ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.json diff --git a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets index e975f42d4d536790ab9ffdf31c182598ab6375f1..a8d6e79d57859051401d12d0dc37f02441ffc749 100755 --- a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets +++ b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets @@ -13,10 +13,43 @@ * limitations under the License. */ -import {worker} from '@kit.ArkTS'; +import {worker} from '@kit.ArkTS'; // sdk-type-query report in real env +// // test1 +import sendablePhotoAccessHelper from '@ohos.file.sendablePhotoAccessHelper' // 报错 PASS + +// test2 +import mySendablePhotoAccessHelper from '@ohos.file.sendablePhotoAccessHelper' // 报错 PASS + +import { dataSharePredicates } from '@kit.ArkData'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import spHelper from '@ohos.file.sendablePhotoAccessHelper'; // Error-sendable不再支持 worker.parentPort.self; const self = worker.parentPort.self; -console.log(worker.parentPort.self) \ No newline at end of file +console.log(worker.parentPort.self) + +const parentPort = worker.parentPort; +parentPort.self.name; +parentPort.self.clearTimeout; + +const workerport = worker.workerPort; +workerport.self.name; +workerport.self.clearTimeout; + +let sHelper = spHelper.getPhotoAccessHelper(globalThis.abilityContext); +let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); +let fetchOptions: photoAccessHelper.FetchOptions = { + fetchColumns: [], + predicates: predicates +}; +// Array +export const sharedPhotoAssetList = sHelper.getSharedPhotoAssets(fetchOptions); +sharedPhotoAssetList.forEach((asset, index) => { + let pt = asset.position // Error-position:PositionType不再可用-未识别 + let ps = asset.subtype // Error-subtype:PhotoSubtype不再可用-未识别 + let aa = asset.movingPhotoEffectMode // Error-movingPhotoEffectMode:MovingPhotoEffectMode 不再可用-未识别 + let bb = asset.dynamicRangeType // Error-dynamicRangeType:DynamicRangeType 不再可用-未识别 + let cc = asset.thumbnailVisible // Error-thumbnailVisible:ThumbnailVisibility 不再可用-未识别 +}); \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json index d13b1aa522bf9a3e34e26a7150ddbf804c5b8d05..67a42975bf378b67bc2de3e51dd05fa085910e55 100755 --- a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json @@ -15,29 +15,49 @@ ], "result": [ { - "line": 16, - "column": 1, - "endLine": 16, - "endColumn": 35, - "problem": "LimitedStdLibApi", + "line": 18, + "column": 39, + "endLine": 18, + "endColumn": 77, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 18, + "line": 21, + "column": 41, + "endLine": 21, + "endColumn": 79, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 22, + "endLine": 25, + "endColumn": 60, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 27, "column": 19, - "endLine": 18, + "endLine": 27, "endColumn": 23, "problem": "SdkTypeQuery", "suggest": "", - "rule": "Using typeof as a type is not allowed in this API (arkts-sdk-Type-Query)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 20, + "line": 29, "column": 7, - "endLine": 20, + "endLine": 29, "endColumn": 36, "problem": "AnyType", "suggest": "", @@ -45,23 +65,243 @@ "severity": "ERROR" }, { - "line": 20, + "line": 29, "column": 32, - "endLine": 20, + "endLine": 29, "endColumn": 36, "problem": "SdkTypeQuery", "suggest": "", - "rule": "Using typeof as a type is not allowed in this API (arkts-sdk-Type-Query)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 22, + "line": 31, "column": 31, - "endLine": 22, + "endLine": 31, "endColumn": 35, "problem": "SdkTypeQuery", "suggest": "", - "rule": "Using typeof as a type is not allowed in this API (arkts-sdk-Type-Query)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 17, + "endLine": 34, + "endColumn": 21, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 17, + "endLine": 35, + "endColumn": 29, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 17, + "endLine": 39, + "endColumn": 29, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 71, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 45, + "endLine": 41, + "endColumn": 70, + "problem": "GlobalThisError", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 63, + "endLine": 42, + "endColumn": 102, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 14, + "endLine": 48, + "endColumn": 79, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 31, + "endLine": 49, + "endColumn": 36, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 38, + "endLine": 49, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 7, + "endLine": 50, + "endColumn": 26, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 18, + "endLine": 50, + "endColumn": 26, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 7, + "endLine": 51, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 18, + "endLine": 51, + "endColumn": 25, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 7, + "endLine": 52, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 18, + "endLine": 52, + "endColumn": 39, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 7, + "endLine": 53, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 18, + "endLine": 53, + "endColumn": 34, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 18, + "endLine": 54, + "endColumn": 34, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.json b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.json index 41b84cda9d95d94cf66124d1479e2291db162222..0ab8ef5d47eb572b0c10ce268978a5d243d049e2 100755 --- a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.json +++ b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.json @@ -15,14 +15,164 @@ ], "result": [ { - "line": 20, - "column": 7, - "endLine": 20, - "endColumn": 36, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" + "line": 18, + "column": 39, + "endLine": 18, + "endColumn": 77, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 41, + "endLine": 21, + "endColumn": 79, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 22, + "endLine": 25, + "endColumn": 60, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 36, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 71, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 45, + "endLine": 41, + "endColumn": 55, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "WARNING" + }, + { + "line": 48, + "column": 14, + "endLine": 48, + "endColumn": 79, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 31, + "endLine": 49, + "endColumn": 36, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 38, + "endLine": 49, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 7, + "endLine": 50, + "endColumn": 26, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 7, + "endLine": 51, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 7, + "endLine": 52, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 7, + "endLine": 53, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" } - ] + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets similarity index 92% rename from ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets rename to ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets index 3b39666b33afaab303e4e94ed96043d9a101f6d2..6b0535ba89c5308ed33473b5be9a1c4014bf4bb0 100644 --- a/ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets +++ b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets @@ -13,5 +13,6 @@ * limitations under the License. */ +// they both is not in sdkwhitelist after updated sdkwhitelist. import { SharedPhotoAsset } from '@ohos.file.sendablePhotoAccessHelper'; import { SharedPhotoAsset } from '@ohos.file.photoAccessHelper'; diff --git a/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.arkts2.json similarity index 74% rename from ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets.arkts2.json rename to ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.arkts2.json index 824e83e4a19bd999b48013208d96225698034ae9..c65d038d23121eefab8e368259656f68644e6d6c 100644 --- a/ets2panda/linter/test/main/sendable_class_interface_property_sdk.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 Huawei Device Co., Ltd.", + "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", @@ -15,13 +15,13 @@ ], "result": [ { - "line": 16, + "line": 17, "column": 34, - "endLine": 16, + "endLine": 17, "endColumn": 72, - "problem": "SendablePropTypeFromSdk", + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (sdk-no-sendable-prop-types)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.json b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..eecd9ba0f40e73a2d8f6749d55ebaecbcb859c2f --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.json @@ -0,0 +1,28 @@ +{ + "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": 34, + "endLine": 17, + "endColumn": 72, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/webpack.config.js b/ets2panda/linter/webpack.config.js index f8269189a80967835f80206f755b39047cc40945..15ee37c29b5dc1cf0dd3e6ae4468a81a5e4a514d 100644 --- a/ets2panda/linter/webpack.config.js +++ b/ets2panda/linter/webpack.config.js @@ -25,5 +25,10 @@ module.exports = { }, output: { filename: 'tslinter.js' - } + }, + resolve: { + alias: { + json5: require.resolve('json5/dist/index.js'), + } + } }; diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 1734a7eec8c01cc01372846f58a567fead47e046..9aa2bcd87f5eeba1c9240c13a432372aa3f721e2 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -654,6 +654,9 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); + if (typeAnnotation == nullptr) { + return nullptr; + } typeAliasDecl->SetTsTypeAnnotation(typeAnnotation); typeAnnotation->SetParent(typeAliasDecl); typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()}); @@ -1145,6 +1148,25 @@ bool ETSParser::IsDefaultImport() return false; } +bool TypedParser::IsPrimitiveType(const lexer::TokenType &tokenType) +{ + switch (tokenType) { + case lexer::TokenType::KEYW_BIGINT: + case lexer::TokenType::KEYW_BOOLEAN: + case lexer::TokenType::KEYW_BYTE: + case lexer::TokenType::KEYW_CHAR: + case lexer::TokenType::KEYW_DOUBLE: + case lexer::TokenType::KEYW_FLOAT: + case lexer::TokenType::KEYW_INT: + case lexer::TokenType::KEYW_LONG: + case lexer::TokenType::KEYW_SHORT: + case lexer::TokenType::KEYW_VOID: + return true; + default: + return false; + } +} + void ETSParser::ParseNamedSpecifiesDefaultImport(ArenaVector *resultDefault, const std::string &fileName) { @@ -1590,7 +1612,7 @@ ir::Statement *ETSParser::ParseImportDeclaration([[maybe_unused]] StatementParsi ir::Statement *ETSParser::ParseExportDeclaration([[maybe_unused]] StatementParsingFlags flags) { LogUnexpectedToken(lexer::TokenType::KEYW_EXPORT); - return nullptr; + return AllocBrokenStatement(Lexer()->GetToken().Start()); } ir::Expression *ETSParser::ParseExpressionOrTypeAnnotation(lexer::TokenType type, @@ -1847,7 +1869,8 @@ void ETSParser::CheckDeclare() case lexer::TokenType::KEYW_FINAL: case lexer::TokenType::KEYW_INTERFACE: case lexer::TokenType::KEYW_TYPE: - case lexer::TokenType::KEYW_ASYNC: { + case lexer::TokenType::KEYW_ASYNC: + case lexer::TokenType::KEYW_STRUCT: { return; } default: { @@ -1952,11 +1975,11 @@ ir::FunctionDeclaration *ETSParser::ParseAccessorWithReceiver(ir::ModifierFlags void ETSParser::AddPackageSourcesToParseList() { - importPathManager_->AddImplicitPackageImportToParseList(GetProgram()->SourceFileFolder(), + importPathManager_->AddImplicitPackageImportToParseList(GetProgram()->SourceFile().GetAbsoluteParentFolder(), Lexer()->GetToken().Start()); // Global program file is always in the same folder that we scanned, but we don't need to parse it twice - importPathManager_->MarkAsParsed(globalProgram_->SourceFilePath()); + importPathManager_->MarkAsParsed(globalProgram_->SourceFile().GetAbsolutePath()); } //================================================================================================// diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 52195e384dc3bc99eb956ae551776861b5ceb117..7721a8ffa68fe0c63b9eacabc5c959223b4612e1 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -18,6 +18,7 @@ #include "util/arktsconfig.h" #include "util/importPathManager.h" +#include "util/recursiveGuard.h" #include "innerSourceParser.h" #include "TypedParser.h" #include "ir/base/classDefinition.h" @@ -400,6 +401,7 @@ private: VariableParsingFlags flags) override; ir::VariableDeclarator *ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags, const lexer::SourcePosition &startLoc) override; + bool IsFieldStartToken(lexer::TokenType t); ir::AstNode *ParseTypeLiteralOrInterfaceMember() override; ir::AstNode *ParseAnnotationsInInterfaceBody(); void ParseNameSpaceSpecifier(ArenaVector *specifiers, bool isReExport = false); @@ -550,6 +552,7 @@ private: friend class ExternalSourceParser; friend class InnerSourceParser; + friend ir::Expression *HandleLeftParanthesis(ETSParser *parser, ExpressionParseFlags flags); private: uint32_t namespaceNestedRank_; @@ -559,6 +562,7 @@ private: parser::Program *globalProgram_; std::vector insertingNodes_ {}; std::unique_ptr importPathManager_ {nullptr}; + RecursiveContext recursiveCtx_; }; class ExternalSourceParser { diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index eed7dce2af96dad344eedd17210e83739129ae91..70df4332515ab87584e17eeaa601abc9f9ca688c 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -430,6 +430,10 @@ ir::ModifierFlags ETSParser::ParseClassMethodModifiers(bool seenStatic) ir::TypeNode *ETSParser::ConvertToOptionalUnionType(ir::TypeNode *typeAnno) { + if (typeAnno == nullptr) { + return nullptr; + } + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) if (!typeAnno->IsETSUnionType()) { ArenaVector types(Allocator()->Adapter()); @@ -470,6 +474,11 @@ void ETSParser::ParseClassFieldDefinition(ir::Identifier *fieldName, ir::Modifie } if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { typeAnnotation = ParseTypeAnnotation(&options); + if (typeAnnotation == nullptr) { + LogError(diagnostic::ID_EXPECTED); + return; + } + endLoc = typeAnnotation->End(); } @@ -1031,53 +1040,52 @@ ir::AstNode *ETSParser::ParseAnnotationsInInterfaceBody() return result; } +bool ETSParser::IsFieldStartToken(lexer::TokenType tokenType) +{ + return tokenType == lexer::TokenType::LITERAL_IDENT || + tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET || + tokenType == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS; +} + ir::AstNode *ETSParser::ParseTypeLiteralOrInterfaceMember() { if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { return ParseAnnotationsInInterfaceBody(); } - auto startLoc = Lexer()->GetToken().Start(); - if (Lexer()->Lookahead() != lexer::LEX_CHAR_LEFT_PAREN && Lexer()->Lookahead() != lexer::LEX_CHAR_LESS_THAN && (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GET || Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_SET)) { return ParseInterfaceGetterSetterMethod(ir::ModifierFlags::PUBLIC); } - if (Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_READONLY)) { - char32_t nextCp = Lexer()->Lookahead(); - if (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN) { + ir::ModifierFlags modifiers = ParseInterfaceMethodModifiers(); + char32_t nextCp = Lexer()->Lookahead(); + auto startLoc = Lexer()->GetToken().Start(); + auto readonlyTok = Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_READONLY); + bool isReadonly = readonlyTok.has_value(); + + if (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN) { + if (isReadonly) { LogError(diagnostic::READONLY_INTERFACE_METHOD, {}, startLoc); - ir::ModifierFlags modfiers = ParseInterfaceMethodModifiers(); - auto *method = ParseInterfaceMethod(modfiers, ir::MethodDefinitionKind::METHOD); - method->SetStart(startLoc); - return method; } - auto *field = ParseInterfaceField(); - field->SetStart(startLoc); - field->AddModifier(ir::ModifierFlags::READONLY); - return field; + auto *method = ParseInterfaceMethod(modifiers, ir::MethodDefinitionKind::METHOD); + method->SetStart(startLoc); + return method; } - ir::ModifierFlags modfiers = ParseInterfaceMethodModifiers(); - if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT && - Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && - Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { - LogError(diagnostic::ID_EXPECTED); + auto tok = Lexer()->GetToken().Type(); + if (!IsFieldStartToken(tok)) { + LogError(diagnostic::ID_EXPECTED, {}, startLoc); return AllocBrokenExpression(Lexer()->GetToken().Loc()); } - char32_t nextCp = Lexer()->Lookahead(); - if (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN) { - auto *method = ParseInterfaceMethod(modfiers, ir::MethodDefinitionKind::METHOD); - method->SetStart(startLoc); - return method; - } - auto *field = ParseInterfaceField(); if (field != nullptr) { field->SetStart(startLoc); + if (isReadonly) { + field->AddModifier(ir::ModifierFlags::READONLY); + } return field; } diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 4ba354bbaebf7b9eaba5c04644134b2493de14e0..594c038963bd7c8ec51e48b6b83b5705e937aff9 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -15,11 +15,16 @@ #include "ETSparser.h" +#include "generated/tokenType.h" #include "lexer/lexer.h" #include "ir/expressions/literals/undefinedLiteral.h" #include "ir/ets/etsTuple.h" +#include "macros.h" +#include "parserFlags.h" #include "util/errorRecovery.h" #include "generated/diagnostic.h" +#include "parserImpl.h" +#include "util/recursiveGuard.h" namespace ark::es2panda::parser { class FunctionContext; @@ -47,11 +52,11 @@ ir::Expression *ETSParser::ParseLaunchExpression(ExpressionParseFlags flags) static std::string GetArgumentsSourceView(lexer::Lexer *lexer, const util::StringView::Iterator &lexerPos) { std::string value = lexer->SourceView(lexerPos.Index(), lexer->Save().Iterator().Index()).Mutf8(); - while (value.back() == ' ') { + while (!value.empty() && value.back() == ' ') { value.pop_back(); } - if (value.back() == ')' || value.back() == ',') { + if (!value.empty() && (value.back() == ')' || value.back() == ',')) { value.pop_back(); } @@ -302,12 +307,26 @@ ir::Expression *ETSParser::ParsePrimaryExpressionWithLiterals(ExpressionParseFla } } +// This function is used to handle the left parenthesis in the expression parsing. +ir::Expression *HandleLeftParanthesis(ETSParser *parser, ExpressionParseFlags flags) +{ + TrackRecursive trackRecursive(parser->recursiveCtx_); + if (!trackRecursive) { + parser->LogError(diagnostic::DEEP_NESTING); + while (parser->Lexer()->GetToken().Type() != lexer::TokenType::EOS) { + parser->Lexer()->NextToken(); + } + return parser->AllocBrokenExpression(parser->Lexer()->GetToken().Loc()); + } + return parser->ParseCoverParenthesizedExpressionAndArrowParameterList(flags); +} + // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ETSParser::ParsePrimaryExpression(ExpressionParseFlags flags) { switch (Lexer()->GetToken().Type()) { case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { - return ParseCoverParenthesizedExpressionAndArrowParameterList(flags); + return HandleLeftParanthesis(this, flags); } case lexer::TokenType::KEYW_THIS: { return ParseThisExpression(); @@ -370,13 +389,13 @@ bool IsPunctuartorSpecialCharacter(lexer::TokenType tokenType) } // This function was created to reduce the size of `EatArrowFunctionParams`. -static bool IsValidTokenTypeOfArrowFunctionStart(lexer::TokenType tokenType) +bool TypedParser::IsValidTokenTypeOfArrowFunctionStart(lexer::TokenType tokenType) { - return (tokenType == lexer::TokenType::LITERAL_IDENT || + return (tokenType == lexer::TokenType::LITERAL_IDENT || IsPrimitiveType(tokenType) || tokenType == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD || tokenType == lexer::TokenType::KEYW_THIS); } -static bool EatArrowFunctionParams(lexer::Lexer *lexer) +bool TypedParser::EatArrowFunctionParams(lexer::Lexer *lexer) { ES2PANDA_ASSERT(lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); lexer->NextToken(); diff --git a/ets2panda/parser/ETSparserTypes.cpp b/ets2panda/parser/ETSparserTypes.cpp index 98a1a79cd7c196b069d520e57bba7dcaa55a04e3..7c247dcb73f4ec2783f47f50decaf280bcb13168 100644 --- a/ets2panda/parser/ETSparserTypes.cpp +++ b/ets2panda/parser/ETSparserTypes.cpp @@ -190,7 +190,8 @@ ir::TypeNode *ETSParser::ParseFunctionType(TypeAnnotationParsingOptions *options { auto startLoc = Lexer()->GetToken().Start(); auto params = ParseFunctionParams(); - bool hasReceiver = !params.empty() && params[0]->AsETSParameterExpression()->Ident()->IsReceiver(); + bool hasReceiver = !params.empty() && params[0]->IsETSParameterExpression() && + params[0]->AsETSParameterExpression()->Ident()->IsReceiver(); if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_ARROW)) { if (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_ARROW); @@ -309,15 +310,17 @@ ir::TypeNode *ETSParser::ParsePotentialFunctionalType(TypeAnnotationParsingOptio // Just to reduce the size of ParseTypeAnnotation(...) method std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnotationParsingOptions *options) { - switch (Lexer()->GetToken().Type()) { - case lexer::TokenType::LITERAL_IDENT: { - auto typeAnnotation = ParseLiteralIdent(options); - if (((*options) & TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL) != 0 && - (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword())) { - return std::make_pair(typeAnnotation, false); - } - return std::make_pair(typeAnnotation, true); + auto tokenType = Lexer()->GetToken().Type(); + if (IsPrimitiveType(Lexer()->GetToken().KeywordType()) || tokenType == lexer::TokenType::LITERAL_IDENT) { + auto typeAnnotation = ParseLiteralIdent(options); + if (((*options) & TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL) != 0 && + (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword())) { + return std::make_pair(typeAnnotation, false); } + return std::make_pair(typeAnnotation, true); + } + + switch (tokenType) { case lexer::TokenType::LITERAL_NULL: { auto typeAnnotation = AllocNode(Allocator()); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); @@ -506,11 +509,15 @@ bool ETSParser::ParseReadonlyInTypeAnnotation() ir::TypeNode *ETSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options) { - ir::TypeNode *typeAnnotation = nullptr; - auto startPos = Lexer()->GetToken().Start(); + const auto startPos = Lexer()->GetToken().Start(); // if there is prefix readonly parameter type, change the return result to ETSTypeReference, like Readonly<> if (Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_READONLY)) { - typeAnnotation = ParseTypeAnnotationNoPreferParam(options); + const auto beforeTypeAnnotation = Lexer()->GetToken().Loc(); + auto typeAnnotation = ParseTypeAnnotationNoPreferParam(options); + if (typeAnnotation == nullptr) { + LogError(diagnostic::INVALID_TYPE); + return AllocBrokenType(beforeTypeAnnotation); + } if (!typeAnnotation->IsTSArrayType() && !typeAnnotation->IsETSTuple() && !(typeAnnotation->IsETSTypeReference() && typeAnnotation->AsETSTypeReference()->BaseName()->Name() == compiler::Signatures::ARRAY)) { @@ -522,10 +529,9 @@ ir::TypeNode *ETSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *optio } typeAnnotation->SetStart(startPos); typeAnnotation->AddModifier(ir::ModifierFlags::READONLY_PARAMETER); - } else { - typeAnnotation = ParseTypeAnnotationNoPreferParam(options); + return typeAnnotation; } - return typeAnnotation; + return ParseTypeAnnotationNoPreferParam(options); } ir::TypeNode *ETSParser::ParseMultilineString() diff --git a/ets2panda/parser/TypedParser.h b/ets2panda/parser/TypedParser.h index d9caee03b60e428f30f95b4e69cca452a142ae0f..8101ab712324f90a8655a990b4220811eb90ba0a 100644 --- a/ets2panda/parser/TypedParser.h +++ b/ets2panda/parser/TypedParser.h @@ -73,6 +73,9 @@ protected: bool CheckClassElement(ir::AstNode *property, ir::MethodDefinition *&ctor, ArenaVector &properties) override; bool IsNamespaceDecl(); + bool IsPrimitiveType(const lexer::TokenType &tokenType); + bool IsValidTokenTypeOfArrowFunctionStart(lexer::TokenType tokenType); + bool EatArrowFunctionParams(lexer::Lexer *lexer); ir::ModifierFlags ParseModifiers() override; ParserStatus ValidateArrowParameter(ir::Expression *expr, bool *seenOptional) override; diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index dc9ad8cce57ba5929ab9662064ea8ada099f96c0..d3fcb64454ff68338e5acff23d7d481bb70ebc57 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -1021,6 +1021,10 @@ ir::Statement *ParserImpl::ParseForStatement() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); ir::Statement *bodyNode = ParseStatement(); + if (bodyNode == nullptr) { + return AllocBrokenStatement(Lexer()->GetToken().Loc()); + } + return CreateForStatement({initNode, rightNode, updateNode, bodyNode}, forKind, startLoc, isAwait); } diff --git a/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets b/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets index 0833b29c81946ef9f212aa5bdffb8f5dd334285a..e4aa2cd0ce15b3402c5df5e68586c4894df26094 100644 --- a/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets +++ b/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets @@ -16,6 +16,8 @@ let f = ()=>int {} f() -/* @@? 16:13 Error TypeError: Unresolved reference int */ +/* @@? 16:13 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:13 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:13 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:13 Error SyntaxError: Unexpected token 'int'. */ /* @@? 16:13 Error TypeError: Unexpected return value, enclosing method return type is void. */ -/* @@? 16:17 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/compiler/ets/ambient_struct/declare_struct.d.ets b/ets2panda/test/ast/compiler/ets/ambient_struct/declare_struct.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..820aa91867dd36de5024171926e11f96c67cc5bd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/ambient_struct/declare_struct.d.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ + +export declare struct Point2D { + x: number; + y: number; +} + +/* @@? 16:16 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ diff --git a/ets2panda/test/ast/compiler/ets/comparability_of_never_type01.ets b/ets2panda/test/ast/compiler/ets/comparability_of_never_type01.ets new file mode 100644 index 0000000000000000000000000000000000000000..02cf672e62a5a8b326cc98737d85e2f6790be9bc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/comparability_of_never_type01.ets @@ -0,0 +1,18 @@ +/* + * 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. + */ + +const a: readonly Array> = new Array>() +const b: readonly Array> = new Array>() +const c: readonly Array> = new Array>() diff --git a/ets2panda/test/ast/compiler/ets/comparability_of_never_type02.ets b/ets2panda/test/ast/compiler/ets/comparability_of_never_type02.ets new file mode 100644 index 0000000000000000000000000000000000000000..04e270a8c1859ef8d6ec8bae8b5c8d23c159339f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/comparability_of_never_type02.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ + +function foo(a:readonly Array){} +function bar(a:Array){ + foo(a) +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/comparability_of_never_type03.ets b/ets2panda/test/ast/compiler/ets/comparability_of_never_type03.ets new file mode 100644 index 0000000000000000000000000000000000000000..582677c3d48af5b87eeb019d8894a0f8454fdc68 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/comparability_of_never_type03.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ + +function foo(a:readonly Array){} +function bar(a:readonly Array){ + foo(a) +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/declareType_neg_1.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_1.ets index 0d5dab8c8a4fc4f9b254aa4c113d8218592f84f2..ad56d9aa62741d2a70350484509799af72e881ea 100644 --- a/ets2panda/test/ast/compiler/ets/declareType_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_1.ets @@ -19,5 +19,7 @@ declare const type typeA = int; /* @@? 16:20 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 16:20 Error SyntaxError: Unexpected token 'typeA'. */ /* @@? 16:20 Error TypeError: Unresolved reference typeA */ -/* @@? 16:28 Error TypeError: Unresolved reference int */ - +/* @@? 16:28 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:28 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:28 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:28 Error SyntaxError: Unexpected token 'int'. */ diff --git a/ets2panda/test/ast/compiler/ets/func_as_param.ets b/ets2panda/test/ast/compiler/ets/func_as_param.ets index e78a161c811a95e6622a5d3a1448c51ead6bd841..7d03377605808363ee9d614305db7f37aed9a5fc 100644 --- a/ets2panda/test/ast/compiler/ets/func_as_param.ets +++ b/ets2panda/test/ast/compiler/ets/func_as_param.ets @@ -16,7 +16,7 @@ function getFuncWithArgsZero(func: (() => void) | (() => Promise)) { return new Promise(async (resolve: (value: PromiseLike) => void) => { await (func as () => Promise)(); - const funcStr = (func as object).toString() + const funcStr = Type.of(func as object).getLiteral() const argsCount = getFunctionArgumentsCount(funcStr) const isAsync = checkIsAsyncFunction(funcStr) resolve(Promise.resolve()); @@ -47,4 +47,69 @@ function checkIsAsyncFunction(funcStr: string): boolean { } } +async function testAsyncGetFuncWithArgsZeroSafe() { + let success = false; + try { + await getFuncWithArgsZero( async () => {}); + success = true; + } catch (e) { + success = false; + } + assertEQ(success, true, "getFuncWithArgsZero with async should not throw"); +} + +function testGetFuncWithArgsZeroSafe() { + let success = false; + try { + getFuncWithArgsZero(() => {}); + success = true; + } catch (e) { + success = false; + } + assertEQ(success, true, "getFuncWithArgsZero should not throw"); +} + +function main(): void { + const func1 = (a: number, b: number): number => { + return a + b; + }; + + const func2 = async (): Promise => {}; + + const func3 = (): number => { + return 42; + }; + + const func4 = async (x: number, y: number, z: number): Promise => {}; + + const funcStr1: string = Type.of(func1 as object).getLiteral(); + const funcStr2: string = Type.of(func2 as object).getLiteral(); + const funcStr3: string = Type.of(func3 as object).getLiteral(); + const funcStr4: string = Type.of(func4 as object).getLiteral(); + + // Test getLiteral() + assertEQ(funcStr1, "(1: std.core.Double, 2: std.core.Double): std.core.Double", "func1 literal check"); + assertEQ(funcStr2, "(): std.core.Promise", "func2 literal check"); + assertEQ(funcStr3, "(): std.core.Double", "func3 literal check"); + assertEQ(funcStr4, "(1: std.core.Double, 2: std.core.Double, 3: std.core.Double): std.core.Promise", "func4 literal check"); + + // Test getFunctionArgumentsCount + assertEQ(getFunctionArgumentsCount(funcStr1), 2, "func1 should have 2 arguments"); + assertEQ(getFunctionArgumentsCount(funcStr2), 0, "func2 should have 0 arguments"); + assertEQ(getFunctionArgumentsCount(funcStr3), 0, "func3 should have 0 arguments"); + assertEQ(getFunctionArgumentsCount(funcStr4), 3, "func4 should have 3 arguments"); + + // Test checkIsAsyncFunction + assertEQ(checkIsAsyncFunction(funcStr1), false, "func1 should not be async"); + assertEQ(checkIsAsyncFunction(funcStr2), true, "func2 should be async"); + assertEQ(checkIsAsyncFunction(funcStr3), false, "func3 should not be async"); + assertEQ(checkIsAsyncFunction(funcStr4), true, "func4 should be async"); + + // execute getFuncWithArgsZero with async + testAsyncGetFuncWithArgsZeroSafe() + + // execute getFuncWithArgsZero with sync + testGetFuncWithArgsZeroSafe() +} + diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets index 025f58661541fbf89ba83a9c3cda9a950bb38919..60a86f221b1b5f3f0fbd4a6f1254d8c77bd12eb2 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets @@ -19,5 +19,4 @@ import {myvar} from "./package_module_2" // compiling this file will fail with import from it's own package /* @@? 17:1 Error SyntaxError: Package module cannot import from a file in it's own package. */ -/* @@? package_module_2.ets:18:12 Error TypeError: Variable 'myvar' has already been declared. */ /* @@? 17:21 Error TypeError: Cannot find import: ./package_module_2 */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets index 1d9762690a969b7b920403559fe7088e3fcca6f0..a0e59061b587eeab94a4c350ca25591aae86a627 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets @@ -22,7 +22,5 @@ export let a: String = "SubpackageA"; /* @@? 18:1 Error SyntaxError: Package module cannot import from a file in it's own package. */ /* @@? 19:1 Error SyntaxError: Package module cannot import from a file in it's own package. */ -/* @@? package_module.ets:20:12 Error TypeError: Variable 'myvar' has already been declared. */ -/* @@? package_module.ets:21:12 Error TypeError: Variable 'myvar2' has already been declared. */ /* @@? 18:21 Error TypeError: Cannot find import: ./package_module */ /* @@? 19:22 Error TypeError: Cannot find import: ./package_module */ diff --git a/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets b/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets new file mode 100644 index 0000000000000000000000000000000000000000..6abcf73491b7c19261f3ef18a8291aa6783fe638 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +function foo(arr:Array, f:(a:Array)=>string){ + return f(arr[0]) // CTE +} + +function bar(arr:Array){ + return foo(arr, (a):string=>{ + let res = a.toString(); + return res + }) +} + +/* @@? 17:12 Error TypeError: No matching call signature for (T) */ +/* @@? 17:14 Error TypeError: Type 'T' is not compatible with type 'Array' at index 1 */ diff --git a/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets b/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets index cd1e04e08693d21b40319500b80407de63485d3a..9c7a8b2ce24dc5bd0c788e3cd69d762b1389c544 100644 --- a/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets +++ b/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets @@ -23,6 +23,8 @@ function foo1() { let undefined }; +/* @@? 21:9 Error TypeError: Variable 'NaN' has already been declared. */ +/* @@? 22:9 Error TypeError: Variable 'Infinity' has already been declared. */ /* @@? 22:20 Error TypeError: Unresolved reference test */ /* @@? 23:9 Error SyntaxError: Identifier expected, got 'undefined'. */ /* @@? 24:1 Error SyntaxError: Variable must be initialized or it's type must be declared. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets b/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets new file mode 100644 index 0000000000000000000000000000000000000000..f0f192c0a9a6dc1285bf34c8b9c8c4da53346af3 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +WE: /* @@ readonly1 */readonly /* @@ true */true; +let/* @@ colon */: /* @@ readonly2 */readonly/* @@ end */; + +/* @@@ readonly1 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@@ readonly1 Error TypeError: Unresolved reference readonly */ +/* @@@ true Error SyntaxError: Invalid Type. */ +/* @@@ true Error SyntaxError: Unexpected token 'true'. */ + +/* @@@ colon Error SyntaxError: Identifier expected, got ':'. */ +/* @@@ readonly2 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@@ readonly2 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@@ readonly2 Error SyntaxError: Unexpected token 'readonly'. */ +/* @@@ end Error SyntaxError: Invalid Type. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets new file mode 100644 index 0000000000000000000000000000000000000000..4b6b812ce65e1dfe5fe85ef340763c9348c19016 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +let a: readonly int [/* @@ E1 */""/* @@ E2 */]; + +/* @@@ E1 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@@ E1 Error SyntaxError: Invalid Type. */ +/* @@@ E1 Error SyntaxError: Unexpected token ']'. */ +/* @@@ E1 Error SyntaxError: Unexpected token ']'. */ +/* @@@ E1 Error SyntaxError: Unexpected token ']'. */ +/* @@@ E2 Error SyntaxError: Unexpected token ']'. */ +/* @@@ E2 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_as_args_type.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_args_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe4d6158f78c51023de89e1f32803c86ea9f73d9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_args_type.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +function foo(param1: readonly/* @@ foo_param1 */, param2: readonly /* @@ foo_param2 */true) {} + +/* @@@ foo_param1 Error SyntaxError: Invalid Type. */ +/* @@@ foo_param1 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ + +/* @@@ foo_param2 Error SyntaxError: Invalid Type. */ +/* @@@ foo_param2 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_as_fields_type.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_fields_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..3830a00052e10a05e2dadd2cd1222756c99a44be --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_fields_type.ets @@ -0,0 +1,31 @@ +/* + * 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. + */ + +class A { + a: readonly/* @@ A_a */; + b: readonly /* @@ A_b */false; + c: readonly /* @@ A_c */1; +} + +/* @@@ A_a Error SyntaxError: Invalid Type. */ +/* @@@ A_a Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ + +/* @@@ A_b Error SyntaxError: Invalid Type. */ +/* @@@ A_b Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@@ A_b Error SyntaxError: Unexpected token 'false'. */ + +/* @@@ A_c Error SyntaxError: Invalid Type. */ +/* @@@ A_c Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@@ A_c Error SyntaxError: Unexpected token '1'. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets new file mode 100644 index 0000000000000000000000000000000000000000..816f9ea537cbdd0608b1cbb1b204d5eedc539e1c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/* @@ readonly */readonly /* @@ static */static /* @@ S */S = c' '; + +/* @@@ readonly Error TypeError: Unresolved reference readonly */ +/* @@@ static Error SyntaxError: Invalid Type. */ +/* @@@ static Error SyntaxError: Unexpected token 'static'. */ +/* @@@ static Error SyntaxError: Unexpected token 'static'. */ +/* @@@ S Error SyntaxError: Unexpected token 'S'. */ +/* @@@ S Error TypeError: Unresolved reference S */ diff --git a/ets2panda/test/ast/compiler/ets/readonly_array01.ets b/ets2panda/test/ast/compiler/ets/readonly_array01.ets new file mode 100644 index 0000000000000000000000000000000000000000..d377fa27f9c66e4041ebb53d2585c89e9f1e938b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly_array01.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + +function main() { + let v: readonly number[][] = [[1.0,2.0]] + v[0][0] = 3.0 // ok + v[0] = [] // CTE +} + +/* @@? 19:5 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ + diff --git a/ets2panda/test/ast/compiler/ets/tolocalString.ets b/ets2panda/test/ast/compiler/ets/tolocalString.ets new file mode 100644 index 0000000000000000000000000000000000000000..e2576c4fd4f6f5090b1070e2e577071dae29c3c0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/tolocalString.ets @@ -0,0 +1,20 @@ +/* + * 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. + */ + +class A { + toLocaleString = () => {} +} + +/* @@? 16:7 Error TypeError: Cannot inherit from class Object, because field toLocaleString is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_union_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_union_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..34a2d31c5a5412e10a0a02a091d94183e2ffbf59 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/tuple_union_neg.ets @@ -0,0 +1,18 @@ +/* + * 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. + */ +let v: [number]|null = ["A"] + +/* @@? 15:25 Error TypeError: Array initializer's type is not assignable to tuple type at index: 0 */ + diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.ets b/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.ets index e183093f43332c10f492f6b8946756f152ee63cd..f845db8bb1c59e9476aa76d659bceac367ce60f7 100644 --- a/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.ets +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.ets @@ -26,5 +26,6 @@ function foo() { /* @@? 16:1 Error TypeError: Unresolved reference a */ /* @@? 20:1 Error TypeError: Unresolved reference c */ -/* @@? 24:5 Error TypeError: Unresolved reference void */ +/* @@? 24:5 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 24:10 Error SyntaxError: Unexpected token '='. */ /* @@? 24:18 Error TypeError: Unresolved reference asyncGenerator */ diff --git a/ets2panda/test/ast/compiler/ets/union_method.ets b/ets2panda/test/ast/compiler/ets/union_method.ets index 8820ee691aef20eccd5bb54a3c8c725a2891ae02..9a46c72c4006ccf34fbd15d2ddb6a7f1098b2c1b 100644 --- a/ets2panda/test/ast/compiler/ets/union_method.ets +++ b/ets2panda/test/ast/compiler/ets/union_method.ets @@ -14,19 +14,19 @@ */ class A { - short(v: string): void {} + shorting(v: string): void {} ordinary(a: int, b: int, c: int): void {} range(a: int, b: int, c: int, d: int, e: int, f: int): void {} } class B { - short(v: string): void {} + shorting(v: string): void {} ordinary(a: int, b: int, c: int): void {} range(a: int, b: int, c: int, d: int, e: int, f: int): void {} } -function short(x: A|B) { - x.short("123") +function shorting(x: A|B) { + x.shorting("123") } function ordinary(x: A|B) { diff --git a/ets2panda/test/ast/compiler/ets/union_method_3.ets b/ets2panda/test/ast/compiler/ets/union_method_3.ets index a6c0a9191e8a445833680ca1958ed5f8b5769c21..80b3ba46de8235c370adad7a14ca5a2a1b568125 100644 --- a/ets2panda/test/ast/compiler/ets/union_method_3.ets +++ b/ets2panda/test/ast/compiler/ets/union_method_3.ets @@ -24,7 +24,5 @@ class B { } function foo(x: A|B) { - /* @@ label */x.foo("123") + x.foo("123") } - -/* @@@ label Error TypeError: Union constituent types should have only one common method signature. */ diff --git a/ets2panda/test/ast/compiler/ets/void_as_return_type_neg_1.ets b/ets2panda/test/ast/compiler/ets/void_as_return_type_neg_1.ets index 1626420399e8ddec4a2ba0c8ecc8e237cd7ee27e..c54c59d67a72ef256bd830f57e4f54a1c101b441 100644 --- a/ets2panda/test/ast/compiler/ets/void_as_return_type_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/void_as_return_type_neg_1.ets @@ -17,4 +17,7 @@ async function foo():Promise{ return void; } -/* @@? 17:12 Error TypeError: Unresolved reference void */ \ No newline at end of file +/* @@? 17:12 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 17:12 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 17:12 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 17:12 Error SyntaxError: Unexpected token 'void'. */ diff --git a/ets2panda/test/ast/compiler/ets/void_as_value_neg_3.ets b/ets2panda/test/ast/compiler/ets/void_as_value_neg_3.ets index a292b7d1761aa0c0ded64a8031e5bf505359aefd..d93580a127a2e4c45a243461d049dd5836025550 100644 --- a/ets2panda/test/ast/compiler/ets/void_as_value_neg_3.ets +++ b/ets2panda/test/ast/compiler/ets/void_as_value_neg_3.ets @@ -15,7 +15,12 @@ function foo(x: T) {} -foo(/* @@ label */void) - -/* @@@ label Error TypeError: Unresolved reference void */ +foo(void) +/* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 18:11 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 18:15 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:15 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets b/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets index 558fbe032a3396dc9da8c75372c3395a04bba46b..78b272bb38af482c3cb05ba89df214ccddb781b6 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets @@ -174,8 +174,8 @@ function main(): void { /* @@? 39:14 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 39:14 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 39:24 Error TypeError: Unresolved reference int */ -/* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ +/* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ /* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ /* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ /* @@? 39:31 Error SyntaxError: return keyword should be used in function body. */ @@ -195,12 +195,13 @@ function main(): void { /* @@? 51:43 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 51:43 Error TypeError: Unresolved reference FixedArray */ /* @@? 51:58 Error SyntaxError: Unexpected token, expected '('. */ -/* @@? 51:59 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ /* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ +/* @@? 51:59 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ +/* @@? 51:59 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ -/* @@? 51:65 Error SyntaxError: Unexpected token '{'. */ +/* @@? 51:61 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 51:61 Error SyntaxError: Unexpected token 'int'. */ /* @@? 52:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 52:12 Error TypeError: Unresolved reference q */ /* @@? 52:12 Error TypeError: All return statements in the function should be empty or have a value. */ @@ -226,6 +227,10 @@ function main(): void { /* @@? 115:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 115:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 115:26 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 115:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 115:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 115:26 Error SyntaxError: Unexpected token 'case'. */ +/* @@? 115:26 Error SyntaxError: Unexpected token 'case'. */ /* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 115:32 Error TypeError: Unresolved reference U */ @@ -284,4 +289,4 @@ function main(): void { /* @@? 165:5 Error TypeError: This expression is not callable. */ /* @@? 166:5 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 166:5 Error TypeError: No matching call signature */ -/* @@? 288:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 293:1 Error SyntaxError: Expected '}', got 'eos'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets b/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets index e3fef3a17680db97880f0a0704eb882207e3cc01..9ad1e60b924c2b2fff1506bb5af87cfe6942e87e 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets @@ -90,8 +90,8 @@ let var6: [a0: , a1: ]; /* @@? 30:18 Error SyntaxError: Unexpected token ':'. */ /* @@? 30:20 Error SyntaxError: Unexpected token '...'. */ /* @@? 30:20 Error SyntaxError: Unexpected token '...'. */ -/* @@? 30:23 Error TypeError: Unresolved reference int */ -/* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ +/* @@? 30:23 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 30:23 Error SyntaxError: Unexpected token 'int'. */ /* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token, expected ',' or ']'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/rest_parameter_04.ets b/ets2panda/test/ast/parser/ets/FixedArray/rest_parameter_04.ets index 37e28e816e2e71d9ba76c1f351726c16037d2f60..a408eaf019b4a4b7be1eb52bcfbc18e07e941bd6 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/rest_parameter_04.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/rest_parameter_04.ets @@ -19,5 +19,5 @@ function hehe(...items: FixedArray/* @@ label */: void /* @@ label1 */{ /* @@? 16:10 Error TypeError: Only abstract or native methods can't have body. */ /* @@? 16:57 Error SyntaxError: Rest parameter must be the last formal parameter. */ -/* @@? 16:59 Error TypeError: Unresolved reference void */ -/* @@? 16:79 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:59 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 16:59 Error SyntaxError: Unexpected token 'void'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets index f3c1bde715740ef2b3570df6573fd346bdc0ea83..bb6c655e2b323ee2d5d5015c4712528689e920a3 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets @@ -25,8 +25,8 @@ function foo(...^number: FixedArray): int { /* @@? 16:41 Error SyntaxError: Unexpected token ')'. */ /* @@? 16:42 Error SyntaxError: Unexpected token ':'. */ /* @@? 16:42 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:44 Error TypeError: Unresolved reference int */ -/* @@? 16:48 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:44 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:44 Error SyntaxError: Unexpected token 'int'. */ /* @@? 17:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 17:12 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:12 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets index 35bf7c584f538d138a257f1db0d8c9e60706c409..fa85f223688b82814631dc7e055b3328edda1c66 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets @@ -41,7 +41,9 @@ export class AccessNSieve { /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:16 Error TypeError: Unresolved reference int */ +/* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 29:20 Error SyntaxError: Unexpected token '='. */ /* @@? 29:25 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets b/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets index 72316999b9d5a269d4916313f7ad5e702584fd67..521660666b2fe92500891371b034004bb0e32719 100644 --- a/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets +++ b/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets @@ -76,7 +76,10 @@ let a = [1, 2, 3); /* @@? 24:24 Error SyntaxError: Unexpected token ')'. */ /* @@? 24:25 Error SyntaxError: Unexpected token ':'. */ /* @@? 24:25 Error SyntaxError: Unexpected token ':'. */ -/* @@? 24:27 Error TypeError: The type of parameter 'void' cannot be inferred */ +/* @@? 24:27 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 24:27 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 24:32 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 24:32 Error SyntaxError: Unexpected token '=>'. */ /* @@? 26:7 Error SyntaxError: Unexpected token '||='. */ /* @@? 28:5 Error TypeError: Variable 'a' has already been declared. */ /* @@? 28:16 Error TypeError: Bad operand type, the types of the operands must be numeric type, enum or String. */ @@ -87,9 +90,9 @@ let a = [1, 2, 3); /* @@? 30:13 Error SyntaxError: Invalid Type. */ /* @@? 32:10 Error TypeError: Variable 'f' has already been declared. */ /* @@? 32:10 Error TypeError: Variable 'f' has already been declared. */ -/* @@? 33:5 Error TypeError: No matching call signature for std.core.Object(int) */ -/* @@? 33:5 Error TypeError: Expected 0 arguments, got 1. */ /* @@? 33:5 Error TypeError: Call to 'super' must be first statement in constructor */ +/* @@? 33:5 Error TypeError: Expected 0 arguments, got 1. */ +/* @@? 33:5 Error TypeError: No matching call signature for std.core.Object(int) */ /* @@? 33:10 Error SyntaxError: Unexpected super keyword. */ /* @@? 36:1 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 36:8 Error SyntaxError: Unexpected token, expected ']'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets b/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets index 2439731f6e6e6cbd537dce1eac79e8a8de16e4b0..f1a1bac9355051e04eba42620f38d97b2d736581 100644 --- a/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets +++ b/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets @@ -15,14 +15,15 @@ class A { get abc(x: number) {} - /* @@ label */set abc(x: number, a: string) {} -/* @@ label1 */} + set abc(x: number, a: string) {} +} function fun(this: A) {} -class /* @@ label2 */int {} +class int {} -/* @@@ label Error SyntaxError: Getter must not have formal parameters. */ -/* @@@ label1 Error SyntaxError: Setter must have exactly one formal parameter. */ -/* @@@ label2 Error SyntaxError: Cannot be used as user-defined type. */ /* @@? 17:12 Error TypeError: Getter must return a value */ +/* @@? 18:5 Error SyntaxError: Getter must not have formal parameters. */ +/* @@? 19:1 Error SyntaxError: Setter must have exactly one formal parameter. */ +/* @@? 23:7 Error SyntaxError: Cannot be used as user-defined type. */ +/* @@? 23:7 Error SyntaxError: Identifier expected, got 'int'. */ diff --git a/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets b/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets index 7b052e2990a98fed85f77c53148af08f4e03e88e..758b001e43f51cd7b526f4767f442c1f877d4121 100644 --- a/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets +++ b/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets @@ -174,15 +174,15 @@ function main(): void { /* @@? 39:14 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 39:14 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 39:24 Error TypeError: Unresolved reference int */ -/* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ +/* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ /* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ /* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ /* @@? 39:31 Error SyntaxError: return keyword should be used in function body. */ /* @@? 39:38 Error TypeError: All return statements in the function should be empty or have a value. */ /* @@? 41:6 Error SyntaxError: Identifier expected, got 'number literal'. */ -/* @@? 43:6 Error SyntaxError: Type alias name cannot be 'null'. */ /* @@? 43:6 Error SyntaxError: Identifier expected, got 'null'. */ +/* @@? 43:6 Error SyntaxError: Type alias name cannot be 'null'. */ /* @@? 45:6 Error SyntaxError: Identifier expected, got 'this'. */ /* @@? 47:8 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 47:8 Error SyntaxError: Variable must be initialized or it's type must be declared. */ @@ -198,7 +198,8 @@ function main(): void { /* @@? 51:38 Error SyntaxError: Unexpected token ')'. */ /* @@? 51:39 Error SyntaxError: Unexpected token ':'. */ /* @@? 51:39 Error SyntaxError: Unexpected token ':'. */ -/* @@? 51:45 Error SyntaxError: Unexpected token '{'. */ +/* @@? 51:41 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 51:41 Error SyntaxError: Unexpected token 'int'. */ /* @@? 52:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 52:12 Error TypeError: Unresolved reference q */ /* @@? 52:12 Error TypeError: All return statements in the function should be empty or have a value. */ @@ -236,11 +237,11 @@ function main(): void { /* @@? 115:38 Error SyntaxError: Unexpected token '{'. */ /* @@? 116:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 116:12 Error TypeError: All return statements in the function should be empty or have a value. */ -/* @@? 119:26 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 119:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ -/* @@? 119:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 119:26 Error SyntaxError: Unexpected token 'case'. */ /* @@? 119:26 Error SyntaxError: Unexpected token 'case'. */ +/* @@? 119:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 119:26 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ @@ -282,4 +283,4 @@ function main(): void { /* @@? 165:5 Error TypeError: This expression is not callable. */ /* @@? 166:5 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 166:5 Error TypeError: No matching call signature */ -/* @@? 286:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 287:1 Error SyntaxError: Expected '}', got 'eos'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets index 4e5c7ed46cbcdc44b6a92bdc0efa05a7bdd63e5c..6516d74eb9c355ee292ccf832a5787ad1bc7d40b 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets @@ -31,9 +31,9 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: /* @@? 19:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 19:20 Error TypeError: need to specify target type for class composite */ /* @@? 19:42 Error SyntaxError: Unexpected token 'x'. */ +/* @@? 19:45 Error SyntaxError: Unexpected token 'int'. */ /* @@? 19:45 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 19:45 Error TypeError: Unresolved reference int */ -/* @@? 19:48 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:45 Error SyntaxError: Unexpected token 'int'. */ /* @@? 19:48 Error SyntaxError: Unexpected token ')'. */ /* @@? 19:48 Error SyntaxError: Unexpected token ')'. */ /* @@? 22:1 Error TypeError: Function foo is already declared. */ @@ -43,7 +43,8 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: /* @@? 22:20 Error TypeError: need to specify target type for class composite */ /* @@? 22:42 Error SyntaxError: Unexpected token 'x'. */ /* @@? 22:45 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 22:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:45 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 22:45 Error SyntaxError: Unexpected token 'int'. */ /* @@? 22:48 Error SyntaxError: Unexpected token ','. */ /* @@? 22:48 Error SyntaxError: Unexpected token ','. */ /* @@? 22:50 Error TypeError: This expression is not callable. */ @@ -57,12 +58,13 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: /* @@? 25:1 Error TypeError: Function foo is already declared. */ /* @@? 25:1 Error TypeError: Function foo is already declared. */ /* @@? 25:14 Error TypeError: The type of parameter 'MyAnno' cannot be inferred */ -/* @@? 25:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 25:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 25:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 25:20 Error TypeError: need to specify target type for class composite */ /* @@? 25:42 Error SyntaxError: Unexpected token 'x'. */ /* @@? 25:45 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 25:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 25:45 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 25:45 Error SyntaxError: Unexpected token 'int'. */ /* @@? 25:48 Error SyntaxError: Unexpected token ','. */ /* @@? 25:48 Error SyntaxError: Unexpected token ','. */ /* @@? 25:50 Error TypeError: Annotation missing '@' symbol before annotation name. */ diff --git a/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets b/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets new file mode 100644 index 0000000000000000000000000000000000000000..d31d7c3e7a9b63085039b91a46b9988c1aaa4024 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets @@ -0,0 +1,27 @@ +/* + * 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. + */ + +class C { + constructor(x: number, y: string); + constructor(s: string); + constructor(xs: any, y?: any) {} +} +let c = new C(10, 'foo'); + +/* @@? 17:14 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 19:3 Error TypeError: No matching call signature for constructor */ +/* @@? 19:19 Error TypeError: Cannot find type 'any'. */ +/* @@? 19:28 Error TypeError: Cannot find type 'any'. */ + diff --git a/ets2panda/test/ast/parser/ets/empty_array_map_inference_fail.ets b/ets2panda/test/ast/parser/ets/empty_array_map_inference_fail.ets new file mode 100644 index 0000000000000000000000000000000000000000..9552cc43a987d63b20da913d3326f7cbaef23102 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/empty_array_map_inference_fail.ets @@ -0,0 +1,38 @@ +/* + * 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. + */ + +(function() { + return 37; +})(); + +[].map(function(x) { + return x+1; +}); + +/* @@? 16:1 Error TypeError: No matching call signature */ +/* @@? 16:1 Error TypeError: Expected 1 arguments, got 0. */ +/* @@? 16:2 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 16:2 Error SyntaxError: Unexpected token 'function'. */ +/* @@? 18:2 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:4 Error SyntaxError: Unexpected token ')'. */ +/* @@? 20:1 Error TypeError: Can't resolve array type */ +/* @@? 20:8 Error SyntaxError: Unexpected token 'function'. */ +/* @@? 20:8 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 20:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 20:17 Error TypeError: The type of parameter 'x' cannot be inferred */ +/* @@? 20:18 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 22:2 Error SyntaxError: Unexpected token ')'. */ + + diff --git a/ets2panda/test/ast/parser/ets/for_of_04.ets b/ets2panda/test/ast/parser/ets/for_of_04.ets index 73102569bed6a023ab3e2c2d7e13769bc34e6e6c..1131b1d91f3555d3c28476ff467088eb53ca3bef 100644 --- a/ets2panda/test/ast/parser/ets/for_of_04.ets +++ b/ets2panda/test/ast/parser/ets/for_of_04.ets @@ -26,11 +26,17 @@ for (i in 50) { a += 10 } /* @@? 20:9 Error SyntaxError: Type annotation is not allowed when existing variable is used as loop iterator in 'for' statement. */ -/* @@? 20:11 Error SyntaxError: Expected ';', got 'identification literal'. */ -/* @@? 20:11 Error TypeError: Unresolved reference double */ -/* @@? 20:18 Error SyntaxError: Expected ';', got 'identification literal'. */ +/* @@? 20:11 Error SyntaxError: Expected ';', got 'double'. */ +/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ +/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ +/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ +/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ +/* @@? 20:11 Error SyntaxError: Expected ')', got 'double'. */ +/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ +/* @@? 20:11 Error SyntaxError: Expected ';', got 'double'. */ +/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ /* @@? 20:18 Error TypeError: Unresolved reference of */ -/* @@? 20:21 Error SyntaxError: Expected ')', got 'identification literal'. */ +/* @@? 20:21 Error SyntaxError: Unexpected token 'a'. */ /* @@? 20:21 Error TypeError: Unresolved reference a */ /* @@? 20:22 Error SyntaxError: Unexpected token ')'. */ /* @@? 20:22 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/for_with_empty_body.ets b/ets2panda/test/ast/parser/ets/for_with_empty_body.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1e35845ea6a878d0d19b02859dced6014839eb3 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/for_with_empty_body.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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +for ( ; ; ) + +try { + +} + +/* @@? 22:1 Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ diff --git a/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined.ets b/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined.ets index 16985cfec4f38ff643ac629e9def3ef9cd689405..975a0fe9468d1ec9432809dcf607e841c59d8adf 100644 --- a/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined.ets +++ b/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined.ets @@ -18,4 +18,6 @@ } /* @@? 17:3 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ - /* @@? 17:3 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ \ No newline at end of file + /* @@? 17:3 Error TypeError: Cannot cast 'null' or 'undefined' to non-nullish type. */ + /* @@? 17:3 Error TypeError: Type 'Double' cannot be assigned to type 'undefined' */ + diff --git a/ets2panda/test/ast/parser/ets/interfaceMethodReadonlyModifier.ets b/ets2panda/test/ast/parser/ets/interfaceMethodReadonlyModifier.ets index 0bcf0c313b351645224b545b3b0f8f836dc4ac51..39dcced0fd57af716fe1df1d7969c1132a68d59e 100644 --- a/ets2panda/test/ast/parser/ets/interfaceMethodReadonlyModifier.ets +++ b/ets2panda/test/ast/parser/ets/interfaceMethodReadonlyModifier.ets @@ -14,7 +14,11 @@ */ interface I { - /* @@ label */readonly foo() + readonly foo() } -/* @@@ label Error SyntaxError: Modifier 'readonly' cannot be applied to an interface method. */ +/* @@? 17:17 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 17:18 Error SyntaxError: Invalid Type. */ +/* @@? 17:18 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:18 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:1 Error SyntaxError: Identifier expected. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets b/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..d18aff410856f2183deefcae726070359e924d78 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets @@ -0,0 +1,78 @@ +/** + * 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. + */ + +b: Geit { + t { + name(): + + interface I { + readonly: boolean + } + inter + + class A implements I { + reanstructor() { + this.a = f�ls + s A { + @ constructor() { + this.a = ruO; + } +}* +function mdin() { let a = new A(); + ass + +/* @@? 16:4 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 16:4 Error TypeError: Unresolved reference Geit */ +/* @@? 16:9 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:2 Error TypeError: Unresolved reference t */ +/* @@? 17:4 Error SyntaxError: Unexpected token '{'. */ +/* @@? 18:9 Error TypeError: Unresolved reference name */ +/* @@? 18:15 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:15 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:15 Error SyntaxError: Unexpected token ':'. */ +/* @@? 21:13 Error SyntaxError: Identifier expected. */ +/* @@? 21:21 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 21:21 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 21:23 Error SyntaxError: Identifier expected. */ +/* @@? 21:23 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 21:23 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 22:9 Error SyntaxError: Identifier expected. */ +/* @@? 23:9 Error TypeError: Class literal is not yet supported. */ +/* @@? 23:9 Error TypeError: Cannot find type 'inter'. */ +/* @@? 25:15 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 25:15 Error TypeError: Unresolved reference A */ +/* @@? 25:17 Error SyntaxError: Unexpected token 'implements'. */ +/* @@? 25:17 Error SyntaxError: Unexpected token 'implements'. */ +/* @@? 25:17 Error SyntaxError: Unexpected token 'implements'. */ +/* @@? 25:28 Error TypeError: Interface name 'I' used in the wrong context */ +/* @@? 25:30 Error SyntaxError: Unexpected token '{'. */ +/* @@? 26:13 Error TypeError: Unresolved reference reanstructor */ +/* @@? 27:27 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 27:27 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 27:27 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 27:27 Error SyntaxError: Unexpected token '�ls'. */ +/* @@? 28:5 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 28:7 Error SyntaxError: Unexpected token '{'. */ +/* @@? 29:5 Error SyntaxError: Identifier expected, got 'constructor'. */ +/* @@? 29:19 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 30:18 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 32:2 Error SyntaxError: Unexpected token '*'. */ +/* @@? 33:1 Error SyntaxError: Nested functions are not allowed. */ +/* @@? 33:1 Error SyntaxError: Unexpected token 'function'. */ +/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/interface_parser_error_2.ets b/ets2panda/test/ast/parser/ets/interface_parser_error_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..bc6fdafb255e9d9312597951e21c00fa6b0074a1 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/interface_parser_error_2.ets @@ -0,0 +1,24 @@ +/** + * 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. + */ + +interface I { + : boolean +} + +/* @@? 17:5 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:7 Error SyntaxError: Identifier expected. */ +/* @@? 17:7 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:7 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:1 Error SyntaxError: Identifier expected. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/invalidTypes.ets b/ets2panda/test/ast/parser/ets/invalidTypes.ets index e67924adcbed0e40dd403ded873ed15729581491..276d27a280f2e44f04784445b96494c1663a1514 100644 --- a/ets2panda/test/ast/parser/ets/invalidTypes.ets +++ b/ets2panda/test/ast/parser/ets/invalidTypes.ets @@ -75,8 +75,8 @@ let var6: [a0: , a1: ]; /* @@? 30:18 Error SyntaxError: Unexpected token ':'. */ /* @@? 30:20 Error SyntaxError: Unexpected token '...'. */ /* @@? 30:20 Error SyntaxError: Unexpected token '...'. */ -/* @@? 30:23 Error TypeError: Unresolved reference int */ -/* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ +/* @@? 30:23 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 30:23 Error SyntaxError: Unexpected token 'int'. */ /* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token, expected ',' or ']'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_decorator_usage.ets b/ets2panda/test/ast/parser/ets/invalid_decorator_usage.ets new file mode 100644 index 0000000000000000000000000000000000000000..3299f8885389ef4d5a5c26439619ab6311c9b31b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_decorator_usage.ets @@ -0,0 +1,35 @@ +/* + * 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. + */ + +@ q.M function i ( this : ( this : @ e ( ) [ ] ) => ( @ V ( ) "" ) ) { } + +/* @@? 16:3 Error TypeError: Cannot find type 'q'. */ +/* @@? 16:5 Error TypeError: 'M' is not an annotation. */ +/* @@? 16:5 Error TypeError: 'M' type does not exist. */ +/* @@? 16:16 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 16:29 Error SyntaxError: Unexpected 'this' keyword in non-receiver context. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 16:44 Error SyntaxError: Invalid Type. */ +/* @@? 16:46 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 16:46 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:48 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:50 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 16:59 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 16:61 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:63 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 16:66 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:68 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_type.ets b/ets2panda/test/ast/parser/ets/invalid_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..36b08c0491a44c777dcbbfa168f921f647ed916e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_type.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +class Function extends Intl.DateTimeFormat{ +let RegExp = Intl.PluralRules +} + +/* @@? 1:3 Error TypeError: Variable 'Function' is already defined with different type. */ +/* @@? 17:1 Error SyntaxError: Unexpected token 'let'. */ +/* @@? 17:19 Error TypeError: Property 'PluralRules' does not exist on type 'Intl' */ diff --git a/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets b/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets new file mode 100644 index 0000000000000000000000000000000000000000..d270acffb05684b31d748822d4fb95c3509dcd62 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets @@ -0,0 +1,34 @@ +/* + * 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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + + type Point = { x: number; y: number }; + type AxeX = Point['x']; + +/* @@? 20:18 Error SyntaxError: Invalid Type. */ +/* @@? 20:23 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 20:23 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 20:34 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 20:34 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 21:23 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 21:23 Error SyntaxError: Unexpected token ']'. */ +/* @@? 21:23 Error SyntaxError: Unexpected token ']'. */ +/* @@? 21:23 Error SyntaxError: Unexpected token ']'. */ +/* @@? 21:23 Error SyntaxError: Unexpected token ']'. */ +/* @@? 21:26 Error SyntaxError: Unexpected token ']'. */ +/* @@? 21:26 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets b/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets index 13b37a95ce900f6219dc4bfa41873745877d56cb..b4952f183a6ea6613685d702d4608330a6ec312b 100644 --- a/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets +++ b/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets @@ -17,4 +17,8 @@ let a: int => void /* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ /* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ \ No newline at end of file +/* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/minus_sign_as_index_1.ets b/ets2panda/test/ast/parser/ets/minus_sign_as_index_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3f2ffefd8c24ff34159ecdcedadd356dcc3fc8d2 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/minus_sign_as_index_1.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024-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. + */ + +class URIError extends WebAssembly {WebAssembly : WeakMap [-6]} + +/* @@? 1:3 Error TypeError: Class 'URIError' is already defined. */ +/* @@? 16:24 Error TypeError: Cannot find type 'WebAssembly'. */ +/* @@? 16:24 Error TypeError: The super type of 'URIError' class is not extensible. */ +/* @@? 16:60 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 16:60 Error SyntaxError: Identifier expected. */ +/* @@? 16:60 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:61 Error SyntaxError: Unexpected token '6'. */ +/* @@? 16:62 Error SyntaxError: Unexpected token ']'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets b/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets index 5f618161da4f65d2d4a1fa5f607c449f83ba1541..b7ddfb7d672ad4072cb9c20ca2127ed9fdb61a7d 100644 --- a/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets +++ b/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets @@ -19,3 +19,5 @@ declare namespace MySpace{ /* @@? 17:10 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:10 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:10 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:11 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 17:11 Error SyntaxError: Unexpected token 'void'. */ diff --git a/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets b/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..b36e68e76effbfd270e363ae7267f223fdfb321c --- /dev/null +++ b/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024-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. + */ + + +func: readonly (Y : object | long [] ) => [ ] + +/* @@? 17:7 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:7 Error TypeError: Unresolved reference readonly */ +/* @@? 17:17 Error SyntaxError: Invalid Type. */ +/* @@? 17:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:20 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:20 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:20 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:22 Error TypeError: Type name 'object' used in the wrong context */ +/* @@? 17:22 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 17:39 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:39 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:39 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:42 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 17:42 Error SyntaxError: Unexpected token '=>'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_04.ets b/ets2panda/test/ast/parser/ets/rest_parameter_04.ets index 9b08f8851eec41b97e0df8b1c80e7815043f58c8..1e574c661ded0e6b86ffb5d2adc24d69bcd3de0a 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_04.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_04.ets @@ -19,5 +19,5 @@ function hehe(...items: number[]/* @@ label */: void /* @@ label1 */{ /* @@? 16:10 Error TypeError: Only abstract or native methods can't have body. */ /* @@? 16:47 Error SyntaxError: Rest parameter must be the last formal parameter. */ -/* @@? 16:49 Error TypeError: Unresolved reference void */ -/* @@? 16:69 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:49 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 16:49 Error SyntaxError: Unexpected token 'void'. */ diff --git a/ets2panda/test/ast/parser/ets/return_while_warning.ets b/ets2panda/test/ast/parser/ets/return_while_warning.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c9a15296e79a347f8dad57fdc18238f944c8f3f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/return_while_warning.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +function main(): void { + while (false) { + assertTrue( false ); + } +} + +/* @@? 17:19 Warning Warning: Unreachable statement. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/too_many_expression.ets b/ets2panda/test/ast/parser/ets/too_many_expression.ets new file mode 100644 index 0000000000000000000000000000000000000000..6b51d785426e8a069a4a9ce562edf78440ce24f6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/too_many_expression.ets @@ -0,0 +1,1042 @@ +/* + * 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. + */ + +(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + +/* @@? 16:1025 Error SyntaxError: Maximum allowed nesting level exceeded. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets index 3ab56c1963cb4e1fc2e97dcad20e3e2280aaedfa..efd161568ce1a49ade7948dc0034b2cc98aff744 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets @@ -24,4 +24,4 @@ function foo(): int { } } -/* @@@ label Error TypeError: Unreachable statement. */ +/* @@@ label Warning Warning: Unreachable statement. */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_6.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_6.ets index 307bae6833d9faa458a6784634afb5c96be8dc40..40fe55f8cca60b657f80b229a2c79d58cefbcd8f 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_6.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_6.ets @@ -25,5 +25,5 @@ function foo(): int { } -/* @@@ label1 Error TypeError: Unreachable statement. */ +/* @@@ label1 Warning Warning: Unreachable statement. */ /* @@@ label Warning Warning: Finally clause cannot complete normally */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_8.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_8.ets index 33824549a9b663fa5a949a70407d9cead2a7b4b9..356e8c5c6dabc7930c1b5fd9f1c877d78f240848 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_8.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_8.ets @@ -25,4 +25,4 @@ function foo(): int { } /* @@@ label Warning Warning: Finally clause cannot complete normally */ -/* @@@ label1 Error TypeError: Unreachable statement. */ +/* @@@ label1 Warning Warning: Unreachable statement. */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_9.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_9.ets index 8c4d938a5ac18df3a3f8e4ccb788f93a647b88ed..2b31a764f13361e147457cfa2745f52003d412e9 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_9.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_9.ets @@ -24,5 +24,5 @@ function foo(): int { } } -/* @@@ label Error TypeError: Unreachable statement. */ +/* @@@ label Warning Warning: Unreachable statement. */ /* @@@ label1 Warning Warning: Finally clause cannot complete normally */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_31.ets b/ets2panda/test/ast/parser/ets/unexpected_token_31.ets index 17af310ec18ff4c8a17b77c159ac81cdf242a030..3d6c57802d136ff181810d00a4d676d699e82929 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_31.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_31.ets @@ -25,8 +25,8 @@ function foo(...^number: int[]): int { /* @@? 16:31 Error SyntaxError: Unexpected token ')'. */ /* @@? 16:32 Error SyntaxError: Unexpected token ':'. */ /* @@? 16:32 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:34 Error TypeError: Unresolved reference int */ -/* @@? 16:38 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:34 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:34 Error SyntaxError: Unexpected token 'int'. */ /* @@? 17:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 17:12 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:12 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_36.ets b/ets2panda/test/ast/parser/ets/unexpected_token_36.ets index 453e5cd1e24eba1e03958c2459cea7b0776c6335..d9bc05814bdace6e19962dc2acde91403958f861 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_36.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_36.ets @@ -41,7 +41,9 @@ export class AccessNSieve { /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:16 Error TypeError: Unresolved reference int */ +/* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 29:20 Error SyntaxError: Unexpected token '='. */ /* @@? 29:25 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_62.ets b/ets2panda/test/ast/parser/ets/unexpected_token_62.ets new file mode 100644 index 0000000000000000000000000000000000000000..e4a3e105d136f21c9068e33b8a646f49e26d6cec --- /dev/null +++ b/ets2panda/test/ast/parser/ets/unexpected_token_62.ets @@ -0,0 +1,84 @@ +/* + * 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. + */ + +class A {} +class B extendsA {} + +functioew Nu +nt = 10 A {} + +functioew Nu +nt = 10 +)void {nt = 20, g: s A {} +int = 10 +) => B = (p:+): A6=> { reƒurn _ew B(ô } +|ó + +/* @@? 17:9 Error SyntaxError: Expected '{', got 'identification literal'. */ +/* @@? 17:18 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:1 Error TypeError: Unresolved reference functioew */ +/* @@? 19:11 Error SyntaxError: Unexpected token 'Nu'. */ +/* @@? 19:11 Error TypeError: Unresolved reference Nu */ +/* @@? 20:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 20:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 20:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 20:1 Error TypeError: Unresolved reference nt */ +/* @@? 20:10 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 20:10 Error TypeError: Class name 'A' used in the wrong context */ +/* @@? 20:12 Error SyntaxError: Unexpected token '{'. */ +/* @@? 22:11 Error SyntaxError: Unexpected token 'Nu'. */ +/* @@? 23:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 23:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 23:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 24:1 Error SyntaxError: Unexpected token ')'. */ +/* @@? 24:2 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 24:2 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 24:8 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 24:8 Error TypeError: Unresolved reference nt */ +/* @@? 24:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 24:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 24:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 24:21 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 24:21 Error TypeError: Unresolved reference s */ +/* @@? 24:23 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 24:23 Error TypeError: Class name 'A' used in the wrong context */ +/* @@? 24:25 Error SyntaxError: Unexpected token '{'. */ +/* @@? 25:1 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 25:5 Error SyntaxError: Unexpected token '='. */ +/* @@? 26:1 Error SyntaxError: Unexpected token ')'. */ +/* @@? 26:3 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 26:3 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 26:13 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 26:13 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 26:13 Error TypeError: Cannot find type ''. */ +/* @@? 26:14 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 26:14 Error SyntaxError: Expected '=>', got '+'. */ +/* @@? 26:15 Error SyntaxError: Unexpected token ')'. */ +/* @@? 26:15 Error SyntaxError: Unexpected token ')'. */ +/* @@? 26:15 Error SyntaxError: Unexpected token ')'. */ +/* @@? 26:15 Error SyntaxError: Unexpected token ')'. */ +/* @@? 26:16 Error SyntaxError: Unexpected token ':'. */ +/* @@? 26:16 Error SyntaxError: Unexpected token ':'. */ +/* @@? 26:18 Error TypeError: The type of parameter 'A6' cannot be inferred */ +/* @@? 26:18 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 26:25 Error TypeError: Unresolved reference reƒurn */ +/* @@? 26:32 Error SyntaxError: Unexpected token '_ew'. */ +/* @@? 26:32 Error TypeError: Unresolved reference _ew */ +/* @@? 26:36 Error SyntaxError: Unexpected token 'B'. */ +/* @@? 26:36 Error TypeError: No static $_invoke method and static $_instantiate method in B. B() is not allowed. */ +/* @@? 26:36 Error TypeError: Type 'B' has no call signatures. */ +/* @@? 26:40 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 27:2 Error TypeError: Unresolved reference ó */ +/* @@? 85:1 Error SyntaxError: Expected '}', got 'eos'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_63.ets b/ets2panda/test/ast/parser/ets/unexpected_token_63.ets new file mode 100644 index 0000000000000000000000000000000000000000..833cf39392af4e1f38e1c0aec5594b1c876f67c9 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/unexpected_token_63.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. + */ + +class A { + func1(list : number, final : number) { + while(true) { + if(false) { + break; + } else { + let endSequence = false + this.func(list, final, endSequence) + } + } + } +} + +/* @@? 17:7 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:23 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:23 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:23 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 17:29 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:31 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ +/* @@? 17:37 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:37 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:39 Error SyntaxError: Unexpected token '{'. */ +/* @@? 18:3 Error SyntaxError: Unexpected token 'while'. */ +/* @@? 18:8 Error SyntaxError: Unexpected token '('. */ +/* @@? 18:9 Error SyntaxError: Unexpected token 'true'. */ +/* @@? 18:13 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:15 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:4 Error SyntaxError: Unexpected token 'if'. */ +/* @@? 19:6 Error SyntaxError: Unexpected token '('. */ +/* @@? 19:7 Error SyntaxError: Unexpected token 'false'. */ +/* @@? 19:12 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:14 Error SyntaxError: Unexpected token '{'. */ +/* @@? 20:5 Error SyntaxError: Unexpected token 'break'. */ +/* @@? 21:6 Error SyntaxError: Unexpected token 'else'. */ +/* @@? 21:6 Error SyntaxError: Unexpected token 'else'. */ +/* @@? 23:5 Error TypeError: Cannot reference 'this' in this context. */ +/* @@? 23:10 Error TypeError: Property 'func' does not exist on type 'Error' */ +/* @@? 23:21 Error SyntaxError: Unexpected token 'final'. */ +/* @@? 23:21 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 23:21 Error SyntaxError: Unexpected token 'final'. */ +/* @@? 23:39 Error SyntaxError: Expected '{', got ')'. */ +/* @@? 26:2 Error SyntaxError: Unexpected token '}'. */ +/* @@? 27:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets b/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..94b7879b28bc998a71ef37e9ca09723de8e90e8b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets @@ -0,0 +1,30 @@ +/* + * 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. + */ + + let x = z.meth(foo) + +{ + assert(y[0] == 1) + assert(y[1] == 2) + +classtext: string, reviver: ((key: string, value: NullishType) => NullishType) | undefined, type: Type + +/* @@? 16:13 Error TypeError: Unresolved reference z */ +/* @@? 22:12 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 22:18 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:29 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 22:91 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:99 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 30:60 Error SyntaxError: Expected '}', got 'eos'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/user_defined_5.ets b/ets2panda/test/ast/parser/ets/user_defined_5.ets index bfd46c9f78414948cf25721b2c610fc685748f6f..bdf44a3c52233139d5dfcb3a16e90824bcb0b80b 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_5.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_5.ets @@ -17,4 +17,5 @@ enum /* @@ label */double { A, B, C } -/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ +/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ +/* @@@ label Error SyntaxError: Identifier expected, got 'double'. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_7.ets b/ets2panda/test/ast/parser/ets/user_defined_7.ets index d6f9dc12f8a1a961df4f604d6ada9da3613eab36..67c6eec0952f3d56ce21ecaac8914f1f39d2f4bc 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_7.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_7.ets @@ -18,6 +18,7 @@ interface /* @@ label1 */double { /* @@ label4 */} /* @@@ label1 Error SyntaxError: Cannot be used as user-defined type. */ +/* @@@ label1 Error SyntaxError: Identifier expected, got 'double'. */ /* @@@ label2 Error SyntaxError: Interface member initialization is prohibited. */ /* @@@ label3 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 17:51 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ diff --git a/ets2panda/test/parser/ets/interfaces-expected.txt b/ets2panda/test/parser/ets/interfaces-expected.txt index 2a1b0fcc2742b23c87f1f98db17eb1964b5ba274..020f98c54cc57d5318c6330c263cb614cff1e719 100644 --- a/ets2panda/test/parser/ets/interfaces-expected.txt +++ b/ets2panda/test/parser/ets/interfaces-expected.txt @@ -739,7 +739,7 @@ "loc": { "start": { "line": 22, - "column": 3, + "column": 11, "program": "interfaces.ets" }, "end": { @@ -1204,7 +1204,7 @@ "program": "interfaces.ets" }, "end": { - "line": 29, + "line": 31, "column": 1, "program": "interfaces.ets" } @@ -1480,7 +1480,7 @@ "program": "interfaces.ets" }, "end": { - "line": 29, + "line": 31, "column": 1, "program": "interfaces.ets" } diff --git a/ets2panda/test/parser/ets/interfaces.ets b/ets2panda/test/parser/ets/interfaces.ets index 4d9b87c7a08f5c7ce723174ed586c17c0e3131ba..e6ff2c2e03c8837850aab5225fdd798cd2fbac5b 100644 --- a/ets2panda/test/parser/ets/interfaces.ets +++ b/ets2panda/test/parser/ets/interfaces.ets @@ -26,3 +26,5 @@ interface I0 { interface I1 extends I, I0 { } + +/* @@? 22:28 Error TypeError: 'nopnop' is an instance property of 'I0' */ diff --git a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt index e8ff142dfab12c9d126c16cfe673bec65e76d4c4..2203a5146a498ba93346a9bcdc120d7fc3c8d873 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt @@ -1643,4 +1643,3 @@ } } } -TypeError: Reference to foo is ambiguous [lambda-type-inference-overloaded.ets:28:5] diff --git a/ets2panda/test/parser/ets/test_interface-expected.txt b/ets2panda/test/parser/ets/test_interface-expected.txt index 468b94076038216538ee715eda95625a123bbfbc..2661e891fd69f197dac43538d730edfe621ab39c 100644 --- a/ets2panda/test/parser/ets/test_interface-expected.txt +++ b/ets2panda/test/parser/ets/test_interface-expected.txt @@ -913,7 +913,7 @@ "loc": { "start": { "line": 24, - "column": 5, + "column": 13, "program": "test_interface.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/user_defined_1-expected.txt b/ets2panda/test/parser/ets/user_defined_1-expected.txt deleted file mode 100644 index f8859d89fcdcd7b400f0d77e627c755d6970de29..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/user_defined_1-expected.txt +++ /dev/null @@ -1,766 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_1.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_1.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_1.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_1.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "float", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 17, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 24, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 14, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 17, - "column": 27, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 32, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 32, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 33, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "double", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 18, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 25, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 15, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 18, - "column": 28, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 33, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 33, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 34, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "byte", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 16, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 23, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 13, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 19, - "column": 26, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 31, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 31, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 32, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "short", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 17, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 24, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 14, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 20, - "column": 27, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 32, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 32, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 33, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "int", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 15, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 22, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 12, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 21, - "column": 25, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 30, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 30, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 21, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 31, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "char", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 22, - "column": 16, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 23, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 13, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 22, - "column": 26, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 31, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 31, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 32, - "program": "user_defined_1.ets" - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 17, - "program": "user_defined_1.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_1.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_1.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "user_defined_1.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "user_defined_1.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 25, - "column": 1, - "program": "user_defined_1.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/user_defined_2-expected.txt b/ets2panda/test/parser/ets/user_defined_2-expected.txt deleted file mode 100644 index bbf7d8f4791534b097f7e6dd90eeabf898735d65..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/user_defined_2-expected.txt +++ /dev/null @@ -1,808 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_2.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_2.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_2.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_2.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "float", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 17, - "program": "user_defined_2.ets" - }, - "end": { - "line": 17, - "column": 22, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 17, - "column": 14, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 17, - "column": 14, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 17, - "column": 23, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "boolean", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 19, - "program": "user_defined_2.ets" - }, - "end": { - "line": 18, - "column": 26, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 18, - "column": 16, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 18, - "column": 16, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 18, - "column": 27, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "double", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 18, - "program": "user_defined_2.ets" - }, - "end": { - "line": 19, - "column": 24, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 19, - "column": 15, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 19, - "column": 15, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 19, - "column": 25, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "byte", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 16, - "program": "user_defined_2.ets" - }, - "end": { - "line": 20, - "column": 20, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 20, - "column": 13, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 20, - "column": 13, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 20, - "column": 21, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "short", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 17, - "program": "user_defined_2.ets" - }, - "end": { - "line": 21, - "column": 22, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 21, - "column": 14, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 21, - "column": 14, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 21, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 21, - "column": 23, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "int", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 22, - "column": 15, - "program": "user_defined_2.ets" - }, - "end": { - "line": 22, - "column": 18, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 22, - "column": 12, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 22, - "column": 12, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 22, - "column": 19, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "char", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 16, - "program": "user_defined_2.ets" - }, - "end": { - "line": 23, - "column": 20, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 23, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 23, - "column": 21, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "long", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 24, - "column": 16, - "program": "user_defined_2.ets" - }, - "end": { - "line": 24, - "column": 20, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 24, - "column": 13, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 24, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 24, - "column": 13, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 24, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 24, - "column": 21, - "program": "user_defined_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 17, - "program": "user_defined_2.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "user_defined_2.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_2.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "user_defined_2.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_2.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "user_defined_2.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "user_defined_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 26, - "column": 1, - "program": "user_defined_2.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/user_defined_3-expected.txt b/ets2panda/test/parser/ets/user_defined_3-expected.txt deleted file mode 100644 index 858f5aa77784299bb74db0495dad36baebd4c916..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/user_defined_3-expected.txt +++ /dev/null @@ -1,1248 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "float", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 16, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 16, - "column": 22, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "boolean", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 17, - "column": 16, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 19, - "program": "user_defined_3.ets" - }, - "end": { - "line": 17, - "column": 26, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 17, - "column": 16, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "double", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 18, - "column": 15, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 18, - "program": "user_defined_3.ets" - }, - "end": { - "line": 18, - "column": 24, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 18, - "column": 15, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "byte", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 19, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 19, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 19, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "short", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 20, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 20, - "column": 22, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 20, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "int", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 21, - "column": 12, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 15, - "program": "user_defined_3.ets" - }, - "end": { - "line": 21, - "column": 18, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 21, - "column": 12, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "char", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 22, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 22, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 22, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 22, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "long", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 23, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "user_defined_3.ets" - }, - "end": { - "line": 25, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "user_defined_3.ets" - }, - "end": { - "line": 25, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "float", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 26, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 26, - "column": 22, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 26, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 26, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 26, - "column": 14, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 26, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 26, - "column": 23, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "boolean", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 27, - "column": 19, - "program": "user_defined_3.ets" - }, - "end": { - "line": 27, - "column": 26, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 27, - "column": 16, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 27, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 27, - "column": 16, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 27, - "column": 27, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "double", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 28, - "column": 18, - "program": "user_defined_3.ets" - }, - "end": { - "line": 28, - "column": 24, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 28, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 28, - "column": 15, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 28, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 28, - "column": 15, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 28, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 28, - "column": 25, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "byte", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 29, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 29, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 29, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 29, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 29, - "column": 13, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 29, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 29, - "column": 21, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "short", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 30, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 30, - "column": 22, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 30, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 30, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 30, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 30, - "column": 14, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 30, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 30, - "column": 23, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "int", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 31, - "column": 15, - "program": "user_defined_3.ets" - }, - "end": { - "line": 31, - "column": 18, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 31, - "column": 12, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 31, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 31, - "column": 12, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 31, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 31, - "column": 19, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "char", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 32, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 32, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 32, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 32, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 32, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 32, - "column": 13, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 32, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 32, - "column": 21, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "long", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 33, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 33, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 33, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 33, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 33, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 33, - "column": 13, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 33, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 33, - "column": 21, - "program": "user_defined_3.ets" - } - } - } - ], - "loc": { - "start": { - "line": 25, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 34, - "column": 2, - "program": "user_defined_3.ets" - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "user_defined_3.ets" - }, - "end": { - "line": 34, - "column": 2, - "program": "user_defined_3.ets" - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "user_defined_3.ets" - }, - "end": { - "line": 34, - "column": 2, - "program": "user_defined_3.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 34, - "column": 2, - "program": "user_defined_3.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 35, - "column": 1, - "program": "user_defined_3.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/user_defined_6-expected.txt b/ets2panda/test/parser/ets/user_defined_6-expected.txt deleted file mode 100644 index 8d2467b61a27377e06a3f3325a796a6bb9422f73..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/user_defined_6-expected.txt +++ /dev/null @@ -1,385 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "float", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_6.ets" - }, - "end": { - "line": 16, - "column": 15, - "program": "user_defined_6.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "float", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_6.ets" - }, - "end": { - "line": 16, - "column": 15, - "program": "user_defined_6.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 16, - "column": 18, - "program": "user_defined_6.ets" - }, - "end": { - "line": 17, - "column": 2, - "program": "user_defined_6.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_6.ets" - }, - "end": { - "line": 17, - "column": 2, - "program": "user_defined_6.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_6.ets" - }, - "end": { - "line": 17, - "column": 2, - "program": "user_defined_6.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 17, - "column": 2, - "program": "user_defined_6.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 18, - "column": 1, - "program": "user_defined_6.ets" - } - } -} diff --git a/ets2panda/test/runtime/ets/accessor_functional_declaration.ets b/ets2panda/test/runtime/ets/accessor_functional_declaration.ets new file mode 100644 index 0000000000000000000000000000000000000000..acee9091004e39af702f239eac147f6eeee48ff7 --- /dev/null +++ b/ets2panda/test/runtime/ets/accessor_functional_declaration.ets @@ -0,0 +1,32 @@ +/* + * 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. + */ + +class A{ + a_:()=>void = ()=>{}; + get a(){ + return this.a_; + } + set a(a:()=>void){ + this.a_ = a + } + method(){ + this.a + this.a() + } +} +function main(){ + let a = new A(); + a.method() +} diff --git a/ets2panda/test/runtime/ets/await_promise_union_type.ets b/ets2panda/test/runtime/ets/await_promise_union_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4529432ca8b9210da1821429e62cb41321ffb4e --- /dev/null +++ b/ets2panda/test/runtime/ets/await_promise_union_type.ets @@ -0,0 +1,33 @@ +/* + * 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. + */ + +class Person{ + name:string; + fetchData?:()=>Promise; + constructor(name:string){ + this.name = name; + } +} + +async function foo():Promise{ +const bob = new Person("Bob"); +const resultPromise = bob.fetchData?.()??Promise.resolve(undefined); +const result = await resultPromise; +assertEQ(result,undefined); +} + +function main():void{ + foo(); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/class-fields-same-name.ets b/ets2panda/test/runtime/ets/class-fields-same-name.ets index 82ae8aa38c181fcb5940a2ae2af7bf5875aedd6f..c556135949d9df2ba741884e4d13dab7bc694cea 100644 --- a/ets2panda/test/runtime/ets/class-fields-same-name.ets +++ b/ets2panda/test/runtime/ets/class-fields-same-name.ets @@ -23,9 +23,29 @@ class D extends C { public foo: int = 40 } +class E { + public static foo: int = 50 +} + +class F extends E { + public foo: int = 60 +} + +class G { + public foo: int = 70 +} + +class H extends G { + public static foo: int = 80 +} + function main(): void { assertEQ(C.foo, 10) assertEQ(new C().foo, 20) assertEQ(D.foo, 30) assertEQ(new D().foo, 40) + assertEQ(F.foo, 50) + assertEQ(new F().foo, 60) + assertEQ(H.foo, 80) + assertEQ(new H().foo, 70) } diff --git a/ets2panda/test/runtime/ets/define_var_test.ets b/ets2panda/test/runtime/ets/define_var_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..4de85c7aa4bf06c62d21da92b4cde318aa5b2728 --- /dev/null +++ b/ets2panda/test/runtime/ets/define_var_test.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ + +function main() { + let Infinity: number = Double.POSITIVE_INFINITY; + let NaN: number; + assertEQ(Infinity, Double.POSITIVE_INFINITY); + assertEQ(NaN, 0); +} diff --git a/ets2panda/test/runtime/ets/enum-initialize-with-enum3.ets b/ets2panda/test/runtime/ets/enum-initialize-with-enum3.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d263d01ebaec54979373dab71c4b59066cd81d8 --- /dev/null +++ b/ets2panda/test/runtime/ets/enum-initialize-with-enum3.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +namespace NS { + export enum E { + B = 4, + C = B + 1 + } +} +enum F { + R = 1 << 1, + W = 1 << 2, + O = NS.E.C +} + +assertEQ(F.O.valueOf(), 5) diff --git a/ets2panda/test/runtime/ets/enum-initialize-with-itself.ets b/ets2panda/test/runtime/ets/enum-initialize-with-itself.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c116a0eb25f354c69878a75743a6822e5bfb545 --- /dev/null +++ b/ets2panda/test/runtime/ets/enum-initialize-with-itself.ets @@ -0,0 +1,31 @@ +/* + * 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. + */ + +enum FileAccess { + None, + Read = 1 << 1, + Write = 1 << 2, + ReadWrite = Read | Write +} + +enum FileAccess2 { + None, + Read = 1 << 1, + Write = 1 << 2, + ReadWrite = Read +} + +assertEQ(FileAccess.ReadWrite.valueOf(), 6) +assertEQ(FileAccess2.ReadWrite.valueOf(), 2) \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/enum_as_key_of_record.ets b/ets2panda/test/runtime/ets/enum_as_key_of_record.ets new file mode 100644 index 0000000000000000000000000000000000000000..93d19bb9f681e4ddcdfa5e5659e6c11d1b7c248e --- /dev/null +++ b/ets2panda/test/runtime/ets/enum_as_key_of_record.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + + + enum StringEnum { + up = "1" + } + + enum IntEnum { + up = 1 + } + + +function foo(val1:Record, val2:Record){ + +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/function_assignable.ets b/ets2panda/test/runtime/ets/function_assignable.ets new file mode 100644 index 0000000000000000000000000000000000000000..80a1638485e1d983efb02683d170a0ba5a14e49a --- /dev/null +++ b/ets2panda/test/runtime/ets/function_assignable.ets @@ -0,0 +1,68 @@ +/* + * 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. + */ + +function ccc(): string { + return "function ccc" +} + +let foo: () => string = () => { return "lambda foo" } + +interface AAAOp { + aa?: () => string +} + +class A { + _aa?: () => string + get aa(): () => string { + return this._aa!; + } + set aa(value: () => string) { + this._aa = value; + } + _init1(it?: AAAOp) { + this._aa = it?.aa ?? ccc; + } + _init2(it?: AAAOp) { + this.aa = it?.aa ?? ccc; + } + _init3() { + this._aa = foo ?? ccc; + } + _init4() { + this.aa = ccc ?? foo; + } + _init5(it?: AAAOp) { + this._aa = it == undefined ? ccc:it.aa; + } + _init6(it?: AAAOp) { + this._aa = it?.aa || ccc; + } +} + +function main(){ + let a = new A(); + a._init1() + assertEQ(a.aa(),"function ccc") + a._init2() + assertEQ(a.aa(),"function ccc") + a._init3() + assertEQ(a.aa(),"lambda foo") + a._init4() + assertEQ(a.aa(),"function ccc") + a._init5() + assertEQ(a.aa(),"function ccc") + a._init6() + assertEQ(a.aa(),"function ccc") +} diff --git a/ets2panda/test/runtime/ets/generic_union.ets b/ets2panda/test/runtime/ets/generic_union.ets new file mode 100644 index 0000000000000000000000000000000000000000..08d2e6444888d0938e6c678de0899e99a6f75423 --- /dev/null +++ b/ets2panda/test/runtime/ets/generic_union.ets @@ -0,0 +1,36 @@ +/* + * 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. + */ + +class A { + foo(a : int){} + foo() { + return 1 + } +} + +class B { + foo(a : int){} + foo() { + return 2 + } +} +type AAA = A | B +function foo(a : T) { + return a.foo() +} +function main() { + assertEQ(foo(new A()), 1) + assertEQ(foo(new B()), 2) +} diff --git a/ets2panda/test/runtime/ets/inferTypeLambda_14.ets b/ets2panda/test/runtime/ets/inferTypeLambda_14.ets new file mode 100644 index 0000000000000000000000000000000000000000..0dfd8932a1d92cf80eefc4f5a0fb95cef58fcf85 --- /dev/null +++ b/ets2panda/test/runtime/ets/inferTypeLambda_14.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ +function foo(arr:FixedArray, f:(a:FixedArray)=>string){ + return f(arr) +} + +function bar(arr:FixedArray){ + return foo(arr, a=>a.toString()) +} + +function main(){ + assertTrue(bar([1,2,3,4]) == "1,2,3,4") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/interface_objliteral.ets b/ets2panda/test/runtime/ets/interface_objliteral.ets new file mode 100644 index 0000000000000000000000000000000000000000..821f013ac73f6c7fbf4e03e2aacc691d8a1798db --- /dev/null +++ b/ets2panda/test/runtime/ets/interface_objliteral.ets @@ -0,0 +1,34 @@ +/* + * 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. + */ + +interface InterfaceA { + propA: string +} +interface InterfaceAA extends InterfaceA {} + +interface InterfaceB { + propB: number; +} +interface ParentInterface extends InterfaceA, InterfaceB {} +interface ChildInterface extends ParentInterface {} + +function main() { + const obj: ChildInterface = { + propA: "Hello", + propB: 42 + } + assertEQ(obj.propA, "Hello") + assertEQ(obj.propB, 42) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/lambda_call_base.ets b/ets2panda/test/runtime/ets/lambda_call_base.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a34d3f2445c9dae3b11315d54e280636e1a13d3 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_call_base.ets @@ -0,0 +1,31 @@ +/* + * 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. + */ + +class MyDate { + public getFullYear(): int { + return 20; + } +} + +class DateC extends MyDate { + bigY() { + let x = this.getFullYear + return x(); + } +} + +function main() { + assertEQ(new DateC().bigY(), 20) +} diff --git a/ets2panda/test/runtime/ets/opAssignmentWithUpdateExpression.ets b/ets2panda/test/runtime/ets/opAssignmentWithUpdateExpression.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ee3133e77e90563b4f4f8a4e198ac55c076fb2f --- /dev/null +++ b/ets2panda/test/runtime/ets/opAssignmentWithUpdateExpression.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + +let line = 0; +let pixelOffset = 0; +let weight = 1; +let output = new Array(1, 2, 3, 4); +let buffer = new Array(5, 6, 7, 8); +output[line++] += buffer[pixelOffset]; +assertEQ(line, 1); +assertEQ(output[0], 6); diff --git a/ets2panda/test/runtime/ets/signature_match_lambda.ets b/ets2panda/test/runtime/ets/signature_match_lambda.ets new file mode 100644 index 0000000000000000000000000000000000000000..54f38746a30030549843dd83dc28ed9c6756a518 --- /dev/null +++ b/ets2panda/test/runtime/ets/signature_match_lambda.ets @@ -0,0 +1,42 @@ +/* + * 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. + */ + +class A { + catch(onRejected: () => U | PromiseLike): string { + onRejected() + return "first catch is matched" + } + catch(onRejected: (error: Error) => U | PromiseLike): string { + onRejected(new Error()) + return "second catch is matched" + } + catch(onRejected: (a: Error, b: Error) => U | PromiseLike): string { + onRejected(new Error(), new Error()) + return "third catch is matched" + } + catch(onRejected: (a: Error, b: Error, c: Error) => U | PromiseLike): string { + onRejected(new Error(), new Error(), new Error()) + return "fourth catch is matched" + } +} + +function main(){ + let a = new A() + assertEQ(a.catch(()=>{}),"first catch is matched") + assertEQ(a.catch((e:Error|undefined|null)=>{}),"second catch is matched") + assertEQ(a.catch((e:Error)=>{}),"second catch is matched") + assertEQ(a.catch((e:Error,e2:Error)=>{}),"third catch is matched") + assertEQ(a.catch((e:Error,e2:Error,e3:Error)=>{}),"fourth catch is matched") +} diff --git a/ets2panda/test/runtime/ets/tuple_union.ets b/ets2panda/test/runtime/ets/tuple_union.ets new file mode 100644 index 0000000000000000000000000000000000000000..5864a616353e95ceec4830c8f23120341e241c38 --- /dev/null +++ b/ets2panda/test/runtime/ets/tuple_union.ets @@ -0,0 +1,18 @@ +/* + * 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. + */ + + +let v: [string]|null = ["A"] + diff --git a/ets2panda/test/runtime/ets/type_param_infer_in_union_1.ets b/ets2panda/test/runtime/ets/type_param_infer_in_union_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..95a6a06e5076dd925ad69b459c7daf32cab884b2 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_param_infer_in_union_1.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +class A{} +function foo1(array:Iterable|U>){ + return "foo1 should be ok" +} +function foo2(array:Iterable>){ + return "foo2 should be ok too" +} + +function main(){ + let a = new Array(1,2,3) + assertEQ(foo1(a), "foo1 should be ok") + assertEQ(foo2(a), "foo2 should be ok too") +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ts_decorator.ets b/ets2panda/test/runtime/ets/type_param_infer_in_union_2.ets similarity index 65% rename from ets2panda/linter/test/interop/ts_decorator.ets rename to ets2panda/test/runtime/ets/type_param_infer_in_union_2.ets index 8ce1c11817408d298182c7cf8160fe8100d3aa98..487dfda9d383f2b60890b682f3a2c4d54ab9290b 100644 --- a/ets2panda/linter/test/interop/ts_decorator.ets +++ b/ets2panda/test/runtime/ets/type_param_infer_in_union_2.ets @@ -13,22 +13,17 @@ * limitations under the License. */ -import {MyClassDecorator, MyClassDecorator2} from "./oh_modules/ts_decorator" -import { MyDecorator } from "./oh_modules/ets_decorator"; +class A { } +class B { } -@MyClassDecorator -class K {} - -@Entry //legal -class X {} - -@MyDecorator //legal -class Y {} +function testNested(data: A> | U): string { + return "nested passed"; +} -@MyClassDecorator2 -class Z {} +function main() { + const validInput: A> = new A>(); + assertEQ(testNested(validInput), "nested passed"); -class Example { - @MyClassDecorator2 //legal - doSomething() {} -} + const validValue = 42; + assertEQ(testNested(validValue), "nested passed"); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_param_infer_in_union_3.ets b/ets2panda/test/runtime/ets/type_param_infer_in_union_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..ced320a63b31f2d8ce232583ce034b05953224a6 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_param_infer_in_union_3.ets @@ -0,0 +1,31 @@ +/* + * 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. + */ + +class A { } + +function testConstraints(arg: A | U[] | U): string { + return "constraints passed"; +} + +function main() { + const valid1: A = new A(); + assertEQ(testConstraints(valid1), "constraints passed"); + + const valid2 = ["text"]; + assertEQ(testConstraints(valid2), "constraints passed"); + + const valid3 = "text"; + assertEQ(testConstraints(valid3), "constraints passed"); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/union_call.ets b/ets2panda/test/runtime/ets/union_call.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb39f1e81360872ec65c46c2e498b70011e24298 --- /dev/null +++ b/ets2panda/test/runtime/ets/union_call.ets @@ -0,0 +1,34 @@ +/* + * 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. + */ + +class A { + foo() { + return 1 + } +} + +final class B { + foo() { + return 2 + } +} +type AAA = A | B +function foo(a : AAA) { + return a.foo() +} +function main() { + assertEQ(foo(new A()), 1) + assertEQ(foo(new B()), 2) +} diff --git a/ets2panda/test/runtime/ets/unreachable.ets b/ets2panda/test/runtime/ets/unreachable.ets new file mode 100644 index 0000000000000000000000000000000000000000..3415a066c53d5fddeccdeff225b77117ebfc49b3 --- /dev/null +++ b/ets2panda/test/runtime/ets/unreachable.ets @@ -0,0 +1,36 @@ +/* + * 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. + */ + +function SwitchTest(value:int){ + let result = 0; + switch(value) { + case 0: + switch(value) { + case 0: + result += 3; + break; + default: + result += 32; + break; + } + result *= 2; + break; + result=3; + default: + result += 32; + break; + } + return result; +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/user_defined_1.ets b/ets2panda/test/runtime/ets/user_defined_1.ets index 3052f4066b5c0acc5e17929fd39b80c1efb7a555..e6371f450b30d2abbe993e52c203d8ff0c2216f6 100644 --- a/ets2panda/test/runtime/ets/user_defined_1.ets +++ b/ets2panda/test/runtime/ets/user_defined_1.ets @@ -20,11 +20,8 @@ class B { a: boolean; } -let boolean: int = 3; - let x: B = new B(true); function main() { assertEQ(x.a, true) - assertEQ(boolean, 3) } diff --git a/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt b/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt index c2369f6c0051145add41f1871525ccf675579980..ada93aefcffc3f547e92a79f385abb78c84df36f 100644 --- a/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt +++ b/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt @@ -7,38 +7,18 @@ funcRefWithRestArguments.ets struct-identifier.ets struct-init2.ets type_param_in_union.ets -#FailKind.TSC_FAIL - 34 tests: +#FailKind.TSC_FAIL - 14 tests: ClassNewInstance.ets Enum7.ets GenericBridges_01.ets GenericBridges_02.ets -InterfacePrivateMethod.ets +InterfaceWithDefaultFunction1.ets RecordKeyTypeCheck.ets -classGetterSetter.ets -class_implements_interface.ets function_type_with_receiver/validReturnThisOfExtensionFunction.ets generic_constraint_implicit.ets generics_1.ets -getteSetterImplementation.ets -getterSetterImplementationWithConstructor.ets -implementClassPropertyFunctionOptionCall.ets -implementsClassPropertyFunctionType.ets -implementsClassPropertyFunctionType2.ets -implementsClassPropertyUnionType1.ets -implementsClassPropertyUnionType2.ets -import_self_head_tests/A/test.ets -inherited_getter_setter_implementation_1.ets -inherited_getter_setter_implementation_2.ets -interfacePropertyTypeAnnotationWithParameter.ets -interface_prop.ets -interface_with_optional_property_cycle_import/class_file.ets lambda_with_receiver/lambda_with_receiver_generics_return_this_rotate.ets lambda_with_receiver/lambda_with_receiver_return_this3.ets lambda_with_receiver/lambda_with_receiver_trailing_in_function_return_this_rotate.ets -multiple_inheritance.ets -multiple_inheritance_2.ets -override_for_partial_02.ets -readonly_simple_form_pos.ets -simple_form_pos.ets static-invoke.ets top_level_03.ets diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index ed76e9c73b6951a8779e7e44bc463cc44da1d3e1..66c523e6466deda179642affbebbee12be200646 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -95,3 +95,6 @@ override_for_partial_01.ets #HEAD FILE NO NEED TO RUN import_self_head_tests/B/test.d.ets + +#Issue 25550 +enum-initialize-with-enum3.ets diff --git a/ets2panda/test/test-lists/recheck/recheck-ignored.txt b/ets2panda/test/test-lists/recheck/recheck-ignored.txt index 408ac1b5b35077a3d8c57eb7132be4c61bff1659..b860b7bb00ad1de7fa4d48e1f96d0affc93bad73 100644 --- a/ets2panda/test/test-lists/recheck/recheck-ignored.txt +++ b/ets2panda/test/test-lists/recheck/recheck-ignored.txt @@ -2,6 +2,7 @@ # Negative tests that are ignored ast/parser/ets/import_tests/export_and_import_class.ets ast/parser/ets/import_tests/export_and_import_top_level.ets +ast/parser/ets/too_many_expression.ets compiler/ets/ConditionalExpressionCallVoidNeg.ets compiler/ets/abstractNewClassInstanceExpression.ets compiler/ets/dynamic_instanceof_error.ets @@ -131,6 +132,7 @@ ast/parser/ets/for_of_02.ets ast/parser/ets/method_modifier_check_3.ets ast/parser/ets/unexpected_token_31.ets ast/parser/ets/array_2.ets +ast/parser/ets/invalid_type.ets ast/parser/ets/visible_signatures_1.ets ast/parser/multierror_switchcases.ets ast/parser/ets/method_modifier_check_9.ets @@ -152,6 +154,7 @@ ast/parser/ets/StructTest3.ets ast/parser/ets/trailing_comma_1.ets ast/parser/ets/invalid_access_static.ets ast/parser/ets/interfaces2.ets +ast/parser/ets/for_with_empty_body.ets ast/parser/ets/generics_type_param_no_typeargs_no_default_2.ets ast/parser/ets/namespace_badtoken04.ets ast/parser/ets/InvalidStatements1.ets @@ -284,6 +287,7 @@ ast/parser/ets/string_literal_const_cast.ets ast/parser/ets/InvalidClasses.ets ast/parser/ets/interfaceExtendInterfaces1.ets ast/parser/ets/method_modifier_check_17.ets +ast/parser/ets/invalid_decorator_usage.ets ast/parser/ets/operator_logical_and_euqal.ets ast/parser/ets/ambient_indexer_5.ets ast/parser/ets/declare_class_bad_2.ets @@ -303,6 +307,7 @@ ast/parser/ets/empty_launch.ets ast/parser/ets/increment-on-nullish-type-undefined.ets ast/parser/ets/generics_type_param_no_typeargs_no_default.ets ast/parser/ets/lambda_infer_type_neg_1.ets +ast/parser/ets/readonlyFunctionTypeAnnotation.ets ast/parser/ets/readonlyGetterSetterReassignment1.ets ast/parser/ets/interface_instantiation.ets ast/parser/ets/Dollar_doller_invalid2.ets @@ -438,6 +443,7 @@ ast/parser/ets/class-instance-field-redeclaration.ets ast/parser/ets/enum11.ets ast/parser/ets/user_defined_11.ets ast/parser/ets/InvalidTyped.ets +ast/parser/ets/invalid_type_assignment.ets ast/parser/ets/DeclareAsyncFunction.ets ast/parser/ets/unexpected_token_1.ets ast/parser/ets/InvalidStatements3.ets @@ -631,8 +637,16 @@ ast/parser/ets/method_modifier_check_15.ets ast/parser/ets/user_defined_16.ets ast/parser/ets/enum_default_invalid_value_type.ets ast/parser/ets/struct_implements_interface.ets +ast/parser/ets/constructor_type_inference_crash.ets ast/parser/ets/wrong_context_function_1.ets +ast/parser/ets/empty_array_map_inference_fail.ets ast/parser/ets/illegal_continue_statement.ets +ast/parser/ets/minus_sign_as_index_1.ets +ast/parser/ets/export_after_statement.ets +ast/parser/ets/unreachable_fuzz_error.ets +ast/parser/ets/unreachable_fuzz_error.ets +ast/parser/ets/interface_parser_error_1.ets +ast/parser/ets/interface_parser_error_2.ets ast/compiler/ets/union_string_literals_5.ets ast/compiler/ets/annotation_tests/annotation_for_type_parameter01.ets ast/compiler/ets/readonlyType_4.ets @@ -1464,4 +1478,4 @@ runtime/ets/objectLiteral-2.ets runtime/ets/objectLiteral.ets runtime/ets/objectLiteralInterfaceType.ets runtime/ets/objectLiteral_abstract_class_object.ets -runtime/ets/rest_object_literal.ets \ No newline at end of file +runtime/ets/rest_object_literal.ets diff --git a/ets2panda/test/unit/CMakeLists.txt b/ets2panda/test/unit/CMakeLists.txt index a0b496400e877dd4a6d6886dabe5d61c70263174..d1e6f78536b7f7bdd26d93a3e3f8ebe5d21da8e6 100644 --- a/ets2panda/test/unit/CMakeLists.txt +++ b/ets2panda/test/unit/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Huawei Device Co., Ltd. +# Copyright (c) 2024-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 @@ -25,6 +25,7 @@ add_subdirectory(plugin_conversion_rule) add_subdirectory(arktsconfig-parser) add_subdirectory(annotations) add_subdirectory(lsp) +add_subdirectory(relative_path) ets2panda_add_gtest(es2panda_astdumper_tests CPP_SOURCES ast_dumper_test.cpp diff --git a/ets2panda/test/unit/relative_path/CMakeLists.txt b/ets2panda/test/unit/relative_path/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..928c34b3f60fd46f53b4be6c3c989efbef5492de --- /dev/null +++ b/ets2panda/test/unit/relative_path/CMakeLists.txt @@ -0,0 +1,43 @@ +# 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. + +add_custom_target(es2panda_relative_path_to_file) + +function(copy_to_workdir filename) + get_filename_component(filename_without_ext ${filename} NAME_WLE) + add_custom_target("copy_test_${filename_without_ext}" + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + ${CMAKE_CURRENT_BINARY_DIR}/${filename_without_ext}/${filename}) +endfunction() + +function(launch_with_reletaive_path_single_file filename) + copy_to_workdir(${filename}) + get_filename_component(filename_without_ext ${filename} NAME_WLE) + set(filename_abc "${filename_without_ext}.abc") + add_custom_command( + OUTPUT "${filename_abc}" + DEPENDS es2panda copy_test_${filename_without_ext} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${filename_without_ext} + COMMAND ${CMAKE_COMMAND} -E env + LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${PANDA_RUN_PREFIX} + $ --extension=ets --ets-unnamed --output=${filename_abc} + ${filename} + ) + add_custom_target(es2panda_relative_path_to_file_${filename_without_ext} DEPENDS ${filename_abc}) + add_dependencies(es2panda_relative_path_to_file es2panda_relative_path_to_file_${filename_without_ext}) +endfunction() + +add_dependencies(es2panda_tests es2panda_relative_path_to_file) + +launch_with_reletaive_path_single_file(package_a_file_1.ets) diff --git a/ets2panda/test/unit/relative_path/package_a_file_1.ets b/ets2panda/test/unit/relative_path/package_a_file_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..db6181aacafa2ee28c009568d618f901a97cfc8d --- /dev/null +++ b/ets2panda/test/unit/relative_path/package_a_file_1.ets @@ -0,0 +1,18 @@ +/** + * 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. + */ + +package A; + +export const num = 1; diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 1d2b8db7e1da941e781cd6c3638610ff172a0559..11e8dc17f58f98ca76f9861270275b7350754fff 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -415,9 +415,9 @@ semantic: id: 101 message: "Initializer must be able to complete normally." -- name: UNREACHABLE_STMT +- name: EXTEND_DYNAMIC id: 102 - message: "Unreachable statement." + message: "Class {} shouldn't extend dynamic class." - name: MISSING_RETURN_STMT id: 103 @@ -1111,9 +1111,9 @@ semantic: id: 279 message: "Tuple types with arity >16 are not yet implemented" -- name: UNION_METHOD_SIGNATURE +- name: PROPERTY_MAYBE_MISSING_INIT id: 280 - message: "Union constituent types should have only one common method signature." + message: "Property '{}' might not have been initialized." - name: NOT_ALLOWED_THIS_IN_UNION_TYPE id: 281 @@ -1345,8 +1345,4 @@ semantic: - name: READONLY_PROPERTY_REASSIGN id: 338 - message: "The 'Readonly' property cannot be reassigned." - -- name: PROPERTY_MAYBE_MISSING_INIT - id: 339 - message: "Property '{}' might not have been initialized." + message: "The 'Readonly' property cannot be reassigned." \ No newline at end of file diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 60d0b0da2e4950f04661f3d96c6a14d321542d2b..465347e084fe629eda60dd36511d7b93fbb3b906 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1191,3 +1191,7 @@ syntax: - name: PREDEFINED_TYPE_AS_IDENTIFIER id: 295 message: "{} is a predefined type, cannot be used as an identifier" + +- name: DEEP_NESTING + id: 306 + message: "Maximum allowed nesting level exceeded." diff --git a/ets2panda/util/diagnostic/warning.yaml b/ets2panda/util/diagnostic/warning.yaml index 7c5314fafb15559d73b5bb1a4182698f1e210e0f..e00451b71ad47866d2060fdcfb3282bdc869407b 100644 --- a/ets2panda/util/diagnostic/warning.yaml +++ b/ets2panda/util/diagnostic/warning.yaml @@ -47,3 +47,71 @@ warning: - name : ANNOTATION_UNUSED_GENERIC_ALIAS_WARN id: 9 message: "Type alias generic parameter '{}' is not used in type annotation" + +- name: DYNAMIC_PATHS_ABSOLUTE + id: 10 + message: "Don't use absolute path '{}' as key in 'dynamicPaths'" + +- name: NO_OHMURL + id: 11 + message: "'ohmUrl' for module '{}' wasn't specified" + +- name: DUPLICATE_SIGS + id: 12 + message: "Detect duplicate signatures, use '{}{}' to replace" + +- name: EXTENSION_NONPUBLIC_COLLISION + id: 13 + message: "The extension function '{}' has the same name with non-public method in class {}" + +- name: NULLISH_OPERAND + id: 14 + message: "Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'." + +- name: INSTANCEOF_ERASED + id: 15 + message: "Type parameter is erased from type '{}' when used in instanceof expression." + +- name: ASSIGN_TO_READONLY + id: 16 + message: "Cannot assign to '{}' because it is a read-only property." + +- name: MAYBE_REASSIGNED + id: 17 + message: "{} '{}' might already have been assigned." + +- name: PROP_MAYBE_UNINITIALIZED + id: 18 + message: "Property '{}' might not have been initialized." + +- name: USE_BEFORE_INIT + id: 19 + message: "{} '{}' is used before being assigned." + +- name: MAYBE_FALLTHROUGH + id: 20 + message: "Possible fall-through into case" + +- name: FINALLY_CANT_COMPLETE + id: 21 + message: "Finally clause cannot complete normally" + +- name: FUNCTION_ASM_SIG_COLLISION + id: 22 + message: "Function {} with this assembly signature already declared." + +- name: GETTER_LOOP + id: 23 + message: "Reading the value of the property inside its getter may lead to an endless loop." + +- name: SETTER_LOOP + id: 24 + message: "Assigning new value to the property inside its setter may lead to an endless loop." + +- name: EXTENSION_MISMATCH + id: 25 + message: "Not matching extensions! Sourcefile: {}, Manual(used): {}" + +- name: UNREACHABLE_STMT + id: 26 + message: "Unreachable statement." \ No newline at end of file diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index e7204d2d33947ee031a17c5dbb38e781159adecb..2b9494e9664797237dbee76f33a1680bd2c33da1 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -402,11 +402,11 @@ bool Helpers::IsPattern(const ir::AstNode *node) return node->IsArrayPattern() || node->IsObjectPattern() || node->IsAssignmentPattern(); } -static void CollectBindingName(ir::AstNode *node, std::vector *bindings) +static void CollectBindingName(varbinder::VarBinder *vb, ir::AstNode *node, std::vector *bindings) { switch (node->Type()) { case ir::AstNodeType::IDENTIFIER: { - if (!Helpers::IsGlobalIdentifier(node->AsIdentifier()->Name())) { + if (!vb->IsGlobalIdentifier(node->AsIdentifier()->Name())) { bindings->push_back(node->AsIdentifier()); } @@ -414,26 +414,26 @@ static void CollectBindingName(ir::AstNode *node, std::vector } case ir::AstNodeType::OBJECT_PATTERN: { for (auto *prop : node->AsObjectPattern()->Properties()) { - CollectBindingName(prop, bindings); + CollectBindingName(vb, prop, bindings); } break; } case ir::AstNodeType::ARRAY_PATTERN: { for (auto *element : node->AsArrayPattern()->Elements()) { - CollectBindingName(element, bindings); + CollectBindingName(vb, element, bindings); } break; } case ir::AstNodeType::ASSIGNMENT_PATTERN: { - CollectBindingName(node->AsAssignmentPattern()->Left(), bindings); + CollectBindingName(vb, node->AsAssignmentPattern()->Left(), bindings); break; } case ir::AstNodeType::PROPERTY: { - CollectBindingName(node->AsProperty()->Value(), bindings); + CollectBindingName(vb, node->AsProperty()->Value(), bindings); break; } case ir::AstNodeType::REST_ELEMENT: { - CollectBindingName(node->AsRestElement()->Argument(), bindings); + CollectBindingName(vb, node->AsRestElement()->Argument(), bindings); break; } default: @@ -441,10 +441,10 @@ static void CollectBindingName(ir::AstNode *node, std::vector } } -std::vector Helpers::CollectBindingNames(ir::Expression *node) +std::vector Helpers::CollectBindingNames(varbinder::VarBinder *vb, ir::Expression *node) { std::vector bindings; - CollectBindingName(node, &bindings); + CollectBindingName(vb, node, &bindings); return bindings; } diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index 3ac27791612128135fbd33bb94c53a6fb131e477..75b9eed90386c1365b5fe083e4a08b028ac5501a 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -149,7 +149,7 @@ public: static compiler::Literal ToConstantLiteral(const ir::Expression *expr); static bool IsBindingPattern(const ir::AstNode *node); static bool IsPattern(const ir::AstNode *node); - static std::vector CollectBindingNames(ir::Expression *node); + static std::vector CollectBindingNames(varbinder::VarBinder *vb, ir::Expression *node); static util::StringView FunctionName(ArenaAllocator *allocator, const ir::ScriptFunction *func); static void CheckImportedName(const ArenaVector &specifiers, const ir::ImportSpecifier *specifier, const std::string &fileName); diff --git a/ets2panda/util/path.cpp b/ets2panda/util/path.cpp index 5c5e54c443f4c0dd3b2bd0baf97385b28db37ad6..23bc2175c32fa9422f0fa0a4d7c5d9734838768d 100644 --- a/ets2panda/util/path.cpp +++ b/ets2panda/util/path.cpp @@ -116,7 +116,7 @@ void Path::InitializeAbsoluteParentFolder() int position = absolutePath_.Mutf8().find_last_of(PATH_DELIMITER); - if (!absolutePath_.Empty() && isRelative_) { + if (!absolutePath_.Empty()) { absoluteParentFolder_ = absolutePath_.Substr(0, position); } } diff --git a/ets2panda/util/recursiveGuard.h b/ets2panda/util/recursiveGuard.h new file mode 100644 index 0000000000000000000000000000000000000000..34b57989b1ec5ec1c1ec112c1a01ccb641901e54 --- /dev/null +++ b/ets2panda/util/recursiveGuard.h @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2021-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. + */ + +#ifndef RECURSIVE_GUARD_H +#define RECURSIVE_GUARD_H + +namespace ark::es2panda::parser { + +constexpr unsigned int MAX_RECURSION_DEPTH = 1024; + +struct RecursiveContext { + unsigned depth = 0; +}; + +class TrackRecursive { +public: + explicit TrackRecursive(RecursiveContext &recursivecontext) : recursivecontext_(recursivecontext) + { + ++recursivecontext_.depth; + valid_ = recursivecontext_.depth <= MAX_RECURSION_DEPTH; + }; + + ~TrackRecursive() + { + --recursivecontext_.depth; + } + + TrackRecursive(const TrackRecursive &) = delete; + TrackRecursive(TrackRecursive &&) = delete; + TrackRecursive &operator=(const TrackRecursive &) = delete; + TrackRecursive &operator=(TrackRecursive &&) = delete; + + explicit operator bool() const + { + return valid_; + } + +private: + RecursiveContext &recursivecontext_; + bool valid_ = true; +}; + +} // namespace ark::es2panda::parser + +#endif // UTIL_GUARD_H diff --git a/ets2panda/util/ustring.h b/ets2panda/util/ustring.h index a1fc97e97df2f68fcbe2b002a74f5aa043fced25..4437014055c8c3cf2873810ad2c69c7605c6fcf8 100644 --- a/ets2panda/util/ustring.h +++ b/ets2panda/util/ustring.h @@ -234,6 +234,10 @@ public: class Constants { public: + static constexpr uint16_t UTF8_2BYTE_REQUIRED = 2; + static constexpr uint16_t UTF8_3BYTE_REQUIRED = 3; + static constexpr uint16_t UTF8_4BYTE_REQUIRED = 4; + static constexpr uint16_t UTF8_1BYTE_LIMIT = 0x80; static constexpr uint16_t UTF8_2BYTE_LIMIT = 0x800; static constexpr uint32_t UTF8_3BYTE_LIMIT = 0x10000; @@ -375,22 +379,25 @@ char32_t StringView::Iterator::DecodeCP([[maybe_unused]] size_t *cpSize) const } const auto *iterNext = iter_; + const auto remain = static_cast(sv_.end() - iterNext); char32_t cu0 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) char32_t res {}; if (cu0 < Constants::UTF8_1BYTE_LIMIT) { res = cu0; - } else if ((cu0 & Constants::UTF8_3BYTE_HEADER) == Constants::UTF8_2BYTE_HEADER) { + } else if ((cu0 & Constants::UTF8_3BYTE_HEADER) == Constants::UTF8_2BYTE_HEADER && + remain >= Constants::UTF8_2BYTE_REQUIRED) { char32_t cu1 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) res = ((cu0 & Constants::UTF8_2BYTE_MASK) << Constants::UTF8_2BYTE_SHIFT) | (cu1 & Constants::UTF8_CONT_MASK); - } else if ((cu0 & Constants::UTF8_4BYTE_HEADER) == Constants::UTF8_3BYTE_HEADER) { + } else if ((cu0 & Constants::UTF8_4BYTE_HEADER) == Constants::UTF8_3BYTE_HEADER && + remain >= Constants::UTF8_3BYTE_REQUIRED) { char32_t cu1 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) char32_t cu2 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) res = ((cu0 & Constants::UTF8_3BYTE_MASK) << Constants::UTF8_3BYTE_SHIFT) | ((cu1 & Constants::UTF8_CONT_MASK) << Constants::UTF8_2BYTE_SHIFT) | (cu2 & Constants::UTF8_CONT_MASK); } else if (((cu0 & Constants::UTF8_DECODE_4BYTE_MASK) == Constants::UTF8_4BYTE_HEADER) && - (cu0 <= Constants::UTF8_DECODE_4BYTE_LIMIT)) { + cu0 <= Constants::UTF8_DECODE_4BYTE_LIMIT && remain >= Constants::UTF8_4BYTE_REQUIRED) { char32_t cu1 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) char32_t cu2 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) char32_t cu3 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 216018b1b4c6701991a51ec7d392f471b200b945..e8a663f1705e923a2830273fce99a4eb484203e4 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -1473,4 +1473,9 @@ void ETSBinder::ThrowError(const lexer::SourcePosition &pos, const std::string_v GetContext()->diagnosticEngine->LogSemanticError(msg, pos); } +bool ETSBinder::IsGlobalIdentifier([[maybe_unused]] const util::StringView &str) const +{ + return false; +} + } // namespace ark::es2panda::varbinder diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 6463ebb852c532f80f45ee31f5244a7144e466a0..dd96529259333ff189d5085d449283b8f0651d1c 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -188,6 +188,7 @@ public: void AddFunctionThisParam(ir::ScriptFunction *func); void ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const override; + bool IsGlobalIdentifier(const util::StringView &str) const override; void SetDefaultImports(ArenaVector defaultImports) noexcept { diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index 7e0673b21016d39cba19118155888208cb148554..292801e3f331aa356f2c926aecc74ab70eff5aa6 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -437,7 +437,8 @@ Variable *ParamScope::AddParameter(ArenaAllocator *allocator, Decl *newDecl, Var return param; } -std::tuple ParamScope::AddParamDecl(ArenaAllocator *allocator, ir::Expression *parameter) +std::tuple ParamScope::AddParamDecl(ArenaAllocator *allocator, varbinder::VarBinder *vb, + ir::Expression *parameter) { auto [name, pattern] = util::Helpers::ParamName(allocator, parameter, params_.size()); if (name.Is(ERROR_LITERAL)) { @@ -450,7 +451,7 @@ std::tuple ParamScope::AddParamDecl(ArenaAllocator } if (pattern) { - std::vector bindings = util::Helpers::CollectBindingNames(parameter); + std::vector bindings = util::Helpers::CollectBindingNames(vb, parameter); for (auto *binding : bindings) { auto *varDecl = NewDecl(allocator, binding->Name()); diff --git a/ets2panda/varbinder/scope.h b/ets2panda/varbinder/scope.h index 5ef35b88d0fefcc3c04486f5bc85f9269938f8cd..8cff3b9d7d257b659477b7d3992b04b38a2e0bff 100644 --- a/ets2panda/varbinder/scope.h +++ b/ets2panda/varbinder/scope.h @@ -441,7 +441,8 @@ public: return params_; } - std::tuple AddParamDecl(ArenaAllocator *allocator, ir::Expression *parameter); + std::tuple AddParamDecl(ArenaAllocator *allocator, varbinder::VarBinder *vb, + ir::Expression *parameter); protected: explicit ParamScope(ArenaAllocator *allocator, Scope *parent) diff --git a/ets2panda/varbinder/varbinder.cpp b/ets2panda/varbinder/varbinder.cpp index 7d668b5de24eca46040b9fff9cfe3b07c09cc012..0dcc26f31e0175d8b3a54183777fb0793e69923f 100644 --- a/ets2panda/varbinder/varbinder.cpp +++ b/ets2panda/varbinder/varbinder.cpp @@ -33,7 +33,7 @@ Variable *VarBinder::AddParamDecl(ir::Expression *param) { ES2PANDA_ASSERT(scope_->IsFunctionParamScope() || scope_->IsCatchParamScope()); - auto [var, node] = static_cast(scope_)->AddParamDecl(Allocator(), param); + auto [var, node] = static_cast(scope_)->AddParamDecl(Allocator(), this, param); ES2PANDA_ASSERT(var != nullptr); if (node != nullptr) { @@ -82,6 +82,11 @@ void VarBinder::ThrowError(const lexer::SourcePosition &pos, const std::string_v context_->diagnosticEngine->ThrowSyntaxError(msg, program_->SourceFilePath().Utf8(), loc.line, loc.col); } +bool VarBinder::IsGlobalIdentifier(const util::StringView &str) const +{ + return util::Helpers::IsGlobalIdentifier(str); +} + void VarBinder::IdentifierAnalysis() { ES2PANDA_ASSERT(program_->Ast()); @@ -249,7 +254,7 @@ void VarBinder::BuildVarDeclaratorId(ir::AstNode *childNode) auto *ident = childNode->AsIdentifier(); const auto &name = ident->Name(); - if (util::Helpers::IsGlobalIdentifier(name) || name.Is(ERROR_LITERAL)) { + if (IsGlobalIdentifier(name) || name.Is(ERROR_LITERAL)) { break; } diff --git a/ets2panda/varbinder/varbinder.h b/ets2panda/varbinder/varbinder.h index 8fe135f211e4d84fa7e16760abc2fb9cd928a844..fe029aad6fdd76e2860c6b1eeefc3b2a3a57f19f 100644 --- a/ets2panda/varbinder/varbinder.h +++ b/ets2panda/varbinder/varbinder.h @@ -165,6 +165,7 @@ public: void ThrowTDZ(const lexer::SourcePosition &pos, const util::StringView &name) const; void ThrowInvalidCapture(const lexer::SourcePosition &pos, const util::StringView &name) const; virtual void ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const; + virtual bool IsGlobalIdentifier(const util::StringView &str) const; void PropagateDirectEval() const;