diff --git a/ets2panda/ast_verifier/ASTVerifier.cpp b/ets2panda/ast_verifier/ASTVerifier.cpp index f3310a909ee8cb849ec5170e04e0717c64c8b570..ced6d67138e67e1846f9c795cf2359821751c276 100644 --- a/ets2panda/ast_verifier/ASTVerifier.cpp +++ b/ets2panda/ast_verifier/ASTVerifier.cpp @@ -200,7 +200,7 @@ void ASTVerifier::DumpMessages() const } if (hasErrors_) { - LOG(FATAL, ES2PANDA) << errMsg; + LOG(ERROR, ES2PANDA) << errMsg; } else if (hasWarnings_) { LOG(WARNING, ES2PANDA) << errMsg; } diff --git a/ets2panda/ast_verifier/checkStructDeclaration.cpp b/ets2panda/ast_verifier/checkStructDeclaration.cpp index 2619d22edc48000d544e0bc446db78646c30e0f4..67969fff2f8a96e50da910ee7076b7081aef98b2 100644 --- a/ets2panda/ast_verifier/checkStructDeclaration.cpp +++ b/ets2panda/ast_verifier/checkStructDeclaration.cpp @@ -15,8 +15,6 @@ #include "checkStructDeclaration.h" -#include "ir/statements/blockStatement.h" - namespace ark::es2panda::compiler::ast_verifier { CheckResult CheckStructDeclaration::operator()(const ir::AstNode *ast) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 6fe30b0ad53a13a4e7b3b8520cae2c3b0394ddb8..cf55e3edfeb4f33be59c861ee69b70f52b8548e1 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -15,8 +15,6 @@ #include "ETSAnalyzer.h" -#include - #include "generated/diagnostic.h" #include "checker/types/globalTypesHolder.h" #include "checker/types/ets/etsTupleType.h" @@ -79,14 +77,17 @@ checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const if (st->TsType() != nullptr) { return st->TsType(); } - ETSChecker *checker = GetETSChecker(); ES2PANDA_ASSERT(st->Id() != nullptr); - if (st->Id()->IsErrorPlaceHolder() || st->Id()->Variable() == nullptr) { - st->Id()->SetTsType(checker->GlobalTypeError()); - return st->SetTsType(checker->GlobalTypeError()); + + ETSChecker *checker = GetETSChecker(); + + if (st->Id()->Variable() == nullptr) { + st->Id()->Check(checker); } + ES2PANDA_ASSERT(st->Id()->Variable() != nullptr); + checker->CheckAnnotations(st->Annotations()); if (st->TypeAnnotation() != nullptr) { st->TypeAnnotation()->Check(checker); @@ -118,7 +119,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const auto *func = st->Function(); checker->BuildFunctionSignature(func); - if (func->Signature() == nullptr || func->Id()->Variable() == nullptr) { + if (func->Signature() == nullptr) { st->SetTsType(checker->GlobalTypeError()); } else { st->SetTsType(checker->BuildMethodType(func)); @@ -1012,18 +1013,25 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const } auto [rightType, relationNode] = CheckAssignmentExprOperatorType(expr, leftType); - if (rightType == nullptr) { - expr->SetTsType(checker->GlobalTypeError()); - return checker->GlobalTypeError(); + if (rightType->IsTypeError()) { + return expr->SetTsType(checker->GlobalTypeError()); } - checker::AssignmentContext(checker->Relation(), relationNode, rightType, leftType, expr->Right()->Start(), - {"Type '", rightType, "' cannot be assigned to type '", leftType, "'"}); - - checker::Type *smartType = GetSmartType(expr, leftType, rightType); + checker::Type *smartType = leftType; + if (!leftType->IsTypeError()) { + if (auto ctx = checker::AssignmentContext( + // CC-OFFNXT(G.FMT.06-CPP) project code style + checker->Relation(), relationNode, rightType, leftType, expr->Right()->Start(), + // CC-OFFNXT(G.FMT.06-CPP) project code style + {"Type '", rightType, "' cannot be assigned to type '", leftType, "'"}); + ctx.IsAssignable()) { + smartType = GetSmartType(expr, leftType, rightType); + } + } else { + smartType = rightType; + } - expr->SetTsType(smartType); - return expr->TsType(); + return expr->SetTsType(smartType); } std::tuple ETSAnalyzer::CheckAssignmentExprOperatorType(ir::AssignmentExpression *expr, @@ -1549,14 +1557,11 @@ checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const ETSChecker *checker = GetETSChecker(); - if (expr->IsErrorPlaceHolder()) { - return expr->SetTsType(checker->GlobalTypeError()); - } - auto *identType = TransformTypeForMethodReference(checker, expr, checker->ResolveIdentifier(expr)); - if (expr->Variable() != nullptr && (expr->Parent() == nullptr || !expr->Parent()->IsAssignmentExpression() || - expr != expr->Parent()->AsAssignmentExpression()->Left())) { + ES2PANDA_ASSERT(expr->Variable() != nullptr); + if (expr->Parent() == nullptr || !expr->Parent()->IsAssignmentExpression() || + expr != expr->Parent()->AsAssignmentExpression()->Left()) { auto *const smartType = checker->Context().GetSmartCast(expr->Variable()); if (smartType != nullptr) { identType = smartType; @@ -2369,8 +2374,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const ETSChecker *checker = GetETSChecker(); st->Expr()->Check(checker); - if (st->GetBaseName()->Variable() == nullptr || - !st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { + if (!st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { checker->LogError(diagnostic::NOT_AN_ANNOTATION, {st->GetBaseName()->Name()}, st->GetBaseName()->Start()); return ReturnTypeForStatement(st); } @@ -2460,12 +2464,6 @@ static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, relation->SetNode(nullptr); relation->SetFlags(checker::TypeRelationFlag::NONE); - if (iterType->Variable() == nullptr && !iterType->IsETSObjectType() && elemType->IsETSObjectType() && - st->Left()->IsVariableDeclaration()) { - for (auto &declarator : st->Left()->AsVariableDeclaration()->Declarators()) { - checker->AddBoxingUnboxingFlagsToNode(declarator->Id(), iterType); - } - } return true; } @@ -2855,9 +2853,7 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const // Processing possible parser errors if (ident->Variable() == nullptr) { - ES2PANDA_ASSERT(checker->IsAnyError()); - ident->SetTsType(checker->GlobalTypeError()); - return st->SetTsType(variableType); + ident->Check(checker); } // Now try to define the actual type of Identifier so that smart cast can be used in further checker processing diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index 69159e015f3450c7946ce9766b83c7cbdaeba7da..d9dcff72b185dace8b56232d05261a257a307356 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -618,15 +618,16 @@ checker::Type *GetIteratorType(ETSChecker *checker, checker::Type *elemType, ir: checker::Type *iterType = nullptr; if (left->IsIdentifier()) { - if (auto *const variable = left->AsIdentifier()->Variable(); variable != nullptr) { - auto *decl = variable->Declaration(); - if (decl->IsConstDecl() || decl->IsReadonlyDecl()) { - const auto errorMsg = decl->IsConstDecl() ? diagnostic::INVALID_CONST_ASSIGNMENT - : diagnostic::INVALID_READONLY_ASSIGNMENT; - // NOTE(pronaip): see memory corruption issue in 23053, replace with LogError once resolved - checker->LogTypeError({errorMsg.Message().substr(0, errorMsg.Message().size() - 2), variable->Name()}, - decl->Node()->Start()); - } + auto *const variable = left->Variable(); + ES2PANDA_ASSERT(variable != nullptr && variable->Declaration() != nullptr); + + auto *decl = variable->Declaration(); + if (decl->IsConstDecl() || decl->IsReadonlyDecl()) { + const auto errorMsg = + decl->IsConstDecl() ? diagnostic::INVALID_CONST_ASSIGNMENT : diagnostic::INVALID_READONLY_ASSIGNMENT; + // NOTE(pronaip): see memory corruption issue in 23053, replace with LogError once resolved + checker->LogTypeError({errorMsg.Message().substr(0, errorMsg.Message().size() - 2), variable->Name()}, + decl->Node()->Start()); } iterType = left->AsIdentifier()->TsType(); } else if (left->IsVariableDeclaration()) { diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index e2417be3134dd2fec7ba9c288d6f1e171f4bbd31..fd22b11a7d73067e90c2c499eb0ee48635dd215a 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -853,7 +853,6 @@ private: void ValidateCallExpressionIdentifier(ir::Identifier *const ident, Type *const type); void ValidateNewClassInstanceIdentifier(ir::Identifier *const ident); void ValidateMemberIdentifier(ir::Identifier *const ident); - void ValidatePropertyOrDeclaratorIdentifier(ir::Identifier *const ident); void ValidateAssignmentIdentifier(ir::Identifier *const ident, Type *const type); bool ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, Type *const type); void ValidateGetterSetter(const ir::MemberExpression *const memberExpr, const varbinder::LocalVariable *const prop, diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 3fbdc353d093e4d5a8da1c311c8913ec9af6ce83..5f42dd946ab6b61b7490e4cf939bff5969eb8c9e 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -1148,7 +1148,7 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, Type *unboxedR = isLogicalExtendedOperator ? MaybeUnboxConditionalInRelation(rightType) : MaybeUnboxInRelation(rightType); - ASSERT(operationType != lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ES2PANDA_ASSERT(operationType != lexer::TokenType::PUNCTUATOR_SUBSTITUTION); bool isEqualOp = lexer::Token::IsBinaryLvalueToken(operationType) && !forcePromotion; if (CheckBinaryOperatorForBigInt(leftType, rightType, operationType)) { diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index 37686a333550feb581cb0d756229ed07bc566e72..a9cbec3ae021aaa87917d4dc023b310705c2c139 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -1068,9 +1068,7 @@ void AssignAnalyzer::AnalyzeId(const ir::Identifier *id) } } - if (id->Variable() != nullptr) { - CheckInit(id); - } + CheckInit(id); } static bool IsIdentOrThisDotIdent(const ir::AstNode *node) @@ -1342,11 +1340,8 @@ const ir::AstNode *AssignAnalyzer::GetDeclaringNode(const ir::AstNode *node) } } } else if (node->IsIdentifier()) { - const ir::Identifier *id = node->AsIdentifier(); - if (id->Variable() != nullptr) { - if (id->Variable()->Declaration() != nullptr) { - ret = id->Variable()->Declaration()->Node(); - } + if (auto *const variable = node->Variable(); variable != nullptr) { + ret = variable->Declaration()->Node(); } } @@ -1372,9 +1367,8 @@ bool AssignAnalyzer::VariableHasDefaultValue(const ir::AstNode *node) isNonReadonlyField = !node->IsReadonly(); // NOTE(pantos) readonly is true, const is not set? } else if (node->IsVariableDeclarator()) { varbinder::Variable *variable = GetBoundVariable(node); - if (variable != nullptr) { - type = variable->TsType(); - } + ES2PANDA_ASSERT(variable != nullptr); + type = variable->TsType(); } else { UNREACHABLE(); } diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 12504a9a3ff8afa2c8b5218c0f771ca452253861..0ac461a7cfadf1b7f52192a6ff4112ba8625697d 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1022,7 +1022,7 @@ bool ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType { // Don't necessary to check overload for invalid functions if (func->Name().Is(ERROR_LITERAL)) { - ASSERT(IsAnyError()); + ES2PANDA_ASSERT(IsAnyError()); return false; } @@ -1794,7 +1794,7 @@ static void CreateFuncDecl(ETSChecker *checker, ir::MethodDefinition *func, varb varbinder::Variable *var = scope->FindLocal(func->Id()->Name(), varbinder::ResolveBindingOptions::ALL_DECLARATION); if (var == nullptr) { var = std::get<1>( - varBinder->NewVarDecl(func->Start(), allocator, func->Id()->Name(), func)); + varBinder->NewVarDecl(func->Id()->Start(), allocator, func->Id()->Name(), func)); } var->AddFlag(varbinder::VariableFlags::METHOD); var->SetScope(ctx.GetScope()); @@ -1893,15 +1893,10 @@ varbinder::FunctionParamScope *ETSChecker::CopyParams(const ArenaVectorClone(Allocator(), paramOld->Parent())->AsETSParameterExpression(); - varbinder::Variable *var = nullptr; - Type *paramType = GlobalTypeError(); - - if (paramOld->Ident()->Variable() != nullptr) { - var = std::get<1>(VarBinder()->AddParamDecl(paramNew)); - paramType = paramOld->Ident()->Variable()->TsType(); - var->SetTsType(paramType); - var->SetScope(paramCtx.GetScope()); - } + varbinder::Variable *var = VarBinder()->AddParamDecl(paramNew); + Type *paramType = paramOld->Variable()->TsType(); + var->SetTsType(paramType); + var->SetScope(paramCtx.GetScope()); paramNew->SetVariable(var); paramNew->SetTsType(paramType); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 1b8878b63c580049dba47a011fcbd5bece501c15..032058b2f664556575eadb607adb24ef4bf3e7e7 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -13,16 +13,15 @@ * limitations under the License. */ -#include "checker/types/ets/etsTupleType.h" -#include "checker/ets/typeRelationContext.h" #include "checker/ETSchecker.h" + #include "checker/types/globalTypesHolder.h" +#include "checker/types/ets/etsTupleType.h" +#include "checker/ets/typeRelationContext.h" #include "evaluate/scopedDebugInfoPlugin.h" #include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "compiler/lowering/util.h" -#include - namespace ark::es2panda::checker { varbinder::Variable *ETSChecker::FindVariableInFunctionScope(const util::StringView name, const varbinder::ResolveBindingOptions options) @@ -76,34 +75,52 @@ void ETSChecker::LogUnresolvedReferenceError(ir::Identifier *const ident) void ETSChecker::WrongContextErrorClassifyByType(ir::Identifier *ident) { - std::string identCategoryName; + if (ident->IsErrorPlaceHolder()) { + return; + } + + std::string identCategoryName {}; switch (static_cast( ident->Variable()->Flags() & - (varbinder::VariableFlags::CLASS_OR_INTERFACE_OR_ENUM | varbinder::VariableFlags::METHOD))) { - case varbinder::VariableFlags::CLASS: { + (varbinder::VariableFlags::CLASS_OR_INTERFACE_OR_ENUM | varbinder::VariableFlags::METHOD | + varbinder::VariableFlags::NAMESPACE | varbinder::VariableFlags::ANNOTATIONDECL | + varbinder::VariableFlags::ANNOTATIONUSAGE | varbinder::VariableFlags::TYPE_ALIAS | + varbinder::VariableFlags::TYPE))) { + case varbinder::VariableFlags::CLASS: identCategoryName = "Class"; break; - } - case varbinder::VariableFlags::NAMESPACE: { + + case varbinder::VariableFlags::NAMESPACE: identCategoryName = "Namespace"; break; - } - case varbinder::VariableFlags::METHOD: { + + case varbinder::VariableFlags::METHOD: identCategoryName = "Function"; break; - } - case varbinder::VariableFlags::INTERFACE: { + + case varbinder::VariableFlags::INTERFACE: identCategoryName = "Interface"; break; - } - case varbinder::VariableFlags::ENUM_LITERAL: { + + case varbinder::VariableFlags::ENUM_LITERAL: identCategoryName = "Enum"; break; - } - default: { - LogUnresolvedReferenceError(ident); + + case varbinder::VariableFlags::ANNOTATIONDECL: + [[fallthrough]]; + case varbinder::VariableFlags::ANNOTATIONUSAGE: + identCategoryName = "Annotation"; + break; + + case varbinder::VariableFlags::TYPE: + [[fallthrough]]; + case varbinder::VariableFlags::TYPE_ALIAS: + identCategoryName = "Type"; + break; + + default: + LogTypeError({"Identifier '", ident->Name(), "' is used in wrong context."}, ident->Start()); return; - } } LogError(diagnostic::ID_IN_WRONG_CTX, {identCategoryName.c_str(), ident->Name()}, ident->Start()); } @@ -264,7 +281,12 @@ Type *ETSChecker::ResolveIdentifier(ir::Identifier *ident) if (resolved == nullptr) { resolved = ExtraCheckForResolvedError(ident); if (resolved == nullptr) { - return GlobalTypeError(); + auto [decl, var] = VarBinder()->NewVarDecl( + ident->Start(), !ident->IsErrorPlaceHolder() ? ident->Name() : compiler::GenName(Allocator()).View()); + var->SetScope(VarBinder()->GetScope()); + ident->SetVariable(var); + decl->BindNode(ident); + return ident->SetTsType(var->SetTsType(GlobalTypeError())); } ident->SetVariable(resolved); return GetTypeOfVariable(resolved); @@ -653,8 +675,7 @@ static bool NeedWidening(ir::Expression *e) if (e->IsUnaryExpression()) { return NeedWidening(e->AsUnaryExpression()->Argument()); } - const bool isConstInit = - e->IsIdentifier() && e->Variable() != nullptr && e->Variable()->Declaration()->IsConstDecl(); + const bool isConstInit = e->IsIdentifier() && e->Variable()->Declaration()->IsConstDecl(); return e->IsConditionalExpression() || e->IsLiteral() || isConstInit; } @@ -780,6 +801,11 @@ checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker:: return targetType; } + // For left-hand invalid variable set smart type to right-hand type. + if (targetType->IsTypeError()) { + return sourceType; + } + // For left-hand variable of builtin type leave it as is. if (targetType->IsETSObjectType() && targetType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { return targetType; @@ -1395,8 +1421,9 @@ Type *ETSChecker::GetReferencedTypeBase(ir::Expression *name) ES2PANDA_ASSERT(name->IsIdentifier()); auto *const var = name->AsIdentifier()->Variable(); - if (var == nullptr) { - ES2PANDA_ASSERT(IsAnyError()); + ES2PANDA_ASSERT(var != nullptr); + + if (var->TsType() != nullptr && var->TsType()->IsTypeError()) { return name->SetTsType(GlobalTypeError()); } @@ -1619,8 +1646,15 @@ std::optional ETSChecker::FindJumpTarget(ir::AstNode *node) // Look for label auto label = isContinue ? node->AsContinueStatement()->Ident() : node->AsBreakStatement()->Ident(); if (label != nullptr) { - auto var = label->Variable(); - if (var != nullptr && var->Declaration()->IsLabelDecl()) { + if (auto var = label->Variable(); var == nullptr) { + varbinder::LetDecl *decl; + std::tie(decl, var) = VarBinder()->NewVarDecl( + label->Start(), !label->IsErrorPlaceHolder() ? label->Name() : compiler::GenName(Allocator()).View()); + var->SetScope(VarBinder()->GetScope()); + label->SetVariable(var); + decl->BindNode(label); + label->SetTsType(var->SetTsType(GlobalTypeError())); + } else if (var->Declaration()->IsLabelDecl()) { return var->Declaration()->Node(); } @@ -2317,9 +2351,7 @@ ir::ClassProperty *ETSChecker::ClassPropToImplementationProp(ir::ClassProperty * auto fieldVar = scope->InstanceFieldScope()->AddDecl(Allocator(), fieldDecl, ScriptExtension::STS); fieldVar->AddFlag(varbinder::VariableFlags::PROPERTY); - classProp->Key()->SetVariable(fieldVar); - classProp->Key()->AsIdentifier()->SetVariable(fieldVar); fieldVar->SetTsType(classProp->TsType()); auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), scope); @@ -2375,12 +2407,15 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *paramExpression = AllocNode(paramIdent, false, Allocator()); paramExpression->SetRange(paramIdent->Range()); - auto *const paramVar = std::get<2>(paramScope->AddParamDecl(Allocator(), paramExpression)); - paramExpression->SetVariable(paramVar); + auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), paramExpression); + if (node != nullptr) { + VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name()); + } + + paramExpression->SetVariable(paramVar); params.push_back(paramExpression); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *assignmentExpression = AllocNode( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) memberExpression, paramExpression->Clone(Allocator(), nullptr), lexer::TokenType::PUNCTUATOR_SUBSTITUTION); @@ -2546,8 +2581,8 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin auto *const methodScope = scope->InstanceMethodScope(); auto *const decl = Allocator()->New(Allocator(), name, getter); - auto *var = methodScope->AddDecl(Allocator(), decl, ScriptExtension::STS); + auto *var = methodScope->AddDecl(Allocator(), decl, ScriptExtension::STS); if (var == nullptr) { auto *const prevDecl = methodScope->FindDecl(name); for (const auto &method : {getter, setter}) { @@ -2556,8 +2591,9 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin } } var = methodScope->FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS); + var->AddFlag(varbinder::VariableFlags::METHOD); } - var->AddFlag(varbinder::VariableFlags::METHOD); + getter->Function()->Id()->SetVariable(var); SetupGetterSetterFlags(originalProp, classType, getter, setter, HasStatus(CheckerStatus::IN_EXTERNAL)); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index c496f8a2d2526d9c098bd560b897baa49bf22de3..b54a298b930a6e6735fd69d382ef8de667deda8c 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -245,16 +245,13 @@ bool ETSChecker::CheckDefaultTypeParameter(const ir::TSTypeParameter *param, Typ if (node->IsETSTypeReferencePart()) { ir::ETSTypeReferencePart *defaultTypePart = node->AsETSTypeReferencePart(); auto *const variable = defaultTypePart->Name()->Variable(); - if (variable == nullptr) { - ES2PANDA_ASSERT(IsAnyError()); - ok = false; - return; - } if (variable->TsType() == nullptr && (variable->Flags() & varbinder::VariableFlags::TYPE_PARAMETER) != 0U && typeParameterDecls.count(variable) == 0U) { LogError(diagnostic::TYPE_PARAM_USE_BEFORE_DEFINE, {defaultTypePart->Name()->AsIdentifier()->Name().Utf8()}, node->Start()); ok = false; + } else if (variable->TsType() != nullptr && variable->TsType()->IsTypeError()) { + ok = false; } } node->Iterate(checkDefault); @@ -320,9 +317,11 @@ void ETSChecker::SetUpTypeParameterConstraint(ir::TSTypeParameter *const param) ETSTypeParameter *ETSChecker::SetUpParameterType(ir::TSTypeParameter *const param) { - if (param->Name()->Variable() != nullptr && param->Name()->Variable()->TsType() != nullptr) { - ES2PANDA_ASSERT(param->Name()->Variable()->TsType()->IsETSTypeParameter()); - return param->Name()->Variable()->TsType()->AsETSTypeParameter(); + auto *const var = param->Name()->Variable(); + ES2PANDA_ASSERT(var != nullptr); + + if (var->TsType() != nullptr) { + return var->TsType()->AsETSTypeParameter(); } auto *const paramType = CreateTypeParameter(); @@ -333,7 +332,7 @@ ETSTypeParameter *ETSChecker::SetUpParameterType(ir::TSTypeParameter *const para // NOTE: #15026 recursive type parameter workaround paramType->SetConstraintType(GlobalETSNullishObjectType()); - param->Name()->Variable()->SetTsType(paramType); + var->SetTsType(paramType); return paramType; } @@ -1822,6 +1821,8 @@ PropertySearchFlags ETSChecker::GetSearchFlags(const ir::MemberExpression *const if (targetRef != nullptr && (targetRef->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE) || + // NOTE (DZ): need to investigate when and why `targetRef->TsType()->Variable()` can be `nullptr` + // (see ast/parser/ets/union_static_method.sts) (targetRef->HasFlag(varbinder::VariableFlags::TYPE_ALIAS) && targetRef->TsType()->Variable() != nullptr && targetRef->TsType()->Variable()->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE)))) { searchFlag &= ~PropertySearchFlags::SEARCH_INSTANCE; diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index a83c3787f7cf0500a5aff4e7f87434091a47b510..908e02b65a173569b635bf3a8db83058a9379765 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -621,13 +621,14 @@ bool ETSChecker::IsAllowedTypeAliasRecursion(const ir::TSTypeAliasDeclaration *t if (!part->Name()->IsIdentifier()) { return false; } - if (part->Name()->AsIdentifier()->Variable() != nullptr && - part->Name()->AsIdentifier()->Variable()->Declaration() != nullptr && - part->Name()->AsIdentifier()->Variable()->Declaration()->Node() != nullptr && - part->Name()->AsIdentifier()->Variable()->Declaration()->Node()->IsTSTypeAliasDeclaration()) { - auto *aliasTypeNode = - part->Name()->AsIdentifier()->Variable()->Declaration()->Node()->AsTSTypeAliasDeclaration(); - return IsAllowedTypeAliasRecursion(aliasTypeNode, typeAliases); + + if (part->Name()->Variable() == nullptr) { + return true; + } + + auto const *const decl = part->Name()->Variable()->Declaration(); + if (auto const *const node = decl->Node(); node != nullptr && node->IsTSTypeAliasDeclaration()) { + return IsAllowedTypeAliasRecursion(node->AsTSTypeAliasDeclaration(), typeAliases); } return true; diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index 06e099c1d5f6c8828ca2e1e5aba69e7b74358a32..3a0ddfbd7867fa8912a7f4cb6157585ede045755 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -82,7 +82,7 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParame checker_->Relation()->SetNode(it); auto *const boxedTypeArg = checker_->MaybeBoxInRelation(paramType); - ASSERT(boxedTypeArg); + ASSERT(boxedTypeArg != nullptr); paramType = boxedTypeArg->Instantiate(checker_->Allocator(), checker_->Relation(), checker_->GetGlobalTypesHolder()); } diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 034c261d02f10add7a4b16c141bd5fef94618258..95647aab0e39a7a10405cd8ebc8e6050eddbd2c4 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -540,8 +540,7 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ir::MethodDefinition *nullishAccessor = accessor->Clone(Allocator(), interface->Body()); - auto *decl = Allocator()->New(Allocator(), nullishAccessor->Key()->AsIdentifier()->Name(), - nullishAccessor); + auto *decl = Allocator()->New(Allocator(), nullishAccessor->Id()->Name(), nullishAccessor); auto *var = Allocator()->New(decl, varbinder::VariableFlags::VAR); var->AddFlag(varbinder::VariableFlags::METHOD); nullishAccessor->Id()->SetVariable(var); @@ -550,8 +549,8 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co functionScope->BindName(interface->InternalName()); auto *function = nullishAccessor->Function(); - function->SetVariable(var); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) function->SetIdent(nullishAccessor->Id()->Clone(Allocator(), function)); function->SetScope(functionScope); @@ -562,12 +561,11 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co auto *propTypeAnn = function->ReturnTypeAnnotation(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *unionType = AllocNode( + function->SetReturnTypeAnnotation(AllocNode( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ArenaVector({propTypeAnn, AllocNode(Allocator())}, Allocator()->Adapter()), - Allocator()); - function->SetReturnTypeAnnotation(unionType); + Allocator())); } else { for (auto *params : function->Params()) { auto *paramExpr = params->AsETSParameterExpression(); @@ -583,12 +581,16 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co paramExpr->Ident()->SetTsTypeAnnotation(unionType); unionType->SetParent(paramExpr->Ident()); - auto *const paramVar = std::get<2>(paramScope->AddParamDecl(Allocator(), paramExpr)); + auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), paramExpr); + if (node != nullptr) { + VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name()); + } + paramExpr->SetVariable(paramVar); } } - ArenaVector overloads(Allocator()->Adapter()); - nullishAccessor->SetOverloads(std::move(overloads)); + + nullishAccessor->SetOverloads(ArenaVector(Allocator()->Adapter())); return nullishAccessor; } diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index cd810799f12204688b76f501f2b89fa566a3847c..7a86bfd8ea4ff5d41da138ef53eed7800344188c 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -55,18 +55,20 @@ void ETSChecker::ValidateCallExpressionIdentifier(ir::Identifier *const ident, T { if (ident->Variable()->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE) && ident->Parent()->AsCallExpression()->Callee() != ident) { - std::ignore = TypeError(ident->Variable(), - {"Class or interface '", ident->Name(), "' cannot be used as object"}, ident->Start()); + std::ignore = + TypeError(ident->Variable(), {"Class or interface '", ident->ToString(), "' cannot be used as object"}, + ident->Start()); } if (ident->Parent()->AsCallExpression()->Callee() != ident) { return; } - if (ident->Variable() != nullptr && // It should always be true! - ident->Variable()->Declaration()->Node() != nullptr && + + ES2PANDA_ASSERT(ident->Variable() != nullptr); + if (ident->Variable()->Declaration()->Node() != nullptr && ident->Variable()->Declaration()->Node()->IsImportNamespaceSpecifier()) { - std::ignore = TypeError(ident->Variable(), {"Namespace style identifier ", ident->Name(), " is not callable."}, - ident->Start()); + std::ignore = TypeError( + ident->Variable(), {"Namespace style identifier ", ident->ToString(), " is not callable."}, ident->Start()); } if (type->IsETSFunctionType() || type->IsETSDynamicType()) { return; @@ -82,10 +84,11 @@ void ETSChecker::ValidateCallExpressionIdentifier(ir::Identifier *const ident, T void ETSChecker::ValidateNewClassInstanceIdentifier(ir::Identifier *const ident) { auto const resolved = ident->Variable(); - if (ident->Parent()->AsETSNewClassInstanceExpression()->GetTypeRef() == ident && (resolved != nullptr) && - !resolved->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE)) { - LogUnresolvedReferenceError(ident); - return; + ES2PANDA_ASSERT(resolved != nullptr); + + if (ident->Parent()->AsETSNewClassInstanceExpression()->GetTypeRef() == ident && + !resolved->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE) && !resolved->TsType()->IsTypeError()) { + LogTypeError({"Invalid reference '", ident->Name(), "'."}, ident->Start()); } } @@ -104,19 +107,6 @@ void ETSChecker::ValidateMemberIdentifier(ir::Identifier *const ident) } } -void ETSChecker::ValidatePropertyOrDeclaratorIdentifier(ir::Identifier *const ident) -{ - auto const resolved = ident->Variable(); - if ((resolved != nullptr) && resolved->TsType() != nullptr && resolved->TsType()->IsETSFunctionType()) { - return; - } - - if ((resolved != nullptr) && !resolved->Declaration()->PossibleTDZ()) { - LogUnresolvedReferenceError(ident); - return; - } -} - void ETSChecker::ValidateAssignmentIdentifier(ir::Identifier *const ident, Type *const type) { auto const resolved = ident->Variable(); @@ -181,10 +171,6 @@ void ETSChecker::ValidateResolvedIdentifier(ir::Identifier *const ident) WrongContextErrorClassifyByType(ident); } break; - case ir::AstNodeType::CLASS_PROPERTY: - case ir::AstNodeType::VARIABLE_DECLARATOR: - ValidatePropertyOrDeclaratorIdentifier(ident); - break; case ir::AstNodeType::ASSIGNMENT_EXPRESSION: ValidateAssignmentIdentifier(ident, resolvedType); break; @@ -212,7 +198,7 @@ bool ETSChecker::ValidateAnnotationPropertyType(checker::Type *type) void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable) { - if (variable == nullptr || IsVariableGetterSetter(variable) || variable->Declaration() == nullptr) { + if (IsVariableGetterSetter(variable)) { return; } diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index 3666da3dc4a4b305cf401a3676e1c8860993ae1c..b1772fbd4fb4ebb493c7f1953fa6ae95e3ddf031 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -17,6 +17,7 @@ #include "checker/ETSchecker.h" #include "ets/etsObjectType.h" +#include "compiler/lowering/util.h" namespace ark::es2panda::checker { @@ -148,7 +149,7 @@ void Signature::ToString(std::stringstream &ss, const varbinder::Variable *varia ss << "("; for (auto it = signatureInfo_->params.begin(); it != signatureInfo_->params.end(); it++) { - ss << (*it)->Name(); + ss << (!(*it)->Name().StartsWith(compiler::GENSYM_CORE) ? (*it)->Name().Utf8() : compiler::DUMMY_ID); if ((*it)->HasFlag(varbinder::VariableFlags::OPTIONAL)) { ss << "?"; @@ -169,7 +170,9 @@ void Signature::ToString(std::stringstream &ss, const varbinder::Variable *varia } ss << "..."; - ss << signatureInfo_->restVar->Name(); + ss << (!signatureInfo_->restVar->Name().StartsWith(compiler::GENSYM_CORE) + ? signatureInfo_->restVar->Name().Utf8() + : compiler::DUMMY_ID); ss << ": "; signatureInfo_->restVar->TsType()->ToString(ss, precise); } diff --git a/ets2panda/compiler/base/lreference.cpp b/ets2panda/compiler/base/lreference.cpp index 066ac1be05fceed321990661e83eb2013650327c..88c4e1839ec708a526c20a787ceddf5511075e6f 100644 --- a/ets2panda/compiler/base/lreference.cpp +++ b/ets2panda/compiler/base/lreference.cpp @@ -206,27 +206,17 @@ ETSLReference::ETSLReference(CodeGen *cg, const ir::AstNode *node, ReferenceKind ETSLReference ETSLReference::Create(CodeGen *const cg, const ir::AstNode *const node, const bool isDeclaration) { if (node->Type() == ir::AstNodeType::IDENTIFIER) { - if (node->AsIdentifier()->Variable() != nullptr) { - auto *var = node->AsIdentifier()->Variable(); - varbinder::ConstScopeFindResult res; - res.name = var->Name(); - res.variable = var; - res.scope = var->GetScope(); - auto refKind = ReferenceKind::VAR_OR_GLOBAL; - if (var->HasFlag(varbinder::VariableFlags::PROPERTY)) { - refKind = ReferenceKind::FIELD; - } - return {cg, node, refKind, res, isDeclaration}; - } - - const auto &name = node->AsIdentifier()->Name(); - auto res = cg->Scope()->FindInFunctionScope(name, varbinder::ResolveBindingOptions::ALL); - if (res.variable == nullptr) { - res = cg->Scope()->FindInGlobal(name, varbinder::ResolveBindingOptions::ALL_VARIABLES | - varbinder::ResolveBindingOptions::ALL_METHOD); + auto *var = node->Variable(); + ES2PANDA_ASSERT(var != nullptr); + varbinder::ConstScopeFindResult res; + res.name = var->Name(); + res.variable = var; + res.scope = var->GetScope(); + auto refKind = ReferenceKind::VAR_OR_GLOBAL; + if (var->HasFlag(varbinder::VariableFlags::PROPERTY)) { + refKind = ReferenceKind::FIELD; } - - return {cg, node, ReferenceKind::VAR_OR_GLOBAL, res, isDeclaration}; + return {cg, node, refKind, res, isDeclaration}; } return std::make_from_tuple(CreateBase(cg, node, isDeclaration)); } diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index b809f2e7feb998ecd061e25ef8c189a1e9ec8087..d09918f019827b1cd674c75e36004da0cd0a7804 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -148,10 +148,6 @@ static bool RunVerifierAndPhases(public_lib::Context &context, const std::vector return false; } - if (name == compiler::ScopesInitPhase::NAME && context.diagnosticEngine->IsAnyError()) { - verifier.Suppress(); - } - if (verifierEachPhase || options.HasVerifierPhase(name)) { verifier.Verify(name); } diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index 294357dc9cd731caf400ad32c6b59ab9d697b27f..ffe21e87227132bd7770ac3634260e205f430d70 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -86,7 +86,10 @@ ir::FunctionSignature InterfacePropertyDeclarationsPhase::GenerateGetterOrSetter auto *const paramExpression = checker->AllocNode(paramIdent, false, checker->Allocator()); paramExpression->SetRange(paramIdent->Range()); - auto *const paramVar = std::get<2>(paramScope->AddParamDecl(checker->Allocator(), paramExpression)); + auto [paramVar, node] = paramScope->AddParamDecl(checker->Allocator(), paramExpression); + if (node != nullptr) { + varbinder->ThrowRedeclaration(node->Start(), paramVar->Name()); + } paramIdent->SetVariable(paramVar); paramExpression->SetVariable(paramVar); @@ -121,14 +124,14 @@ ir::MethodDefinition *InterfacePropertyDeclarationsPhase::GenerateGetterOrSetter isSetter ? ir::ScriptFunctionFlags::SETTER : ir::ScriptFunctionFlags::GETTER, flags}); func->SetRange(field->Range()); - func->SetScope(functionScope); auto const &name = field->Key()->AsIdentifier()->Name(); auto methodIdent = checker->AllocNode(name, checker->Allocator()); + auto *decl = checker->Allocator()->New(name); auto var = functionScope->AddDecl(checker->Allocator(), decl, ScriptExtension::STS); - + ES2PANDA_ASSERT(var != nullptr); methodIdent->SetVariable(var); auto *funcExpr = checker->AllocNode(func); diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 2af414bab14b192c0ad4def85a30539fcf35b360..a4c8588f80f8cdf250439b514817ef9e3423826c 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -167,7 +167,7 @@ ParamsAndVarMap CreateLambdaCalleeParameters(public_lib::Context *ctx, ir::Arrow allocator, capturedVar->Name(), allocator->New(newType, allocator), allocator); auto param = util::NodeAllocator::ForceSetParent(allocator, newId, false, allocator); - auto *var = std::get<1U>(varBinder->AddParamDecl(param)); + auto *var = varBinder->AddParamDecl(param); var->SetTsType(newType); var->SetScope(paramScope); param->SetVariable(var); @@ -187,7 +187,7 @@ ParamsAndVarMap CreateLambdaCalleeParameters(public_lib::Context *ctx, ir::Arrow newParam->Ident()->SetTsTypeAnnotation(allocator->New(newParamType, allocator)); newParam->Ident()->TypeAnnotation()->SetParent(newParam->Ident()); newParam->Ident()->SetVariable(nullptr); // Remove the cloned variable. - auto *var = std::get<1U>(varBinder->AddParamDecl(newParam)); + auto *var = varBinder->AddParamDecl(newParam); var->SetTsType(newParamType); var->SetScope(paramScope); newParam->SetVariable(var); @@ -275,8 +275,8 @@ static ir::MethodDefinition *SetUpCalleeMethod(public_lib::Context *ctx, LambdaI calleeClass->Definition()->Body().push_back(method); method->SetParent(calleeClass->Definition()); - auto [_, var] = varBinder->NewVarDecl(func->Start(), allocator, cmInfo->calleeName, func); - (void)_; + auto *var = + std::get<1>(varBinder->NewVarDecl(func->Start(), allocator, cmInfo->calleeName, func)); var->AddFlag(varbinder::VariableFlags::METHOD); var->SetScope(scopeForMethod); func->Id()->SetVariable(var); diff --git a/ets2panda/compiler/lowering/ets/localClassLowering.cpp b/ets2panda/compiler/lowering/ets/localClassLowering.cpp index 5eddd7679d235d2d33e58681b927b8115b18139a..e72b4b4aad741250d8334708daf6f359f9a9deff 100644 --- a/ets2panda/compiler/lowering/ets/localClassLowering.cpp +++ b/ets2panda/compiler/lowering/ets/localClassLowering.cpp @@ -26,8 +26,7 @@ std::string_view LocalClassConstructionPhase::Name() const } static ir::ClassProperty *CreateCapturedField(checker::ETSChecker *checker, const varbinder::Variable *capturedVar, - varbinder::ClassScope *scope, size_t &idx, - const lexer::SourcePosition &pos) + varbinder::ClassScope *scope, size_t &idx) { auto *allocator = checker->Allocator(); auto *varBinder = checker->VarBinder(); @@ -47,7 +46,7 @@ static ir::ClassProperty *CreateCapturedField(checker::ETSChecker *checker, cons fieldIdent->SetParent(field); // Add the declaration to the scope, and set the type based on the captured variable's scope - auto [decl, var] = varBinder->NewVarDecl(pos, fieldIdent->Name()); + auto [decl, var] = varBinder->NewVarDecl(fieldIdent->Start(), fieldIdent->Name()); var->SetScope(scope->InstanceFieldScope()); var->AddFlag(varbinder::VariableFlags::PROPERTY); var->SetTsType(capturedVar->TsType()); @@ -88,8 +87,8 @@ void LocalClassConstructionPhase::CreateClassPropertiesForCapturedVariables( ArenaVector properties(ctx->allocator->Adapter()); for (auto var : capturedVars) { ES2PANDA_ASSERT(classDef->Scope()->Type() == varbinder::ScopeType::CLASS); - auto *property = CreateCapturedField(checker, var, reinterpret_cast(classDef->Scope()), - idx, classDef->Start()); + auto *property = + CreateCapturedField(checker, var, reinterpret_cast(classDef->Scope()), idx); LOG(DEBUG, ES2PANDA) << " - Creating property (" << property->Id()->Name() << ") for captured variable: " << var->Name(); properties.push_back(property); @@ -110,7 +109,7 @@ ir::ETSParameterExpression *LocalClassConstructionPhase::CreateParam(checker::ET newParam->Ident()->SetTsType(type); auto paramCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), scope, false); - auto *paramVar = std::get<1>(checker->VarBinder()->AddParamDecl(newParam)); + auto *paramVar = checker->VarBinder()->AddParamDecl(newParam); paramVar->SetTsType(newParam->TsType()); newParam->Ident()->SetVariable(paramVar); return newParam; @@ -170,8 +169,10 @@ void LocalClassConstructionPhase::ModifyConstructorParameters( initStatement->SetParent(body); initStatements.push_back(initStatement); } - auto &statements = body->AsBlockStatement()->Statements(); - statements.insert(statements.begin(), initStatements.begin(), initStatements.end()); + if (body != nullptr && body->IsBlockStatement()) { + auto &statements = body->AsBlockStatement()->Statements(); + statements.insert(statements.begin(), initStatements.begin(), initStatements.end()); + } } } @@ -206,7 +207,9 @@ void LocalClassConstructionPhase::RemapReferencesFromCapturedVariablesToClassPro for (auto *signature : classType->ConstructSignatures()) { auto *constructor = signature->Function(); LOG(DEBUG, ES2PANDA) << " - Rebinding variable rerferences in: " << constructor->Id()->Name(); - constructor->Body()->IterateRecursively(remapCapturedVariables); + if (constructor->Body() != nullptr) { + constructor->Body()->IterateRecursively(remapCapturedVariables); + } } } diff --git a/ets2panda/compiler/lowering/ets/tupleLowering.cpp b/ets2panda/compiler/lowering/ets/tupleLowering.cpp index f27282a0799b5cc0174efe511494ac60e38196d3..90c1d4ed7c19083af8b3462340d7b654620db723 100644 --- a/ets2panda/compiler/lowering/ets/tupleLowering.cpp +++ b/ets2panda/compiler/lowering/ets/tupleLowering.cpp @@ -125,12 +125,12 @@ private: std::tuple GenerateSymbol(checker::Type *const type) const { auto *gensym = Gensym(checker_->Allocator()); - auto *const tmpVar = NearestScope(update_)->AddDecl( + auto [variable, _] = NearestScope(update_)->AddDecl( checker_->Allocator(), gensym->Name(), varbinder::VariableFlags::LOCAL); - tmpVar->SetTsType(type); - gensym->SetVariable(tmpVar); - gensym->SetTsType(tmpVar->TsType()); - return std::make_tuple(gensym, tmpVar); + gensym->SetVariable(variable); + variable->SetTsType(type); + gensym->SetTsType(type); + return std::make_tuple(gensym, variable->AsLocalVariable()); } std::tuple CloneArgument( diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index 2c16f6511ee9f1a1d07f8937ad17397ed00a754e..0885e637e1c72141b38d23fa8db94144658af007 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -15,6 +15,7 @@ #include "scopesInitPhase.h" #include "util/diagnosticEngine.h" +#include "compiler/lowering/util.h" namespace ark::es2panda::compiler { @@ -209,14 +210,10 @@ void ScopesInitPhase::VisitCatchClause(ir::CatchClause *catchClause) CallNode(param); if (param != nullptr) { - if (auto *const var = std::get<1>(VarBinder()->AddParamDecl(param)); var != nullptr) { - if (param->IsIdentifier()) { - var->SetScope(catchParamScope); - param->AsIdentifier()->SetVariable(var); - } - } else { - ASSERT(Context()->diagnosticEngine->IsAnyError()); - param->SetTsType(Context()->checker->AsETSChecker()->GlobalTypeError()); + auto *const var = VarBinder()->AddParamDecl(param); + if (param->IsIdentifier()) { + var->SetScope(catchParamScope); + param->AsIdentifier()->SetVariable(var); } } @@ -238,10 +235,8 @@ void ScopesInitPhase::VisitVariableDeclarator(ir::VariableDeclarator *varDecl) auto init = varDecl->Id(); std::vector bindings = util::Helpers::CollectBindingNames(init); for (auto *binding : bindings) { - auto [decl, var] = AddOrGetVarDecl(varDecl->Flag(), varDecl->Start(), binding); - if (var != nullptr) { - BindVarDecl(binding, init, decl, var); - } + auto [decl, var] = AddOrGetVarDecl(varDecl->Flag(), binding); + BindVarDecl(binding, init, decl, var); } Iterate(varDecl); } @@ -473,7 +468,6 @@ void ScopesInitPhase::BindClassDefinition(ir::ClassDefinition *classDef) } std::tuple ScopesInitPhase::AddOrGetVarDecl(ir::VariableDeclaratorFlag flag, - lexer::SourcePosition startLoc, const ir::Identifier *id) { if (auto var = id->Variable(); var != nullptr) { @@ -482,16 +476,22 @@ std::tuple ScopesInitPhase::AddOrGetVa auto name = id->Name(); if (name.Is(ERROR_LITERAL)) { - return {nullptr, nullptr}; + name = compiler::GenName(Allocator()).View(); + } else if (VarBinder()->IsETSBinder()) { + if (auto var = VarBinder()->GetScope()->FindLocal(name, varbinder::ResolveBindingOptions::ALL_VARIABLES); + var != nullptr) { + VarBinder()->ThrowRedeclaration(id->Start(), name); + return {var->Declaration(), var}; + } } switch (flag) { case ir::VariableDeclaratorFlag::LET: - return VarBinder()->NewVarDecl(startLoc, name); + return VarBinder()->NewVarDecl(id->Start(), name); case ir::VariableDeclaratorFlag::VAR: - return VarBinder()->NewVarDecl(startLoc, name); + return VarBinder()->NewVarDecl(id->Start(), name); case ir::VariableDeclaratorFlag::CONST: - return VarBinder()->NewVarDecl(startLoc, name); + return VarBinder()->NewVarDecl(id->Start(), name); default: UNREACHABLE(); } @@ -873,12 +873,15 @@ void InitScopesPhaseETS::VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock return; } - auto *var = std::get<1>(VarBinder()->NewVarDecl(staticBlock->Start(), Allocator(), - func->Id()->Name(), staticBlock)); - if (var != nullptr) { + varbinder::Variable *var; + if (var = VarBinder()->GetScope()->FindLocal(func->Id()->Name(), varbinder::ResolveBindingOptions::STATIC_METHODS); + var == nullptr) { + var = std::get<1>(VarBinder()->NewVarDecl(func->Id()->Start(), Allocator(), + func->Id()->Name(), staticBlock)); var->AddFlag(varbinder::VariableFlags::METHOD); - func->Id()->SetVariable(var); } + + func->Id()->SetVariable(var); } void InitScopesPhaseETS::VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier *importSpec) @@ -897,8 +900,8 @@ void InitScopesPhaseETS::VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecif void InitScopesPhaseETS::VisitImportSpecifier(ir::ImportSpecifier *importSpec) { if (importSpec->Parent()->AsETSImportDeclaration()->IsPureDynamic()) { - auto [decl, var] = - VarBinder()->NewVarDecl(importSpec->Start(), importSpec->Local()->Name(), importSpec); + auto [decl, var] = VarBinder()->NewVarDecl(importSpec->Local()->Start(), + importSpec->Local()->Name(), importSpec); var->AddFlag(varbinder::VariableFlags::INITIALIZED); } Iterate(importSpec); @@ -988,14 +991,11 @@ void InitScopesPhaseETS::VisitETSReExportDeclaration(ir::ETSReExportDeclaration void InitScopesPhaseETS::VisitETSParameterExpression(ir::ETSParameterExpression *paramExpr) { - if (auto *const var = std::get<1>(VarBinder()->AddParamDecl(paramExpr)); var != nullptr) { - paramExpr->Ident()->SetVariable(var); - var->SetScope(VarBinder()->GetScope()); - var->AddFlag(varbinder::VariableFlags::INITIALIZED); - Iterate(paramExpr); - } else { - paramExpr->SetTsType(paramExpr->Ident()->SetTsType(Context()->checker->AsETSChecker()->GlobalTypeError())); - } + auto *const var = VarBinder()->AddParamDecl(paramExpr); + paramExpr->SetVariable(var); + var->SetScope(VarBinder()->GetScope()); + var->AddFlag(varbinder::VariableFlags::INITIALIZED); + Iterate(paramExpr); } void InitScopesPhaseETS::VisitETSImportDeclaration(ir::ETSImportDeclaration *importDecl) @@ -1014,15 +1014,21 @@ void InitScopesPhaseETS::VisitTSEnumMember(ir::TSEnumMember *enumMember) return; } - auto [decl, var] = VarBinder()->NewVarDecl(ident->Start(), ident->Name()); - if (var == nullptr) { - return; + auto const &name = ident->Name(); + varbinder::Variable *var = nullptr; + + if (var = VarBinder()->GetScope()->FindLocal(name, varbinder::ResolveBindingOptions::STATIC_VARIABLES); + var == nullptr) { + varbinder::Decl *decl = nullptr; + std::tie(decl, var) = VarBinder()->NewVarDecl(ident->Start(), name); + var->SetScope(VarBinder()->GetScope()); + var->AddFlag(varbinder::VariableFlags::STATIC); + decl->BindNode(enumMember); + } else { + VarBinder()->ThrowRedeclaration(ident->Start(), name); } - var->SetScope(VarBinder()->GetScope()); - var->AddFlag(varbinder::VariableFlags::STATIC); ident->SetVariable(var); - decl->BindNode(enumMember); Iterate(enumMember); } diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.h b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.h index dabd3e33ab064e9ce9bce558c1f228808c1381a7..3c5e35659f446d23e05a2ee870a540dbfc84e668 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.h +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.h @@ -187,7 +187,6 @@ protected: void BindClassDefinition(ir::ClassDefinition *classDef); std::tuple AddOrGetVarDecl(ir::VariableDeclaratorFlag flag, - lexer::SourcePosition startLoc, const ir::Identifier *id); virtual void BindVarDecl([[maybe_unused]] ir::Identifier *binding, ir::Expression *init, varbinder::Decl *decl, diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index 8b1bba6c6804d0c20459046e81e8828008ea3e59..cf3a4cd25ec225de9cb3ac16728ed39aedc5f22b 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -46,10 +46,8 @@ ir::Identifier *Gensym(ArenaAllocator *const allocator) util::UString GenName(ArenaAllocator *const allocator) { - static std::string const GENSYM_CORE = "gensym%%_"; static std::size_t gensymCounter = 0U; - - return util::UString {GENSYM_CORE + std::to_string(++gensymCounter), allocator}; + return util::UString {std::string(GENSYM_CORE) + std::to_string(++gensymCounter), allocator}; } void SetSourceRangesRecursively(ir::AstNode *node, const lexer::SourceRange &range) diff --git a/ets2panda/compiler/lowering/util.h b/ets2panda/compiler/lowering/util.h index df57fe6e769a7883fc72ecf931343d5b5a3499fc..450392eb533bc1e14abaeba21b705c6bed9cdf48 100644 --- a/ets2panda/compiler/lowering/util.h +++ b/ets2panda/compiler/lowering/util.h @@ -16,12 +16,13 @@ #ifndef ES2PANDA_COMPILER_LOWERING_UTIL_H #define ES2PANDA_COMPILER_LOWERING_UTIL_H -#include "ir/astNode.h" -#include "checker/types/ets/etsObjectType.h" #include "varbinder/ETSBinder.h" namespace ark::es2panda::compiler { +inline constexpr std::string_view const GENSYM_CORE = "gensym%%_"; +inline constexpr std::string_view const DUMMY_ID = "_"; + varbinder::Scope *NearestScope(const ir::AstNode *ast); checker::ETSObjectType const *ContainingClass(const ir::AstNode *ast); ir::Identifier *Gensym(ArenaAllocator *allocator); diff --git a/ets2panda/ir/astNode.cpp b/ets2panda/ir/astNode.cpp index 7bc898727e7f843e4095465428b73f2831e300fb..0168fb5fb8d9eb4b986f1f9770caee62cb86df76 100644 --- a/ets2panda/ir/astNode.cpp +++ b/ets2panda/ir/astNode.cpp @@ -210,7 +210,7 @@ AstNode *AstNode::FindChild(const NodePredicate &cb) const return found; } -varbinder::Scope *AstNode::EnclosingScope(const ir::AstNode *expr) +varbinder::Scope *AstNode::EnclosingScope(const ir::AstNode *expr) noexcept { while (expr != nullptr && !expr->IsScopeBearer()) { expr = expr->Parent(); diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index fbeb0df4126fbee4b20df7442010466a9992464b..30ef3dbf05a77bb4b4105ff668ccc188fd3a3fad 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -513,7 +513,7 @@ public: ir::ClassElement *AsClassElement(); const ir::ClassElement *AsClassElement() const; - static varbinder::Scope *EnclosingScope(const ir::AstNode *expr); + [[nodiscard]] static varbinder::Scope *EnclosingScope(const ir::AstNode *expr) noexcept; [[nodiscard]] virtual bool IsScopeBearer() const noexcept; [[nodiscard]] virtual varbinder::Scope *Scope() const noexcept; diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index 7620abf1a2600b23ba0969969e55b55f76732e3f..ce8ccc290f0893e23ed475fa74c0d10424713b2f 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -121,6 +121,10 @@ checker::Type *ETSTypeReferencePart::HandleInternalTypes(checker::ETSChecker *co return HandlePartialType(checker, ident); } + if (ident->IsErrorPlaceHolder()) { + return checker->GlobalTypeError(); + } + return nullptr; } diff --git a/ets2panda/ir/expressions/identifier.cpp b/ets2panda/ir/expressions/identifier.cpp index e678eacd6a388ce5c97020937e822f85b4fd3037..9bc10a098c83fbebf9e3d8113a44b3276ff5cc5b 100644 --- a/ets2panda/ir/expressions/identifier.cpp +++ b/ets2panda/ir/expressions/identifier.cpp @@ -453,7 +453,7 @@ bool Identifier::CheckDeclarationsPart2(const ir::AstNode *parent, ScriptExtensi std::string Identifier::ToString() const { - if (!Name().Empty() && Name() != ERROR_LITERAL) { + if (!Name().Empty() && !Name().Is(ERROR_LITERAL)) { return std::string {Name().Utf8()}; } diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type12.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type12.sts index 64366d4aad9a34a8c68c5a5af587ab51b87df31f..c44a9295afc25de584c2d60e7186f598ba3ee4c1 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type12.sts +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type12.sts @@ -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 @@ a:string = "1" } -let a = MyAnno +let a = /* @@ label */MyAnno -/* @@? 19:9 Error TypeError: Annotation missing '@' symbol before annotation name. */ -/* @@? 19:9 Error TypeError: Unresolved reference MyAnno */ -/* @@? 19:9 Error TypeError: Annotation missing '@' symbol before annotation name. */ -/* @@? 19:9 Error TypeError: Unresolved reference MyAnno */ +/* @@@ label Error TypeError: Annotation missing '@' symbol before annotation name. */ +/* @@@ label Error TypeError: Annotation name 'MyAnno' used in the wrong context */ +/* @@@ label Error TypeError: Annotation missing '@' symbol before annotation name. */ +/* @@@ label Error TypeError: Annotation name 'MyAnno' used in the wrong context */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT02.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT02.sts index 6fc7166c0bfc3c696f934e70e7b84801933b1bd5..e3162c42f3bb501dd8d68d23e8393eea88699497 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT02.sts +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT02.sts @@ -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,8 +15,8 @@ @interface MyAnno { } -MyAnno +/* @@ label */MyAnno function foo(): void {} -/* @@? 18:1 Error TypeError: Annotation missing '@' symbol before annotation name. */ -/* @@? 18:1 Error TypeError: Unresolved reference MyAnno */ +/* @@@ label Error TypeError: Annotation missing '@' symbol before annotation name. */ +/* @@@ label Error TypeError: Annotation name 'MyAnno' used in the wrong context */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.sts b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.sts index cf11cdf903fc957b191a60e464d78257a574dabb..ba6199220047a079322bdced5134f07bbb3ea6fa 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.sts +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.sts @@ -29,6 +29,8 @@ let myvar: number = wont_exist; /* @@? package_module_2_neg.sts:20:30 Error SyntaxError: Unexpected token 'error'. */ /* @@? package_module_2_neg.sts:20:30 Error TypeError: Unresolved reference error */ /* @@? package_module_2_neg.sts:20:35 Error SyntaxError: Unexpected token ','. */ +/* @@? package_module_2_neg.sts:20:35 Error SyntaxError: Unexpected token ','. */ +/* @@? package_module_2_neg.sts:20:35 Error SyntaxError: Unexpected token ','. */ /* @@? package_module_2_neg.sts:20:37 Error TypeError: Unresolved reference but */ /* @@? package_module_2_neg.sts:20:41 Error SyntaxError: Unexpected token 'compilation'. */ /* @@? package_module_2_neg.sts:20:41 Error TypeError: Unresolved reference compilation */ @@ -42,9 +44,9 @@ let myvar: number = wont_exist; /* @@? package_module_2_neg.sts:20:82 Error SyntaxError: Unexpected token 'aborted'. */ /* @@? package_module_2_neg.sts:20:82 Error TypeError: Unresolved reference aborted */ /* @@? package_module_2_neg.sts:20:89 Error SyntaxError: Unexpected token ','. */ -/* @@? package_module_2_neg.sts:20:91 Error TypeError: Unresolved reference file */ +/* @@? package_module_2_neg.sts:20:89 Error SyntaxError: Unexpected token ','. */ +/* @@? package_module_2_neg.sts:20:89 Error SyntaxError: Unexpected token ','. */ /* @@? package_module_2_neg.sts:20:96 Error SyntaxError: Unexpected token 'is'. */ -/* @@? package_module_2_neg.sts:20:96 Error TypeError: Unresolved reference is */ /* @@? package_module_2_neg.sts:20:99 Error SyntaxError: Unexpected token 'just'. */ /* @@? package_module_2_neg.sts:20:99 Error TypeError: Unresolved reference just */ /* @@? package_module_2_neg.sts:20:104 Error SyntaxError: Unexpected token 'ignored'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.sts b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.sts index 52f554a712c0362277031861de8563052d2bfe34..6e56a6d18f9c59a5354ace67eec2231660f64197 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.sts +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.sts @@ -31,6 +31,8 @@ this file will contain parse error, but compilation of 'package_module_1' is not /* @@? 20:30 Error SyntaxError: Unexpected token 'error'. */ /* @@? 20:30 Error TypeError: Unresolved reference error */ /* @@? 20:35 Error SyntaxError: Unexpected token ','. */ +/* @@? 20:35 Error SyntaxError: Unexpected token ','. */ +/* @@? 20:35 Error SyntaxError: Unexpected token ','. */ /* @@? 20:37 Error TypeError: Unresolved reference but */ /* @@? 20:41 Error SyntaxError: Unexpected token 'compilation'. */ /* @@? 20:41 Error TypeError: Unresolved reference compilation */ @@ -44,9 +46,9 @@ this file will contain parse error, but compilation of 'package_module_1' is not /* @@? 20:82 Error SyntaxError: Unexpected token 'aborted'. */ /* @@? 20:82 Error TypeError: Unresolved reference aborted */ /* @@? 20:89 Error SyntaxError: Unexpected token ','. */ -/* @@? 20:91 Error TypeError: Unresolved reference file */ +/* @@? 20:89 Error SyntaxError: Unexpected token ','. */ +/* @@? 20:89 Error SyntaxError: Unexpected token ','. */ /* @@? 20:96 Error SyntaxError: Unexpected token 'is'. */ -/* @@? 20:96 Error TypeError: Unresolved reference is */ /* @@? 20:99 Error SyntaxError: Unexpected token 'just'. */ /* @@? 20:99 Error TypeError: Unresolved reference just */ /* @@? 20:104 Error SyntaxError: Unexpected token 'ignored'. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.sts b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.sts index d62ed069c121b7b33dfbbf09a892bd620d52b2e3..23978cbbb210953f9d8d3743f483b271f98bf4bc 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.sts +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.sts @@ -31,4 +31,4 @@ function bar(x: notInit) { (=_=) } /* @@? package_with_errors_1.sts:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ /* @@? package_with_errors_1.sts:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ /* @@? package_with_errors_2.sts:19:16 Error TypeError: Unresolved reference foo */ -/* @@? package_with_errors_2.sts:19:16 Error TypeError: Unresolved reference foo */ \ No newline at end of file +/* @@? package_with_errors_2.sts:19:16 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.sts b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.sts index 381a5f1e9d284206f0c3e1117faf3cb961e24038..d8a71c204f560eee2aa880b509bdee55f6573a23 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.sts +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.sts @@ -30,4 +30,4 @@ export let moreImportantInfo = importantInfo as number; /* @@? package_with_errors_1.sts:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ /* @@? package_with_errors_1.sts:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ /* @@? package_with_errors_2.sts:19:16 Error TypeError: Unresolved reference foo */ -/* @@? package_with_errors_2.sts:19:16 Error TypeError: Unresolved reference foo */ +/* @@? package_with_errors_2.sts:19:16 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.sts b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.sts index b21d3706eb1ffd21afbf10130433cecfb4333535..578b8634c3f6f94449a0a5bbbcf69f644aa76428 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.sts +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.sts @@ -32,4 +32,4 @@ export notInit /* @@? package_with_errors_1.sts:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ /* @@? package_with_errors_1.sts:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ /* @@? package_with_errors_2.sts:19:16 Error TypeError: Unresolved reference foo */ -/* @@? package_with_errors_2.sts:19:16 Error TypeError: Unresolved reference foo */ +/* @@? package_with_errors_2.sts:19:16 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.sts b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.sts index 208a6dc12fb4bdb1d68e8df3ce1d6f216929dea9..fdef3178fe307b3cd54768787c50cb0b0ef1adf6 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.sts +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.sts @@ -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 @@ namespace MySpace { let a:string = "1" } -let a = MySpace +let a = /* @@ label */MySpace -/* @@? 19:9 Error TypeError: Unresolved reference MySpace */ -/* @@? 19:9 Error TypeError: Unresolved reference MySpace */ +/* @@@ label Error TypeError: Namespace name 'MySpace' used in the wrong context */ +/* @@@ label Error TypeError: Namespace name 'MySpace' used in the wrong context */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/callExpr_pos.sts b/ets2panda/test/ast/compiler/ets/same_assembly_overload/callExpr_pos.sts index 849dcf0c270a04a69ae2c1017c1b99a6065c157c..6a323766fd983a67dd214be784e7aae60522b1de 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/callExpr_pos.sts +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/callExpr_pos.sts @@ -14,7 +14,7 @@ */ class A {} -declare function foo(a:A):void +declare function foo(a:A):void declare function foo(a:A):number declare function foo(a:int, b:int):void declare function foo(a:double):void @@ -25,4 +25,4 @@ foo(1,2) foo(1.1) /* @@? 17:1 Warning Warning: Function foo with this assembly signature already declared. */ -/* @@? 23:1 Warning Warning: Detect duplicate signatures, use 'foo(...gensym%%_1: (Object|null|undefined)[]): void' to replace */ +/* @@? 23:1 Warning Warning: Detect duplicate signatures, use 'foo(..._: (Object|null|undefined)[]): void' to replace */ diff --git a/ets2panda/test/ast/compiler/ets/same_name_field_err.sts b/ets2panda/test/ast/compiler/ets/same_name_field_err.sts index bb35ac9aadeb58a72f0b80917f4313676194c5a8..c5a321c0b36286b43449044c49225b112f084e46 100644 --- a/ets2panda/test/ast/compiler/ets/same_name_field_err.sts +++ b/ets2panda/test/ast/compiler/ets/same_name_field_err.sts @@ -23,4 +23,5 @@ function main(): void { assertEQ(SameName.a, 32); } -/* @@? 19:12 Error TypeError: Variable 'a' has already been declared. */ +/* @@? 19:12 Error TypeError: Variable 'a' has already been declared. */ +/* @@? 19:12 Error TypeError: Property 'a' must be accessed through 'this' */ diff --git a/ets2panda/test/ast/compiler/ets/string_tuple_type_neg.sts b/ets2panda/test/ast/compiler/ets/string_tuple_type_neg.sts index 73758015633b83495784c72e2208e1ef7921bc89..73023dd24bbe0810d50bc1f966ca7e86f39994b9 100644 --- a/ets2panda/test/ast/compiler/ets/string_tuple_type_neg.sts +++ b/ets2panda/test/ast/compiler/ets/string_tuple_type_neg.sts @@ -15,16 +15,16 @@ type A = [n1:string, n2:string] -/* @@? 16:11 Error TypeError: Cannot find type 'n1'. */ -/* @@? 16:13 Error SyntaxError: Unexpected token, expected ',' or ']'. */ -/* @@? 16:13 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:13 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:14 Error TypeError: Unresolved reference string */ -/* @@? 16:20 Error SyntaxError: Unexpected token ','. */ -/* @@? 16:20 Error SyntaxError: Unexpected token ','. */ -/* @@? 16:20 Error SyntaxError: Unexpected token ','. */ -/* @@? 16:25 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 16:25 Error TypeError: Unresolved reference string */ -/* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ \ No newline at end of file +/* @@? 16:11 Error TypeError: Cannot find type 'n1'. */ +/* @@? 16:13 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 16:13 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:13 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:14 Error TypeError: Type name 'string' used in the wrong context */ +/* @@? 16:20 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:20 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:20 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:25 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 16:25 Error TypeError: Type name 'string' used in the wrong context */ +/* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.sts b/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.sts index 62db1d707ea16239b34d4617f9ede45238f0e670..e183093f43332c10f492f6b8946756f152ee63cd 100644 --- a/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.sts +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.sts @@ -25,10 +25,6 @@ function foo() { } /* @@? 16:1 Error TypeError: Unresolved reference a */ -/* @@? 17:1 Error TypeError: Unresolved reference a */ -/* @@? 18:1 Error TypeError: Unresolved reference a */ /* @@? 20:1 Error TypeError: Unresolved reference c */ -/* @@? 21:9 Error TypeError: Unresolved reference a */ -/* @@? 21:17 Error TypeError: Unresolved reference c */ /* @@? 24:5 Error TypeError: Unresolved reference void */ /* @@? 24:18 Error TypeError: Unresolved reference asyncGenerator */ diff --git a/ets2panda/test/ast/compiler/ets/unresolved_reference.sts b/ets2panda/test/ast/compiler/ets/unresolved_reference.sts index 57a0208631981359ca84d3eeb1e774e84b3f2065..f2dff3a5f03ca1c9f2220cca228ded133516c56c 100644 --- a/ets2panda/test/ast/compiler/ets/unresolved_reference.sts +++ b/ets2panda/test/ast/compiler/ets/unresolved_reference.sts @@ -38,9 +38,4 @@ function main() { } /* @@? 28:13 Error TypeError: Unresolved reference b */ -/* @@? 28:13 Error TypeError: Unresolved reference b */ -/* @@? 16:13 Error TypeError: Unresolved reference b */ -/* @@? 20:13 Error TypeError: Unresolved reference b */ -/* @@? 24:18 Error TypeError: Unresolved reference b */ -/* @@? 32:17 Error TypeError: Unresolved reference b */ /* @@? 37:21 Error TypeError: Property 'b' does not exist on type 'A' */ diff --git a/ets2panda/test/ast/compiler/ets/variable_declaretion_neg_1.sts b/ets2panda/test/ast/compiler/ets/variable_declaretion_neg_1.sts index fafd6e420214669529bf222e62cdbcb14ebda5cd..1d86cb406191d26f763723a66b7ec2a2567c9923 100644 --- a/ets2panda/test/ast/compiler/ets/variable_declaretion_neg_1.sts +++ b/ets2panda/test/ast/compiler/ets/variable_declaretion_neg_1.sts @@ -18,5 +18,7 @@ let negative%%_ = 1 /* @@? 16:13 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 16:13 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 16:13 Error SyntaxError: Unexpected token '%'. */ +/* @@? 16:13 Error SyntaxError: Unexpected token '%'. */ +/* @@? 16:13 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 16:14 Error SyntaxError: Unexpected token '%'. */ /* @@? 16:15 Error TypeError: Unresolved reference _ */ diff --git a/ets2panda/test/ast/parser/ets/Dollar_doller_invalid3.sts b/ets2panda/test/ast/parser/ets/Dollar_doller_invalid3.sts index caac3c0e51e4f23620d80630858b6d66f96f3eec..dece3f1eb2a782ee226e89c7e517c9270d38dc15 100644 --- a/ets2panda/test/ast/parser/ets/Dollar_doller_invalid3.sts +++ b/ets2panda/test/ast/parser/ets/Dollar_doller_invalid3.sts @@ -24,5 +24,3 @@ class A { } /* @@? 22:28 Error TypeError: Unresolved reference $$this */ -/* @@? 22:45 Error TypeError: Unresolved reference $$this */ -/* @@? 22:62 Error TypeError: Unresolved reference $$this */ diff --git a/ets2panda/test/ast/parser/ets/InvalidClasses.sts b/ets2panda/test/ast/parser/ets/InvalidClasses.sts index 445538a978f0f57c5a2f9baa938d22d3fc3079c9..bb4f84e354669e2cdc71815ee78882f896088ebc 100644 --- a/ets2panda/test/ast/parser/ets/InvalidClasses.sts +++ b/ets2panda/test/ast/parser/ets/InvalidClasses.sts @@ -91,7 +91,6 @@ interface I1 { /* @@? 27:5 Error TypeError: Non abstract class has abstract method. */ /* @@? 27:20 Error SyntaxError: Abstract method cannot be async. */ /* @@? 35:5 Error SyntaxError: Only one static block is allowed. */ -/* @@? 35:5 Error TypeError: Variable '' has already been declared. */ /* @@? 38:10 Error SyntaxError: Duplicated modifier is not allowed. */ /* @@? 41:5 Error SyntaxError: The special predefined method '$_get' should have exactly one required parameter. */ /* @@? 41:5 Error SyntaxError: The special predefined method '$_get' cannot be asynchronous. */ @@ -99,8 +98,8 @@ interface I1 { /* @@? 45:5 Error SyntaxError: The special predefined method '$_set' should have exactly two required parameter. */ /* @@? 45:5 Error SyntaxError: The special predefined method '$_set' cannot be asynchronous. */ /* @@? 45:16 Error TypeError: Only abstract or native methods can't have body. */ -/* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' should not have parameters. */ /* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' cannot be asynchronous. */ +/* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' should not have parameters. */ /* @@? 47:21 Error TypeError: The return type of '$_iterator' must be a type that implements Iterator interface. */ /* @@? 47:21 Error TypeError: Return type of async function must be 'Promise'. */ /* @@? 54:21 Error TypeError: Initializers are not allowed in ambient contexts: x */ @@ -117,8 +116,8 @@ interface I1 { /* @@? 66:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ /* @@? 66:18 Error SyntaxError: Private interface methods must have body. */ /* @@? 67:9 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ -/* @@? 67:16 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ /* @@? 67:16 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 67:16 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ /* @@? 67:16 Error SyntaxError: Identifier expected. */ /* @@? 67:24 Error SyntaxError: Private interface methods must have body. */ /* @@? 72:5 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ @@ -128,6 +127,6 @@ interface I1 { /* @@? 74:14 Error TypeError: Extension function can only defined for class, interface or array. */ /* @@? 74:25 Error SyntaxError: Extension Accessor must have a receiver. */ /* @@? 78:8 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 78:8 Error TypeError: Unresolved reference number */ +/* @@? 78:8 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 79:1 Error SyntaxError: Unexpected token '}'. */ /* @@? 79:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidExpressions1.sts b/ets2panda/test/ast/parser/ets/InvalidExpressions1.sts index 8362478abfb3be99830b6c224587f7ec807ffe11..bd061402abb334a1815da3f9822ed14041297d42 100644 --- a/ets2panda/test/ast/parser/ets/InvalidExpressions1.sts +++ b/ets2panda/test/ast/parser/ets/InvalidExpressions1.sts @@ -63,12 +63,13 @@ let a = [1, 2, 3); /* @@? 22:11 Error SyntaxError: Unexpected token at */ /* @@? 24:5 Error TypeError: Variable 'a' has already been declared. */ /* @@? 24:18 Error TypeError: The type of parameter 'y' cannot be inferred */ -/* @@? 24:19 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 24:19 Error SyntaxError: Expected '=>', got '...'. */ +/* @@? 24:18 Error TypeError: The type of parameter 'y' cannot be inferred */ /* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ /* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ /* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ /* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ +/* @@? 24:19 Error SyntaxError: Expected '=>', got '...'. */ +/* @@? 24:19 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 24:22 Error SyntaxError: Unexpected token ','. */ /* @@? 24:22 Error SyntaxError: Unexpected token ','. */ /* @@? 24:24 Error SyntaxError: Unexpected token ')'. */ @@ -79,20 +80,20 @@ let a = [1, 2, 3); /* @@? 24:27 Error SyntaxError: Unexpected token 'void'. */ /* @@? 24:32 Error SyntaxError: Unexpected token '=>'. */ /* @@? 24:32 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 26:5 Error TypeError: Unresolved reference x */ /* @@? 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. */ /* @@? 28:20 Error SyntaxError: Expected '}', got ')'. */ /* @@? 30:5 Error TypeError: Variable 'a' has already been declared. */ -/* @@? 30:13 Error SyntaxError: Invalid Type. */ -/* @@? 30:13 Error SyntaxError: Unexpected token 'import'. */ /* @@? 30:13 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ +/* @@? 30:13 Error SyntaxError: Unexpected token 'import'. */ +/* @@? 30:13 Error SyntaxError: Invalid Type. */ /* @@? 30:13 Error TypeError: 'import' expressions require string as argument. */ /* @@? 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: 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 ']'. */ @@ -100,4 +101,4 @@ let a = [1, 2, 3); /* @@? 38:17 Error SyntaxError: Unexpected token ')'. */ /* @@? 38:17 Error SyntaxError: Unexpected token ')'. */ /* @@? 38:17 Error SyntaxError: Unexpected token ')'. */ -/* @@? 38:17 Error SyntaxError: Unexpected token, expected ',' or ']'. */ \ No newline at end of file +/* @@? 38:17 Error SyntaxError: Unexpected token, expected ',' or ']'. */ diff --git a/ets2panda/test/ast/parser/ets/MultipleParserErrors.sts b/ets2panda/test/ast/parser/ets/MultipleParserErrors.sts index a89e953578015848aa12c26014cc166809ebf60f..cb678ae9f5d1301b025b2ed04ea215cb94bc7006 100644 --- a/ets2panda/test/ast/parser/ets/MultipleParserErrors.sts +++ b/ets2panda/test/ast/parser/ets/MultipleParserErrors.sts @@ -198,7 +198,6 @@ function main(): void { /* @@? 51:38 Error SyntaxError: Unexpected token ')'. */ /* @@? 51:39 Error SyntaxError: Unexpected token ':'. */ /* @@? 51:39 Error SyntaxError: Unexpected token ':'. */ -/* @@? 51:41 Error TypeError: Unresolved reference int */ /* @@? 51:45 Error SyntaxError: Unexpected token '{'. */ /* @@? 52:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 52:12 Error TypeError: Unresolved reference q */ @@ -220,11 +219,11 @@ function main(): void { /* @@? 93:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 103:25 Error SyntaxError: Rest parameter should be of an array type. */ /* @@? 104:32 Error SyntaxError: Rest parameter should be of an array type. */ +/* @@? 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:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ -/* @@? 115:26 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 115:32 Error TypeError: Unresolved reference U */ @@ -244,29 +243,27 @@ function main(): void { /* @@? 119:26 Error SyntaxError: Unexpected token 'case'. */ /* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ -/* @@? 119:32 Error TypeError: Unresolved reference U */ /* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ /* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ /* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ /* @@? 119:34 Error SyntaxError: Unexpected token ':'. */ /* @@? 119:34 Error SyntaxError: Unexpected token ':'. */ -/* @@? 119:36 Error TypeError: Unresolved reference T */ /* @@? 119:38 Error SyntaxError: Unexpected token '{'. */ /* @@? 120:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 120:12 Error TypeError: All return statements in the function should be empty or have a value. */ /* @@? 123:5 Error SyntaxError: Identifier expected, got ','. */ -/* @@? 123:6 Error SyntaxError: Unexpected token 'abc'. */ /* @@? 123:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 123:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 123:6 Error SyntaxError: Unexpected token 'abc'. */ /* @@? 123:6 Error TypeError: Unresolved reference abc */ /* @@? 127:1 Error SyntaxError: The modifier async cannot be used in an ambient context. */ /* @@? 131:9 Error TypeError: This statement can cause an exception, therefore it must be enclosed in a try statement with a default catch clause */ /* @@? 132:14 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 137:16 Error SyntaxError: Expected ')', got '='. */ -/* @@? 137:16 Error SyntaxError: Catch clause variable cannot have an initializer. */ +/* @@? 137:16 Error SyntaxError: Unexpected token '='. */ /* @@? 137:16 Error SyntaxError: Expected '{', got '='. */ /* @@? 137:16 Error SyntaxError: Expected '{', got '='. */ -/* @@? 137:16 Error SyntaxError: Unexpected token '='. */ +/* @@? 137:16 Error SyntaxError: Expected ')', got '='. */ +/* @@? 137:16 Error SyntaxError: Catch clause variable cannot have an initializer. */ /* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ /* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ /* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ @@ -286,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 */ -/* @@? 290:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 287:1 Error SyntaxError: Expected '}', got 'eos'. */ diff --git a/ets2panda/test/ast/parser/ets/UnexpectedToken.sts b/ets2panda/test/ast/parser/ets/UnexpectedToken.sts index 420b529d74a57cf6ba183ba99779cff893f6121e..6f85639581dfb8f5d6d1e473e733b9d3df68d30a 100644 --- a/ets2panda/test/ast/parser/ets/UnexpectedToken.sts +++ b/ets2panda/test/ast/parser/ets/UnexpectedToken.sts @@ -28,7 +28,7 @@ function main(): void { /* @@? 18:38 Error TypeError: Cannot find type 'A'. */ /* @@? 18:68 Error TypeError: Cannot find type 'A'. */ /* @@? 18:70 Error SyntaxError: Expected ')', got ';'. */ -/* @@? 18:72 Error TypeError: Unresolved reference f */ +/* @@? 18:72 Error TypeError: This expression is not callable. */ /* @@? 18:78 Error TypeError: Cannot find type 'A'. */ /* @@? 19:1 Error SyntaxError: Unexpected token ')'. */ /* @@? 19:4 Error TypeError: Unresolved reference i */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.sts index 7f44f6470de054876f0c2e8283c9b50a1d1d494e..c91e54e8e1546c2aa440ca29bec14288070dc0b2 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.sts @@ -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,10 +16,10 @@ class A{} @interface MyAnno { - testProperty1: string = A + testProperty1: string = /* @@ label */A } -/* @@? 19:29 Error TypeError: Unresolved reference A */ -/* @@? 19:29 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 19:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param01.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param01.sts index adcc0716c3cad608fdfcc936eb2078af1ca43e76..291e9fc476b02b5d03e0c415a0f5c32b63d79253 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param01.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param01.sts @@ -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,10 +19,10 @@ class A{} testProperty1: string } -@MyAnno({testProperty1: A}) +@MyAnno({testProperty1: /* @@ label */A}) class B{} -/* @@? 22:25 Error TypeError: Unresolved reference A */ -/* @@? 22:25 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 22:25 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.sts index ac7a105542839c28a73f08b6d623ea49c869fdb3..6bda66d08940770a04e4aba7da07a38063a7dfc2 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.sts @@ -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,16 +21,16 @@ class A{} } class B{ - @MyAnno({testProperty1: A}) + @MyAnno({testProperty1: /* @@ label1 */A}) x : int - @MyAnno({testProperty1: A}) + @MyAnno({testProperty1: /* @@ label2 */A}) y : int } -/* @@? 24:29 Error TypeError: Unresolved reference A */ -/* @@? 24:29 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 24:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ -/* @@? 26:29 Error TypeError: Unresolved reference A */ -/* @@? 26:29 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 26:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label1 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label1 Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label1 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label2 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label2 Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label2 Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.sts index 94447d8ce5c4371a7055eaf0263fd06f3eec0235..4b9930aa0d222eb5214dcade67a4db552f1c4cfc 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.sts @@ -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,9 +20,9 @@ class A{} testProperty1: string } -function foo(@MyAnno({testProperty1: A}) x: int) { +function foo(@MyAnno({testProperty1: /* @@ label */A}) x: int) { } -/* @@? 23:38 Error TypeError: Unresolved reference A */ -/* @@? 23:38 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 23:38 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.sts index a7d22a8ce5d0817b407764526eac93e94156cf9e..42cc5b89bb8b5bda80e4639bcdcd232d948fed20 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.sts @@ -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,10 +20,10 @@ class A{} testProperty1: string } -@MyAnno({testProperty1: A}) +@MyAnno({testProperty1: /* @@ label */A}) let x = "abc" -/* @@? 23:25 Error TypeError: Unresolved reference A */ -/* @@? 23:25 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 23:25 Error TypeError: Invalid value for annotation field, expected a constant literal. */ \ No newline at end of file +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.sts index 8178eb21f8c5c1bc37c01a0b50f6c207e9962a56..b05a133e46f00d369cb474906c343f83d30a8e32 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.sts @@ -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,12 +19,12 @@ class A{} testProperty1: string } -@MyAnno({testProperty1: A}) +@MyAnno({testProperty1: /* @@ label */A}) interface itf { x : int foo() : string } -/* @@? 22:25 Error TypeError: Unresolved reference A */ -/* @@? 22:25 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 22:25 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.sts index 8b5af1b95225199bbb370cd5bc7c32719148fbec..1dc2531c2f20d0531331bbd39a205d2dc142b6a7 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.sts @@ -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,11 +20,11 @@ class A{} } interface itf { - @MyAnno({testProperty1: A}) + @MyAnno({testProperty1: /* @@ label */A}) foo() : string } -/* @@? 23:29 Error TypeError: Unresolved reference A */ -/* @@? 23:29 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 23:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.sts index 3f5e4475ad72f852fae38b8ca5f986a158c49493..0262653495ab65b55d254a03d36c5943582a40a1 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.sts @@ -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,15 +20,14 @@ class A{} } interface itf { - @MyAnno({testProperty1: A}) + @MyAnno({testProperty1: /* @@ label */A}) x: int } -/* @@? 23:29 Error TypeError: Unresolved reference A */ -/* @@? 23:29 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 23:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ -/* @@? 23:29 Error TypeError: Unresolved reference A */ -/* @@? 23:29 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 23:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ -/* @@? 23:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.sts index ec50705e8550ef8f6b55bea602a126a8ddba50a4..bcb548094fdb7a8e0199987cbb6fc293ef37d14f 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.sts @@ -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 @@ class A{} } function main():void { - @MyAnno({testProperty1: A}) + @MyAnno({testProperty1: /* @@ label */A}) let x = "abc" } -/* @@? 24:29 Error TypeError: Unresolved reference A */ -/* @@? 24:29 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 24:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.sts index 59ab23adc21c485bb80c557b3fd7301c5891f997..20828eff75c8e3514fe48652e3652bc4cb590e23 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.sts @@ -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,19 +20,18 @@ class A{} testProperty1: string } -@MyAnno({testProperty1: A}) +@MyAnno({testProperty1: /* @@ label1 */A}) type t1 = int function main(): void { - @MyAnno({testProperty1: A}) + @MyAnno({testProperty1: /* @@ label2 */A}) type t2 = int } -/* @@? 27:29 Error TypeError: Unresolved reference A */ -/* @@? 27:29 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 27:29 Error TypeError: Invalid value for annotation field, expected a constant literal. */ -/* @@? 23:25 Error TypeError: Unresolved reference A */ -/* @@? 23:25 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@? 23:25 Error TypeError: Invalid value for annotation field, expected a constant literal. */ - +/* @@@ label1 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label1 Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label1 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label2 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label2 Error TypeError: Type 'A' cannot be assigned to type 'String' */ +/* @@@ label2 Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.sts index 0914eeb926b23d68a902040a05ef50cd10ee58c5..4e5c7ed46cbcdc44b6a92bdc0efa05a7bdd63e5c 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.sts @@ -43,7 +43,6 @@ 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:45 Error TypeError: Unresolved reference int */ /* @@? 22:48 Error SyntaxError: Unexpected token ','. */ /* @@? 22:48 Error SyntaxError: Unexpected token ','. */ /* @@? 22:48 Error SyntaxError: Unexpected token ','. */ @@ -51,7 +50,7 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: /* @@? 22:50 Error TypeError: Annotation missing '@' symbol before annotation name. */ /* @@? 22:78 Error SyntaxError: Unexpected token 'y'. */ /* @@? 22:81 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 22:81 Error TypeError: Unresolved reference string */ +/* @@? 22:81 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 22:87 Error SyntaxError: Unexpected token ')'. */ /* @@? 22:87 Error SyntaxError: Unexpected token ')'. */ /* @@? 22:87 Error SyntaxError: Unexpected token ')'. */ @@ -63,7 +62,6 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: /* @@? 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:45 Error TypeError: Unresolved reference int */ /* @@? 25:48 Error SyntaxError: Unexpected token ','. */ /* @@? 25:48 Error SyntaxError: Unexpected token ','. */ /* @@? 25:48 Error SyntaxError: Unexpected token ','. */ @@ -71,7 +69,7 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: /* @@? 25:50 Error TypeError: This expression is not callable. */ /* @@? 25:78 Error SyntaxError: Unexpected token 'y'. */ /* @@? 25:81 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 25:81 Error TypeError: Unresolved reference string */ +/* @@? 25:81 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 25:87 Error SyntaxError: Unexpected token ')'. */ /* @@? 25:87 Error SyntaxError: Unexpected token ')'. */ /* @@? 25:87 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/class-instance-field-redeclaration.sts b/ets2panda/test/ast/parser/ets/class-instance-field-redeclaration.sts index 5724caccac56b6e47b75648daeaaed243d5b1a28..ef8d91f4ec84dbd0bdf6199e3a05f264d41c0dd5 100644 --- a/ets2panda/test/ast/parser/ets/class-instance-field-redeclaration.sts +++ b/ets2panda/test/ast/parser/ets/class-instance-field-redeclaration.sts @@ -19,3 +19,4 @@ class C { } /* @@@ label Error TypeError: Variable 'foo' has already been declared. */ +/* @@@ label Error TypeError: Property 'foo' must be accessed through 'this' */ diff --git a/ets2panda/test/ast/parser/ets/class-static-field-redeclaration.sts b/ets2panda/test/ast/parser/ets/class-static-field-redeclaration.sts index 7951f410c99a0826dd9d00f62d92d5022f853a9c..87471276b09cc49968c4d2105a525345c4dabd4e 100644 --- a/ets2panda/test/ast/parser/ets/class-static-field-redeclaration.sts +++ b/ets2panda/test/ast/parser/ets/class-static-field-redeclaration.sts @@ -19,3 +19,4 @@ class C { } /* @@@ label Error TypeError: Variable 'foo' has already been declared. */ +/* @@@ label Error TypeError: Static property 'foo' must be accessed through it's class 'C' */ diff --git a/ets2panda/test/ast/parser/ets/declare_namespace_5.sts b/ets2panda/test/ast/parser/ets/declare_namespace_5.sts index 7997417f95b9886ef1fa5cd2748c919840b42b5b..61605b9c0d41be5e590fd2276c0ed928727e5719 100644 --- a/ets2panda/test/ast/parser/ets/declare_namespace_5.sts +++ b/ets2panda/test/ast/parser/ets/declare_namespace_5.sts @@ -14,10 +14,10 @@ */ class A { - /* @@ label */namespace ns { + namespace ns { dfdfsfdf } - /* @@ label1 */namespace hehe { + namespace hehe { } time: number = foo(); @@ -33,10 +33,10 @@ class A { } class B { - /* @@ label2 */namespace ns { + namespace ns { }ddddddd - /* @@ label3 */time: number = foo(); + time: number = foo(); private uri: string; private routerssdsds() { @@ -48,11 +48,11 @@ class B { } } -/* @@@ label Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ -/* @@@ label1 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ -/* @@@ label2 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ -/* @@@ label3 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ +/* @@? 20:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ /* @@? 23:20 Error TypeError: Unresolved reference foo */ -/* @@? 39:35 Error TypeError: Unresolved reference foo */ -/* @@? 43:11 Error TypeError: Property 'getInstance' does not exist on type 'B' */ /* @@? 27:11 Error TypeError: Property 'getInstance' does not exist on type 'B' */ +/* @@? 36:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ +/* @@? 39:5 Error SyntaxError: Field type annotation expected. */ +/* @@? 39:20 Error TypeError: This expression is not callable. */ +/* @@? 43:11 Error TypeError: Property 'getInstance' does not exist on type 'B' */ diff --git a/ets2panda/test/ast/parser/ets/fields.sts b/ets2panda/test/ast/parser/ets/fields.sts index 31cdc48edbacaced6e755ac2afbb339edea4b54f..414efc3575499d93614f562d11a6059d086b8b90 100644 --- a/ets2panda/test/ast/parser/ets/fields.sts +++ b/ets2panda/test/ast/parser/ets/fields.sts @@ -28,3 +28,4 @@ class C { } /* @@@ label Error TypeError: Variable 'f' has already been declared. */ +/* @@@ label Error TypeError: Static property 'f' must be accessed through it's class 'C' */ diff --git a/ets2panda/test/ast/parser/ets/forOfType.sts b/ets2panda/test/ast/parser/ets/forOfType.sts index 9f589ae11d7c98e6fc55e3f11e54cc2f7675efc6..5fa4f92fe16d57a7d38fc2289b1e611ff7cf90f0 100644 --- a/ets2panda/test/ast/parser/ets/forOfType.sts +++ b/ets2panda/test/ast/parser/ets/forOfType.sts @@ -13,14 +13,7 @@ * limitations under the License. */ -for ( Fi of typeof `k` as () => bigint | long ) +for ( Fi of /* @@ label */typeof `k` as () => bigint | long ) await this instanceof int -/* @@? 16:13 Error TypeError: Object type doesn't have proper iterator method. */ -/* @@? 16:13 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 1:3 Error TypeError: Property '$_iterator' does not exist on type 'Function0' */ -/* @@? 1:1 Error TypeError: Bad operand type, the type of the operand must be boolean type. */ -/* @@? 1:3 Error TypeError: Unresolved reference Fi */ -/* @@? 17:7 Error TypeError: Cannot reference 'this' in this context. */ -/* @@? 17:7 Error TypeError: Bad operand type, the types of the operands must be same type. */ -/* @@? 17:7 Error TypeError: 'await' expressions require Promise object as argument. */ +/* @@@ label Error TypeError: 'For-of' statement source expression is not of iterable type. */ diff --git a/ets2panda/test/ast/parser/ets/illegal_continue_statement.sts b/ets2panda/test/ast/parser/ets/illegal_continue_statement.sts index 03741e22ab17db714e7c95d744689b28bfbbc890..51b0927f20e34f8f11b9ac6404322c41acc2bace 100644 --- a/ets2panda/test/ast/parser/ets/illegal_continue_statement.sts +++ b/ets2panda/test/ast/parser/ets/illegal_continue_statement.sts @@ -15,39 +15,38 @@ let a1: number = 10; function foo() { - /* @@ label1 */continue + continue let a: number = 10 console.log(a + 5) } let a2: number = 10; function foo2() { - /* @@ label2 */continue; + continue; let a2: number = 10 console.log(a + 5) } let a3: number = 10; function foo3() { - /* @@ label3 */break + break let a: number = 10 console.log(a + 5) } let a4: number = 10; function foo4() { - /* @@ label4 */break; + break; let a2: number = 10 console.log(a + 5) } -/* @@@ label1 Error SyntaxError: Illegal continue statement. */ -/* @@@ label2 Error SyntaxError: Illegal continue statement. */ -/* @@@ label3 Error SyntaxError: Illegal break statement. */ -/* @@@ label4 Error SyntaxError: Illegal break statement. */ -/* @@? 18:20 Error TypeError: Control flow redirection statement can not be used out of loop or switch statement. */ -/* @@? 25:20 Error TypeError: Control flow redirection statement can not be used out of loop or switch statement. */ +/* @@? 18:5 Error SyntaxError: Illegal continue statement. */ +/* @@? 18:5 Error TypeError: Control flow redirection statement can not be used out of loop or switch statement. */ +/* @@? 25:5 Error SyntaxError: Illegal continue statement. */ +/* @@? 25:5 Error TypeError: Control flow redirection statement can not be used out of loop or switch statement. */ /* @@? 27:17 Error TypeError: Unresolved reference a */ -/* @@? 32:20 Error TypeError: Control flow redirection statement can not be used out of loop or switch statement. */ -/* @@? 39:20 Error TypeError: Control flow redirection statement can not be used out of loop or switch statement. */ -/* @@? 41:17 Error TypeError: Unresolved reference a */ +/* @@? 32:5 Error SyntaxError: Illegal break statement. */ +/* @@? 32:5 Error TypeError: Control flow redirection statement can not be used out of loop or switch statement. */ +/* @@? 39:5 Error SyntaxError: Illegal break statement. */ +/* @@? 39:5 Error TypeError: Control flow redirection statement can not be used out of loop or switch statement. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_all_alias_2.sts b/ets2panda/test/ast/parser/ets/import_tests/import_all_alias_2.sts index 78a340321bb1b0c0ec26e184e99d50ce7ec81c14..6e328b67b42326b2ae3945e639baf0b6530121ab 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_all_alias_2.sts +++ b/ets2panda/test/ast/parser/ets/import_tests/import_all_alias_2.sts @@ -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,5 +19,5 @@ import * as Test from "import_tests/packages"; let x = foo(dbl /* double based signature */); -/* @@? 20:9 Error TypeError: Unresolved reference foo */ -/* @@? 20:9 Error TypeError: Unresolved reference foo */ +/* @@? 20:9 Error TypeError: Unresolved reference foo */ +/* @@? 20:9 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_name_alias_2.sts b/ets2panda/test/ast/parser/ets/import_tests/import_name_alias_2.sts index b01e482ec0ecd035c43a6d63bdf2eeab30bf7a06..dede176fccbb130dad6d9984f2d7f4486e8e8fab 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_name_alias_2.sts +++ b/ets2panda/test/ast/parser/ets/import_tests/import_name_alias_2.sts @@ -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 {foo as Foo, dbl} from "import_tests/packages"; // Throw error: Foo qualifier should be used instead of foo. let x = foo(dbl); -/* @@? 19:9 Error TypeError: Unresolved reference foo */ -/* @@? 19:9 Error TypeError: Unresolved reference foo */ +/* @@? 19:9 Error TypeError: Unresolved reference foo */ +/* @@? 19:9 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/parser/ets/invalidTypes.sts b/ets2panda/test/ast/parser/ets/invalidTypes.sts index 8b4019076c369fcadb81e8bfe88f8cb5965397d7..e80f6d8f5a8dd73163bc039e12236927fbd7a4d5 100644 --- a/ets2panda/test/ast/parser/ets/invalidTypes.sts +++ b/ets2panda/test/ast/parser/ets/invalidTypes.sts @@ -59,7 +59,7 @@ let var6: [a0: , a1: ]; /* @@? 26:23 Error SyntaxError: Unexpected token ','. */ /* @@? 26:23 Error SyntaxError: Unexpected token ','. */ /* @@? 26:23 Error SyntaxError: Unexpected token ','. */ -/* @@? 26:25 Error TypeError: Unresolved reference string */ +/* @@? 26:25 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 26:31 Error SyntaxError: Unexpected token ']'. */ /* @@? 26:31 Error SyntaxError: Unexpected token ']'. */ /* @@? 26:31 Error SyntaxError: Unexpected token ']'. */ @@ -81,7 +81,7 @@ let var6: [a0: , a1: ]; /* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token 'number'. */ -/* @@? 32:19 Error TypeError: Unresolved reference number */ +/* @@? 32:19 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ /* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ /* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/loops.sts b/ets2panda/test/ast/parser/ets/loops.sts index 0fcc1857c50b93796ddcb1048e1ee4003402fe22..027c90e68219b347b2d236cfc8a803342e5fadeb 100644 --- a/ets2panda/test/ast/parser/ets/loops.sts +++ b/ets2panda/test/ast/parser/ets/loops.sts @@ -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 @@ -66,4 +66,3 @@ function labeledcontinue(): void { /* @@? 19:15 Error TypeError: Unresolved reference i */ /* @@? 19:15 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 19:22 Error TypeError: Unresolved reference i */ diff --git a/ets2panda/test/ast/parser/ets/missing_in_for_statement_1.sts b/ets2panda/test/ast/parser/ets/missing_in_for_statement_1.sts index 4b91f764f554af4a270e2a3d069300a66ab723d0..e348adfa0feb8994a6125e8c7a7f5d281cf1bc66 100644 --- a/ets2panda/test/ast/parser/ets/missing_in_for_statement_1.sts +++ b/ets2panda/test/ast/parser/ets/missing_in_for_statement_1.sts @@ -14,15 +14,14 @@ */ for /* @@ label */let i = 0; i < count; ++i) { - result = result + p[i]!.awaitResolution() * a[i]; + result = result + p[i]!.awaitResolution() * /* @@ label1 */a[i]; } /* @@@ label Error SyntaxError: Expected '(', got 'let'. */ -/* @@? 16:34 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 16:30 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 16:34 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 17:5 Error TypeError: Unresolved reference result */ -/* @@? 17:14 Error TypeError: Unresolved reference result */ /* @@? 17:23 Error TypeError: Unresolved reference p */ /* @@? 17:23 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 17:49 Error TypeError: Unresolved reference a */ -/* @@? 17:49 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@@ label1 Error TypeError: Unresolved reference a */ +/* @@@ label1 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/missing_in_for_statement_2.sts b/ets2panda/test/ast/parser/ets/missing_in_for_statement_2.sts index 4332abe729ccfe8aa6a77480faf7c442af93a89f..b8ba1653ee8cca8f51b788bd45299ad85775ead9 100644 --- a/ets2panda/test/ast/parser/ets/missing_in_for_statement_2.sts +++ b/ets2panda/test/ast/parser/ets/missing_in_for_statement_2.sts @@ -14,15 +14,14 @@ */ for (let i = 0; i < count; ++i /* @@ label */{ - result = result + p[i]!.awaitResolution() * a[i]; + result = result + p[i]!.awaitResolution() * /* @@label1 */a[i]; } /* @@? 16:21 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 16:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@@ label Error SyntaxError: Expected ')', got '{'. */ /* @@? 17:5 Error TypeError: Unresolved reference result */ -/* @@? 17:14 Error TypeError: Unresolved reference result */ /* @@? 17:23 Error TypeError: Unresolved reference p */ /* @@? 17:23 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 17:49 Error TypeError: Unresolved reference a */ -/* @@? 17:49 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@@ label1 Error TypeError: Unresolved reference a */ +/* @@@ label1 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/spreadexpr_in_newexpr_neg01.sts b/ets2panda/test/ast/parser/ets/spreadexpr_in_newexpr_neg01.sts index 88dfc84efcda4bc7a6e4e9453053460f229e777a..2a6b971d872d7eac87a6a3dfe1b4be0454b952f7 100644 --- a/ets2panda/test/ast/parser/ets/spreadexpr_in_newexpr_neg01.sts +++ b/ets2panda/test/ast/parser/ets/spreadexpr_in_newexpr_neg01.sts @@ -15,10 +15,10 @@ class A { fld: number[]; - constructor(...p: number[]/* @@ label */, x: int/* @@ label1 */) /* @@ label2 */{ - /* @@ label3 */this/* @@ label4 */.fld = p; + constructor(...p: number[], x: int) { + this.fld = p; } -/* @@ label5 */} +} let nums: number[] = [1.0, 2.0, 3.0]; @@ -27,10 +27,12 @@ function main() { } /* @@? 18:16 Error TypeError: Only abstract or native methods can't have body. */ -/* @@? 18:45 Error SyntaxError: Rest parameter must be the last formal parameter. */ -/* @@? 18:68 Error SyntaxError: Unexpected token ')'. */ -/* @@? 18:85 Error SyntaxError: Unexpected token '{'. */ -/* @@? 19:24 Error SyntaxError: Unexpected token 'this'. */ -/* @@? 19:43 Error SyntaxError: Unexpected token '.'. */ -/* @@? 19:44 Error TypeError: Variable 'fld' has already been declared. */ -/* @@? 21:16 Error SyntaxError: Unexpected token '}'. */ +/* @@? 18:31 Error SyntaxError: Rest parameter must be the last formal parameter. */ +/* @@? 18:39 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:41 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:9 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 19:13 Error SyntaxError: Unexpected token '.'. */ +/* @@? 19:14 Error TypeError: Variable 'fld' has already been declared. */ +/* @@? 19:14 Error TypeError: Property 'fld' must be accessed through 'this' */ +/* @@? 19:20 Error TypeError: Unresolved reference p */ +/* @@? 21:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/tuple_trailing_comma.sts b/ets2panda/test/ast/parser/ets/tuple_trailing_comma.sts index 80c03aea3485846dbf96665f518dcdf00c11c72a..b04ad1f28b564d94dd877252463f944bebf220a8 100644 --- a/ets2panda/test/ast/parser/ets/tuple_trailing_comma.sts +++ b/ets2panda/test/ast/parser/ets/tuple_trailing_comma.sts @@ -22,11 +22,11 @@ let b: [number, /* @@ label */,number, number,] = [1, 2, 3,]; /* @@? 17:18 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:18 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:18 Error SyntaxError: Unexpected token, expected ',' or ']'. */ -/* @@? 17:20 Error TypeError: Unresolved reference number */ +/* @@? 17:20 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:26 Error SyntaxError: Unexpected token ','. */ /* @@? 17:26 Error SyntaxError: Unexpected token ','. */ /* @@? 17:26 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:28 Error TypeError: Unresolved reference number */ +/* @@? 17:28 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:34 Error SyntaxError: Unexpected token ','. */ /* @@? 17:34 Error SyntaxError: Unexpected token ','. */ /* @@? 17:34 Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/parser/ets/tuple_type_2_neg.sts b/ets2panda/test/ast/parser/ets/tuple_type_2_neg.sts index 2515abc93d971228608c3fe3dd58b756d72a7419..ce0fa517a359c5dd3826df771c5049e3dd0764e4 100644 --- a/ets2panda/test/ast/parser/ets/tuple_type_2_neg.sts +++ b/ets2panda/test/ast/parser/ets/tuple_type_2_neg.sts @@ -24,7 +24,7 @@ let a: [number, ...number[], number] = [1, 2, 3]; /* @@? 17:28 Error SyntaxError: Unexpected token ','. */ /* @@? 17:28 Error SyntaxError: Unexpected token ','. */ /* @@? 17:28 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:30 Error TypeError: Unresolved reference number */ +/* @@? 17:30 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:36 Error SyntaxError: Unexpected token ']'. */ /* @@? 17:36 Error SyntaxError: Unexpected token ']'. */ /* @@? 17:36 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/tuple_type_3_neg.sts b/ets2panda/test/ast/parser/ets/tuple_type_3_neg.sts index 291fea3c45da01085eafa9ba23942f785cd7f7bb..8866e7d801d367f5974e97e83e556a82e3f0b36b 100644 --- a/ets2panda/test/ast/parser/ets/tuple_type_3_neg.sts +++ b/ets2panda/test/ast/parser/ets/tuple_type_3_neg.sts @@ -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,6 +18,8 @@ let a: [number, number number] = [1, 2, 3]; /* @@? 17:24 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 17:24 Error SyntaxError: Unexpected token 'number'. */ -/* @@? 17:24 Error TypeError: Unresolved reference number */ +/* @@? 17:24 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 17:30 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:30 Error SyntaxError: Unexpected token ']'. */ /* @@? 17:30 Error SyntaxError: Unexpected token ']'. */ /* @@? 17:32 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/test/ast/parser/ets/tuple_type_4_neg.sts b/ets2panda/test/ast/parser/ets/tuple_type_4_neg.sts index 42c40382a6e0d72a90747ee500b5a8857b480073..5d7524e821668a613134ec1d9ecfa0756322c603 100644 --- a/ets2panda/test/ast/parser/ets/tuple_type_4_neg.sts +++ b/ets2panda/test/ast/parser/ets/tuple_type_4_neg.sts @@ -24,7 +24,7 @@ let a: [a0: , a1: number] = [1, 2, 3]; /* @@? 17:13 Error SyntaxError: Unexpected token ','. */ /* @@? 17:13 Error SyntaxError: Unexpected token ','. */ /* @@? 17:19 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 17:19 Error TypeError: Unresolved reference number */ +/* @@? 17:19 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:25 Error SyntaxError: Unexpected token ']'. */ /* @@? 17:25 Error SyntaxError: Unexpected token ']'. */ /* @@? 17:25 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/type_references.sts b/ets2panda/test/ast/parser/ets/type_references.sts index dd13fc24ef4ebfbfc1da39ea6d10291d2665f8a0..c62ddc9f7fd890dc981a9b66e890b67fb069fc0a 100644 --- a/ets2panda/test/ast/parser/ets/type_references.sts +++ b/ets2panda/test/ast/parser/ets/type_references.sts @@ -22,12 +22,16 @@ let y: G<{a:String}, B> // Error /* @@? 19:8 Error TypeError: Cannot find type 'G'. */ /* @@? 19:10 Error SyntaxError: Unexpected token, expected '>'. */ /* @@? 19:10 Error SyntaxError: Unexpected token '>'. */ +/* @@? 19:10 Error SyntaxError: Unexpected token '>'. */ /* @@? 19:10 Error SyntaxError: Invalid Type. */ /* @@? 19:11 Error TypeError: Unresolved reference a */ /* @@? 19:12 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:12 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:12 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:13 Error TypeError: Class name 'String' used in the wrong context */ /* @@? 19:19 Error SyntaxError: Unexpected token '}'. */ /* @@? 19:20 Error SyntaxError: Unexpected token ','. */ -/* @@? 19:13 Error TypeError: Class name 'String' used in the wrong context */ -/* @@? 19:22 Error TypeError: Unresolved reference B */ +/* @@? 19:20 Error SyntaxError: Unexpected token ','. */ +/* @@? 19:22 Error TypeError: Type name 'B' used in the wrong context */ /* @@? 19:22 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 34:1 Error SyntaxError: Unexpected token 'eos'. */ +/* @@? 38:1 Error SyntaxError: Unexpected token 'eos'. */ diff --git a/ets2panda/test/ast/parser/ets/types_decls.sts b/ets2panda/test/ast/parser/ets/types_decls.sts index 94549e5da0924b903c25aac1e4d7ae1be874b661..f9455917b72f59db97f4f2db022d91dbe05255c8 100644 --- a/ets2panda/test/ast/parser/ets/types_decls.sts +++ b/ets2panda/test/ast/parser/ets/types_decls.sts @@ -57,8 +57,8 @@ let non_prim_c: Char = c'b'; function v(): void {} /* @@@ label Error TypeError: Variable 'prim_b' has already been declared. */ -/* @@? 46:5 Error TypeError: Variable 'non_prim_b' has already been declared. */ /* @@? 45:27 Error TypeError: Cannot find type 'bool'. */ -/* @@? 46:17 Error TypeError: Cannot find type 'Bool'. */ /* @@? 45:34 Error TypeError: Type 'boolean' cannot be assigned to type 'byte' */ +/* @@? 46:5 Error TypeError: Variable 'non_prim_b' has already been declared. */ +/* @@? 46:17 Error TypeError: Cannot find type 'Bool'. */ /* @@? 46:24 Error TypeError: Type 'boolean' cannot be assigned to type 'Byte' */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_2.sts b/ets2panda/test/ast/parser/ets/unexpected_token_2.sts index 7969ae56bf7b55c60cf56c22722009dd7f03cc87..9fd9559ad1515a22882477427558b628361fba78 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_2.sts +++ b/ets2panda/test/ast/parser/ets/unexpected_token_2.sts @@ -38,4 +38,4 @@ function labeledTest01(): int { /* @@@ label Error SyntaxError: Unexpected token, expected an identifier. */ /* @@@ label1 Error SyntaxError: Unexpected token 'label1'. */ -/* @@@ label1 Error TypeError: Unresolved reference label1 */ +/* @@@ label1 Error TypeError: Identifier 'label1' is used in wrong context. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_22.sts b/ets2panda/test/ast/parser/ets/unexpected_token_22.sts index 0f2f164c3cf186b7325e89c1499705ef1c77a987..9efcf4f388eeb03478c0097ef29f68f185e31f46 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_22.sts +++ b/ets2panda/test/ast/parser/ets/unexpected_token_22.sts @@ -37,5 +37,6 @@ function main(): void { } /* @@? 25:43 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 25:43 Error TypeError: Type '(_: Promise) => Promise' cannot be assigned to type '() => Promise' */ /* @@? 25:44 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 25:60 Error SyntaxError: Unexpected token, expected ',' or ')'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_3.sts b/ets2panda/test/ast/parser/ets/unexpected_token_3.sts index 785cd0c707345f81b9d0641000745dd22cb32247..e32f16e5e5cad35e4e8b3d47b72e8231ba8fdbc9 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_3.sts +++ b/ets2panda/test/ast/parser/ets/unexpected_token_3.sts @@ -38,4 +38,5 @@ function labeledTest01(): int { /* @@@ label Error SyntaxError: Unexpected token, expected an identifier. */ /* @@@ label1 Error SyntaxError: Unexpected token '^'. */ -/* @@? 27:57 Error TypeError: Unresolved reference label1 */ +/* @@@ label1 Error SyntaxError: Unexpected token '^'. */ +/* @@? 27:57 Error TypeError: Identifier 'label1' is used in wrong context. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_31.sts b/ets2panda/test/ast/parser/ets/unexpected_token_31.sts index 9fc60005ae5f10a52af2caf4623d1b38fb12f9bf..17af310ec18ff4c8a17b77c159ac81cdf242a030 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_31.sts +++ b/ets2panda/test/ast/parser/ets/unexpected_token_31.sts @@ -22,10 +22,12 @@ function foo(...^number: int[]): int { /* @@? 16:18 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 16:18 Error SyntaxError: Rest parameter must be the last formal parameter. */ /* @@? 16:31 Error SyntaxError: Unexpected token ')'. */ +/* @@? 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 '{'. */ /* @@? 17:5 Error SyntaxError: return keyword should be used in function body. */ -/* @@? 17:12 Error TypeError: Unresolved reference number */ +/* @@? 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. */ /* @@? 17:12 Error TypeError: All return statements in the function should be empty or have a value. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_36.sts b/ets2panda/test/ast/parser/ets/unexpected_token_36.sts index c3f418f88f01e625c48126c58764938e6948721c..453e5cd1e24eba1e03958c2459cea7b0776c6335 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_36.sts +++ b/ets2panda/test/ast/parser/ets/unexpected_token_36.sts @@ -43,9 +43,6 @@ export class AccessNSieve { /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ /* @@? 29:16 Error TypeError: Unresolved reference int */ /* @@? 29:25 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 29:25 Error TypeError: Unresolved reference i */ -/* @@? 29:33 Error TypeError: Unresolved reference i */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ -/* @@? 30:28 Error TypeError: Unresolved reference i */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_53.sts b/ets2panda/test/ast/parser/ets/unexpected_token_53.sts index a6f7761eae3170f8234be16a6dcbc60a01967185..70bf658604269b790f7f76e435609ec8659ee11e 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_53.sts +++ b/ets2panda/test/ast/parser/ets/unexpected_token_53.sts @@ -27,12 +27,15 @@ export class MathSpectralNorm { /* @@? 19:10 Error TypeError: Unresolved reference i */ /* @@? 19:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 19:17 Error TypeError: Unresolved reference i */ /* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:22 Error SyntaxError: Expected ')', got ':'. */ /* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:22 Error SyntaxError: Expected ')', got ':'. */ /* @@? 19:22 Error SyntaxError: Expected ';', got ':'. */ -/* @@? 19:24 Error TypeError: Unresolved reference i */ +/* @@? 19:27 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:27 Error SyntaxError: Unexpected token ')'. */ /* @@? 19:27 Error SyntaxError: Unexpected token ')'. */ /* @@? 20:7 Error TypeError: Unresolved reference vbv */ /* @@? 20:14 Error TypeError: Unresolved reference u */ @@ -40,9 +43,5 @@ export class MathSpectralNorm { /* @@? 20:21 Error TypeError: Unresolved reference v */ /* @@? 20:21 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 21:7 Error TypeError: Unresolved reference vv */ -/* @@? 21:14 Error TypeError: Unresolved reference v */ /* @@? 21:14 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 21:21 Error TypeError: Unresolved reference v */ /* @@? 21:21 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 24:17 Error TypeError: Unresolved reference vbv */ -/* @@? 24:23 Error TypeError: Unresolved reference vv */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_55.sts b/ets2panda/test/ast/parser/ets/unexpected_token_55.sts index 6d37de75e9ff3d6e2b39107ddbab689eafd776de..20f5a0407b879021d06cf9407087e53d5dca8e31 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_55.sts +++ b/ets2panda/test/ast/parser/ets/unexpected_token_55.sts @@ -28,12 +28,15 @@ export class MathSpectralNorm { /* @@? 19:16 Error TypeError: Unresolved reference i */ /* @@? 19:18 Error SyntaxError: Unexpected token '='. */ /* @@? 19:23 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 19:23 Error TypeError: Unresolved reference i */ /* @@? 19:29 Error SyntaxError: Expected ';', got ':'. */ /* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ /* @@? 19:29 Error SyntaxError: Expected ')', got ':'. */ /* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:31 Error TypeError: Unresolved reference i */ +/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:34 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:34 Error SyntaxError: Unexpected token ')'. */ /* @@? 19:34 Error SyntaxError: Unexpected token ')'. */ /* @@? 20:7 Error TypeError: Unresolved reference vbv */ /* @@? 20:14 Error TypeError: Unresolved reference u */ @@ -41,9 +44,5 @@ export class MathSpectralNorm { /* @@? 20:21 Error TypeError: Unresolved reference v */ /* @@? 20:21 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 21:7 Error TypeError: Unresolved reference vv */ -/* @@? 21:14 Error TypeError: Unresolved reference v */ /* @@? 21:14 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 21:21 Error TypeError: Unresolved reference v */ /* @@? 21:21 Error TypeError: Indexed access is not supported for such expression type. */ -/* @@? 24:17 Error TypeError: Unresolved reference vbv */ -/* @@? 24:23 Error TypeError: Unresolved reference vv */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_56.sts b/ets2panda/test/ast/parser/ets/unexpected_token_56.sts index c07e0adea227e863934f983b38dc66ff9a830d04..1532cda9eb7da9581f2466550c4fdcdd66b6b8f6 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_56.sts +++ b/ets2panda/test/ast/parser/ets/unexpected_token_56.sts @@ -24,10 +24,10 @@ for (let i? : Number = 1;;) { break; } /* @@? 16:48 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 16:44 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 16:68 Error SyntaxError: Expected ')', got ';'. */ -/* @@? 16:72 Error TypeError: Unresolved reference i */ +/* @@? 16:87 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:87 Error SyntaxError: Unexpected token ')'. */ /* @@? 16:87 Error SyntaxError: Unexpected token ')'. */ /* @@? 17:5 Error TypeError: Unresolved reference result */ -/* @@? 17:14 Error TypeError: Unresolved reference result */ /* @@? 17:23 Error TypeError: Unresolved reference p */ /* @@? 17:23 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 17:49 Error TypeError: Unresolved reference a */ diff --git a/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt b/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt index 0abbd6af5f96dc9d56063ef3f3062b783cfce6f8..5badc6128cd159c5b01ca35f09576706e36a728a 100644 --- a/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt +++ b/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt @@ -65,9 +65,6 @@ ast/compiler/ets/implicit_this_method_trailing.sts ast/compiler/ets/recordWithLambdaFunction2.sts ast/compiler/ets/extension_accessor_tests/extensionGetterInWrongUsage.sts -# Issue: ##22719 -ast/parser/ets/forOfType.sts - # Checked only as imported modules. If these files are parsed directly, there will be # errors located in other files (import_type_error_in_class.sts/import_type_error_top_level.sts), # and such case cannot be checked in astchecker diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index f16535317bc8f18003552d691f53b9d9c9b46525..e1524a56c7162a0315c0218af1a0eba371ff598b 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -14,42 +14,40 @@ */ #include "helpers.h" +#include -#include "generated/signatures.h" #include "varbinder/privateBinding.h" -#include "checker/types/ets/types.h" -#include "ir/astNode.h" +#include "lexer/token/letters.h" + #include "ir/base/classDefinition.h" +#include "ir/base/scriptFunction.h" #include "ir/base/classProperty.h" -#include "ir/base/methodDefinition.h" #include "ir/base/property.h" -#include "ir/base/scriptFunction.h" #include "ir/base/spreadElement.h" -#include "ir/expressions/arrayExpression.h" -#include "ir/expressions/assignmentExpression.h" -#include "ir/expressions/callExpression.h" -#include "ir/expressions/functionExpression.h" +#include "ir/base/methodDefinition.h" + #include "ir/expressions/identifier.h" #include "ir/expressions/literals/numberLiteral.h" #include "ir/expressions/literals/stringLiteral.h" #include "ir/expressions/literals/booleanLiteral.h" -#include "ir/expressions/literals/nullLiteral.h" +#include "ir/expressions/functionExpression.h" #include "ir/expressions/objectExpression.h" -#include "ir/statements/returnStatement.h" -#include "ir/statements/variableDeclaration.h" +#include "ir/expressions/arrayExpression.h" +#include "ir/expressions/assignmentExpression.h" + #include "ir/statements/variableDeclarator.h" + #include "ir/module/importSpecifier.h" +#include "ir/module/importDefaultSpecifier.h" + #include "ir/ets/etsImportDeclaration.h" +#include "ir/ets/etsParameterExpression.h" + #include "ir/ts/tsParameterProperty.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/ts/tsEnumDeclaration.h" -#include "ir/ets/etsParameterExpression.h" -#include "ir/module/importDeclaration.h" -#include "lexer/token/letters.h" + #include "libpandabase/utils/utf.h" -#include "libpandabase/os/filesystem.h" -#include "ir/module/importDefaultSpecifier.h" -#include namespace ark::es2panda::util { // Helpers @@ -442,7 +440,7 @@ static void CollectBindingName(ir::AstNode *node, std::vector } } -std::vector Helpers::CollectBindingNames(ir::AstNode *node) +std::vector Helpers::CollectBindingNames(ir::Expression *node) { std::vector bindings; CollectBindingName(node, &bindings); @@ -588,8 +586,8 @@ util::StringView Helpers::FunctionName(ArenaAllocator *allocator, const ir::Scri return FunctionNameFromParent(parent, allocator); } -std::tuple Helpers::ParamName(ArenaAllocator *allocator, const ir::AstNode *param, - uint32_t index) +std::tuple Helpers::ParamName(ArenaAllocator *allocator, const ir::Expression *param, + std::uint32_t index) { switch (param->Type()) { case ir::AstNodeType::IDENTIFIER: { diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index 5e1232ea8bb66cb6b3a74840c8ea9ae082a0352e..58a08822ad2b782d1934643c7df5f637c88d8236 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -146,15 +146,15 @@ 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::AstNode *node); + static std::vector CollectBindingNames(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); static void CheckDefaultImportedName(const ArenaVector &specifiers, const ir::ImportDefaultSpecifier *specifier, const std::string &fileName); static void CheckDefaultImport(const ArenaVector &statements); - static std::tuple ParamName(ArenaAllocator *allocator, const ir::AstNode *param, - uint32_t index); + static std::tuple ParamName(ArenaAllocator *allocator, const ir::Expression *param, + std::uint32_t index); template static ArenaVector ConvertVector(const ArenaVector &src) diff --git a/ets2panda/varbinder/ASBinder.h b/ets2panda/varbinder/ASBinder.h index 08b05d403f71591774124442b5d237f68143877d..debfef764760ef35b37217d8be998f4de6a39adb 100644 --- a/ets2panda/varbinder/ASBinder.h +++ b/ets2panda/varbinder/ASBinder.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 @@ -23,23 +23,22 @@ class ASBinder : public VarBinder { public: explicit ASBinder(ArenaAllocator *allocator) : VarBinder(allocator) {} + ASBinder() = delete; NO_COPY_SEMANTIC(ASBinder); NO_MOVE_SEMANTIC(ASBinder); ~ASBinder() override = default; - ScriptExtension Extension() const override + [[nodiscard]] ScriptExtension Extension() const noexcept override { return ScriptExtension::AS; } - ResolveBindingOptions BindingOptions() const override + [[nodiscard]] ResolveBindingOptions BindingOptions() const noexcept override { return ResolveBindingOptions::BINDINGS; } void IdentifierAnalysis() override {} - -private: }; } // namespace ark::es2panda::varbinder diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 0324325f495ee072014018fea2fb8c55366e782a..ac13a0aa2ac98886902824170ccabed3e37e6aef 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -17,6 +17,7 @@ #include "evaluate/scopedDebugInfoPlugin.h" #include "public/public.h" +#include "compiler/lowering/util.h" namespace ark::es2panda::varbinder { @@ -87,18 +88,39 @@ bool ETSBinder::LookupInDebugInfoPlugin(ir::Identifier *ident) return false; } +// Auxiliary method extracted from LookupTypeReference(...) to avoid too large size +static void CreateDummyVariable(ETSBinder *varBinder, ir::Identifier *ident) +{ + auto expressionCtx = varbinder::LexicalScope::Enter(varBinder, varBinder->VarScope()); + auto [decl, var] = + varBinder->NewVarDecl(ident->Start(), compiler::GenName(varBinder->Allocator()).View()); + var->SetScope(varBinder->GetScope()); + ident->SetVariable(var); + ident->SetTsType(var->SetTsType(varBinder->GetContext()->checker->AsETSChecker()->GlobalTypeError())); + decl->BindNode(ident); +} + void ETSBinder::LookupTypeReference(ir::Identifier *ident, bool allowDynamicNamespaces) { - const auto &name = ident->Name(); - if (IsSpecialName(name) || ident->IsErrorPlaceHolder()) { + if (ident->Variable() != nullptr && ident->Variable()->Declaration()->Node() == ident) { return; } - auto *iter = GetScope(); - while (iter != nullptr) { + auto const &name = ident->Name(); + if (IsSpecialName(name)) { + return; + } + + if (ident->IsErrorPlaceHolder()) { + CreateDummyVariable(this, ident); + return; + } + + auto *scope = GetScope(); + while (scope != nullptr) { auto options = ResolveBindingOptions::DECLARATION | ResolveBindingOptions::TYPE_ALIASES | ResolveBindingOptions::STATIC_DECLARATION; - auto res = iter->Find(name, options); + auto res = scope->Find(name, options); if (res.variable == nullptr) { break; } @@ -121,7 +143,7 @@ void ETSBinder::LookupTypeReference(ir::Identifier *ident, bool allowDynamicName return; } default: { - iter = iter->Parent(); + scope = scope->Parent(); } } } @@ -130,8 +152,8 @@ void ETSBinder::LookupTypeReference(ir::Identifier *ident, bool allowDynamicName return; } - ident->SetTsType(GetContext()->checker->AsETSChecker()->GlobalTypeError()); ThrowUnresolvableType(ident->Start(), name); + CreateDummyVariable(this, ident); } void ETSBinder::ResolveReferencesForScope(ir::AstNode const *const parent, Scope *const scope) @@ -183,7 +205,7 @@ void ETSBinder::ResolveReferencesForScopeWithContext(ir::AstNode *node, Scope *s } bool ETSBinder::AddSelectiveExportAlias(util::StringView const &path, util::StringView const &key, - util::StringView const &value, ir::AstNode const *decl) + util::StringView const &value, ir::AstNode const *decl) noexcept { if (auto foundMap = selectiveExportAliasMultimap_.find(path); foundMap != selectiveExportAliasMultimap_.end()) { return foundMap->second.insert({key, std::make_pair(value, decl)}).second; @@ -485,7 +507,7 @@ void ETSBinder::BuildClassDefinitionImpl(ir::ClassDefinition *classDef) fieldVar->AddFlag(VariableFlags::EXPLICIT_INIT_REQUIRED); } } else { - ASSERT(GetContext()->diagnosticEngine->IsAnyError()); + ES2PANDA_ASSERT(GetContext()->diagnosticEngine->IsAnyError()); auto *checker = GetContext()->checker->AsETSChecker(); prop->SetTsType(checker->GlobalTypeError()); prop->Id()->SetTsType(checker->GlobalTypeError()); @@ -539,8 +561,8 @@ void ETSBinder::AddDynamicSpecifiersToTopBindings(ir::AstNode *const specifier, return specifier->AsImportSpecifier()->Local()->Name(); }(); - ES2PANDA_ASSERT(GetScope()->Find(name, ResolveBindingOptions::DECLARATION).variable != nullptr); auto specDecl = GetScope()->Find(name, ResolveBindingOptions::DECLARATION); + ES2PANDA_ASSERT(specDecl.variable != nullptr); dynamicImportVars_.emplace(specDecl.variable, DynamicImportData {import, specifier, specDecl.variable}); if (specifier->IsImportSpecifier()) { @@ -616,6 +638,8 @@ void ETSBinder::ImportAllForeignBindings(ir::AstNode *const specifier, const varbinder::GlobalScope *const importGlobalScope, const ir::ETSImportDeclaration *const import) { + bool const isStdLib = util::Helpers::IsStdLib(Program()); + for (const auto [bindingName, var] : globalBindings) { if (bindingName.Is(compiler::Signatures::ETS_GLOBAL)) { const auto *const classDef = var->Declaration()->Node()->AsClassDeclaration()->Definition(); @@ -628,17 +652,13 @@ void ETSBinder::ImportAllForeignBindings(ir::AstNode *const specifier, (var->AsLocalVariable()->Declaration()->Node()->IsExported() || var->AsLocalVariable()->Declaration()->Node()->IsExportedType())) { auto variable = Program()->GlobalClassScope()->FindLocal(bindingName, ResolveBindingOptions::ALL); - if (variable != nullptr && var != variable && variable->Declaration()->IsFunctionDecl() && - var->Declaration()->IsFunctionDecl()) { - bool isStdLib = util::Helpers::IsStdLib(Program()); + if (variable == nullptr || var == variable) { + InsertForeignBinding(specifier, import, bindingName, var); + } else if (variable->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { AddOverloadFlag(Allocator(), isStdLib, var, variable); - continue; - } - if (variable != nullptr && var != variable) { + } else { ThrowError(import->Source()->Start(), RedeclarationErrorMessageAssembler(var, variable, bindingName)); - continue; } - InsertForeignBinding(specifier, import, bindingName, var); } } @@ -1380,7 +1400,7 @@ void ETSBinder::ImportGlobalProperties(const ir::ClassDefinition *const classDef } } -const DynamicImportData *ETSBinder::DynamicImportDataForVar(const Variable *var) const +const DynamicImportData *ETSBinder::DynamicImportDataForVar(const Variable *var) const noexcept { auto it = dynamicImportVars_.find(var); if (it == dynamicImportVars_.cend()) { @@ -1390,7 +1410,7 @@ const DynamicImportData *ETSBinder::DynamicImportDataForVar(const Variable *var) return &it->second; } -ArenaVector ETSBinder::GetProgramList(const util::StringView &path) const +ArenaVector ETSBinder::GetProgramList(const util::StringView &path) const noexcept { auto const *globalProgram = globalRecordTable_.Program(); @@ -1414,7 +1434,7 @@ ArenaVector ETSBinder::GetProgramList(const util::StringView return ArenaVector(Allocator()->Adapter()); } -bool ETSBinder::IsDynamicModuleVariable(const Variable *var) const +bool ETSBinder::IsDynamicModuleVariable(const Variable *var) const noexcept { auto *data = DynamicImportDataForVar(var); if (data == nullptr) { @@ -1424,7 +1444,7 @@ bool ETSBinder::IsDynamicModuleVariable(const Variable *var) const return data->specifier->IsImportSpecifier(); } -bool ETSBinder::IsDynamicNamespaceVariable(const Variable *var) const +bool ETSBinder::IsDynamicNamespaceVariable(const Variable *var) const noexcept { auto *data = DynamicImportDataForVar(var); if (data == nullptr) { @@ -1434,7 +1454,7 @@ bool ETSBinder::IsDynamicNamespaceVariable(const Variable *var) const return data->specifier->IsImportNamespaceSpecifier(); } -void ETSBinder::ThrowError(const lexer::SourcePosition &pos, const std::string_view &msg) const +void ETSBinder::ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const { GetContext()->diagnosticEngine->LogSemanticError(msg, pos); } diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 320b2099e68e58e7724aea3dd270c11cc673d9f2..f155b979d5998198ce0a9619a38d73acb59d14c8 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -71,51 +71,52 @@ public: InitImplicitThisParam(); } + ETSBinder() = delete; NO_COPY_SEMANTIC(ETSBinder); NO_MOVE_SEMANTIC(ETSBinder); ~ETSBinder() override = default; - ScriptExtension Extension() const override + [[nodiscard]] ScriptExtension Extension() const noexcept override { return ScriptExtension::STS; } - ResolveBindingOptions BindingOptions() const override + [[nodiscard]] ResolveBindingOptions BindingOptions() const noexcept override { return ResolveBindingOptions::BINDINGS; } - RecordTable *GetRecordTable() + [[nodiscard]] RecordTable *GetRecordTable() noexcept { return recordTable_; } - const RecordTable *GetRecordTable() const + [[nodiscard]] const RecordTable *GetRecordTable() const noexcept { return recordTable_; } - void SetRecordTable(RecordTable *table) + void SetRecordTable(RecordTable *table) noexcept { recordTable_ = table; } - RecordTable *GetGlobalRecordTable() + [[nodiscard]] RecordTable *GetGlobalRecordTable() noexcept { return &globalRecordTable_; } - const RecordTable *GetGlobalRecordTable() const + [[nodiscard]] const RecordTable *GetGlobalRecordTable() const noexcept { return &globalRecordTable_; } - ArenaMap &GetExternalRecordTable() + [[nodiscard]] ArenaMap &GetExternalRecordTable() noexcept { return externalRecordTable_; } - const ArenaMap &GetExternalRecordTable() const + [[nodiscard]] const ArenaMap &GetExternalRecordTable() const noexcept { return externalRecordTable_; } @@ -128,11 +129,11 @@ public: void BuildETSTypeReference(ir::ETSTypeReference *typeRef); void BuildClassProperty(const ir::ClassProperty *prop) override; void LookupIdentReference(ir::Identifier *ident) override; - bool BuildInternalName(ir::ScriptFunction *scriptFunc) override; + [[nodiscard]] bool BuildInternalName(ir::ScriptFunction *scriptFunc) override; void AddCompilableFunction(ir::ScriptFunction *func) override; - bool HandleDynamicVariables(ir::Identifier *ident, Variable *variable, bool allowDynamicNamespaces); - bool LookupInDebugInfoPlugin(ir::Identifier *ident); + [[nodiscard]] bool HandleDynamicVariables(ir::Identifier *ident, Variable *variable, bool allowDynamicNamespaces); + [[nodiscard]] bool LookupInDebugInfoPlugin(ir::Identifier *ident); void LookupTypeReference(ir::Identifier *ident, bool allowDynamicNamespaces); void LookupTypeArgumentReferences(ir::ETSTypeReference *typeRef); void BuildInterfaceDeclaration(ir::TSInterfaceDeclaration *decl); @@ -143,17 +144,18 @@ public: void BuildImportDeclaration(ir::ETSImportDeclaration *decl); void ValidateReexportDeclaration(ir::ETSReExportDeclaration *decl); void ValidateReexports(); - bool ReexportPathMatchesImportPath(const ir::ETSReExportDeclaration *const reexport, - const ir::ETSImportDeclaration *const import) const; + [[nodiscard]] bool ReexportPathMatchesImportPath(const ir::ETSReExportDeclaration *const reexport, + const ir::ETSImportDeclaration *const import) const; Variable *ValidateImportSpecifier(const ir::ImportSpecifier *const specifier, const ir::ETSImportDeclaration *const import, std::vector viewedReExport); void BuildETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression *classInstance); - bool DetectNameConflict(const util::StringView localName, Variable *const var, Variable *const otherVar, - const ir::StringLiteral *const importPath, bool overloadAllowed); + [[nodiscard]] bool DetectNameConflict(const util::StringView localName, Variable *const var, + Variable *const otherVar, const ir::StringLiteral *const importPath, + bool overloadAllowed); void AddSpecifiersToTopBindings(ir::AstNode *specifier, const ir::ETSImportDeclaration *import); - ArenaVector GetExternalProgram(const util::StringView &sourceName, - const ir::StringLiteral *importPath); + [[nodiscard]] ArenaVector GetExternalProgram(const util::StringView &sourceName, + const ir::StringLiteral *importPath); bool AddImportNamespaceSpecifiersToTopBindings(ir::AstNode *specifier, const varbinder::Scope::VariableMap &globalBindings, const parser::Program *importProgram, @@ -191,59 +193,59 @@ public: void BuildProxyMethod(ir::ScriptFunction *func, const util::StringView &containingClassName, bool isExternal); void AddFunctionThisParam(ir::ScriptFunction *func); - void ThrowError(const lexer::SourcePosition &pos, const std::string_view &msg) const override; + void ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const override; - void SetDefaultImports(ArenaVector defaultImports) + void SetDefaultImports(ArenaVector defaultImports) noexcept { defaultImports_ = std::move(defaultImports); } void AddDynamicImport(ir::ETSImportDeclaration *import); - const ArenaVector &DynamicImports() const + [[nodiscard]] const ArenaVector &DynamicImports() const noexcept { return dynamicImports_; } - void AddReExportImport(ir::ETSReExportDeclaration *reExport) + void AddReExportImport(ir::ETSReExportDeclaration *reExport) noexcept { reExportImports_.push_back(reExport); } - const ArenaVector &ReExportImports() const + [[nodiscard]] const ArenaVector &ReExportImports() const noexcept { return reExportImports_; } - const DynamicImportVariables &DynamicImportVars() const + [[nodiscard]] const DynamicImportVariables &DynamicImportVars() const noexcept { return dynamicImportVars_; } - const ir::AstNode *DefaultExport() + [[nodiscard]] const ir::AstNode *DefaultExport() noexcept { return defaultExport_; } - void SetDefaultExport(ir::AstNode *defaultExport) + void SetDefaultExport(ir::AstNode *defaultExport) noexcept { defaultExport_ = defaultExport; } /* Returns the list of programs belonging to the same compilation unit based on a program path */ - ArenaVector GetProgramList(const util::StringView &path) const; + [[nodiscard]] ArenaVector GetProgramList(const util::StringView &path) const noexcept; - bool IsDynamicModuleVariable(const Variable *var) const; - bool IsDynamicNamespaceVariable(const Variable *var) const; - const DynamicImportData *DynamicImportDataForVar(const Variable *var) const; + [[nodiscard]] bool IsDynamicModuleVariable(const Variable *var) const noexcept; + [[nodiscard]] bool IsDynamicNamespaceVariable(const Variable *var) const noexcept; + [[nodiscard]] const DynamicImportData *DynamicImportDataForVar(const Variable *var) const noexcept; void ResolveReferenceForScope(ir::AstNode *node, Scope *scope); void ResolveReferencesForScope(ir::AstNode const *parent, Scope *scope); void ResolveReferencesForScopeWithContext(ir::AstNode *node, Scope *scope); - bool AddSelectiveExportAlias(util::StringView const &path, util::StringView const &key, - util::StringView const &value, ir::AstNode const *decl); + [[nodiscard]] bool AddSelectiveExportAlias(util::StringView const &path, util::StringView const &key, + util::StringView const &value, ir::AstNode const *decl) noexcept; [[nodiscard]] const ModulesToExportedNamesWithAliases &GetSelectiveExportAliasMultimap() const noexcept { diff --git a/ets2panda/varbinder/JSBinder.h b/ets2panda/varbinder/JSBinder.h index b80acdec38aa786ce371d593a2765a09ed97b936..9b2cc876f0da9ad243f158b50ea3f0bd8d6eb330 100644 --- a/ets2panda/varbinder/JSBinder.h +++ b/ets2panda/varbinder/JSBinder.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 @@ -23,11 +23,10 @@ class JSBinder : public VarBinder { public: explicit JSBinder(ArenaAllocator *allocator) : VarBinder(allocator) {} + JSBinder() = delete; NO_COPY_SEMANTIC(JSBinder); NO_MOVE_SEMANTIC(JSBinder); ~JSBinder() override = default; - -private: }; } // namespace ark::es2panda::varbinder diff --git a/ets2panda/varbinder/TSBinder.h b/ets2panda/varbinder/TSBinder.h index 0ce5b99cf809dcce71870d45debb021b20f34127..ec897425365e9bc3b409aee9dbd1f4219ac50189 100644 --- a/ets2panda/varbinder/TSBinder.h +++ b/ets2panda/varbinder/TSBinder.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 @@ -23,22 +23,20 @@ class TSBinder : public TypedBinder { public: explicit TSBinder(ArenaAllocator *allocator) : TypedBinder(allocator) {} + TSBinder() = delete; NO_COPY_SEMANTIC(TSBinder); NO_MOVE_SEMANTIC(TSBinder); ~TSBinder() override = default; - ScriptExtension Extension() const override + [[nodiscard]] ScriptExtension Extension() const noexcept override { return ScriptExtension::TS; } - ResolveBindingOptions BindingOptions() const override + [[nodiscard]] ResolveBindingOptions BindingOptions() const noexcept override { return ResolveBindingOptions::ALL; } - -protected: }; } // namespace ark::es2panda::varbinder - #endif diff --git a/ets2panda/varbinder/TypedBinder.h b/ets2panda/varbinder/TypedBinder.h index 56abe35045295eec0ca2dbb2c357ea5902857be2..533966d64ad304c248bf44c2cc5f53a9202ca315 100644 --- a/ets2panda/varbinder/TypedBinder.h +++ b/ets2panda/varbinder/TypedBinder.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 @@ -23,13 +23,14 @@ class TypedBinder : public VarBinder { public: explicit TypedBinder(ArenaAllocator *allocator) : VarBinder(allocator) {} + TypedBinder() = delete; NO_COPY_SEMANTIC(TypedBinder); NO_MOVE_SEMANTIC(TypedBinder); ~TypedBinder() override = default; protected: void HandleCustomNodes(ir::AstNode *childNode) override; - void BuildSignatureDeclarationBaseParams([[maybe_unused]] ir::AstNode *typeNode) override; + void BuildSignatureDeclarationBaseParams(ir::AstNode *typeNode) override; }; } // namespace ark::es2panda::varbinder diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index f04716e272fa08f07f0eead4bb8d24b62a7cb14b..2860377a0a7358d178ed7aff757e4af5d704b026 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -15,27 +15,17 @@ #include "scope.h" -#include "varbinder/tsBinding.h" #include "public/public.h" -#include "ir/statements/annotationDeclaration.h" +#include "varbinder/tsBinding.h" +#include "compiler/lowering/util.h" namespace ark::es2panda::varbinder { -VariableScope *Scope::EnclosingVariableScope() +VariableScope *Scope::EnclosingVariableScope() noexcept { - Scope *iter = this; - - while (iter != nullptr) { - if (iter->IsVariableScope()) { - return iter->AsVariableScope(); - } - - iter = iter->Parent(); - } - - return nullptr; + return const_cast(const_cast(this)->EnclosingVariableScope()); } -const VariableScope *Scope::EnclosingVariableScope() const +const VariableScope *Scope::EnclosingVariableScope() const noexcept { const auto *iter = this; @@ -50,7 +40,7 @@ const VariableScope *Scope::EnclosingVariableScope() const return nullptr; } -bool Scope::IsSuperscopeOf(const varbinder::Scope *subscope) const +bool Scope::IsSuperscopeOf(const varbinder::Scope *subscope) const noexcept { while (subscope != nullptr) { if (subscope == this) { @@ -61,37 +51,6 @@ bool Scope::IsSuperscopeOf(const varbinder::Scope *subscope) const return false; } -// NOTE(psiket): Duplication -ClassScope *Scope::EnclosingClassScope() -{ - Scope *iter = this; - - while (iter != nullptr) { - if (iter->IsClassScope()) { - return iter->AsClassScope(); - } - - iter = iter->Parent(); - } - - return nullptr; -} - -const ClassScope *Scope::EnclosingClassScope() const -{ - const auto *iter = this; - - while (iter != nullptr) { - if (iter->IsVariableScope()) { - return iter->AsClassScope(); - } - - iter = iter->Parent(); - } - - return nullptr; -} - Variable *Scope::FindLocal(const util::StringView &name, ResolveBindingOptions options) const { if ((options & ResolveBindingOptions::INTERFACES) != 0) { @@ -121,9 +80,8 @@ Scope::InsertResult Scope::InsertBinding(const util::StringView &name, Variable ES2PANDA_ASSERT(var != nullptr); auto insertResult = bindings_.emplace(name, var); if (insertResult.second) { - decls_.push_back(var->Declaration()); + decls_.emplace_back(var->Declaration()); } - return insertResult; } @@ -146,7 +104,7 @@ Scope::VariableMap::size_type Scope::EraseBinding(const util::StringView &name) toBeErased == bindings_.end() || (toBeErased->second->IsLocalVariable() && toBeErased->second->AsLocalVariable()->Declaration()->Node()->IsImportNamespaceSpecifier())) { - return 0; + return 0U; } return bindings_.erase(name); @@ -198,7 +156,7 @@ ConstScopeFindResult Scope::Find(const util::StringView &name, const ResolveBind return FindImpl(this, name, options); } -Decl *Scope::FindDecl(const util::StringView &name) const +Decl *Scope::FindDecl(const util::StringView &name) const noexcept { for (auto *it : decls_) { if (it->Name() == name) { @@ -372,7 +330,8 @@ void VariableScope::CheckDirectEval(public_lib::Context *context) } template -Variable *VariableScope::AddVar(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl) +Variable *VariableScope::AddVar(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, + [[maybe_unused]] ScriptExtension extension) { if (!currentVariable) { return InsertBinding(newDecl->Name(), allocator->New(newDecl, VariableFlags::HOIST_VAR)).first->second; @@ -388,6 +347,7 @@ Variable *VariableScope::AddVar(ArenaAllocator *allocator, Variable *currentVari return currentVariable; } default: { + ES2PANDA_ASSERT(extension == ScriptExtension::JS); return nullptr; } } @@ -414,6 +374,7 @@ Variable *VariableScope::AddFunction(ArenaAllocator *allocator, Variable *curren return currentVariable; } default: { + ES2PANDA_ASSERT(extension == ScriptExtension::JS); return nullptr; } } @@ -437,66 +398,59 @@ Variable *VariableScope::AddLexical(ArenaAllocator *allocator, Variable *current return InsertBinding(newDecl->Name(), allocator->New(newDecl, VariableFlags::NONE)).first->second; } -Variable *ParamScope::AddParam(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, VariableFlags flags) +Variable *ParamScope::AddParameter(ArenaAllocator *allocator, Decl *newDecl, VariableFlags flags) { ES2PANDA_ASSERT(newDecl->IsParameterDecl()); - if (currentVariable != nullptr) { - return nullptr; - } - auto *param = allocator->New(newDecl, flags); param->SetScope(this); - params_.push_back(param); + params_.emplace_back(param); InsertBinding(newDecl->Name(), param); + return param; } -std::tuple ParamScope::AddParamDecl(ArenaAllocator *allocator, - ir::AstNode *param) +std::tuple ParamScope::AddParamDecl(ArenaAllocator *allocator, ir::Expression *parameter) { - const auto [name, pattern] = util::Helpers::ParamName(allocator, param, params_.size()); + auto [name, pattern] = util::Helpers::ParamName(allocator, parameter, params_.size()); if (name.Is(ERROR_LITERAL)) { - return {nullptr, nullptr, nullptr}; + name = compiler::GenName(allocator).View(); } - auto *decl = NewDecl(allocator, name); - auto *var = AddParam(allocator, FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS), decl, - VariableFlags::VAR | VariableFlags::LOCAL); - - if (var == nullptr) { - return {decl, param, nullptr}; + auto *variable = FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS); + if (variable != nullptr) { + return std::make_tuple(variable, parameter); } - if (!pattern) { - decl->BindNode(param); - return {decl, nullptr, var}; - } + if (pattern) { + std::vector bindings = util::Helpers::CollectBindingNames(parameter); - std::vector bindings = util::Helpers::CollectBindingNames(param); + for (auto *binding : bindings) { + auto *varDecl = NewDecl(allocator, binding->Name()); + varDecl->BindNode(binding); - for (auto *binding : bindings) { - auto *varDecl = NewDecl(allocator, binding->Name()); - varDecl->BindNode(binding); + if (variable = FindLocal(varDecl->Name(), varbinder::ResolveBindingOptions::BINDINGS); + variable != nullptr) { + return std::make_tuple(variable, binding); + } - if (FindLocal(varDecl->Name(), varbinder::ResolveBindingOptions::BINDINGS) != nullptr) { - return {decl, binding, nullptr}; + auto *paramVar = allocator->New(varDecl, VariableFlags::VAR | VariableFlags::LOCAL); + TryInsertBinding(varDecl->Name(), paramVar); } - - auto *paramVar = allocator->New(varDecl, VariableFlags::VAR | VariableFlags::LOCAL); - TryInsertBinding(varDecl->Name(), paramVar); } - return {decl, nullptr, var}; + auto *const decl = NewDecl(allocator, name); + variable = AddParameter(allocator, decl, VariableFlags::VAR | VariableFlags::LOCAL); + decl->BindNode(parameter); + + return std::make_tuple(variable, nullptr); } void FunctionParamScope::BindName(ArenaAllocator *allocator, util::StringView name) { - nameVar_ = AddDecl(allocator, name, VariableFlags::INITIALIZED); - if (!functionScope_->InsertBinding(name, nameVar_).second) { - nameVar_ = nullptr; - } + auto [variable, _] = AddDecl(allocator, name, VariableFlags::INITIALIZED); + nameVar_ = functionScope_->InsertBinding(name, variable).second ? variable->AsLocalVariable() : nullptr; } Variable *FunctionParamScope::AddBinding([[maybe_unused]] ArenaAllocator *allocator, @@ -538,7 +492,7 @@ Variable *FunctionScope::AddBinding(ArenaAllocator *allocator, Variable *current Variable *var {}; switch (newDecl->Type()) { case DeclType::VAR: { - return AddVar(allocator, currentVariable, newDecl); + return AddVar(allocator, currentVariable, newDecl, extension); } case DeclType::FUNC: { return AddFunction(allocator, currentVariable, newDecl, extension); @@ -587,7 +541,7 @@ Variable *GlobalScope::AddBinding(ArenaAllocator *allocator, Variable *currentVa { switch (newDecl->Type()) { case DeclType::VAR: { - return AddVar(allocator, currentVariable, newDecl); + return AddVar(allocator, currentVariable, newDecl, extension); } case DeclType::FUNC: { return AddFunction(allocator, currentVariable, newDecl, extension); @@ -686,7 +640,7 @@ Variable *ModuleScope::AddBinding(ArenaAllocator *allocator, Variable *currentVa { switch (newDecl->Type()) { case DeclType::VAR: { - return AddVar(allocator, currentVariable, newDecl); + return AddVar(allocator, currentVariable, newDecl, extension); } case DeclType::FUNC: { return AddFunction(allocator, currentVariable, newDecl, extension); @@ -1127,7 +1081,7 @@ void LoopScope::ConvertToVariableScope(ArenaAllocator *allocator) Variable *CatchParamScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension) { - return AddParam(allocator, currentVariable, newDecl, VariableFlags::INITIALIZED); + return currentVariable != nullptr ? nullptr : AddParameter(allocator, newDecl, VariableFlags::INITIALIZED); } Variable *CatchScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, diff --git a/ets2panda/varbinder/scope.h b/ets2panda/varbinder/scope.h index 7070bd291ec3e0667bd234d94fff6ee18ef415fd..abee6c75d95156ac9ee78ee7ff42d343ace83ef8 100644 --- a/ets2panda/varbinder/scope.h +++ b/ets2panda/varbinder/scope.h @@ -18,11 +18,7 @@ #include "es2panda.h" #include "varbinder/declaration.h" -#include "util/enumbitops.h" -#include "util/ustring.h" -#include "varbinder/variableFlags.h" -#include -#include +#include "varbinder/variable.h" namespace ark::es2panda::public_lib { struct Context; @@ -34,6 +30,7 @@ class IRNode; namespace ark::es2panda::ir { class AstNode; +class Expression; class Identifier; } // namespace ark::es2panda::ir @@ -44,11 +41,6 @@ namespace ark::es2panda::varbinder { SCOPE_TYPES(DECLARE_CLASSES) #undef DECLARE_CLASSES -class Scope; -class VariableScope; -class Variable; -class LocalVariable; - template && std::is_base_of_v>, bool> = true> @@ -76,6 +68,7 @@ using ScopeFindResult = ScopeFindResultT; class Scope { public: + Scope() = delete; virtual ~Scope() = default; NO_COPY_SEMANTIC(Scope); NO_MOVE_SEMANTIC(Scope); @@ -109,125 +102,121 @@ public: SCOPE_TYPES(DECLARE_CHECKS_CASTS) #undef DECLARE_CHECKS_CASTS - bool IsVariableScope() const + [[nodiscard]] bool IsVariableScope() const noexcept { return Type() > ScopeType::LOCAL; } - bool IsFunctionVariableScope() const + [[nodiscard]] bool IsFunctionVariableScope() const noexcept { return Type() >= ScopeType::FUNCTION; } - FunctionScope *AsFunctionVariableScope() + [[nodiscard]] FunctionScope *AsFunctionVariableScope() { ES2PANDA_ASSERT(IsFunctionVariableScope()); return reinterpret_cast(this); } - const FunctionScope *AsFunctionVariableScope() const + [[nodiscard]] const FunctionScope *AsFunctionVariableScope() const { ES2PANDA_ASSERT(IsFunctionVariableScope()); return reinterpret_cast(this); } - VariableScope *AsVariableScope() + [[nodiscard]] VariableScope *AsVariableScope() { ES2PANDA_ASSERT(IsVariableScope()); return reinterpret_cast(this); } - const VariableScope *AsVariableScope() const + [[nodiscard]] const VariableScope *AsVariableScope() const { ES2PANDA_ASSERT(IsVariableScope()); return reinterpret_cast(this); } - VariableScope *EnclosingVariableScope(); - - const VariableScope *EnclosingVariableScope() const; - - ClassScope *EnclosingClassScope(); - const ClassScope *EnclosingClassScope() const; + [[nodiscard]] VariableScope *EnclosingVariableScope() noexcept; + [[nodiscard]] const VariableScope *EnclosingVariableScope() const noexcept; - void AddFlag(ScopeFlags flag) + void AddFlag(ScopeFlags flag) noexcept { flags_ |= flag; } - void ClearFlag(ScopeFlags flag) + void ClearFlag(ScopeFlags flag) noexcept { flags_ &= ~flag; } - bool HasFlag(ScopeFlags flag) const + [[nodiscard]] bool HasFlag(ScopeFlags flag) const noexcept { return (flags_ & flag) != 0; } - ArenaVector &Decls() + [[nodiscard]] ArenaVector &Decls() noexcept { return decls_; } - const ArenaVector &Decls() const + [[nodiscard]] const ArenaVector &Decls() const noexcept { return decls_; } - void SetParent(Scope *parent) + void SetParent(Scope *parent) noexcept { parent_ = parent; } - Scope *Parent() + [[nodiscard]] Scope *Parent() noexcept { return parent_; } - const Scope *Parent() const + [[nodiscard]] const Scope *Parent() const noexcept { return parent_; } - const compiler::IRNode *ScopeStart() const + [[nodiscard]] const compiler::IRNode *ScopeStart() const noexcept { return startIns_; } - const compiler::IRNode *ScopeEnd() const + [[nodiscard]] const compiler::IRNode *ScopeEnd() const noexcept { return endIns_; } - void SetScopeStart(const compiler::IRNode *ins) + void SetScopeStart(const compiler::IRNode *ins) noexcept { startIns_ = ins; } - void SetScopeEnd(const compiler::IRNode *ins) + void SetScopeEnd(const compiler::IRNode *ins) noexcept { endIns_ = ins; } - ir::AstNode *Node() + [[nodiscard]] ir::AstNode *Node() noexcept { return node_; } - const ir::AstNode *Node() const + [[nodiscard]] const ir::AstNode *Node() const noexcept { return node_; } - void BindNode(ir::AstNode *node) + void BindNode(ir::AstNode *node) noexcept { node_ = node; } Variable *AddDecl(ArenaAllocator *allocator, Decl *decl, ScriptExtension extension) { - decls_.push_back(decl); + decls_.emplace_back(decl); auto options = decl->IsTypeAliasDecl() ? varbinder::ResolveBindingOptions::TYPE_ALIASES : varbinder::ResolveBindingOptions::BINDINGS; return AddBinding(allocator, FindLocal(decl->Name(), options), decl, extension); @@ -235,7 +224,7 @@ public: Variable *AddTsDecl(ArenaAllocator *allocator, Decl *decl, ScriptExtension extension) { - decls_.push_back(decl); + decls_.emplace_back(decl); return AddBinding(allocator, FindLocal(decl->Name(), ResolveBindingOptions::ALL), decl, extension); } @@ -243,7 +232,8 @@ public: T *NewDecl(ArenaAllocator *allocator, Args &&...args); template - VariableType *AddDecl(ArenaAllocator *allocator, util::StringView name, VariableFlags flags); + std::pair AddDecl(ArenaAllocator *allocator, util::StringView name, + VariableFlags flags); template static VariableType *CreateVar(ArenaAllocator *allocator, util::StringView name, VariableFlags flags, @@ -257,12 +247,12 @@ public: virtual void MergeBindings(VariableMap const &bindings); virtual VariableMap::size_type EraseBinding(const util::StringView &name); - const VariableMap &Bindings() const + [[nodiscard]] const VariableMap &Bindings() const noexcept { return bindings_; } - ArenaMap OrderedBindings(ArenaAllocator *allocator) const + [[nodiscard]] ArenaMap OrderedBindings(ArenaAllocator *allocator) const noexcept { ArenaMap result(allocator->Adapter()); result.insert(bindings_.begin(), bindings_.end()); @@ -274,7 +264,7 @@ public: virtual Variable *FindLocal(const util::StringView &name, ResolveBindingOptions options) const; - bool IsSuperscopeOf(const varbinder::Scope *subscope) const; + [[nodiscard]] bool IsSuperscopeOf(const varbinder::Scope *subscope) const noexcept; ConstScopeFindResult Find(const util::StringView &name, ResolveBindingOptions options = ResolveBindingOptions::BINDINGS) const; @@ -287,7 +277,7 @@ public: ConstScopeFindResult FindInFunctionScope(const util::StringView &name, ResolveBindingOptions options = ResolveBindingOptions::BINDINGS) const; - Decl *FindDecl(const util::StringView &name) const; + [[nodiscard]] Decl *FindDecl(const util::StringView &name) const noexcept; protected: explicit Scope(ArenaAllocator *allocator, Scope *parent) @@ -411,7 +401,7 @@ protected: explicit VariableScope(ArenaAllocator *allocator, Scope *parent) : Scope(allocator, parent) {} template - Variable *AddVar(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl); + Variable *AddVar(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, ScriptExtension extension); template Variable *AddFunction(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, @@ -446,7 +436,7 @@ public: return params_; } - std::tuple AddParamDecl(ArenaAllocator *allocator, ir::AstNode *param); + std::tuple AddParamDecl(ArenaAllocator *allocator, ir::Expression *parameter); protected: explicit ParamScope(ArenaAllocator *allocator, Scope *parent) @@ -454,7 +444,7 @@ protected: { } - Variable *AddParam(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, VariableFlags flags); + Variable *AddParameter(ArenaAllocator *allocator, Decl *newDecl, VariableFlags flags); // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) ArenaVector params_; @@ -476,7 +466,7 @@ public: functionScope_ = funcScope; } - LocalVariable *NameVar() const + [[nodiscard]] LocalVariable *NameVar() const noexcept { return nameVar_; } @@ -992,20 +982,22 @@ T *Scope::NewDecl(ArenaAllocator *allocator, Args &&...args) } template -VariableType *Scope::AddDecl(ArenaAllocator *allocator, util::StringView name, VariableFlags flags) +std::pair Scope::AddDecl(ArenaAllocator *allocator, util::StringView name, + VariableFlags flags) { - if (FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS)) { - return nullptr; + varbinder::Variable *variable = FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS); + if (variable != nullptr) { + return std::make_pair(variable, true); } auto *decl = allocator->New(name); - auto *variable = allocator->New(decl, flags); + variable = allocator->New(decl, flags); - decls_.push_back(decl); + decls_.emplace_back(decl); bindings_.insert({decl->Name(), variable}); variable->SetScope(this); - return variable; + return std::make_pair(variable, false); } template diff --git a/ets2panda/varbinder/varbinder.cpp b/ets2panda/varbinder/varbinder.cpp index 4752fa94d9886c6e79fe99879e4614ad4a8aa8fc..0d0bc01e39c39f460a2c6b7f935f890c134d478d 100644 --- a/ets2panda/varbinder/varbinder.cpp +++ b/ets2panda/varbinder/varbinder.cpp @@ -29,61 +29,52 @@ void VarBinder::InitTopScope() varScope_ = topScope_; } -std::tuple VarBinder::AddParamDecl(ir::AstNode *param) +Variable *VarBinder::AddParamDecl(ir::Expression *param) { ES2PANDA_ASSERT(scope_->IsFunctionParamScope() || scope_->IsCatchParamScope()); - auto [decl, node, var] = static_cast(scope_)->AddParamDecl(Allocator(), param); + + auto [var, node] = static_cast(scope_)->AddParamDecl(Allocator(), param); + ES2PANDA_ASSERT(var != nullptr); if (node != nullptr) { - ThrowRedeclaration(node->Start(), decl->Name()); + ThrowRedeclaration(node->Start(), var->Name()); } - return {decl, var}; -} -void VarBinder::ThrowRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name) const -{ - std::stringstream ss; - ss << "Variable '" << name << "' has already been declared."; - ThrowError(pos, ss.str()); + return var; } -void VarBinder::ThrowUnresolvableVariable(const lexer::SourcePosition &pos, const util::StringView &name) const +void VarBinder::ThrowRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name) const { - std::stringstream ss; - ss << "Cannot find variable '" << name << "'."; - ThrowError(pos, ss.str()); + auto const str = std::string {"Variable '"}.append(name.Utf8()).append("' has already been declared."); + ThrowError(pos, str); } void VarBinder::ThrowUnresolvableType(const lexer::SourcePosition &pos, const util::StringView &name) const { - std::stringstream ss; - ss << "Cannot find type '" << name << "'."; - ThrowError(pos, ss.str()); + auto const str = std::string {"Cannot find type '"}.append(name.Utf8()).append("'."); + ThrowError(pos, str); } void VarBinder::ThrowTDZ(const lexer::SourcePosition &pos, const util::StringView &name) const { - std::stringstream ss; - ss << "Variable '" << name << "' is accessed before it's initialization."; - ThrowError(pos, ss.str()); + auto const str = std::string {"Variable '"}.append(name.Utf8()).append("' is accessed before it's initialization."); + ThrowError(pos, str); } void VarBinder::ThrowInvalidCapture(const lexer::SourcePosition &pos, const util::StringView &name) const { - std::stringstream ss; - ss << "Cannot capture variable'" << name << "'."; - ThrowError(pos, ss.str()); + auto const str = std::string {"Cannot capture variable '"}.append(name.Utf8()).append("'."); + ThrowError(pos, str); } void VarBinder::ThrowPrivateFieldMismatch(const lexer::SourcePosition &pos, const util::StringView &name) const { - std::stringstream ss; - ss << "Private field '" << name << "' must be declared in an enclosing class"; - - ThrowError(pos, ss.str()); + auto const str = + std::string {"Private field '"}.append(name.Utf8()).append("' must be declared in an enclosing class"); + ThrowError(pos, str); } -void VarBinder::ThrowError(const lexer::SourcePosition &pos, const std::string_view &msg) const +void VarBinder::ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const { lexer::LineIndex index(program_->SourceCode()); lexer::SourceLocation loc = index.GetLocation(pos); @@ -124,13 +115,12 @@ bool VarBinder::InstantiateArgumentsImpl(Scope **scope, Scope *iter, const ir::A if (node->AsScriptFunction()->IsArrow()) { return false; } - auto *argumentsVariable = - (*scope)->AddDecl(Allocator(), FUNCTION_ARGUMENTS, VariableFlags::INITIALIZED); - if (iter->IsFunctionParamScope()) { - if (argumentsVariable == nullptr) { - return true; - } + auto [argumentsVariable, exists] = + (*scope)->AddDecl(Allocator(), FUNCTION_ARGUMENTS, VariableFlags::INITIALIZED); + if (exists && Extension() != ScriptExtension::JS) { + ThrowRedeclaration(node->Start(), FUNCTION_ARGUMENTS); + } else if (iter->IsFunctionParamScope()) { *scope = iter->AsFunctionParamScope()->GetFunctionScope(); (*scope)->InsertBinding(argumentsVariable->Name(), argumentsVariable); } diff --git a/ets2panda/varbinder/varbinder.h b/ets2panda/varbinder/varbinder.h index 8f0b94a7446e20ef0df7f9945af47f678159b747..f0ef59ea2699e0afab5d1730ad171b8fdcf5b03c 100644 --- a/ets2panda/varbinder/varbinder.h +++ b/ets2panda/varbinder/varbinder.h @@ -55,6 +55,7 @@ class VarBinder { public: explicit VarBinder(ArenaAllocator *allocator) : allocator_(allocator), functionScopes_(allocator_->Adapter()) {} + VarBinder() = delete; NO_COPY_SEMANTIC(VarBinder); NO_MOVE_SEMANTIC(VarBinder); virtual ~VarBinder() = default; @@ -71,19 +72,19 @@ public: template std::tuple NewVarDecl(const lexer::SourcePosition &pos, Args &&...args); - std::tuple AddParamDecl(ir::AstNode *param); + Variable *AddParamDecl(ir::Expression *param); - void SetProgram(parser::Program *program) + void SetProgram(parser::Program *program) noexcept { program_ = program; } - parser::Program *Program() + [[nodiscard]] parser::Program *Program() noexcept { return program_; } - const parser::Program *Program() const + [[nodiscard]] const parser::Program *Program() const { ES2PANDA_ASSERT(program_); return program_; @@ -95,28 +96,28 @@ public: context_ = context; } - public_lib::Context *GetContext() const + [[nodiscard]] public_lib::Context *GetContext() const { ES2PANDA_ASSERT(context_); return context_; } - void SetGenStdLib(bool genStdLib) + void SetGenStdLib(bool genStdLib) noexcept { genStdLib_ = genStdLib; } - bool IsGenStdLib() + [[nodiscard]] bool IsGenStdLib() noexcept { return genStdLib_; } - Scope *GetScope() const + [[nodiscard]] Scope *GetScope() const noexcept { return scope_; } - void ResetAllScopes(GlobalScope *topScope, VariableScope *varScope, Scope *scope) + void ResetAllScopes(GlobalScope *topScope, VariableScope *varScope, Scope *scope) noexcept { topScope_ = topScope; varScope_ = varScope; @@ -131,28 +132,28 @@ public: scope_ = topScope_; } - GlobalScope *TopScope() const + [[nodiscard]] GlobalScope *TopScope() const noexcept { return topScope_; } - VariableScope *VarScope() const + [[nodiscard]] VariableScope *VarScope() const noexcept { return varScope_; } - bool IsETSBinder() const + [[nodiscard]] bool IsETSBinder() const noexcept { return Extension() == ScriptExtension::STS; } - const ETSBinder *AsETSBinder() const + [[nodiscard]] const ETSBinder *AsETSBinder() const { - ASSERT(Extension() == ScriptExtension::STS); + ES2PANDA_ASSERT(Extension() == ScriptExtension::STS); return reinterpret_cast(this); } - ETSBinder *AsETSBinder() + [[nodiscard]] ETSBinder *AsETSBinder() { ES2PANDA_ASSERT(Extension() == ScriptExtension::STS); return reinterpret_cast(this); @@ -160,60 +161,59 @@ public: void ThrowPrivateFieldMismatch(const lexer::SourcePosition &pos, const util::StringView &name) const; void ThrowRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name) const; - void ThrowUnresolvableVariable(const lexer::SourcePosition &pos, const util::StringView &name) const; void ThrowUnresolvableType(const lexer::SourcePosition &pos, const util::StringView &name) const; 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 void ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const; void PropagateDirectEval() const; template friend class LexicalScope; - inline ArenaAllocator *Allocator() const + [[nodiscard]] ArenaAllocator *Allocator() const noexcept { return allocator_; } - const ArenaVector &Functions() const + [[nodiscard]] const ArenaVector &Functions() const noexcept { return functionScopes_; } - ArenaVector &Functions() + [[nodiscard]] ArenaVector &Functions() noexcept { return functionScopes_; } - virtual ScriptExtension Extension() const + [[nodiscard]] virtual ScriptExtension Extension() const noexcept { return ScriptExtension::JS; } - virtual ResolveBindingOptions BindingOptions() const + [[nodiscard]] virtual ResolveBindingOptions BindingOptions() const noexcept { return ResolveBindingOptions::BINDINGS; } LocalVariable *AddMandatoryParam(const std::string_view &name); - static constexpr std::string_view FUNCTION_ARGUMENTS = "arguments"; - static constexpr std::string_view MANDATORY_PARAM_FUNC = "=f"; - static constexpr std::string_view MANDATORY_PARAM_NEW_TARGET = "=nt"; - static constexpr std::string_view MANDATORY_PARAM_THIS = "=t"; + inline static constexpr std::string_view const FUNCTION_ARGUMENTS = "arguments"; + inline static constexpr std::string_view const MANDATORY_PARAM_FUNC = "=f"; + inline static constexpr std::string_view const MANDATORY_PARAM_NEW_TARGET = "=nt"; + inline static constexpr std::string_view const MANDATORY_PARAM_THIS = "=t"; - static constexpr uint32_t MANDATORY_PARAM_FUNC_REG = 0; - static constexpr uint32_t MANDATORY_PARAMS_NUMBER = 3; + inline static constexpr std::uint32_t const MANDATORY_PARAM_FUNC_REG = 0U; + inline static constexpr std::uint32_t const MANDATORY_PARAMS_NUMBER = 3U; - static constexpr std::string_view LEXICAL_MANDATORY_PARAM_FUNC = "!f"; - static constexpr std::string_view LEXICAL_MANDATORY_PARAM_NEW_TARGET = "!nt"; - static constexpr std::string_view LEXICAL_MANDATORY_PARAM_THIS = "!t"; + inline static constexpr std::string_view const LEXICAL_MANDATORY_PARAM_FUNC = "!f"; + inline static constexpr std::string_view const LEXICAL_MANDATORY_PARAM_NEW_TARGET = "!nt"; + inline static constexpr std::string_view const LEXICAL_MANDATORY_PARAM_THIS = "!t"; - static constexpr std::string_view LEXICAL_CONTEXT_PARAM = "=eval"; - static constexpr std::string_view MAIN = "main"; - static constexpr uint32_t LEXICAL_CONTEXT_PARAM_REG = MANDATORY_PARAMS_NUMBER; - static constexpr std::string_view STAR_IMPORT = "*"; + inline static constexpr std::string_view const LEXICAL_CONTEXT_PARAM = "=eval"; + inline static constexpr std::string_view const MAIN = "main"; + inline static constexpr std::uint32_t const LEXICAL_CONTEXT_PARAM_REG = MANDATORY_PARAMS_NUMBER; + inline static constexpr std::string_view const STAR_IMPORT = "*"; void ResolveReferenceDoWhileHelper(ir::AstNode *childNode); void ResolveReferenceWhileHelper(ir::AstNode *childNode); @@ -241,7 +241,7 @@ protected: void AddMandatoryParams(); void LookupReference(const util::StringView &name); void InstantiateArguments(); - bool InstantiateArgumentsImpl(Scope **scope, Scope *iter, const ir::AstNode *node); + [[nodiscard]] bool InstantiateArgumentsImpl(Scope **scope, Scope *iter, const ir::AstNode *node); void InstantiatePrivateContext(const ir::Identifier *ident) const; void BuildVarDeclarator(ir::VariableDeclarator *varDecl); void BuildVarDeclaratorId(ir::AstNode *childNode); @@ -253,7 +253,7 @@ protected: void ResolveReferences(const ir::AstNode *parent); void VisitScriptFunctionWithPotentialTypeParams(ir::ScriptFunction *func); void VisitScriptFunction(ir::ScriptFunction *func); - util::StringView BuildFunctionName(util::StringView name, uint32_t idx); + [[nodiscard]] util::StringView BuildFunctionName(util::StringView name, uint32_t idx); void AddCompilableFunctionScope(varbinder::FunctionScope *funcScope); @@ -268,7 +268,7 @@ protected: virtual void BuildSignatureDeclarationBaseParams([[maybe_unused]] ir::AstNode *typeNode) {}; virtual void BuildClassDefinition(ir::ClassDefinition *classDef); virtual void BuildClassProperty(const ir::ClassProperty *prop); - virtual bool BuildInternalName(ir::ScriptFunction *scriptFunc); + [[nodiscard]] virtual bool BuildInternalName(ir::ScriptFunction *scriptFunc); virtual void AddCompilableFunction(ir::ScriptFunction *func); private: @@ -362,7 +362,7 @@ void VarBinder::AddMandatoryParams(const MandatoryParams ¶ms) auto scopeCtx = LexicalScope::Enter(this, scope_->AsFunctionVariableScope()->ParamScope()); - for (auto iter = params.rbegin(); iter != params.rend(); iter++) { + for (auto iter = params.rbegin(); iter != params.rend(); ++iter) { AddMandatoryParam(*iter); } } @@ -399,10 +399,11 @@ std::tuple VarBinder::NewVarDecl(const lexer::Source if (var == nullptr) { ThrowRedeclaration(pos, decl->Name()); + var = scope_->FindLocal(decl->Name(), ResolveBindingOptions::BINDINGS); } + ES2PANDA_ASSERT(var != nullptr); return {decl, var}; } } // namespace ark::es2panda::varbinder - #endif