From 4d6069318fd26a6ed541a20a5d91bb890ce58672 Mon Sep 17 00:00:00 2001 From: Igor Sharonov Date: Tue, 23 Jul 2024 13:10:58 +0300 Subject: [PATCH] [CodeCheck] Fix code check warnings for varbinder Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IAFIHM Signed-off-by: Igor Sharonov --- ets2panda/checker/ETSAnalyzer.cpp | 13 +- ets2panda/checker/ETSAnalyzerHelpers.cpp | 6 +- ets2panda/checker/TSAnalyzer.cpp | 29 ++- ets2panda/checker/checkerContext.cpp | 2 +- ets2panda/checker/ets/dynamic.cpp | 4 +- ets2panda/checker/ets/function.cpp | 14 +- ets2panda/checker/ets/helpers.cpp | 62 +++-- ets2panda/checker/ets/object.cpp | 34 +-- ets2panda/checker/ets/typeCreation.cpp | 5 +- ets2panda/checker/ets/utilityTypeHandlers.cpp | 8 +- ets2panda/checker/ets/validateHelpers.cpp | 4 +- ets2panda/checker/ts/destructuringContext.cpp | 2 +- ets2panda/checker/ts/function.cpp | 20 +- ets2panda/checker/ts/helpers.cpp | 11 +- ets2panda/checker/ts/object.cpp | 12 +- ets2panda/checker/types/ets/etsEnumType.cpp | 6 +- ets2panda/compiler/base/hoisting.cpp | 15 +- ets2panda/compiler/base/lexenv.cpp | 20 +- ets2panda/compiler/core/ASTVerifier.cpp | 6 +- ets2panda/compiler/core/ETSGen.cpp | 6 +- ets2panda/compiler/core/ETSfunction.cpp | 4 +- ets2panda/compiler/core/JSCompiler.cpp | 8 +- ets2panda/compiler/core/emitter.cpp | 13 +- ets2panda/compiler/core/envScope.cpp | 6 +- ets2panda/compiler/core/envScope.h | 4 +- ets2panda/compiler/core/function.cpp | 12 +- ets2panda/compiler/core/moduleContext.cpp | 4 +- ets2panda/compiler/core/pandagen.cpp | 17 +- ets2panda/compiler/core/regScope.cpp | 14 +- .../compiler/function/functionBuilder.cpp | 6 +- .../compiler/lowering/ets/boxingForLocals.cpp | 14 +- .../compiler/lowering/ets/enumLowering.cpp | 4 +- .../ets/interfacePropertyDeclarations.cpp | 8 +- .../compiler/lowering/ets/lambdaLowering.cpp | 12 +- .../lowering/ets/localClassLowering.cpp | 6 +- .../compiler/lowering/ets/unionLowering.cpp | 6 +- .../lowering/scopesInit/savedBindingsCtx.cpp | 10 +- .../lowering/scopesInit/scopesInitPhase.cpp | 56 ++-- ets2panda/compiler/lowering/util.cpp | 7 +- ets2panda/ir/ets/etsTypeReferencePart.cpp | 2 +- ets2panda/ir/expressions/memberExpression.cpp | 2 +- ets2panda/ir/expressions/memberExpression.h | 4 +- ets2panda/parser/program/program.cpp | 8 +- .../test/unit/union_normalization_test.cpp | 5 +- ets2panda/varbinder/ETSBinder.cpp | 35 +-- ets2panda/varbinder/TypedBinder.cpp | 4 +- ets2panda/varbinder/declaration.h | 244 ++++++------------ ets2panda/varbinder/scope.cpp | 48 ++-- ets2panda/varbinder/scope.h | 113 ++++---- ets2panda/varbinder/varbinder.cpp | 167 ++++++------ ets2panda/varbinder/varbinder.h | 9 +- ets2panda/varbinder/variable.cpp | 6 +- ets2panda/varbinder/variable.h | 83 +++--- ets2panda/varbinder/variableFlags.h | 95 +++---- 54 files changed, 608 insertions(+), 707 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 3c2b0b35f5..9c9cb4cdb8 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -826,10 +826,11 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const // Add/Remove/Modify smart cast for identifier // (excluding the variables defined at top-level scope or captured in lambda-functions!) auto const *const variableScope = variable->GetScope(); - auto const topLevelVariable = variableScope != nullptr - ? variableScope->IsGlobalScope() || (variableScope->Parent() != nullptr && - variableScope->Parent()->IsGlobalScope()) - : false; + auto const topLevelVariable = + variableScope != nullptr + ? variableScope->Is() || + (variableScope->Parent() != nullptr && variableScope->Parent()->Is()) + : false; if (!topLevelVariable) { if (checker->Relation()->IsIdenticalTo(leftType, smartType)) { checker->Context().RemoveSmartCast(variable); @@ -1865,10 +1866,10 @@ checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const // Remove possible smart casts for variables declared in inner scope: if (auto const *const scope = st->Scope(); - scope->IsFunctionScope() && st->Parent()->Parent()->Parent()->IsMethodDefinition()) { + scope->Is() && st->Parent()->Parent()->Parent()->IsMethodDefinition()) { // When exiting method definition, just clear all smart casts checker->Context().ClearSmartCasts(); - } else if (!scope->IsGlobalScope()) { + } else if (!scope->Is()) { // otherwise only check inner declarations for (auto const *const decl : scope->Decls()) { if (decl->IsLetOrConstDecl() && decl->Node()->IsIdentifier()) { diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index 40137fbd1a..a560ad0d1b 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -290,7 +290,7 @@ checker::Type *InitAnonymousLambdaCallee(checker::ETSChecker *checker, ir::Expre auto signature = ir::FunctionSignature(nullptr, std::move(params), typeAnnotation); auto *funcType = checker->AllocNode(std::move(signature), ir::ScriptFunctionFlags::NONE); - funcType->SetScope(arrowFunc->Scope()->AsFunctionScope()->ParamScope()); + funcType->SetScope(arrowFunc->Scope()->As()->ParamScope()); auto *const funcIface = typeAnnotation != nullptr ? funcType->Check(checker) : funcReturnType; checker->Relation()->SetNode(callee); checker->Relation()->IsAssignableTo(calleeType, funcIface); @@ -519,9 +519,9 @@ checker::Type *GetIteratorType(ETSChecker *checker, checker::Type *elemType, ir: if (left->IsIdentifier()) { if (auto *const variable = left->AsIdentifier()->Variable(); variable != nullptr) { auto *decl = variable->Declaration(); - if (decl->IsConstDecl() || decl->IsReadonlyDecl()) { + if (decl->Is() || decl->Is()) { std::string_view errorMsg = - decl->IsConstDecl() ? INVALID_CONST_ASSIGNMENT : INVALID_READONLY_ASSIGNMENT; + decl->Is() ? INVALID_CONST_ASSIGNMENT : INVALID_READONLY_ASSIGNMENT; checker->ThrowTypeError({errorMsg, variable->Name()}, decl->Node()->Start()); } } diff --git a/ets2panda/checker/TSAnalyzer.cpp b/ets2panda/checker/TSAnalyzer.cpp index 0d92ef220d..051e4ed99a 100644 --- a/ets2panda/checker/TSAnalyzer.cpp +++ b/ets2panda/checker/TSAnalyzer.cpp @@ -544,7 +544,7 @@ checker::Type *TSAnalyzer::Check(ir::AssignmentExpression *expr) const } if (expr->Left()->IsIdentifier() && expr->Left()->AsIdentifier()->Variable() != nullptr && - expr->Left()->AsIdentifier()->Variable()->Declaration()->IsConstDecl()) { + expr->Left()->AsIdentifier()->Variable()->Declaration()->Is()) { checker->ThrowTypeError( {"Cannot assign to ", expr->Left()->AsIdentifier()->Name(), " because it is a constant."}, expr->Left()->Start()); @@ -756,7 +756,7 @@ checker::Type *TSAnalyzer::Check(ir::Identifier *expr) const const varbinder::Decl *decl = expr->Variable()->Declaration(); - if (decl->IsTypeAliasDecl() || decl->IsInterfaceDecl()) { + if (decl->Is() || decl->Is()) { checker->ThrowTypeError({expr->Name(), " only refers to a type, but is being used as a value here."}, expr->Start()); } @@ -1445,7 +1445,8 @@ checker::Type *TSAnalyzer::Check(ir::FunctionDeclaration *st) const checker::ScopeContext scopeCtx(checker, st->Function()->Scope()); if (result.variable->TsType() == nullptr) { - checker->InferFunctionDeclarationType(result.variable->Declaration()->AsFunctionDecl(), result.variable); + checker->InferFunctionDeclarationType(result.variable->Declaration()->As(), + result.variable); } st->Function()->Body()->Check(checker); @@ -1818,8 +1819,8 @@ static varbinder::EnumMemberResult EvaluateIdentifier(checker::TSChecker *checke enumVar->Declaration()->Node()->Start()); } - if (enumMember->IsEnumVariable()) { - varbinder::EnumVariable *exprEnumVar = enumMember->AsEnumVariable(); + if (enumMember->Is()) { + auto exprEnumVar = enumMember->As(); if (std::holds_alternative(exprEnumVar->Value())) { checker->ThrowTypeError( "A member initializer in a enum declaration cannot reference members declared after it, " @@ -2000,7 +2001,7 @@ static void AddEnumValueDeclaration(checker::TSChecker *checker, double number, util::StringView memberStr = util::Helpers::ToStringView(checker->Allocator(), number); - varbinder::LocalScope *enumScope = checker->Scope()->AsLocalScope(); + auto enumScope = checker->Scope()->As(); varbinder::Variable *res = enumScope->FindLocal(memberStr, varbinder::ResolveBindingOptions::BINDINGS); varbinder::EnumVariable *enumVar = nullptr; @@ -2009,13 +2010,13 @@ static void AddEnumValueDeclaration(checker::TSChecker *checker, double number, decl->BindNode(variable->Declaration()->Node()); enumScope->AddDecl(checker->Allocator(), decl, ScriptExtension::TS); res = enumScope->FindLocal(memberStr, varbinder::ResolveBindingOptions::BINDINGS); - ASSERT(res && res->IsEnumVariable()); - enumVar = res->AsEnumVariable(); - enumVar->AsEnumVariable()->SetBackReference(); + ASSERT(res && res->Is()); + enumVar = res->As(); + enumVar->As()->SetBackReference(); enumVar->SetTsType(checker->GlobalStringType()); } else { - ASSERT(res->IsEnumVariable()); - enumVar = res->AsEnumVariable(); + ASSERT(res->Is()); + enumVar = res->As(); auto *decl = checker->Allocator()->New(memberStr); decl->BindNode(variable->Declaration()->Node()); enumVar->ResetDecl(decl); @@ -2093,7 +2094,7 @@ checker::Type *TSAnalyzer::InferType(checker::TSChecker *checker, bool isConst, { double value = -1.0; - varbinder::LocalScope *enumScope = checker->Scope()->AsLocalScope(); + auto enumScope = checker->Scope()->As(); bool initNext = false; bool isLiteralEnum = false; @@ -2102,8 +2103,8 @@ checker::Type *TSAnalyzer::InferType(checker::TSChecker *checker, bool isConst, for (size_t i = 0; i < localsSize; i++) { const util::StringView ¤tName = enumScope->Decls()[i]->Name(); varbinder::Variable *currentVar = enumScope->FindLocal(currentName, varbinder::ResolveBindingOptions::BINDINGS); - ASSERT(currentVar && currentVar->IsEnumVariable()); - InferEnumVariableType(currentVar->AsEnumVariable(), &value, &initNext, &isLiteralEnum, isConst); + ASSERT(currentVar && currentVar->Is()); + InferEnumVariableType(currentVar->As(), &value, &initNext, &isLiteralEnum, isConst); } checker::Type *enumType = checker->Allocator()->New( diff --git a/ets2panda/checker/checkerContext.cpp b/ets2panda/checker/checkerContext.cpp index d69b16dcf0..5681fa37f2 100644 --- a/ets2panda/checker/checkerContext.cpp +++ b/ets2panda/checker/checkerContext.cpp @@ -422,7 +422,7 @@ void CheckerContext::OnBreakStatement(ir::BreakStatement const *breakStatement) smartCasts.reserve(smartCasts_.size()); for (auto const [variable, type] : smartCasts_) { - if (!inInnerScope(variable->AsLocalVariable()->GetScope(), breakStatement)) { + if (!inInnerScope(variable->As()->GetScope(), breakStatement)) { smartCasts.emplace_back(variable, type); } } diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index bac9018236..ab9e8fcef7 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -50,7 +50,7 @@ namespace ark::es2panda::checker { void ProcessCheckerNode(ETSChecker *checker, ir::AstNode *node) { auto scope = compiler::NearestScope(node); - if (scope->IsGlobalScope()) { + if (scope->Is()) { // NOTE(aleksisch): All classes are contained in ETSGlobal class scope (not just Global scope), // however it's parent is ETSScript. It should be fixed scope = checker->VarBinder()->Program()->GlobalClassScope(); @@ -73,7 +73,7 @@ void ProcessCheckerNode(ETSChecker *checker, ir::AstNode *node) void ProcessScopesNode(ETSChecker *checker, ir::AstNode *node) { auto *scope = compiler::NearestScope(node); - if (scope->IsGlobalScope()) { + if (scope->Is()) { // NOTE(aleksisch): All classes are contained in ETSGlobal scope, // however it's parent is ETSScript (not ETSGlobal). It should be fixed scope = checker->VarBinder()->Program()->GlobalClassScope(); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index c1bc7afee5..39bd6e79eb 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1064,7 +1064,7 @@ SignatureInfo *ETSChecker::ComposeSignatureInfo(ir::ScriptFunction *func) auto const *const restIdent = param->Ident(); ASSERT(restIdent->Variable()); - signatureInfo->restVar = restIdent->Variable()->AsLocalVariable(); + signatureInfo->restVar = restIdent->Variable()->As(); auto *const restParamTypeAnnotation = param->TypeAnnotation(); ASSERT(restParamTypeAnnotation); @@ -1086,7 +1086,7 @@ SignatureInfo *ETSChecker::ComposeSignatureInfo(ir::ScriptFunction *func) } else { paramVar->SetTsType(paramIdent->TsType()); } - signatureInfo->params.push_back(paramVar->AsLocalVariable()); + signatureInfo->params.push_back(paramVar->As()); ++signatureInfo->minArgCount; } } @@ -1527,7 +1527,7 @@ void ETSChecker::CheckCapturedVariables() // If we want to capture non constant local variables, we should wrap them in a generic reference class for (auto [var, _] : Context().CapturedVars()) { (void)_; - if ((var->Declaration() == nullptr) || var->Declaration()->IsConstDecl() || + if ((var->Declaration() == nullptr) || var->Declaration()->Is() || !var->HasFlag(varbinder::VariableFlags::LOCAL) || var->GetScope()->Node()->IsArrowFunctionExpression()) { continue; } @@ -1618,8 +1618,8 @@ ir::MethodDefinition *ETSChecker::CreateAsyncImplMethod(ir::MethodDefinition *as asyncMethod->AddModifier(ir::ModifierFlags::NATIVE); asyncFunc->AddModifier(ir::ModifierFlags::NATIVE); // Create async_impl method copied from CreateInvokeFunction - auto scopeCtx = - varbinder::LexicalScope::Enter(VarBinder(), classDef->Scope()->AsClassScope()); + auto scopeCtx = varbinder::LexicalScope::Enter( + VarBinder(), classDef->Scope()->As()); auto *body = asyncFunc->Body(); ArenaVector params(Allocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -1705,9 +1705,9 @@ ir::MethodDefinition *ETSChecker::CreateAsyncProxy(ir::MethodDefinition *asyncMe bool isStatic = asyncMethod->IsStatic(); if (createDecl) { if (isStatic) { - CreateFuncDecl(this, implMethod, classDef->Scope()->AsClassScope()->StaticMethodScope()); + CreateFuncDecl(this, implMethod, classDef->Scope()->As()->StaticMethodScope()); } else { - CreateFuncDecl(this, implMethod, classDef->Scope()->AsClassScope()->InstanceMethodScope()); + CreateFuncDecl(this, implMethod, classDef->Scope()->As()->InstanceMethodScope()); } implMethod->Id()->SetVariable(implMethod->Function()->Id()->Variable()); } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 6fde4aa632..81c2575d12 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -180,7 +180,7 @@ bool ETSChecker::SaveCapturedVariableInLocalClass(varbinder::Variable *const var return; } - if (var->Declaration()->IsParameterDecl()) { + if (var->Declaration()->Is()) { LOG(DEBUG, ES2PANDA) << " - Modified parameter "; scopeIter->Node()->AsClassDefinition()->AddToLocalVariableIsNeeded(var); } @@ -223,7 +223,7 @@ void ETSChecker::SaveCapturedVariable(varbinder::Variable *const var, ir::Identi const auto *scopeIter = Scope(); while (scopeIter != var->GetScope()) { - if (scopeIter->IsFunctionScope()) { + if (scopeIter->Is()) { Context().AddCapturedVar(var, pos); return; } @@ -949,10 +949,10 @@ std::optional CheckerContext::ResolveSmartCastTypes() // Exclude processing of global variables and those captured in lambdas and modified there auto const *const variableScope = testCondition_.variable->GetScope(); - auto const topLevelVariable = - variableScope != nullptr ? variableScope->IsGlobalScope() || - (variableScope->Parent() != nullptr && variableScope->Parent()->IsGlobalScope()) - : false; + auto const topLevelVariable = variableScope != nullptr ? variableScope->Is() || + (variableScope->Parent() != nullptr && + variableScope->Parent()->Is()) + : false; if (topLevelVariable) { return std::nullopt; } @@ -1136,10 +1136,14 @@ static void CheckExpandedType(Type *expandedAliasType, std::setIsIdentifier() && name->AsIdentifier()->Variable() && - name->AsIdentifier()->Variable()->Declaration()->IsTypeAliasDecl()); + name->AsIdentifier()->Variable()->Declaration()->Is()); - auto *const typeAliasNode = - name->AsIdentifier()->Variable()->Declaration()->AsTypeAliasDecl()->Node()->AsTSTypeAliasDeclaration(); + auto *const typeAliasNode = name->AsIdentifier() + ->Variable() + ->Declaration() + ->As() + ->Node() + ->AsTSTypeAliasDeclaration(); // NOTE (mmartin): modify for default params if ((typeParams == nullptr) != (typeAliasNode->TypeParams() == nullptr)) { @@ -1236,14 +1240,15 @@ void ETSChecker::BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleO { for (auto [_, var] : bindings) { (void)_; - auto [found, aliasedName] = FindSpecifierForModuleObject(importDecl, var->AsLocalVariable()->Name()); - if ((var->AsLocalVariable()->Declaration()->Node()->IsExported() || - var->AsLocalVariable()->Declaration()->Node()->IsExportedType()) && + auto [found, aliasedName] = + FindSpecifierForModuleObject(importDecl, var->template As()->Name()); + if ((var->template As()->Declaration()->Node()->IsExported() || + var->template As()->Declaration()->Node()->IsExportedType()) && found) { if (!aliasedName.Empty()) { moduleObjType->AddReExportAlias(var->Declaration()->Name(), aliasedName); } - moduleObjType->AddProperty(var->AsLocalVariable()); + moduleObjType->AddProperty(var->template As()); } } } @@ -1303,7 +1308,7 @@ Type *ETSChecker::GetReferencedTypeBase(ir::Expression *name) return name->TsType(); } - auto *refVar = name->AsIdentifier()->Variable()->AsLocalVariable(); + auto *refVar = name->AsIdentifier()->Variable()->As(); checker::Type *tsType = nullptr; switch (refVar->Declaration()->Node()->Type()) { @@ -1518,7 +1523,7 @@ const ir::AstNode *ETSChecker::FindJumpTarget(ir::AstNode *node) auto label = isContinue ? node->AsContinueStatement()->Ident() : node->AsBreakStatement()->Ident(); if (label != nullptr) { auto var = label->Variable(); - if (var != nullptr && var->Declaration()->IsLabelDecl()) { + if (var != nullptr && var->Declaration()->Is()) { return var->Declaration()->Node(); } @@ -1736,14 +1741,14 @@ bool IsConstantMemberOrIdentifierExpression(ir::Expression *expression) { if (expression->IsMemberExpression()) { auto *var = expression->AsMemberExpression()->PropVar(); - return var->Declaration()->IsConstDecl() || - (var->Declaration()->IsReadonlyDecl() && var->HasFlag(varbinder::VariableFlags::STATIC)); + return var->Declaration()->Is() || + (var->Declaration()->Is() && var->HasFlag(varbinder::VariableFlags::STATIC)); } if (expression->IsIdentifier()) { auto *var = expression->AsIdentifier()->Variable(); - return var->Declaration()->IsConstDecl() || - (var->Declaration()->IsReadonlyDecl() && var->HasFlag(varbinder::VariableFlags::STATIC)); + return var->Declaration()->Is() || + (var->Declaration()->Is() && var->HasFlag(varbinder::VariableFlags::STATIC)); } return false; @@ -1907,7 +1912,7 @@ void ETSChecker::CheckRethrowingFunction(ir::ScriptFunction *func) if (type->IsETSTypeReference()) { auto *typeDecl = type->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Variable()->Declaration(); - if (typeDecl->IsTypeAliasDecl()) { + if (typeDecl->Is()) { type = typeDecl->Node()->AsTSTypeAliasDeclaration()->TypeAnnotation(); } } @@ -2199,7 +2204,7 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A AllocNode(baseExpression, field->Key()->AsIdentifier()->Clone(Allocator(), nullptr), ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); memberExpression->SetTsType(field->TsType()); - memberExpression->SetPropVar(field->Key()->Variable()->AsLocalVariable()); + memberExpression->SetPropVar(field->Key()->Variable()->As()); memberExpression->SetRange(classDef->Range()); if (memberExpression->ObjType() == nullptr && classDef->TsType() != nullptr) { memberExpression->SetObjectType(classDef->TsType()->AsETSObjectType()); @@ -2312,10 +2317,11 @@ ir::ClassProperty *GetImplementationClassProp(ETSChecker *checker, ir::ClassProp bool isSuperOwner = ((originalProp->Modifiers() & ir::ModifierFlags::SUPER_OWNER) != 0U); if (!isSuperOwner) { auto *const classDef = classType->GetDeclNode()->AsClassDefinition(); - auto *const scope = checker->Scope()->AsClassScope(); + auto *const scope = checker->Scope()->As(); auto *const classProp = checker->ClassPropToImplementationProp( interfaceProp->Clone(checker->Allocator(), originalProp->Parent()), scope); - classType->AddProperty(classProp->Key()->Variable()->AsLocalVariable()); + classType->AddProperty( + classProp->Key()->Variable()->As()); classDef->Body().push_back(classProp); return classProp; } @@ -2336,8 +2342,8 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin auto *interfaceProp = originalProp->Clone(Allocator(), originalProp->Parent()); interfaceProp->ClearModifier(ir::ModifierFlags::GETTER_SETTER | ir::ModifierFlags::EXTERNAL); - ASSERT(Scope()->IsClassScope()); - auto *const scope = Scope()->AsClassScope(); + ASSERT(Scope()->Is()); + auto *const scope = Scope()->As(); scope->InstanceFieldScope()->EraseBinding(interfaceProp->Key()->AsIdentifier()->Name()); interfaceProp->SetRange(originalProp->Range()); @@ -2352,7 +2358,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin getter->SetParent(classDef); getter->TsType()->AddTypeFlag(TypeFlag::GETTER); getter->Variable()->SetTsType(getter->TsType()); - classType->AddProperty(getter->Variable()->AsLocalVariable()); + classType->AddProperty(getter->Variable()->As()); auto *const methodScope = scope->InstanceMethodScope(); auto name = getter->Key()->AsIdentifier()->Name(); @@ -2383,7 +2389,7 @@ ir::MethodDefinition *ETSChecker::GenerateSetterForProperty(ir::ClassProperty *o ir::MethodDefinition *getter) { ir::MethodDefinition *setter = - GenerateDefaultGetterSetter(interfaceProp, classProp, Scope()->AsClassScope(), true, this); + GenerateDefaultGetterSetter(interfaceProp, classProp, Scope()->As(), true, this); if (((originalProp->Modifiers() & ir::ModifierFlags::SETTER) != 0U)) { setter->Function()->AddModifier(ir::ModifierFlags::OVERRIDE); } @@ -2396,7 +2402,7 @@ ir::MethodDefinition *ETSChecker::GenerateSetterForProperty(ir::ClassProperty *o setter->TsType()->AddTypeFlag(TypeFlag::SETTER); getter->Variable()->TsType()->AsETSFunctionType()->AddCallSignature( setter->TsType()->AsETSFunctionType()->CallSignatures()[0]); - classType->AddProperty(setter->Variable()->AsLocalVariable()); + classType->AddProperty(setter->Variable()->As()); getter->AddOverload(setter); return setter; } diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index a9b6d01793..a3010f35c2 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -393,7 +393,7 @@ static void ResolveDeclaredFieldsOfObject(ETSChecker *checker, const ETSObjectTy ASSERT(it->Declaration()->Node()->IsClassProperty()); auto *classProp = it->Declaration()->Node()->AsClassProperty(); it->AddFlag(checker->GetAccessFlagFromNode(classProp)); - type->AddProperty(it->AsLocalVariable()); + type->AddProperty(it->As()); } for (auto &[_, it] : scope->StaticFieldScope()->Bindings()) { @@ -401,7 +401,7 @@ static void ResolveDeclaredFieldsOfObject(ETSChecker *checker, const ETSObjectTy ASSERT(it->Declaration()->Node()->IsClassProperty()); auto *classProp = it->Declaration()->Node()->AsClassProperty(); it->AddFlag(checker->GetAccessFlagFromNode(classProp)); - type->AddProperty(it->AsLocalVariable()); + type->AddProperty(it->As()); } } @@ -426,7 +426,7 @@ static void ResolveDeclaredMethodsOfObject(ETSChecker *checker, const ETSObjectT it->SetTsType(funcType); funcType->SetVariable(it); method->SetTsType(funcType); - type->AddProperty(it->AsLocalVariable()); + type->AddProperty(it->As()); } for (auto &[_, it] : scope->StaticMethodScope()->Bindings()) { @@ -458,7 +458,7 @@ static void ResolveDeclaredMethodsOfObject(ETSChecker *checker, const ETSObjectT continue; } - type->AddProperty(it->AsLocalVariable()); + type->AddProperty(it->As()); } } @@ -467,13 +467,13 @@ static void ResolveDeclaredDeclsOfObject(ETSChecker *checker, const ETSObjectTyp for (auto &[_, it] : scope->InstanceDeclScope()->Bindings()) { (void)_; it->AddFlag(checker->GetAccessFlagFromNode(it->Declaration()->Node())); - type->AddProperty(it->AsLocalVariable()); + type->AddProperty(it->As()); } for (auto &[_, it] : scope->StaticDeclScope()->Bindings()) { (void)_; it->AddFlag(checker->GetAccessFlagFromNode(it->Declaration()->Node())); - type->AddProperty(it->AsLocalVariable()); + type->AddProperty(it->As()); } } @@ -510,9 +510,9 @@ void ETSChecker::ResolveDeclaredMembersOfObject(const ETSObjectType *type) auto savedContext = checker::SavedCheckerContext(this, status, type); checker::ScopeContext scopeCtx(this, scope); - ResolveDeclaredFieldsOfObject(this, type, scope->AsClassScope()); - ResolveDeclaredMethodsOfObject(this, type, scope->AsClassScope()); - ResolveDeclaredDeclsOfObject(this, type, scope->AsClassScope()); + ResolveDeclaredFieldsOfObject(this, type, scope->As()); + ResolveDeclaredMethodsOfObject(this, type, scope->As()); + ResolveDeclaredDeclsOfObject(this, type, scope->As()); } bool ETSChecker::HasETSFunctionType(ir::TypeNode *typeAnnotation) @@ -540,7 +540,7 @@ bool ETSChecker::HasETSFunctionType(ir::TypeNode *typeAnnotation) }; auto *typeDecl = typeAnnotation->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Variable()->Declaration(); - if (typeDecl != nullptr && typeDecl->IsTypeAliasDecl()) { + if (typeDecl != nullptr && typeDecl->Is()) { addTypeAlias(typeDecl); } @@ -826,10 +826,10 @@ void ETSChecker::ValidateNonOverriddenFunction(ETSObjectType *classType, ArenaVe auto newFieldVar = classType->GetDeclNode() ->Scope() - ->AsClassScope() + ->As() ->InstanceFieldScope() ->AddDecl(Allocator(), newFieldDecl, ScriptExtension::ETS) - ->AsLocalVariable(); + ->As(); newFieldVar->AddFlag(varbinder::VariableFlags::PROPERTY); newFieldVar->AddFlag(varbinder::VariableFlags::PUBLIC); classType->AddProperty(newFieldVar); @@ -1240,7 +1240,7 @@ ArenaVector ETSChecker::CheckMemberOrCallOrObjectExpress void ETSChecker::CheckConstFields(const ETSObjectType *classType) { for (const auto &prop : classType->Fields()) { - if (!(prop->Declaration()->IsConstDecl() || prop->Declaration()->IsReadonlyDecl()) || + if (!(prop->Declaration()->Is() || prop->Declaration()->Is()) || !prop->HasFlag(varbinder::VariableFlags::EXPLICIT_INIT_REQUIRED)) { continue; } @@ -1319,7 +1319,7 @@ void ETSChecker::CheckInnerClassMembers(const ETSObjectType *classType) for (const auto &[_, it] : classType->StaticFields()) { (void)_; - if (!it->Declaration()->IsReadonlyDecl()) { + if (!it->Declaration()->Is()) { ThrowTypeError("Inner class cannot have non-readonly static properties", it->Declaration()->Node()->Start()); } @@ -2021,11 +2021,11 @@ void ETSChecker::AddElementsToModuleObject(ETSObjectType *moduleObj, const util: } if (var->HasFlag(varbinder::VariableFlags::METHOD)) { - moduleObj->AddProperty(var->AsLocalVariable()); + moduleObj->AddProperty(var->As()); } else if (var->HasFlag(varbinder::VariableFlags::PROPERTY)) { - moduleObj->AddProperty(var->AsLocalVariable()); + moduleObj->AddProperty(var->As()); } else { - moduleObj->AddProperty(var->AsLocalVariable()); + moduleObj->AddProperty(var->As()); } } } diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index ef6a390284..77e99ae0eb 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -160,7 +160,7 @@ namespace { auto *const signatureInfo = checker->CreateSignatureInfo(); signatureInfo->params.reserve(function->Params().size()); for (const auto *const param : function->Params()) { - signatureInfo->params.push_back(param->AsETSParameterExpression()->Variable()->AsLocalVariable()); + signatureInfo->params.push_back(param->AsETSParameterExpression()->Variable()->As()); } signatureInfo->minArgCount = signatureInfo->params.size(); @@ -197,7 +197,8 @@ ETSEnumType::Method ETSChecker::MakeMethod(ir::TSEnumDeclaration const *const en if (buildPorxyParam) { return {MakeGlobalSignature(this, function, returnType), MakeProxyFunctionType( - this, name, {function->Params()[0]->AsETSParameterExpression()->Variable()->AsLocalVariable()}, + this, name, + {function->Params()[0]->AsETSParameterExpression()->Variable()->As()}, function, returnType)}; } return {MakeGlobalSignature(this, function, returnType), diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 965fc49975..cb7b3ccd67 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -173,9 +173,9 @@ ir::ClassProperty *ETSChecker::CreateNullishProperty(ir::ClassProperty *const pr propClone->SetVariable(Allocator()->New(newDecl, varbinder::VariableFlags::PROPERTY)); - propClone->Variable()->SetScope(classProp->IsStatic() - ? newClassDefinition->Scope()->AsClassScope()->StaticFieldScope() - : newClassDefinition->Scope()->AsClassScope()->InstanceFieldScope()); + propClone->Variable()->SetScope( + classProp->IsStatic() ? newClassDefinition->Scope()->As()->StaticFieldScope() + : newClassDefinition->Scope()->As()->InstanceFieldScope()); propClone->Variable()->Declaration()->BindNode(propClone); @@ -238,7 +238,7 @@ void ETSChecker::CreateConstructorForPartialType(ir::ClassDefinition *const part varbinder::RecordTable *const recordTable) { // Create scopes - auto *const scope = partialClassDef->Scope()->AsClassScope(); + auto *const scope = partialClassDef->Scope()->As(); const auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), scope); // Create ctor diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index a98aaeb8f6..17e35733af 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -240,8 +240,8 @@ void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable) return; } - if (variable->Declaration()->IsConstDecl() || variable->Declaration()->IsReadonlyDecl()) { - std::string_view fieldType = variable->Declaration()->IsConstDecl() ? "constant" : "readonly"; + if (variable->Declaration()->Is() || variable->Declaration()->Is()) { + std::string_view fieldType = variable->Declaration()->Is() ? "constant" : "readonly"; if (HasStatus(CheckerStatus::IN_CONSTRUCTOR | CheckerStatus::IN_STATIC_BLOCK) && !variable->HasFlag(varbinder::VariableFlags::EXPLICIT_INIT_REQUIRED)) { ThrowTypeError({"Cannot reassign ", fieldType, " ", variable->Name()}, diff --git a/ets2panda/checker/ts/destructuringContext.cpp b/ets2panda/checker/ts/destructuringContext.cpp index 2d6fb4ab67..292084af71 100644 --- a/ets2panda/checker/ts/destructuringContext.cpp +++ b/ets2panda/checker/ts/destructuringContext.cpp @@ -89,7 +89,7 @@ void DestructuringContext::SetInferredTypeForVariable(varbinder::Variable *var, } if (signatureInfo_ != nullptr) { - signatureInfo_->params.push_back(var->AsLocalVariable()); + signatureInfo_->params.push_back(var->As()); signatureInfo_->minArgCount++; } diff --git a/ets2panda/checker/ts/function.cpp b/ets2panda/checker/ts/function.cpp index bb5662a677..d1c3e3fc90 100644 --- a/ets2panda/checker/ts/function.cpp +++ b/ets2panda/checker/ts/function.cpp @@ -133,7 +133,7 @@ std::tuple TSCheck param->TypeAnnotation()->Check(this); paramVar->SetTsType(param->TypeAnnotation()->GetType(this)); - return {paramVar->AsLocalVariable(), nullptr, isOptional}; + return {paramVar->As(), nullptr, isOptional}; } Type *TSChecker::CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpression *arrayPattern, Type *inferredType) @@ -214,12 +214,12 @@ ReturnedVariable TSChecker::CheckFunctionAssignmentPatternParameter(ir::Assignme Type *paramType = paramIdent->TypeAnnotation()->GetType(this); paramVar->SetTsType(paramType); ElaborateElementwise(paramType, param->Right(), paramIdent->Start()); - return {paramVar->AsLocalVariable(), nullptr, true}; + return {paramVar->As(), nullptr, true}; } paramVar->SetTsType(GetBaseTypeOfLiteralType(param->Right()->Check(this))); paramVar->AddFlag(varbinder::VariableFlags::OPTIONAL); - return {paramVar->AsLocalVariable(), nullptr, true}; + return {paramVar->As(), nullptr, true}; } Type *paramType = nullptr; @@ -248,7 +248,7 @@ ReturnedVariable TSChecker::CheckFunctionAssignmentPatternParameter(ir::Assignme varbinder::Scope::CreateVar(Allocator(), pn.View(), varbinder::VariableFlags::NONE, param); patternVar->SetTsType(paramType); patternVar->AddFlag(varbinder::VariableFlags::OPTIONAL); - return {patternVar->AsLocalVariable(), nullptr, true}; + return {patternVar->As(), nullptr, true}; } std::tuple TSChecker::CheckFunctionRestParameter( @@ -274,7 +274,7 @@ std::tuple TSCheck ir::Identifier *restIdent = param->Argument()->AsIdentifier(); ASSERT(restIdent->Variable()); restIdent->Variable()->SetTsType(restType->AsArrayType()->ElementType()); - return {nullptr, restIdent->Variable()->AsLocalVariable(), false}; + return {nullptr, restIdent->Variable()->As(), false}; } case ir::AstNodeType::OBJECT_PATTERN: { ASSERT(param->Argument()->IsObjectPattern()); @@ -316,11 +316,11 @@ std::tuple TSCheck ArrayDestructuringContext({this, param->AsArrayPattern(), false, false, param->TypeAnnotation(), nullptr}); destructuringContext.Start(); patternVar->SetTsType(destructuringContext.InferredType()); - return {patternVar->AsLocalVariable(), nullptr, false}; + return {patternVar->As(), nullptr, false}; } patternVar->SetTsType(param->CheckPattern(this)); - return {patternVar->AsLocalVariable(), nullptr, false}; + return {patternVar->As(), nullptr, false}; } std::tuple TSChecker::CheckFunctionObjectPatternParameter( @@ -338,11 +338,11 @@ std::tuple TSCheck {this, param->AsObjectPattern(), false, false, param->TypeAnnotation(), nullptr}); destructuringContext.Start(); patternVar->SetTsType(destructuringContext.InferredType()); - return {patternVar->AsLocalVariable(), nullptr, false}; + return {patternVar->As(), nullptr, false}; } patternVar->SetTsType(param->CheckPattern(this)); - return {patternVar->AsLocalVariable(), nullptr, false}; + return {patternVar->As(), nullptr, false}; } std::tuple TSChecker::CheckFunctionParameter( @@ -352,7 +352,7 @@ std::tuple TSCheck if (param->TsType() != nullptr) { ASSERT(param->TsType()->Variable()); varbinder::Variable *var = param->TsType()->Variable(); - result = {var->AsLocalVariable(), nullptr, var->HasFlag(varbinder::VariableFlags::OPTIONAL)}; + result = {var->As(), nullptr, var->HasFlag(varbinder::VariableFlags::OPTIONAL)}; return result; } diff --git a/ets2panda/checker/ts/helpers.cpp b/ets2panda/checker/ts/helpers.cpp index 5b2b9a1937..3fa97d2494 100644 --- a/ets2panda/checker/ts/helpers.cpp +++ b/ets2panda/checker/ts/helpers.cpp @@ -400,9 +400,8 @@ void TSChecker::GetTypeParam(varbinder::Variable *var, varbinder::Decl *decl) void TSChecker::GetTypeEnum(varbinder::Variable *var, varbinder::Decl *decl) { - ASSERT(var->IsEnumVariable()); - varbinder::EnumVariable *enumVar = var->AsEnumVariable(); - + ASSERT(var->Is()); + auto enumVar = var->As(); if (std::holds_alternative(enumVar->Value())) { ThrowTypeError( "A member initializer in a enum declaration cannot reference members declared after it, " @@ -443,7 +442,7 @@ Type *TSChecker::GetDeclTsType(varbinder::Variable *var, varbinder::Decl *decl) } case varbinder::DeclType::FUNC: { checker::ScopeContext scopeCtx(this, decl->Node()->AsScriptFunction()->Scope()); - InferFunctionDeclarationType(decl->AsFunctionDecl(), var); + InferFunctionDeclarationType(decl->As(), var); break; } case varbinder::DeclType::PARAM: { @@ -520,11 +519,11 @@ Type *TSChecker::GetTypeReferenceType(ir::TSTypeReference *node, varbinder::Vari ASSERT(var->Declaration()); varbinder::Decl *decl = var->Declaration(); - if (decl->IsInterfaceDecl()) { + if (decl->Is()) { return GetTypeFromClassOrInterfaceReference(node, var); } - if (decl->IsTypeAliasDecl()) { + if (decl->Is()) { return GetTypeFromTypeAliasReference(node, var); } diff --git a/ets2panda/checker/ts/object.cpp b/ets2panda/checker/ts/object.cpp index 793103f5a1..afd537c63a 100644 --- a/ets2panda/checker/ts/object.cpp +++ b/ets2panda/checker/ts/object.cpp @@ -201,7 +201,7 @@ void TSChecker::ResolvePropertiesOfObjectType(ObjectType *type, ir::AstNode *mem if (!isInterface || ValidateInterfaceMemberRedeclaration(type, prop, member->AsTSPropertySignature()->Key()->Start())) { - type->AddProperty(prop->AsLocalVariable()); + type->AddProperty(prop->As()); } return; @@ -212,7 +212,7 @@ void TSChecker::ResolvePropertiesOfObjectType(ObjectType *type, ir::AstNode *mem if (!isInterface || ValidateInterfaceMemberRedeclaration(type, method, member->AsTSMethodSignature()->Key()->Start())) { - type->AddProperty(method->AsLocalVariable()); + type->AddProperty(method->As()); } return; @@ -439,8 +439,8 @@ ArenaVector TSChecker::GetBaseTypes(InterfaceType *type) return type->Bases(); } - ASSERT(type->Variable() && type->Variable()->Declaration()->IsInterfaceDecl()); - varbinder::InterfaceDecl *decl = type->Variable()->Declaration()->AsInterfaceDecl(); + ASSERT(type->Variable() && type->Variable()->Declaration()->Is()); + auto decl = type->Variable()->Declaration()->As(); TypeStackElement tse(this, type, {"Type ", type->Name(), " recursively references itself as a base type."}, decl->Node()->AsTSInterfaceDeclaration()->Id()->Start()); @@ -498,8 +498,8 @@ void TSChecker::ResolveDeclaredMembers(InterfaceType *type) return; } - ASSERT(type->Variable() && type->Variable()->Declaration()->IsInterfaceDecl()); - varbinder::InterfaceDecl *decl = type->Variable()->Declaration()->AsInterfaceDecl(); + ASSERT(type->Variable() && type->Variable()->Declaration()->Is()); + auto decl = type->Variable()->Declaration()->As(); ArenaVector signatureDeclarations(Allocator()->Adapter()); ArenaVector indexDeclarations(Allocator()->Adapter()); diff --git a/ets2panda/checker/types/ets/etsEnumType.cpp b/ets2panda/checker/types/ets/etsEnumType.cpp index d9f78c18cc..096574e17b 100644 --- a/ets2panda/checker/types/ets/etsEnumType.cpp +++ b/ets2panda/checker/types/ets/etsEnumType.cpp @@ -110,7 +110,7 @@ const ArenaVector &ETSEnumInterface::GetMembers() const noexcept varbinder::LocalVariable *ETSEnumInterface::GetMemberVar() const noexcept { ASSERT(IsLiteralType()); - return member_->Key()->AsIdentifier()->Variable()->AsLocalVariable(); + return member_->Key()->AsIdentifier()->Variable()->As(); } util::StringView ETSEnumInterface::GetName() const noexcept @@ -226,9 +226,9 @@ bool ETSEnumInterface::IsEnumTypeExpression(const ir::Expression *const expressi const auto *const memberExpr = expression->AsMemberExpression(); return memberExpr->PropVar() != nullptr ? memberExpr->PropVar() - : memberExpr->Object()->AsIdentifier()->Variable()->AsLocalVariable(); + : memberExpr->Object()->AsIdentifier()->Variable()->As(); } - return expression->AsIdentifier()->Variable()->AsLocalVariable(); + return expression->AsIdentifier()->Variable()->As(); }(); ASSERT(localVar->Declaration() == decl_->Key()->AsIdentifier()->Variable()->Declaration() || diff --git a/ets2panda/compiler/base/hoisting.cpp b/ets2panda/compiler/base/hoisting.cpp index 73a4cd3b05..0612570810 100644 --- a/ets2panda/compiler/base/hoisting.cpp +++ b/ets2panda/compiler/base/hoisting.cpp @@ -24,7 +24,7 @@ static void HoistVar(PandaGen *pg, varbinder::Variable *var, const varbinder::Va { auto *scope = pg->Scope(); - if (scope->IsGlobalScope()) { + if (scope->Is()) { pg->LoadConst(decl->Node(), Constant::JS_UNDEFINED); pg->StoreGlobalVar(decl->Node(), decl->Name()); return; @@ -43,13 +43,14 @@ static void HoistFunction(PandaGen *pg, varbinder::Variable *var, const varbinde const auto &internalName = scriptFunction->Scope()->InternalName(); - if (scope->IsGlobalScope()) { + if (scope->Is()) { pg->DefineFunction(decl->Node(), scriptFunction, internalName); pg->StoreGlobalVar(decl->Node(), var->Declaration()->Name()); return; } - ASSERT(scope->IsFunctionScope() || scope->IsCatchScope() || scope->IsLocalScope() || scope->IsModuleScope()); + ASSERT(scope->Is() || scope->Is() || + scope->Is() || scope->Is()); varbinder::ConstScopeFindResult result(decl->Name(), scope, 0, var); pg->DefineFunction(decl->Node(), scriptFunction, internalName); @@ -68,11 +69,11 @@ void Hoisting::Hoist(PandaGen *pg) const auto *decl = var->Declaration(); - if (decl->IsVarDecl()) { - HoistVar(pg, var, decl->AsVarDecl()); + if (decl->Is()) { + HoistVar(pg, var, decl->As()); } else { - ASSERT(decl->IsFunctionDecl()); - HoistFunction(pg, var, decl->AsFunctionDecl()); + ASSERT(decl->Is()); + HoistFunction(pg, var, decl->As()); } } } diff --git a/ets2panda/compiler/base/lexenv.cpp b/ets2panda/compiler/base/lexenv.cpp index e9abb4a615..3ccd486c5f 100644 --- a/ets2panda/compiler/base/lexenv.cpp +++ b/ets2panda/compiler/base/lexenv.cpp @@ -31,7 +31,7 @@ static bool CheckTdz(const ir::AstNode *node) static void CheckConstAssignment(PandaGen *pg, const ir::AstNode *node, varbinder::Variable *variable) { - if (!variable->Declaration()->IsConstDecl()) { + if (!variable->Declaration()->Is()) { return; } @@ -42,16 +42,16 @@ static void CheckConstAssignment(PandaGen *pg, const ir::AstNode *node, varbinde static void ExpandLoadLexVar(PandaGen *pg, const ir::AstNode *node, const varbinder::ConstScopeFindResult &result) { - if (result.variable->Declaration()->IsVarDecl()) { - pg->LoadLexicalVar(node, result.lexLevel, result.variable->AsLocalVariable()->LexIdx()); + if (result.variable->Declaration()->Is()) { + pg->LoadLexicalVar(node, result.lexLevel, result.variable->As()->LexIdx()); } else { - pg->LoadLexical(node, result.name, result.lexLevel, result.variable->AsLocalVariable()->LexIdx()); + pg->LoadLexical(node, result.name, result.lexLevel, result.variable->As()->LexIdx()); } } static void ExpandLoadNormalVar(PandaGen *pg, const ir::AstNode *node, const varbinder::ConstScopeFindResult &result) { - auto *local = result.variable->AsLocalVariable(); + auto *local = result.variable->As(); if (CheckTdz(node)) { pg->ThrowTdz(node, local->Name()); @@ -73,11 +73,11 @@ void VirtualLoadVar::Expand(PandaGen *pg, const ir::AstNode *node, const varbind static void StoreLocalExport(PandaGen *pg, const ir::AstNode *node, varbinder::Variable *variable) { - if (!variable->HasFlag(varbinder::VariableFlags::LOCAL_EXPORT) || !pg->Scope()->IsModuleScope()) { + if (!variable->HasFlag(varbinder::VariableFlags::LOCAL_EXPORT) || !pg->Scope()->Is()) { return; } - auto range = pg->Scope()->AsModuleScope()->LocalExports().equal_range(variable); + auto range = pg->Scope()->As()->LocalExports().equal_range(variable); for (auto it = range.first; it != range.second; ++it) { if (it->second != "default") { @@ -89,12 +89,12 @@ static void StoreLocalExport(PandaGen *pg, const ir::AstNode *node, varbinder::V static void ExpandStoreLexVar(PandaGen *pg, const ir::AstNode *node, const varbinder::ConstScopeFindResult &result, bool isDecl) { - varbinder::LocalVariable *local = result.variable->AsLocalVariable(); + auto local = result.variable->As(); const auto *decl = result.variable->Declaration(); if (decl->IsLetOrConstDecl() && !isDecl) { - if (decl->IsConstDecl()) { + if (decl->Is()) { pg->ThrowConstAssignment(node, local->Name()); } @@ -109,7 +109,7 @@ static void ExpandStoreLexVar(PandaGen *pg, const ir::AstNode *node, const varbi static void ExpandStoreNormalVar(PandaGen *pg, const ir::AstNode *node, const varbinder::ConstScopeFindResult &result, bool isDecl) { - auto *local = result.variable->AsLocalVariable(); + auto *local = result.variable->As(); VReg localReg = local->Vreg(); if (!isDecl) { diff --git a/ets2panda/compiler/core/ASTVerifier.cpp b/ets2panda/compiler/core/ASTVerifier.cpp index ebb27993e3..10e0ce9b66 100644 --- a/ets2panda/compiler/core/ASTVerifier.cpp +++ b/ets2panda/compiler/core/ASTVerifier.cpp @@ -746,8 +746,8 @@ public: return std::nullopt; } - if (decision == CheckDecision::CORRECT && variable->IsLocalVariable()) { - const auto localVar = variable->AsLocalVariable(); + if (decision == CheckDecision::CORRECT && variable->Is()) { + const auto localVar = variable->As(); if (localVar->HasFlag(varbinder::VariableFlags::LOCAL)) { return localVar; } @@ -1297,7 +1297,7 @@ private: auto varParent = var->Declaration()->Node()->Parent(); if (varParent != nullptr && !IsContainedIn(ident->Parent(), varParent) && ident->Parent() != varParent) { if (var->GetScope() != nullptr && var->GetScope()->Parent() != nullptr && - var->GetScope()->Parent()->IsGlobalScope() && + var->GetScope()->Parent()->Is() && ident->GetTopStatement() == varParent->GetTopStatement()) { return true; } diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index c5638130e2..3859d4be78 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -292,7 +292,7 @@ void ETSGen::LoadVar(const ir::Identifier *node, varbinder::Variable const *cons return; } - auto *local = var->AsLocalVariable(); + auto *local = var->As(); switch (ETSLReference::ResolveReferenceKind(var)) { case ReferenceKind::STATIC_FIELD: { @@ -325,7 +325,7 @@ void ETSGen::LoadVar(const ir::Identifier *node, varbinder::Variable const *cons void ETSGen::StoreVar(const ir::Identifier *node, const varbinder::ConstScopeFindResult &result) { - auto *local = result.variable->AsLocalVariable(); + auto *local = result.variable->As(); ApplyConversion(node, local->TsType()); switch (ETSLReference::ResolveReferenceKind(result.variable)) { @@ -619,7 +619,7 @@ void ETSGen::CreateBigIntObject(const ir::AstNode *node, VReg arg0, std::string_ VReg ETSGen::GetThisReg() const { const auto res = Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS); - return res.variable->AsLocalVariable()->Vreg(); + return res.variable->As()->Vreg(); } const checker::Type *ETSGen::LoadDefaultValue([[maybe_unused]] const ir::AstNode *node, diff --git a/ets2panda/compiler/core/ETSfunction.cpp b/ets2panda/compiler/core/ETSfunction.cpp index 96af9126ea..09667220bc 100644 --- a/ets2panda/compiler/core/ETSfunction.cpp +++ b/ets2panda/compiler/core/ETSfunction.cpp @@ -160,10 +160,10 @@ void ETSFunction::Compile(ETSGen *etsg) FunctionRegScope lrs(etsg); auto *topScope = etsg->TopScope(); - if (topScope->IsFunctionScope()) { + if (topScope->Is()) { CompileFunction(etsg); } else { - ASSERT(topScope->IsGlobalScope()); + ASSERT(topScope->Is()); CompileSourceBlock(etsg, etsg->RootNode()->AsBlockStatement()); } diff --git a/ets2panda/compiler/core/JSCompiler.cpp b/ets2panda/compiler/core/JSCompiler.cpp index c259f55592..9980bef6d8 100644 --- a/ets2panda/compiler/core/JSCompiler.cpp +++ b/ets2panda/compiler/core/JSCompiler.cpp @@ -406,8 +406,8 @@ void JSCompiler::Compile(const ir::ClassDefinition *node) const auto res = pg->Scope()->Find(node->PrivateId()); ASSERT(res.variable); - if (res.variable->AsLocalVariable()->LexicalBound()) { - pg->StoreLexicalVar(node, res.lexLevel, res.variable->AsLocalVariable()->LexIdx()); + if (res.variable->As()->LexicalBound()) { + pg->StoreLexicalVar(node, res.lexLevel, res.variable->As()->LexIdx()); } InitializeClassName(pg, node); @@ -1263,7 +1263,7 @@ void JSCompiler::Compile(const ir::ThisExpression *expr) const PandaGen *pg = GetPandaGen(); auto res = pg->Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS); - ASSERT(res.variable && res.variable->IsLocalVariable()); + ASSERT(res.variable && res.variable->Is()); pg->LoadAccFromLexEnv(expr, res); const ir::ScriptFunction *func = util::Helpers::GetContainingConstructor(expr); @@ -1302,7 +1302,7 @@ void JSCompiler::Compile(const ir::UnaryExpression *expr) const if (expr->Argument()->IsIdentifier()) { auto result = pg->Scope()->Find(expr->Argument()->AsIdentifier()->Name()); if (result.variable == nullptr || - (result.scope->IsGlobalScope() && result.variable->IsGlobalVariable())) { + (result.scope->Is() && result.variable->Is())) { compiler::RegScope rs(pg); compiler::VReg variable = pg->AllocReg(); compiler::VReg global = pg->AllocReg(); diff --git a/ets2panda/compiler/core/emitter.cpp b/ets2panda/compiler/core/emitter.cpp index 41f0b53192..9e8b2dac4b 100644 --- a/ets2panda/compiler/core/emitter.cpp +++ b/ets2panda/compiler/core/emitter.cpp @@ -298,13 +298,13 @@ static void GenLocalVariableInfo(pandasm::debuginfo::LocalVariable &variableDebu variableDebug.signatureType = "any"; } else { std::stringstream ss; - var->AsLocalVariable()->TsType()->ToDebugInfoType(ss); + var->As()->TsType()->ToDebugInfoType(ss); variableDebug.signature = ss.str(); variableDebug.signatureType = ss.str(); // NOTE: Handle typeParams, either class or interface } variableDebug.reg = - static_cast(IRNode::MapRegister(var->AsLocalVariable()->Vreg().GetIndex(), totalRegsNum)); + static_cast(IRNode::MapRegister(var->As()->Vreg().GetIndex(), totalRegsNum)); variableDebug.start = start; variableDebug.length = static_cast(varsLength); } @@ -315,8 +315,8 @@ void FunctionEmitter::GenScopeVariableInfoEnd(pandasm::Function *func, const var const auto extension = cg_->VarBinder()->Program()->Extension(); auto varsLength = static_cast(count - start + 1); - if (scope->IsFunctionScope()) { - for (auto *param : scope->AsFunctionScope()->ParamScope()->Params()) { + if (scope->Is()) { + for (auto *param : scope->As()->ParamScope()->Params()) { auto &variableDebug = func->localVariableDebug.emplace_back(); GenLocalVariableInfo(variableDebug, param, std::make_tuple(start, varsLength, cg_->TotalRegsNum()), extension); @@ -327,8 +327,9 @@ void FunctionEmitter::GenScopeVariableInfoEnd(pandasm::Function *func, const var unsortedBindings.end()); for (const auto &[_, variable] : bindings) { (void)_; - if (!variable->IsLocalVariable() || variable->LexicalBound() || variable->Declaration()->IsParameterDecl() || - variable->Declaration()->IsTypeAliasDecl()) { + if (!variable->Is() || variable->LexicalBound() || + variable->Declaration()->Is() || + variable->Declaration()->Is()) { continue; } diff --git a/ets2panda/compiler/core/envScope.cpp b/ets2panda/compiler/core/envScope.cpp index 7d167fde0e..b869eea6f5 100644 --- a/ets2panda/compiler/core/envScope.cpp +++ b/ets2panda/compiler/core/envScope.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -66,8 +66,8 @@ void LoopEnvScope::CopyBindings(PandaGen *pg, varbinder::VariableScope *scope, v continue; } - pg->LoadLexicalVar(scope_->Node(), 1, variable->AsLocalVariable()->LexIdx()); - pg->StoreLexicalVar(scope_->Parent()->Node(), 0, variable->AsLocalVariable()->LexIdx()); + pg->LoadLexicalVar(scope_->Node(), 1, variable->As()->LexIdx()); + pg->StoreLexicalVar(scope_->Parent()->Node(), 0, variable->As()->LexIdx()); } } diff --git a/ets2panda/compiler/core/envScope.h b/ets2panda/compiler/core/envScope.h index 288db98fe9..27d87474af 100644 --- a/ets2panda/compiler/core/envScope.h +++ b/ets2panda/compiler/core/envScope.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -109,7 +109,7 @@ public: private: static bool NeedEnv(varbinder::VariableScope *scope) { - return scope->IsVariableScope() && scope->AsVariableScope()->NeedLexEnv(); + return scope->Is() && scope->As()->NeedLexEnv(); } void CopyBindings(PandaGen *pg, varbinder::VariableScope *scope, varbinder::VariableFlags flag); diff --git a/ets2panda/compiler/core/function.cpp b/ets2panda/compiler/core/function.cpp index 98abf21803..d474630ea7 100644 --- a/ets2panda/compiler/core/function.cpp +++ b/ets2panda/compiler/core/function.cpp @@ -81,10 +81,10 @@ static void CompileFunctionParameterDeclaration(PandaGen *pg, const ir::ScriptFu paramVar = pg->Scope()->FindLocal(name, varbinder::ResolveBindingOptions::BINDINGS); } - ASSERT(paramVar && paramVar->IsLocalVariable()); + ASSERT(paramVar && paramVar->Is()); VReg paramReg = VReg(varbinder::VarBinder::MANDATORY_PARAMS_NUMBER + VReg::PARAM_START + index++); - ASSERT(paramVar->LexicalBound() || paramVar->AsLocalVariable()->Vreg() == paramReg); + ASSERT(paramVar->LexicalBound() || paramVar->As()->Vreg() == paramReg); if (param->IsAssignmentPattern()) { RegScope rs(pg); @@ -134,7 +134,7 @@ void Function::LoadClassContexts(const ir::AstNode *node, PandaGen *pg, VReg cto ASSERT(res.variable); if (classDef->HasMatchingPrivateKey(name)) { - pg->LoadLexicalVar(node, res.lexLevel, res.variable->AsLocalVariable()->LexIdx()); + pg->LoadLexicalVar(node, res.lexLevel, res.variable->As()->LexIdx()); pg->StoreAccumulator(node, ctor); break; } @@ -254,7 +254,7 @@ void Function::Compile(PandaGen *pg) auto *topScope = pg->TopScope(); if (pg->FunctionHasFinalizer()) { - ASSERT(topScope->IsFunctionScope()); + ASSERT(topScope->Is()); TryContext tryCtx(pg); pg->FunctionInit(tryCtx.GetCatchTable()); @@ -263,10 +263,10 @@ void Function::Compile(PandaGen *pg) } else { pg->FunctionInit(nullptr); - if (topScope->IsFunctionScope()) { + if (topScope->Is()) { CompileFunction(pg); } else { - ASSERT(topScope->IsGlobalScope() || topScope->IsModuleScope()); + ASSERT(topScope->Is() || topScope->Is()); CompileSourceBlock(pg, pg->RootNode()->AsBlockStatement()); } } diff --git a/ets2panda/compiler/core/moduleContext.cpp b/ets2panda/compiler/core/moduleContext.cpp index 25c00db01b..af8917acdd 100644 --- a/ets2panda/compiler/core/moduleContext.cpp +++ b/ets2panda/compiler/core/moduleContext.cpp @@ -36,13 +36,13 @@ void CompileImports(PandaGen *pg, varbinder::ModuleScope *scope) for (const auto *decl : decls) { varbinder::Variable *v = scope->FindLocal(decl->LocalName(), varbinder::ResolveBindingOptions::BINDINGS); - if (!v->IsModuleVariable()) { + if (!v->Is()) { ASSERT(decl->ImportName() == "*"); varbinder::ConstScopeFindResult result(decl->LocalName(), scope, 0, v); pg->StoreAccToLexEnv(decl->Node(), result, true); } else { - v->AsModuleVariable()->ModuleReg() = moduleReg; + v->As()->ModuleReg() = moduleReg; } } } diff --git a/ets2panda/compiler/core/pandagen.cpp b/ets2panda/compiler/core/pandagen.cpp index b7195f8453..b00a9874a3 100644 --- a/ets2panda/compiler/core/pandagen.cpp +++ b/ets2panda/compiler/core/pandagen.cpp @@ -444,17 +444,18 @@ void PandaGen::LoadVar(const ir::Identifier *node, const varbinder::ConstScopeFi return; } - if (var->IsGlobalVariable()) { + if (var->Is()) { LoadGlobalVar(node, var->Name()); return; } - if (var->IsModuleVariable()) { - LoadModuleVariable(node, var->AsModuleVariable()->ModuleReg(), var->AsModuleVariable()->ExoticName()); + if (var->Is()) { + LoadModuleVariable(node, var->As()->ModuleReg(), + var->As()->ExoticName()); return; } - ASSERT(var->IsLocalVariable()); + ASSERT(var->Is()); LoadAccFromLexEnv(node, result); } @@ -471,17 +472,17 @@ void PandaGen::StoreVar(const ir::AstNode *node, const varbinder::ConstScopeFind return; } - if (var->IsGlobalVariable()) { + if (var->Is()) { StoreGlobalVar(node, var->Name()); return; } - if (var->IsModuleVariable()) { + if (var->Is()) { ThrowConstAssignment(node, var->Name()); return; } - ASSERT(var->IsLocalVariable()); + ASSERT(var->Is()); StoreAccToLexEnv(node, result, isDeclaration); } @@ -1836,7 +1837,7 @@ void PandaGen::DirectEval(const ir::AstNode *node, uint32_t parserStatus) void PandaGen::LoadLexicalContext(const ir::AstNode *node) { auto result = Scope()->Find(varbinder::VarBinder::LEXICAL_CONTEXT_PARAM); - LoadLexicalVar(node, result.lexLevel, result.variable->AsLocalVariable()->LexIdx()); + LoadLexicalVar(node, result.lexLevel, result.variable->As()->LexIdx()); } bool PandaGen::IsDirectEval() const diff --git a/ets2panda/compiler/core/regScope.cpp b/ets2panda/compiler/core/regScope.cpp index 16c56677c5..2e360cf4f8 100644 --- a/ets2panda/compiler/core/regScope.cpp +++ b/ets2panda/compiler/core/regScope.cpp @@ -54,8 +54,8 @@ LocalRegScope::LocalRegScope(CodeGen *cg, varbinder::Scope *scope) : RegScope(cg for (const auto &[_, var] : scope->OrderedBindings(cg_->Allocator())) { (void)_; - if (!var->LexicalBound() && var->IsLocalVariable()) { - var->AsLocalVariable()->BindVReg(cg_->AllocReg()); + if (!var->LexicalBound() && var->Is()) { + var->As()->BindVReg(cg_->AllocReg()); } } @@ -101,13 +101,13 @@ void FunctionRegScope::InitializeParams(const StoreParamCb &cb) for (const auto it : funcScope->OrderedBindings(cg_->Allocator())) { auto *const var = std::get<1>(it); - if (var->Declaration()->IsParameterDecl() || var->Declaration()->IsTypeAliasDecl()) { + if (var->Declaration()->Is() || var->Declaration()->Is()) { continue; } - if (!var->LexicalBound() && var->IsLocalVariable()) { + if (!var->LexicalBound() && var->Is()) { const auto vreg = cg_->AllocReg(); - var->AsLocalVariable()->BindVReg(vreg); + var->As()->BindVReg(vreg); } } @@ -146,8 +146,8 @@ FunctionRegScope::FunctionRegScope(PandaGen *pg) : RegScope(pg), envScope_(pg->A pg->LoadAccFromArgs(pg->rootNode_); - if (funcScope->IsModuleScope()) { - ModuleContext::Compile(pg, pg->scope_->AsModuleScope()); + if (funcScope->Is()) { + ModuleContext::Compile(pg, pg->scope_->As()); } Hoisting::Hoist(pg); diff --git a/ets2panda/compiler/function/functionBuilder.cpp b/ets2panda/compiler/function/functionBuilder.cpp index 4f1d0e6377..decc5c4a39 100644 --- a/ets2panda/compiler/function/functionBuilder.cpp +++ b/ets2panda/compiler/function/functionBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -86,8 +86,8 @@ VReg FunctionBuilder::FunctionReg(const ir::ScriptFunction *node) const { varbinder::FunctionScope *scope = node->Scope(); auto res = scope->Find(varbinder::VarBinder::MANDATORY_PARAM_FUNC); - ASSERT(res.level == 0 && res.variable->IsLocalVariable()); - return res.variable->AsLocalVariable()->Vreg(); + ASSERT(res.level == 0 && res.variable->Is()); + return res.variable->As()->Vreg(); } void FunctionBuilder::Await(const ir::AstNode *node) diff --git a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp index e2279312f3..93265cf83a 100644 --- a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp +++ b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp @@ -49,14 +49,14 @@ static ArenaSet FindCaptured(public_lib::Context *ctx, ir if (withinLambda && ast->IsScopeBearer()) { innermostArrowScopes.insert(ast->Scope()); - if (ast->Scope()->IsFunctionScope()) { - innermostArrowScopes.insert(ast->Scope()->AsFunctionScope()->ParamScope()); + if (ast->Scope()->Is()) { + innermostArrowScopes.insert(ast->Scope()->As()->ParamScope()); } - if (ast->Scope()->IsCatchScope()) { - innermostArrowScopes.insert(ast->Scope()->AsCatchScope()->ParamScope()); + if (ast->Scope()->Is()) { + innermostArrowScopes.insert(ast->Scope()->As()->ParamScope()); } - if (ast->Scope()->IsLoopScope()) { - innermostArrowScopes.insert(ast->Scope()->AsLoopScope()->DeclScope()); + if (ast->Scope()->Is()) { + innermostArrowScopes.insert(ast->Scope()->As()->DeclScope()); } } else if (withinLambda && ast->IsIdentifier()) { auto *var = ast->AsIdentifier()->Variable(); @@ -64,7 +64,7 @@ static ArenaSet FindCaptured(public_lib::Context *ctx, ir return; } auto *scope = var->GetScope(); - if (scope != nullptr && !scope->IsClassScope() && !scope->IsGlobalScope() && + if (scope != nullptr && !scope->Is() && !scope->Is() && innermostArrowScopes.count(scope) == 0) { captured.insert(var); } diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index afe92fd949..20251ed218 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -152,7 +152,7 @@ template ElementMaker &&elementMaker) { auto fieldCtx = varbinder::LexicalScope::Enter( - varbinder_, globalClass->Scope()->AsClassScope()->StaticFieldScope()); + varbinder_, globalClass->Scope()->As()->StaticFieldScope()); ArenaVector elements(checker_->Allocator()->Adapter()); elements.reserve(enumDecl->Members().size()); for (const auto *const member : enumDecl->Members()) { @@ -668,4 +668,4 @@ void EnumLoweringPhase::CreateEnumValuesMethod(const ir::TSEnumDeclaration *cons functionIdent->SetReference(); } -} // namespace ark::es2panda::compiler \ No newline at end of file +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index 5a8f89886d..10c4996802 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -144,7 +144,7 @@ static ir::Expression *UpdateInterfacePropertys(checker::ETSChecker *const check ArenaVector newPropertyList(checker->Allocator()->Adapter()); auto scope = NearestScope(interface); - ASSERT(scope->IsClassScope()); + ASSERT(scope->Is()); for (const auto &prop : propertyList) { if (!prop->IsClassProperty()) { @@ -154,7 +154,7 @@ static ir::Expression *UpdateInterfacePropertys(checker::ETSChecker *const check auto getter = GenerateGetterOrSetter(checker, prop->AsClassProperty(), false); newPropertyList.emplace_back(getter); - auto methodScope = scope->AsClassScope()->InstanceMethodScope(); + auto methodScope = scope->As()->InstanceMethodScope(); auto name = getter->Key()->AsIdentifier()->Name(); auto *decl = checker->Allocator()->New(checker->Allocator(), name, getter); @@ -163,7 +163,7 @@ static ir::Expression *UpdateInterfacePropertys(checker::ETSChecker *const check if (var == nullptr) { auto prevDecl = methodScope->FindDecl(name); - ASSERT(prevDecl->IsFunctionDecl()); + ASSERT(prevDecl->Is()); prevDecl->Node()->AsMethodDefinition()->AddOverload(getter); if (!prop->AsClassProperty()->IsReadonly()) { @@ -182,7 +182,7 @@ static ir::Expression *UpdateInterfacePropertys(checker::ETSChecker *const check newPropertyList.emplace_back(setter); getter->AddOverload(setter); } - scope->AsClassScope()->InstanceFieldScope()->EraseBinding(name); + scope->As()->InstanceFieldScope()->EraseBinding(name); } auto newInterface = checker->AllocNode(std::move(newPropertyList)); diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index a4c293ae85..ad227f3338 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -264,10 +264,10 @@ static ir::MethodDefinition *SetUpCalleeMethod(public_lib::Context *ctx, LambdaI auto paramScopeCtx = varbinder::LexicalScope::Enter(varBinder, paramScope); varBinder->AddMandatoryParam(varbinder::TypedBinder::MANDATORY_PARAM_THIS); calleeClass->Definition()->TsType()->AsETSObjectType()->AddProperty( - var->AsLocalVariable()); + var->As()); } else { calleeClass->Definition()->TsType()->AsETSObjectType()->AddProperty( - var->AsLocalVariable()); + var->As()); } varbinder::BoundContext bctx {varBinder->GetRecordTable(), calleeClass->Definition(), true}; @@ -287,7 +287,7 @@ static ir::MethodDefinition *CreateCalleeMethod(public_lib::Context *ctx, ir::Ar auto *varBinder = ctx->checker->VarBinder()->AsETSBinder(); auto *checker = ctx->checker->AsETSChecker(); - auto *classScope = info->calleeClass->Definition()->Scope()->AsClassScope(); + auto *classScope = info->calleeClass->Definition()->Scope()->As(); auto *oldTypeParams = (info->enclosingFunction != nullptr) ? info->enclosingFunction->TypeParams() : nullptr; auto enclosingScope = @@ -320,7 +320,7 @@ static ir::MethodDefinition *CreateCalleeMethod(public_lib::Context *ctx, ir::Ar cmInfo->body, ir::FunctionSignature(newTypeParams, std::move(params), returnTypeAnnotation), funcFlags, modifierFlags}); auto *funcScope = cmInfo->body == nullptr ? allocator->New(allocator, paramScope) - : cmInfo->body->Scope()->AsFunctionScope(); + : cmInfo->body->Scope()->As(); funcScope->BindName(info->calleeClass->Definition()->TsType()->AsETSObjectType()->AssemblerName()); func->SetScope(funcScope); @@ -929,7 +929,7 @@ static ir::AstNode *BuildLambdaClassWhenNeeded(public_lib::Context *ctx, ir::Ast auto *id = node->AsIdentifier(); auto *var = id->Variable(); if (id->IsReference() && id->TsType() != nullptr && id->TsType()->IsETSFunctionType() && var != nullptr && - var->Declaration()->IsFunctionDecl() && !IsInCalleePosition(id)) { + var->Declaration()->Is() && !IsInCalleePosition(id)) { return ConvertFunctionReference(ctx, id); } } @@ -943,7 +943,7 @@ static ir::AstNode *BuildLambdaClassWhenNeeded(public_lib::Context *ctx, ir::Ast checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | checker::PropertySearchFlags::SEARCH_STATIC_METHOD | checker::PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION); - if (var != nullptr && var->Declaration()->IsFunctionDecl() && !IsInCalleePosition(mexpr)) { + if (var != nullptr && var->Declaration()->Is() && !IsInCalleePosition(mexpr)) { return ConvertFunctionReference(ctx, mexpr); } } diff --git a/ets2panda/compiler/lowering/ets/localClassLowering.cpp b/ets2panda/compiler/lowering/ets/localClassLowering.cpp index c79dfda9af..9006b57911 100644 --- a/ets2panda/compiler/lowering/ets/localClassLowering.cpp +++ b/ets2panda/compiler/lowering/ets/localClassLowering.cpp @@ -146,8 +146,8 @@ void LocalClassConstructionPhase::ModifyConstructorParameters( parameters.insert(parameters.begin(), newParam); ASSERT(newParam->Variable()->Type() == varbinder::VariableType::LOCAL); - sigParams.insert(sigParams.begin(), newParam->Ident()->Variable()->AsLocalVariable()); - parameterMap[var] = newParam->Ident()->Variable()->AsLocalVariable(); + sigParams.insert(sigParams.begin(), newParam->Ident()->Variable()->As()); + parameterMap[var] = newParam->Ident()->Variable()->As(); } reinterpret_cast(checker->VarBinder())->BuildFunctionName(constructor); LOG(DEBUG, ES2PANDA) << " Transformed Constructor: " << signature->InternalName(); @@ -162,7 +162,7 @@ void LocalClassConstructionPhase::ModifyConstructorParameters( auto *fieldVar = variableMap[var]; auto *leftHandSide = fieldInit->Left(); leftHandSide->AsMemberExpression()->SetObjectType(classType); - leftHandSide->AsMemberExpression()->SetPropVar(fieldVar->AsLocalVariable()); + leftHandSide->AsMemberExpression()->SetPropVar(fieldVar->As()); leftHandSide->AsMemberExpression()->SetIgnoreBox(); leftHandSide->AsMemberExpression()->SetTsType(fieldVar->TsType()); leftHandSide->AsMemberExpression()->Object()->SetTsType(classType); diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index a95619817c..777eb25e7f 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -76,13 +76,13 @@ static varbinder::LocalVariable *CreateUnionFieldClassProperty(checker::ETSCheck { auto *const allocator = checker->Allocator(); auto *const dummyClass = GetUnionFieldClass(checker, varbinder); - auto *classScope = dummyClass->Scope()->AsClassScope(); + auto *classScope = dummyClass->Scope()->As(); // Enter the union filed class instance field scope auto fieldCtx = varbinder::LexicalScope::Enter(varbinder, classScope->InstanceFieldScope()); if (auto *var = classScope->FindLocal(propName, varbinder::ResolveBindingOptions::VARIABLES); var != nullptr) { - return var->AsLocalVariable(); + return var->As(); } // Create field name for synthetic class @@ -103,7 +103,7 @@ static varbinder::LocalVariable *CreateUnionFieldClassProperty(checker::ETSCheck ArenaVector fieldDecl {allocator->Adapter()}; fieldDecl.push_back(field); dummyClass->AddProperties(std::move(fieldDecl)); - return var->AsLocalVariable(); + return var->As(); } static void HandleUnionPropertyAccess(checker::ETSChecker *checker, varbinder::VarBinder *vbind, diff --git a/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp b/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp index 56aa8c8318..ba9d91f381 100644 --- a/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp +++ b/ets2panda/compiler/lowering/scopesInit/savedBindingsCtx.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -31,10 +31,10 @@ void ImportDeclarationContext::BindImportDecl(ir::ImportDeclaration *importDecl) continue; } - declList.push_back(variable->Declaration()->AsImportDecl()); + declList.push_back(variable->Declaration()->As()); } - VarBinder()->GetScope()->AsModuleScope()->AddImportDecl(importDecl, std::move(declList)); + VarBinder()->GetScope()->As()->AddImportDecl(importDecl, std::move(declList)); } void ExportDeclarationContext::BindExportDecl(ir::AstNode *exportDecl) @@ -73,8 +73,8 @@ void ExportDeclarationContext::BindExportDecl(ir::AstNode *exportDecl) declList.push_back(decl); } - auto *moduleScope = VarBinder()->GetScope()->AsModuleScope(); + auto *moduleScope = VarBinder()->GetScope()->As(); moduleScope->AddExportDecl(exportDecl, std::move(declList)); } -} // namespace ark::es2panda::compiler \ No newline at end of file +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index 2249844f19..649758c745 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -271,7 +271,7 @@ void ScopesInitPhase::VisitExportAllDeclaration(ir::ExportAllDeclaration *export const auto name = exportAllDecl->Exported() != nullptr ? exportAllDecl->Exported()->Name() : "*"; auto *decl = AddOrGetDecl(VarBinder(), name, exportAllDecl, exportAllDecl->Start(), name, "*"); - VarBinder()->GetScope()->AsModuleScope()->AddExportDecl(exportAllDecl, decl); + VarBinder()->GetScope()->As()->AddExportDecl(exportAllDecl, decl); } void ScopesInitPhase::VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecifier *importSpec) @@ -330,7 +330,7 @@ void ScopesInitPhase::VisitExportNamedDeclaration(ir::ExportNamedDeclaration *ex spec->Exported()->Name(), spec->Local()->Name(), spec); exportDecls.push_back(decl); } - VarBinder()->GetScope()->AsModuleScope()->AddExportDecl(exportDecl, std::move(exportDecls)); + VarBinder()->GetScope()->As()->AddExportDecl(exportDecl, std::move(exportDecls)); } } @@ -471,8 +471,8 @@ void ScopesInitPhase::Finalize() void ScopesInitPhase::AnalyzeExports() { - if (Program()->Kind() == parser::ScriptKind::MODULE && VarBinder()->TopScope()->IsModuleScope() && - !VarBinder()->TopScope()->AsModuleScope()->ExportAnalysis()) { + if (Program()->Kind() == parser::ScriptKind::MODULE && VarBinder()->TopScope()->Is() && + !VarBinder()->TopScope()->As()->ExportAnalysis()) { ThrowSyntaxError("Invalid exported binding", Program()->Ast()->End()); } } @@ -526,10 +526,10 @@ void ScopeInitTyped::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *int decl = VarBinder()->AddTsDecl(ident->Start(), Allocator(), name); } else if (!AllowInterfaceRedeclaration()) { ThrowSyntaxError("Interface redeclaration is not allowed", interfDecl->Start()); - } else if (!res->second->Declaration()->IsInterfaceDecl()) { + } else if (!res->second->Declaration()->Is()) { VarBinder()->ThrowRedeclaration(ident->Start(), ident->Name()); } else { - decl = res->second->Declaration()->AsInterfaceDecl(); + decl = res->second->Declaration()->As(); alreadyExists = true; } @@ -577,14 +577,14 @@ void ScopeInitTyped::VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl) decl = VarBinder()->AddTsDecl(enumDecl->Start(), ident, enumDecl->IsConst()); varbinder::LexicalScope enumCtx = LexicalScopeCreateOrEnter(VarBinder(), enumDecl); decl->BindScope(enumCtx.GetScope()); - BindScopeNode(VarBinder()->GetScope()->AsLocalScope(), enumDecl); - } else if (!res->second->Declaration()->IsEnumLiteralDecl() || - (enumDecl->IsConst() ^ res->second->Declaration()->AsEnumLiteralDecl()->IsConst()) != 0) { + BindScopeNode(VarBinder()->GetScope()->As(), enumDecl); + } else if (!res->second->Declaration()->Is() || + (enumDecl->IsConst() ^ res->second->Declaration()->As()->IsConst()) != 0) { auto loc = enumDecl->Key()->End(); loc.index++; VarBinder()->ThrowRedeclaration(loc, enumDecl->Key()->Name()); } else { - decl = res->second->Declaration()->AsEnumLiteralDecl(); + decl = res->second->Declaration()->As(); auto scopeCtx = varbinder::LexicalScope::Enter(VarBinder(), decl->Scope()); } @@ -602,7 +602,7 @@ void ScopeInitTyped::VisitTSTypeParameter(ir::TSTypeParameter *typeParam) void ScopeInitTyped::VisitTSTypeParameterDeclaration(ir::TSTypeParameterDeclaration *paramDecl) { - BindScopeNode(VarBinder()->GetScope()->AsLocalScope(), paramDecl); + BindScopeNode(VarBinder()->GetScope()->As(), paramDecl); Iterate(paramDecl); } @@ -659,16 +659,16 @@ void InitScopesPhaseTs::CreateFuncDecl(ir::ScriptFunction *func) } else { varbinder::Decl *currentDecl = res->second->Declaration(); - auto &existing = currentDecl->AsFunctionDecl()->Decls(); + auto &existing = currentDecl->As()->Decls(); if (std::find(existing.begin(), existing.end(), func) != existing.end()) { return; } - if (!currentDecl->IsFunctionDecl() || - !currentDecl->AsFunctionDecl()->Node()->AsScriptFunction()->IsOverload()) { + if (!currentDecl->Is() || + !currentDecl->As()->Node()->AsScriptFunction()->IsOverload()) { VarBinder()->ThrowRedeclaration(startLoc, currentDecl->Name()); } - decl = currentDecl->AsFunctionDecl(); + decl = currentDecl->As(); } decl->Add(func); @@ -798,7 +798,7 @@ void InitScopesPhaseETS::VisitClassStaticBlock(ir::ClassStaticBlock *staticBlock } auto classCtx = varbinder::LexicalScope::Enter( - VarBinder(), VarBinder()->GetScope()->AsClassScope()->StaticMethodScope()); + VarBinder(), VarBinder()->GetScope()->As()->StaticMethodScope()); if (func->Id()->Variable() != nullptr) { return; @@ -844,14 +844,14 @@ void AddOverload(ir::MethodDefinition *overload, varbinder::Variable *variable) void InitScopesPhaseETS::DeclareClassMethod(ir::MethodDefinition *method) { - ASSERT(VarBinder()->GetScope()->IsClassScope()); + ASSERT(VarBinder()->GetScope()->Is()); if ((method->AsMethodDefinition()->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) != 0) { return; } const auto methodName = method->Id(); - auto *const clsScope = VarBinder()->GetScope()->AsClassScope(); + auto *const clsScope = VarBinder()->GetScope()->As(); auto options = method->IsStatic() ? varbinder::ResolveBindingOptions::STATIC_VARIABLES | varbinder::ResolveBindingOptions::STATIC_DECLARATION @@ -892,7 +892,7 @@ void InitScopesPhaseETS::MaybeAddOverload(ir::MethodDefinition *method, ir::Iden overload->SetParent(var->Declaration()->Node()); } } else { - if (methodName->Name().Is(compiler::Signatures::MAIN) && clsScope->Parent()->IsGlobalScope()) { + if (methodName->Name().Is(compiler::Signatures::MAIN) && clsScope->Parent()->Is()) { ThrowSyntaxError("Main overload is not enabled", methodName->Start()); } AddOverload(method, found); @@ -953,7 +953,8 @@ void InitScopesPhaseETS::VisitMethodDefinition(ir::MethodDefinition *method) auto res = curScope->Find(methodName->Name(), method->IsStatic() ? varbinder::ResolveBindingOptions::ALL_STATIC : varbinder::ResolveBindingOptions::ALL_NON_STATIC); - if (res.variable != nullptr && !res.variable->Declaration()->IsFunctionDecl() && res.scope == curScope) { + if (res.variable != nullptr && !res.variable->Declaration()->Is() && + res.scope == curScope) { VarBinder()->ThrowRedeclaration(methodName->Start(), res.name); } Iterate(method); @@ -976,13 +977,14 @@ void InitScopesPhaseETS::VisitETSNewClassInstanceExpression(ir::ETSNewClassInsta if (newClassExpr->ClassDefinition() != nullptr) { const auto classDef = newClassExpr->ClassDefinition(); auto *parentClassScope = VarBinder()->GetScope(); - while (!parentClassScope->IsClassScope()) { + while (!parentClassScope->Is()) { ASSERT(parentClassScope->Parent()); parentClassScope = parentClassScope->Parent(); } auto classCtx = LexicalScopeCreateOrEnter(VarBinder(), newClassExpr->ClassDefinition()); util::UString anonymousName(util::StringView("#"), Allocator()); - anonymousName.Append(std::to_string(parentClassScope->AsClassScope()->GetAndIncrementAnonymousClassIdx())); + anonymousName.Append( + std::to_string(parentClassScope->As()->GetAndIncrementAnonymousClassIdx())); classDef->SetInternalName(anonymousName.View()); classDef->Ident()->SetName(anonymousName.View()); CallNode(classDef); @@ -1015,7 +1017,7 @@ void InitScopesPhaseETS::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration auto name = FormInterfaceOrEnumDeclarationIdBinding(interfaceDecl->Id()); auto *decl = AddOrGetDecl(VarBinder(), name, interfaceDecl, interfaceDecl->Start(), Allocator(), name, interfaceDecl); - decl->AsInterfaceDecl()->Add(interfaceDecl); + decl->As()->Add(interfaceDecl); } void InitScopesPhaseETS::VisitTSEnumDeclaration(ir::TSEnumDeclaration *enumDecl) @@ -1126,9 +1128,9 @@ void InitScopesPhaseETS::VisitClassProperty(ir::ClassProperty *classProp) auto curScope = VarBinder()->GetScope(); const auto name = classProp->Key()->AsIdentifier()->Name(); if (classProp->IsClassStaticBlock()) { - ASSERT(curScope->IsClassScope()); + ASSERT(curScope->Is()); auto classCtx = varbinder::LexicalScope::Enter( - VarBinder(), curScope->AsClassScope()->StaticMethodScope()); + VarBinder(), curScope->As()->StaticMethodScope()); auto *var = classProp->Id()->Variable(); if (var == nullptr) { var = std::get<1>(VarBinder()->NewVarDecl(classProp->Start(), Allocator(), @@ -1139,7 +1141,7 @@ void InitScopesPhaseETS::VisitClassProperty(ir::ClassProperty *classProp) } else if (classProp->IsConst()) { ASSERT(curScope->Parent() != nullptr); const auto initializer = classProp->Value(); - if (initializer == nullptr && curScope->Parent()->IsGlobalScope() && !classProp->IsDeclare()) { + if (initializer == nullptr && curScope->Parent()->Is() && !classProp->IsDeclare()) { auto pos = classProp->End(); // NOTE: Just use property Name? if (!classProp->TypeAnnotation()->IsETSPrimitiveType()) { @@ -1150,7 +1152,7 @@ void InitScopesPhaseETS::VisitClassProperty(ir::ClassProperty *classProp) AddOrGetDecl(VarBinder(), name, classProp, classProp->Key()->Start(), name, classProp); } else if (classProp->IsReadonly()) { ASSERT(curScope->Parent() != nullptr); - if (curScope->Parent()->IsGlobalScope() && !classProp->IsDeclare()) { + if (curScope->Parent()->Is() && !classProp->IsDeclare()) { auto pos = classProp->End(); ThrowSyntaxError("Readonly field cannot be in Global scope", pos); } diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index e4af296608..8d4c58f084 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -81,8 +81,8 @@ ArenaSet FindCaptured(ArenaAllocator *allocator, ir::AstN scopeBearer->IterateRecursivelyPreorder([&result, &scopes](ir::AstNode *ast) { if (ast->IsScopeBearer() && ast->Scope() != nullptr) { scopes.insert(ast->Scope()); - if (ast->Scope()->IsFunctionScope()) { - scopes.insert(ast->Scope()->AsFunctionScope()->ParamScope()); + if (ast->Scope()->Is()) { + scopes.insert(ast->Scope()->As()->ParamScope()); } else if (ast->IsForUpdateStatement() || ast->IsForInStatement() || ast->IsForOfStatement() || ast->IsCatchClause()) { // NOTE(gogabr) LoopScope _does not_ currently respond to IsLoopScope(). @@ -96,7 +96,8 @@ ArenaSet FindCaptured(ArenaAllocator *allocator, ir::AstN return; } auto *sc = var->GetScope(); - if (sc != nullptr && !sc->IsClassScope() && !sc->IsGlobalScope() && scopes.count(var->GetScope()) == 0) { + if (sc != nullptr && !sc->Is() && !sc->Is() && + scopes.count(var->GetScope()) == 0) { result.insert(var); } } diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index 349fc18ac6..834a0ad00b 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -100,7 +100,7 @@ checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) if (prev_ == nullptr) { if (name_->IsIdentifier()) { const auto ident = name_->AsIdentifier(); - if ((ident->Variable() != nullptr) && (ident->Variable()->Declaration()->IsTypeAliasDecl())) { + if ((ident->Variable() != nullptr) && (ident->Variable()->Declaration()->Is())) { SetTsType(checker->HandleTypeAlias(name_, typeParams_)); } else if (ident->Name() == compiler::Signatures::UNDEFINED) { SetTsType(checker->GlobalETSUndefinedType()); diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index 24fba035f3..affd851b31 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -172,7 +172,7 @@ std::pair MemberExpression::Resolve switch (resolveRes.size()) { case 1U: { if (resolveRes[0]->Kind() == checker::ResolvedKind::PROPERTY) { - auto var = resolveRes[0]->Variable()->AsLocalVariable(); + auto var = resolveRes[0]->Variable()->As(); checker->ValidatePropertyAccess(var, objType_, property_->Start()); return {checker->GetTypeOfVariable(var), var}; } diff --git a/ets2panda/ir/expressions/memberExpression.h b/ets2panda/ir/expressions/memberExpression.h index 15da29d46e..8d7fc89af2 100644 --- a/ets2panda/ir/expressions/memberExpression.h +++ b/ets2panda/ir/expressions/memberExpression.h @@ -113,7 +113,7 @@ public: if (Kind() == MemberExpressionKind::ELEMENT_ACCESS) { return nullptr; } - return Property()->Variable() != nullptr ? Property()->Variable()->AsLocalVariable() : nullptr; + return Property()->Variable() != nullptr ? Property()->Variable()->As() : nullptr; } [[nodiscard]] const varbinder::LocalVariable *PropVar() const noexcept @@ -121,7 +121,7 @@ public: if (Kind() == MemberExpressionKind::ELEMENT_ACCESS) { return nullptr; } - return Property()->Variable() != nullptr ? Property()->Variable()->AsLocalVariable() : nullptr; + return Property()->Variable() != nullptr ? Property()->Variable()->As() : nullptr; } [[nodiscard]] bool IsComputed() const noexcept diff --git a/ets2panda/parser/program/program.cpp b/ets2panda/parser/program/program.cpp index 7c83401ad5..08ba4b7c0f 100644 --- a/ets2panda/parser/program/program.cpp +++ b/ets2panda/parser/program/program.cpp @@ -37,23 +37,23 @@ void Program::DumpSilent() const varbinder::ClassScope *Program::GlobalClassScope() { - return globalClass_->Scope()->AsClassScope(); + return globalClass_->Scope()->As(); } const varbinder::ClassScope *Program::GlobalClassScope() const { - return globalClass_->Scope()->AsClassScope(); + return globalClass_->Scope()->As(); } varbinder::GlobalScope *Program::GlobalScope() { - ASSERT(ast_->Scope()->IsGlobalScope() || ast_->Scope()->IsModuleScope()); + ASSERT(ast_->Scope()->Is() || ast_->Scope()->Is()); return static_cast(ast_->Scope()); } const varbinder::GlobalScope *Program::GlobalScope() const { - ASSERT(ast_->Scope()->IsGlobalScope() || ast_->Scope()->IsModuleScope()); + ASSERT(ast_->Scope()->Is() || ast_->Scope()->Is()); return static_cast(ast_->Scope()); } diff --git a/ets2panda/test/unit/union_normalization_test.cpp b/ets2panda/test/unit/union_normalization_test.cpp index 7304023460..7cb98946d7 100644 --- a/ets2panda/test/unit/union_normalization_test.cpp +++ b/ets2panda/test/unit/union_normalization_test.cpp @@ -160,8 +160,9 @@ public: static checker::Type *FindTypeAlias(checker::ETSChecker *checker, std::string_view aliasName) { - auto *foundVar = - checker->Scope()->FindLocal(aliasName, varbinder::ResolveBindingOptions::TYPE_ALIASES)->AsLocalVariable(); + auto *foundVar = checker->Scope() + ->FindLocal(aliasName, varbinder::ResolveBindingOptions::TYPE_ALIASES) + ->As(); if (foundVar == nullptr) { return nullptr; } diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 44a4f609b1..f008f04b29 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -197,7 +197,8 @@ void ETSBinder::LookupIdentReference(ir::Identifier *ident) auto *outerFunction = GetScope()->EnclosingVariableScope()->Node(); if ((!outerFunction->IsScriptFunction() || !outerFunction->AsScriptFunction()->IsArrow()) && - !res.variable->IsGlobalVariable() && res.variable->HasFlag(VariableFlags::LOCAL) && res.level > 1) { + !res.variable->Is() && res.variable->HasFlag(VariableFlags::LOCAL) && + res.level > 1) { ThrowInvalidCapture(ident->Start(), name); } } @@ -221,7 +222,7 @@ void ETSBinder::InitializeInterfaceIdent(ir::TSInterfaceDeclaration *decl) { auto res = GetScope()->Find(decl->Id()->Name()); - ASSERT(res.variable && res.variable->Declaration()->IsInterfaceDecl()); + ASSERT(res.variable && res.variable->Declaration()->Is()); res.variable->AddFlag(VariableFlags::INITIALIZED); decl->Id()->SetVariable(res.variable); } @@ -243,7 +244,7 @@ void ETSBinder::ResolveInterfaceDeclaration(ir::TSInterfaceDeclaration *decl) ResolveReference(extend); } - auto scopeCtx = LexicalScope::Enter(this, decl->Scope()->AsClassScope()); + auto scopeCtx = LexicalScope::Enter(this, decl->Scope()->As()); for (auto *stmt : decl->Body()->Body()) { if (!stmt->IsClassProperty()) { @@ -253,7 +254,7 @@ void ETSBinder::ResolveInterfaceDeclaration(ir::TSInterfaceDeclaration *decl) ResolveReference(stmt); auto fieldVar = - ResolvePropertyReference(stmt->AsClassProperty(), decl->Scope()->AsClassScope()) + ResolvePropertyReference(stmt->AsClassProperty(), decl->Scope()->As()) ->FindLocal(stmt->AsClassProperty()->Id()->Name(), varbinder::ResolveBindingOptions::BINDINGS); fieldVar->AddFlag(VariableFlags::INITIALIZED); } @@ -343,7 +344,7 @@ LocalScope *ETSBinder::ResolvePropertyReference(ir::ClassProperty *prop, ClassSc void ETSBinder::BuildClassDefinitionImpl(ir::ClassDefinition *classDef) { - auto classCtx = LexicalScope::Enter(this, classDef->Scope()->AsClassScope()); + auto classCtx = LexicalScope::Enter(this, classDef->Scope()->As()); if (classDef->Super() != nullptr) { ResolveReference(classDef->Super()); @@ -358,11 +359,11 @@ void ETSBinder::BuildClassDefinitionImpl(ir::ClassDefinition *classDef) continue; } - auto fieldScope = ResolvePropertyReference(stmt->AsClassProperty(), classDef->Scope()->AsClassScope()); + auto fieldScope = ResolvePropertyReference(stmt->AsClassProperty(), classDef->Scope()->As()); auto fieldName = stmt->AsClassProperty()->Id()->Name(); auto fieldVar = fieldScope->FindLocal(fieldName, varbinder::ResolveBindingOptions::BINDINGS); fieldVar->AddFlag(VariableFlags::INITIALIZED); - if ((fieldVar->Declaration()->IsConstDecl() || fieldVar->Declaration()->IsReadonlyDecl()) && + if ((fieldVar->Declaration()->Is() || fieldVar->Declaration()->Is()) && stmt->AsClassProperty()->Value() == nullptr) { fieldVar->AddFlag(VariableFlags::EXPLICIT_INIT_REQUIRED); } @@ -436,7 +437,7 @@ std::string RedeclarationErrorMessageAssembler(const Variable *const var, const util::StringView localName) { auto type = var->Declaration()->Node()->IsClassDefinition() ? "Class '" - : var->Declaration()->IsFunctionDecl() ? "Function '" + : var->Declaration()->Is() ? "Function '" : "Variable '"; auto str = util::Helpers::AppendAll(type, localName.Utf8(), "'"); str += variable->Declaration()->Type() == var->Declaration()->Type() ? " is already defined." @@ -498,11 +499,11 @@ void ETSBinder::ImportAllForeignBindings(ir::AstNode *const specifier, } if (!importGlobalScope->IsForeignBinding(bindingName) && !var->Declaration()->Node()->IsDefaultExported() && - (var->AsLocalVariable()->Declaration()->Node()->IsExported() || - var->AsLocalVariable()->Declaration()->Node()->IsExportedType())) { + (var->As()->Declaration()->Node()->IsExported() || + var->As()->Declaration()->Node()->IsExportedType())) { auto variable = Program()->GlobalClassScope()->FindLocal(bindingName, ResolveBindingOptions::ALL); - if (variable != nullptr && var != variable && variable->Declaration()->IsFunctionDecl() && - var->Declaration()->IsFunctionDecl()) { + if (variable != nullptr && var != variable && variable->Declaration()->Is() && + var->Declaration()->Is()) { bool isStdLib = util::Helpers::IsStdLib(Program()); AddOverloadFlag(isStdLib, var, variable); continue; @@ -623,7 +624,7 @@ Variable *ETSBinder::FindImportSpecifiersVariable(const util::StringView &import foundVar = staticFieldBindings.find(searchImported); if (foundVar != staticFieldBindings.end()) { found = true; - foundVar->second->AsLocalVariable()->AddFlag(VariableFlags::INITIALIZED); + foundVar->second->As()->AddFlag(VariableFlags::INITIALIZED); break; } } @@ -754,7 +755,7 @@ bool ETSBinder::AddImportSpecifiersToTopBindings(ir::AstNode *const specifier, auto variable = Program()->GlobalClassScope()->FindLocal(localName, ResolveBindingOptions::ALL); if (variable != nullptr && var != variable) { - if (variable->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { + if (variable->Declaration()->Is() && var->Declaration()->Is()) { bool isStdLib = util::Helpers::IsStdLib(Program()); AddOverloadFlag(isStdLib, var, variable); return true; @@ -1079,7 +1080,7 @@ bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable bool isStdLib = util::Helpers::IsStdLib(Program()); if (variable != nullptr && var != variable) { - if (variable->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { + if (variable->Declaration()->Is() && var->Declaration()->Is()) { AddOverloadFlag(isStdLib, var, variable); return true; } @@ -1091,7 +1092,7 @@ bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable if (!(!insRes.second && insRes.first != TopScope()->Bindings().end()) || !(insRes.first->second != var)) { return true; } - if (insRes.first->second->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { + if (insRes.first->second->Declaration()->Is() && var->Declaration()->Is()) { AddOverloadFlag(isStdLib, var, insRes.first->second); return true; } @@ -1101,7 +1102,7 @@ bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable void ETSBinder::ImportGlobalProperties(const ir::ClassDefinition *const classDef) { - const auto scopeCtx = LexicalScope::Enter(this, classDef->Scope()->AsClassScope()); + const auto scopeCtx = LexicalScope::Enter(this, classDef->Scope()->As()); for (const auto *const prop : classDef->Body()) { const auto *const classElement = prop->AsClassElement(); diff --git a/ets2panda/varbinder/TypedBinder.cpp b/ets2panda/varbinder/TypedBinder.cpp index 7677ca3c1c..90f0b2bb11 100644 --- a/ets2panda/varbinder/TypedBinder.cpp +++ b/ets2panda/varbinder/TypedBinder.cpp @@ -57,9 +57,9 @@ void TypedBinder::BuildSignatureDeclarationBaseParams(ir::AstNode *typeNode) } } - ASSERT(scope && scope->IsFunctionParamScope()); + ASSERT(scope && scope->Is()); - auto scopeCtx = LexicalScope::Enter(this, scope->AsFunctionParamScope(), false); + auto scopeCtx = LexicalScope::Enter(this, scope->As(), false); ResolveReferences(typeNode); } diff --git a/ets2panda/varbinder/declaration.h b/ets2panda/varbinder/declaration.h index ddf6c034f9..3a2b088b15 100644 --- a/ets2panda/varbinder/declaration.h +++ b/ets2panda/varbinder/declaration.h @@ -31,11 +31,9 @@ class ETSImportDeclaration; namespace ark::es2panda::varbinder { class Scope; class LocalScope; - -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DECLARE_CLASSES(decl_kind, className) class className; -DECLARATION_KINDS(DECLARE_CLASSES) -#undef DECLARE_CLASSES +class LetDecl; +class ConstDecl; +class ParameterDecl; class Decl { public: @@ -60,24 +58,24 @@ public: return node_; } -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DECLARE_CHECKS_CASTS(declKind, className) \ - bool Is##className() const \ - { \ - return Type() == DeclType::declKind; \ - } \ - className *As##className() \ - { \ - ASSERT(Is##className()); \ - return reinterpret_cast(this); \ - } \ - const className *As##className() const \ - { \ - ASSERT(Is##className()); \ - return reinterpret_cast(this); \ + template + bool Is() const + { + return Type() == T::TYPE; + } + + template + const T *As() const + { + ASSERT(Is()); + return reinterpret_cast(this); + } + + template + T *As() + { + return const_cast(const_cast(this)->As()); } - DECLARATION_KINDS(DECLARE_CHECKS_CASTS) -#undef DECLARE_CHECKS_CASTS void BindNode(ir::AstNode *node) { @@ -86,12 +84,12 @@ public: bool IsLetOrConstDecl() const { - return IsLetDecl() || IsConstDecl(); + return Is() || Is(); } bool PossibleTDZ() const { - return IsLetOrConstDecl() || IsParameterDecl(); + return IsLetOrConstDecl() || Is(); } protected: @@ -104,16 +102,30 @@ protected: // NOLINTEND(misc-non-private-member-variables-in-classes) }; -template -class MultiDecl : public Decl { +template +class TypedDecl : public Decl { +public: + static constexpr DeclType TYPE = D; + + DeclType Type() const override + { + return TYPE; + } + +protected: + using Decl::Decl; +}; + +template +class MultiDecl : public TypedDecl { public: explicit MultiDecl(ArenaAllocator *allocator, util::StringView name) - : Decl(name), declarations_(allocator->Adapter()) + : MultiDecl::TypedDecl(name), declarations_(allocator->Adapter()) { } explicit MultiDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode) - : Decl(name, declNode), declarations_(allocator->Adapter()) + : MultiDecl::TypedDecl(name, declNode), declarations_(allocator->Adapter()) { } @@ -131,19 +143,14 @@ private: ArenaVector declarations_; }; -class EnumLiteralDecl : public Decl { +class EnumLiteralDecl : public TypedDecl { public: - explicit EnumLiteralDecl(util::StringView name, bool isConst) : Decl(name), isConst_(isConst) {} + explicit EnumLiteralDecl(util::StringView name, bool isConst) : TypedDecl(name), isConst_(isConst) {} explicit EnumLiteralDecl(util::StringView name, ir::AstNode *declNode, bool isConst) - : Decl(name, declNode), isConst_(isConst) + : TypedDecl(name, declNode), isConst_(isConst) { } - DeclType Type() const override - { - return DeclType::ENUM_LITERAL; - } - bool IsConst() const { return isConst_; @@ -164,179 +171,104 @@ private: bool isConst_ {}; }; -class InterfaceDecl : public MultiDecl { +class InterfaceDecl : public MultiDecl { public: explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name) : MultiDecl(allocator, name) {} explicit InterfaceDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *declNode) : MultiDecl(allocator, name, declNode) { } - - DeclType Type() const override - { - return DeclType::INTERFACE; - } }; -class ClassDecl : public Decl { +class ClassDecl : public TypedDecl { public: - explicit ClassDecl(util::StringView name) : Decl(name) {} - explicit ClassDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {} - - DeclType Type() const override - { - return DeclType::CLASS; - } + explicit ClassDecl(util::StringView name) : TypedDecl(name) {} + explicit ClassDecl(util::StringView name, ir::AstNode *node) : TypedDecl(name, node) {} }; -class FunctionDecl : public MultiDecl { +class FunctionDecl : public MultiDecl { public: explicit FunctionDecl(ArenaAllocator *allocator, util::StringView name, ir::AstNode *node) : MultiDecl(allocator, name) { node_ = node; } - - DeclType Type() const override - { - return DeclType::FUNC; - } }; -class TypeParameterDecl : public Decl { +class TypeParameterDecl : public TypedDecl { public: - explicit TypeParameterDecl(util::StringView name) : Decl(name) {} - - DeclType Type() const override - { - return DeclType::TYPE_PARAMETER; - } + explicit TypeParameterDecl(util::StringView name) : TypedDecl(name) {} }; -class PropertyDecl : public Decl { +class PropertyDecl : public TypedDecl { public: - explicit PropertyDecl(util::StringView name) : Decl(name) {} - - DeclType Type() const override - { - return DeclType::PROPERTY; - } + explicit PropertyDecl(util::StringView name) : TypedDecl(name) {} }; -class MethodDecl : public Decl { +class MethodDecl : public TypedDecl { public: - explicit MethodDecl(util::StringView name) : Decl(name) {} - - DeclType Type() const override - { - return DeclType::METHOD; - } + explicit MethodDecl(util::StringView name) : TypedDecl(name) {} }; -class EnumDecl : public Decl { +class EnumDecl : public TypedDecl { public: - explicit EnumDecl(util::StringView name) : Decl(name) {} - - DeclType Type() const override - { - return DeclType::ENUM; - } + explicit EnumDecl(util::StringView name) : TypedDecl(name) {} }; -class TypeAliasDecl : public Decl { +class TypeAliasDecl : public TypedDecl { public: - explicit TypeAliasDecl(util::StringView name) : Decl(name) {} - explicit TypeAliasDecl(util::StringView name, ir::AstNode *node) : Decl(name, node) {} - - DeclType Type() const override - { - return DeclType::TYPE_ALIAS; - } + explicit TypeAliasDecl(util::StringView name) : TypedDecl(name) {} + explicit TypeAliasDecl(util::StringView name, ir::AstNode *node) : TypedDecl(name, node) {} }; -class NameSpaceDecl : public Decl { +class NameSpaceDecl : public TypedDecl { public: - explicit NameSpaceDecl(util::StringView name) : Decl(name) {} - - DeclType Type() const override - { - return DeclType::NAMESPACE; - } + explicit NameSpaceDecl(util::StringView name) : TypedDecl(name) {} }; -class VarDecl : public Decl { +class VarDecl : public TypedDecl { public: - explicit VarDecl(util::StringView name) : Decl(name) {} - - DeclType Type() const override - { - return DeclType::VAR; - } + explicit VarDecl(util::StringView name) : TypedDecl(name) {} }; -class LetDecl : public Decl { +class LetDecl : public TypedDecl { public: - explicit LetDecl(util::StringView name) : Decl(name) {} - explicit LetDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {} - - DeclType Type() const override - { - return DeclType::LET; - } + explicit LetDecl(util::StringView name) : TypedDecl(name) {} + explicit LetDecl(util::StringView name, ir::AstNode *declNode) : TypedDecl(name, declNode) {} }; -class ConstDecl : public Decl { +class ConstDecl : public TypedDecl { public: - explicit ConstDecl(util::StringView name) : Decl(name) {} - explicit ConstDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {} - - DeclType Type() const override - { - return DeclType::CONST; - } + explicit ConstDecl(util::StringView name) : TypedDecl(name) {} + explicit ConstDecl(util::StringView name, ir::AstNode *declNode) : TypedDecl(name, declNode) {} }; -class LabelDecl : public Decl { +class LabelDecl : public TypedDecl { public: - explicit LabelDecl(util::StringView name) : Decl(name) {} - explicit LabelDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {} - - DeclType Type() const override - { - return DeclType::LABEL; - } + explicit LabelDecl(util::StringView name) : TypedDecl(name) {} + explicit LabelDecl(util::StringView name, ir::AstNode *declNode) : TypedDecl(name, declNode) {} }; -class ReadonlyDecl : public Decl { +class ReadonlyDecl : public TypedDecl { public: - explicit ReadonlyDecl(util::StringView name) : Decl(name) {} - explicit ReadonlyDecl(util::StringView name, ir::AstNode *declNode) : Decl(name, declNode) {} - - DeclType Type() const override - { - return DeclType::READONLY; - } + explicit ReadonlyDecl(util::StringView name) : TypedDecl(name) {} + explicit ReadonlyDecl(util::StringView name, ir::AstNode *declNode) : TypedDecl(name, declNode) {} }; -class ParameterDecl : public Decl { +class ParameterDecl : public TypedDecl { public: - explicit ParameterDecl(util::StringView name) : Decl(name) {} - - DeclType Type() const override - { - return DeclType::PARAM; - } + explicit ParameterDecl(util::StringView name) : TypedDecl(name) {} }; -class ImportDecl : public Decl { +class ImportDecl : public TypedDecl { public: explicit ImportDecl(util::StringView importName, util::StringView localName) - : Decl(localName), importName_(importName) + : TypedDecl(localName), importName_(importName) { } explicit ImportDecl(util::StringView importName, util::StringView localName, ir::AstNode *node) - : Decl(localName), importName_(importName) + : TypedDecl(localName), importName_(importName) { BindNode(node); } @@ -351,24 +283,19 @@ public: return name_; } - DeclType Type() const override - { - return DeclType::IMPORT; - } - private: util::StringView importName_; }; -class ExportDecl : public Decl { +class ExportDecl : public TypedDecl { public: explicit ExportDecl(util::StringView exportName, util::StringView localName) - : Decl(localName), exportName_(exportName) + : TypedDecl(localName), exportName_(exportName) { } explicit ExportDecl(util::StringView exportName, util::StringView localName, ir::AstNode *node) - : Decl(localName), exportName_(exportName) + : TypedDecl(localName), exportName_(exportName) { BindNode(node); } @@ -383,11 +310,6 @@ public: return name_; } - DeclType Type() const override - { - return DeclType::EXPORT; - } - private: util::StringView exportName_; }; diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index 6687c0b8c7..0aced523a4 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -48,8 +48,8 @@ VariableScope *Scope::EnclosingVariableScope() Scope *iter = this; while (iter != nullptr) { - if (iter->IsVariableScope()) { - return iter->AsVariableScope(); + if (iter->Is()) { + return iter->As(); } iter = iter->Parent(); @@ -63,8 +63,8 @@ const VariableScope *Scope::EnclosingVariableScope() const const auto *iter = this; while (iter != nullptr) { - if (iter->IsVariableScope()) { - return iter->AsVariableScope(); + if (iter->Is()) { + return iter->As(); } iter = iter->Parent(); @@ -90,8 +90,8 @@ ClassScope *Scope::EnclosingClassScope() Scope *iter = this; while (iter != nullptr) { - if (iter->IsClassScope()) { - return iter->AsClassScope(); + if (iter->Is()) { + return iter->As(); } iter = iter->Parent(); @@ -105,8 +105,8 @@ const ClassScope *Scope::EnclosingClassScope() const const auto *iter = this; while (iter != nullptr) { - if (iter->IsVariableScope()) { - return iter->AsClassScope(); + if (iter->Is()) { + return iter->As(); } iter = iter->Parent(); @@ -173,7 +173,7 @@ ConstScopeFindResult Scope::FindInGlobal(const util::StringView &name, const Res const auto *scopeIter = this; const auto *scopeParent = this->Parent(); // One scope below true global is ETSGLOBAL - while (scopeParent != nullptr && !scopeParent->IsGlobalScope()) { + while (scopeParent != nullptr && !scopeParent->Is()) { scopeIter = scopeParent; scopeParent = scopeIter->Parent(); } @@ -191,8 +191,8 @@ ConstScopeFindResult Scope::FindInGlobal(const util::StringView &name, const Res ConstScopeFindResult Scope::FindInFunctionScope(const util::StringView &name, const ResolveBindingOptions options) const { const auto *scopeIter = this; - while (scopeIter != nullptr && !scopeIter->IsGlobalScope()) { - if (!scopeIter->IsClassScope()) { + while (scopeIter != nullptr && !scopeIter->Is()) { + if (!scopeIter->Is()) { if (auto *const resolved = scopeIter->FindLocal(name, options); resolved != nullptr) { return ConstScopeFindResult(name, scopeIter, 0, 0, resolved); } @@ -255,7 +255,7 @@ Variable *Scope::AddLocalVar(ArenaAllocator *allocator, Decl *newDecl) } VariableFlags varFlags = VariableFlags::HOIST_VAR | VariableFlags::LEXICAL_VAR; - if (scope->IsGlobalScope()) { + if (scope->Is()) { return scope->InsertBinding(newDecl->Name(), allocator->New(newDecl, varFlags)).first->second; } @@ -328,7 +328,7 @@ void VariableScope::CheckDirectEval(public_lib::Context *context) (void)name; var->SetLexical(this); - if (var->LexicalBound() && var->Declaration()->IsConstDecl()) { + if (var->LexicalBound() && var->Declaration()->Is()) { constBindings++; } } @@ -341,7 +341,7 @@ void VariableScope::CheckDirectEval(public_lib::Context *context) continue; } - literals[variable->AsLocalVariable()->LexIdx()] = compiler::Literal(name); + literals[variable->As()->LexIdx()] = compiler::Literal(name); } } else { std::vector bindings(LexicalSlots()); @@ -352,7 +352,7 @@ void VariableScope::CheckDirectEval(public_lib::Context *context) continue; } - bindings[variable->AsLocalVariable()->LexIdx()] = variable; + bindings[variable->As()->LexIdx()] = variable; } uint32_t buffIndex = 0; @@ -362,7 +362,7 @@ void VariableScope::CheckDirectEval(public_lib::Context *context) buffIndex++; continue; } - if (variable->Declaration()->IsConstDecl()) { + if (variable->Declaration()->Is()) { literals[buffIndex++] = compiler::Literal(true); } literals[buffIndex++] = compiler::Literal(variable->Name()); @@ -374,7 +374,7 @@ void VariableScope::CheckDirectEval(public_lib::Context *context) Variable *ParamScope::AddParam(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, VariableFlags flags) { - ASSERT(newDecl->IsParameterDecl()); + ASSERT(newDecl->Is()); if (currentVariable != nullptr) { return nullptr; @@ -656,7 +656,7 @@ Variable *ModuleScope::AddImport(ArenaAllocator *allocator, Variable *currentVar } auto *variable = allocator->New(newDecl, VariableFlags::NONE); - variable->ExoticName() = newDecl->AsImportDecl()->ImportName(); + variable->ExoticName() = newDecl->As()->ImportName(); InsertBinding(newDecl->Name(), variable); return variable; } @@ -701,7 +701,7 @@ bool ModuleScope::ExportAnalysis() return false; } - if (!variable->IsModuleVariable()) { + if (!variable->Is()) { variable->AddFlag(VariableFlags::LOCAL_EXPORT); localExports_.insert({variable, decl->ExportName()}); } @@ -757,7 +757,7 @@ Variable *LocalScope::AddBinding(ArenaAllocator *allocator, Variable *currentVar Variable *LocalScopeWithTypeAlias::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension) { - if (newDecl->IsTypeAliasDecl()) { + if (newDecl->Is()) { auto *ident = newDecl->Node()->AsTSTypeAliasDeclaration()->Id(); auto *var = typeAliasScope_->AddBinding(allocator, currentVariable, newDecl, extension); if (var != nullptr) { @@ -962,7 +962,7 @@ void LoopDeclarationScope::ConvertToVariableScope(ArenaAllocator *allocator) slotIndex_++; loopType_ = ScopeType::LOOP_DECL; - auto *copiedVar = var->AsLocalVariable()->Copy(allocator, var->Declaration()); + auto *copiedVar = var->As()->Copy(allocator, var->Declaration()); copiedVar->AddFlag(VariableFlags::INITIALIZED | VariableFlags::PER_ITERATION); var->AddFlag(VariableFlags::LOOP_DECL); loopScope_->InsertBinding(name, copiedVar); @@ -988,7 +988,7 @@ void LoopScope::ConvertToVariableScope(ArenaAllocator *allocator) for (const auto &[_, var] : Bindings()) { (void)_; - if (var->LexicalBound() && var->Declaration()->IsLetDecl()) { + if (var->LexicalBound() && var->Declaration()->Is()) { ASSERT(declScope_->NeedLexEnv()); loopType_ = ScopeType::LOOP; break; @@ -1010,12 +1010,12 @@ Variable *CatchParamScope::AddBinding(ArenaAllocator *allocator, Variable *curre Variable *CatchScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension) { - if (!newDecl->IsVarDecl() && + if (!newDecl->Is() && (paramScope_->FindLocal(newDecl->Name(), varbinder::ResolveBindingOptions::BINDINGS) != nullptr)) { return nullptr; } - if (newDecl->IsTypeAliasDecl()) { + if (newDecl->Is()) { auto *ident = newDecl->Node()->AsTSTypeAliasDeclaration()->Id(); auto *var = TypeAliasScope()->AddBinding(allocator, currentVariable, newDecl, extension); if (var != nullptr) { diff --git a/ets2panda/varbinder/scope.h b/ets2panda/varbinder/scope.h index 42cebd3e1c..716d67372a 100644 --- a/ets2panda/varbinder/scope.h +++ b/ets2panda/varbinder/scope.h @@ -35,14 +35,12 @@ class IRNode; } // namespace ark::es2panda::compiler namespace ark::es2panda::varbinder { -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DECLARE_CLASSES(type, className) class className; -SCOPE_TYPES(DECLARE_CLASSES) -#undef DECLARE_CLASSES - class Scope; class VariableScope; class Variable; +class FunctionScope; +class FunctionParamScope; +class ClassScope; template && std::is_base_of_v>, bool> = @@ -80,28 +78,23 @@ public: virtual ScopeType Type() const = 0; -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DECLARE_CHECKS_CASTS(scopeType, className) \ - bool Is##className() const \ - { \ - return Type() == ScopeType::scopeType; \ - } \ - className *As##className() \ - { \ - ASSERT(Is##className()); \ - return reinterpret_cast(this); \ - } \ - const className *As##className() const \ - { \ - ASSERT(Is##className()); \ - return reinterpret_cast(this); \ + template + bool Is() const + { + return Type() == T::TYPE; } - SCOPE_TYPES(DECLARE_CHECKS_CASTS) -#undef DECLARE_CHECKS_CASTS - bool IsVariableScope() const + template + const T *As() const { - return Type() > ScopeType::LOCAL; + ASSERT(Is()); + return reinterpret_cast(this); + } + + template + T *As() + { + return const_cast(const_cast(this)->As()); } bool IsFunctionVariableScope() const @@ -121,18 +114,6 @@ public: return reinterpret_cast(this); } - VariableScope *AsVariableScope() - { - ASSERT(IsVariableScope()); - return reinterpret_cast(this); - } - - const VariableScope *AsVariableScope() const - { - ASSERT(IsVariableScope()); - return reinterpret_cast(this); - } - VariableScope *EnclosingVariableScope(); const VariableScope *EnclosingVariableScope() const; @@ -218,8 +199,8 @@ public: Variable *AddDecl(ArenaAllocator *allocator, Decl *decl, [[maybe_unused]] ScriptExtension extension) { decls_.push_back(decl); - auto options = decl->IsTypeAliasDecl() ? varbinder::ResolveBindingOptions::TYPE_ALIASES - : varbinder::ResolveBindingOptions::BINDINGS; + auto options = decl->Is() ? varbinder::ResolveBindingOptions::TYPE_ALIASES + : varbinder::ResolveBindingOptions::BINDINGS; return AddBinding(allocator, FindLocal(decl->Name(), options), decl, extension); } @@ -321,7 +302,7 @@ private: // iter will be the EXACT type of scope with cv-qualifiers auto &&iter = scope; - if (iter->IsFunctionParamScope()) { + if (iter->template Is()) { auto *const v = iter->FindLocal(name, options); if (v != nullptr) { @@ -329,7 +310,7 @@ private: } level++; - const auto *const funcVariableScope = iter->AsFunctionParamScope()->GetFunctionScope(); + const auto *const funcVariableScope = iter->template As()->GetFunctionScope(); if (funcVariableScope != nullptr && funcVariableScope->NeedLexEnv()) { lexLevel++; @@ -345,10 +326,10 @@ private: return {name, iter, level, lexLevel, v}; } - if (iter->IsVariableScope()) { + if (iter->template Is()) { level++; - if (iter->AsVariableScope()->NeedLexEnv()) { + if (iter->template As()->NeedLexEnv()) { lexLevel++; } } @@ -368,6 +349,12 @@ private: const compiler::IRNode *endIns_ {}; }; +template <> +inline bool Scope::Is() const +{ + return Type() > ScopeType::LOCAL; +} + class VariableScope : public Scope { public: ~VariableScope() override = default; @@ -420,9 +407,11 @@ protected: class ParamScope : public Scope { public: + static constexpr auto TYPE = ScopeType::PARAM; + ScopeType Type() const override { - return ScopeType::PARAM; + return TYPE; } ArenaVector &Params() @@ -453,6 +442,8 @@ class FunctionScope; class FunctionParamScope : public ParamScope { public: + static constexpr auto TYPE = ScopeType::FUNCTION_PARAM; + explicit FunctionParamScope(ArenaAllocator *allocator, Scope *parent) : ParamScope(allocator, parent) {} FunctionScope *GetFunctionScope() const @@ -474,7 +465,7 @@ public: ScopeType Type() const override { - return ScopeType::FUNCTION_PARAM; + return TYPE; } Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, @@ -525,12 +516,14 @@ protected: class LocalScope : public Scope { public: + static constexpr auto TYPE = ScopeType::LOCAL; + explicit LocalScope(ArenaAllocator *allocator, Scope *parent) : Scope(allocator, parent) {} explicit LocalScope(ArenaAllocator *allocator, Scope *parent, ScopeFlags flags) : Scope(allocator, parent, flags) {} ScopeType Type() const override { - return ScopeType::LOCAL; + return TYPE; } Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, @@ -571,6 +564,8 @@ private: class FunctionScope : public ScopeWithParamScope { public: + static constexpr auto TYPE = ScopeType::FUNCTION; + explicit FunctionScope(ArenaAllocator *allocator, Scope *parent) : ScopeWithParamScope(allocator, parent), typeAliasScope_(allocator->New(allocator, this, ScopeFlags::TYPE_ALIAS)) @@ -579,7 +574,7 @@ public: ScopeType Type() const override { - return ScopeType::FUNCTION; + return TYPE; } void BindName(util::StringView name) @@ -620,6 +615,8 @@ private: class ClassScope : public LocalScopeWithTypeAlias { public: + static constexpr auto TYPE = ScopeType::CLASS; + explicit ClassScope(ArenaAllocator *allocator, Scope *parent) : LocalScopeWithTypeAlias(allocator, parent), staticDeclScope_(allocator->New(allocator, this, ScopeFlags::STATIC_DECL_SCOPE)), @@ -633,7 +630,7 @@ public: ScopeType Type() const override { - return ScopeType::CLASS; + return TYPE; } LocalScope *StaticDeclScope() @@ -753,11 +750,13 @@ private: class CatchParamScope : public ParamScope { public: + static constexpr auto TYPE = ScopeType::CATCH_PARAM; + explicit CatchParamScope(ArenaAllocator *allocator, Scope *parent) : ParamScope(allocator, parent) {} ScopeType Type() const override { - return ScopeType::CATCH_PARAM; + return TYPE; } Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, @@ -768,11 +767,13 @@ public: class CatchScope : public ScopeWithParamScope { public: + static constexpr auto TYPE = ScopeType::CATCH; + explicit CatchScope(ArenaAllocator *allocator, Scope *parent) : ScopeWithParamScope(allocator, parent) {} ScopeType Type() const override { - return ScopeType::CATCH; + return TYPE; } Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, @@ -783,6 +784,8 @@ class LoopScope; class LoopDeclarationScope : public VariableScope { public: + static constexpr auto TYPE = ScopeType::LOOP_DECL; + explicit LoopDeclarationScope(ArenaAllocator *allocator, Scope *parent) : VariableScope(allocator, parent) {} ScopeType Type() const override @@ -816,6 +819,8 @@ private: class LoopScope : public VariableScope { public: + static constexpr auto TYPE = ScopeType::LOOP; + explicit LoopScope(ArenaAllocator *allocator, Scope *parent) : VariableScope(allocator, parent) {} LoopDeclarationScope *DeclScope() @@ -851,6 +856,8 @@ protected: class GlobalScope : public FunctionScope { public: + static constexpr auto TYPE = ScopeType::GLOBAL; + explicit GlobalScope(ArenaAllocator *allocator) : FunctionScope(allocator, nullptr), foreignBindings_(allocator->Adapter()) { @@ -861,7 +868,7 @@ public: ScopeType Type() const override { - return ScopeType::GLOBAL; + return TYPE; } Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, @@ -891,6 +898,8 @@ public: using ExportDeclList = ArenaVector; using LocalExportNameMap = ArenaMultiMap; + static constexpr auto TYPE = ScopeType::MODULE; + explicit ModuleScope(ArenaAllocator *allocator) : GlobalScope(allocator), allocator_(allocator), @@ -902,7 +911,7 @@ public: ScopeType Type() const override { - return ScopeType::MODULE; + return TYPE; } const ModuleEntry &Imports() const @@ -972,7 +981,7 @@ Variable *VariableScope::AddFunction(ArenaAllocator *allocator, Variable *curren return InsertBinding(newDecl->Name(), allocator->New(newDecl, flags)).first->second; } - if (extension != ScriptExtension::JS || IsModuleScope()) { + if (extension != ScriptExtension::JS || Is()) { return nullptr; } diff --git a/ets2panda/varbinder/varbinder.cpp b/ets2panda/varbinder/varbinder.cpp index b9c9c3e1ef..918d9709d3 100644 --- a/ets2panda/varbinder/varbinder.cpp +++ b/ets2panda/varbinder/varbinder.cpp @@ -75,7 +75,7 @@ void VarBinder::InitTopScope() std::tuple VarBinder::AddParamDecl(ir::AstNode *param) { - ASSERT(scope_->IsFunctionParamScope() || scope_->IsCatchParamScope()); + ASSERT(scope_->Is() || scope_->Is()); auto [decl, node, var] = static_cast(scope_)->AddParamDecl(Allocator(), param); if (node == nullptr) { @@ -170,12 +170,12 @@ bool VarBinder::InstantiateArgumentsImpl(Scope **scope, Scope *iter, const ir::A } auto *argumentsVariable = (*scope)->AddDecl(Allocator(), FUNCTION_ARGUMENTS, VariableFlags::INITIALIZED); - if (iter->IsFunctionParamScope()) { + if (iter->Is()) { if (argumentsVariable == nullptr) { return true; } - *scope = iter->AsFunctionParamScope()->GetFunctionScope(); + *scope = iter->As()->GetFunctionScope(); (*scope)->InsertBinding(argumentsVariable->Name(), argumentsVariable); } @@ -187,11 +187,11 @@ void VarBinder::InstantiateArguments() { auto *iter = scope_; while (true) { - Scope *scope = iter->IsFunctionParamScope() ? iter : iter->EnclosingVariableScope(); + Scope *scope = iter->Is() ? iter : iter->EnclosingVariableScope(); const auto *node = scope->Node(); - if (scope->IsLoopScope()) { + if (scope->Is()) { iter = scope->Parent(); continue; } @@ -213,8 +213,8 @@ void VarBinder::PropagateDirectEval() const auto *iter = scope_; do { - VariableScope *scope = iter->IsFunctionParamScope() ? iter->AsFunctionParamScope()->GetFunctionScope() - : iter->EnclosingVariableScope(); + VariableScope *scope = iter->Is() ? iter->As()->GetFunctionScope() + : iter->EnclosingVariableScope(); scope->AddFlag(ScopeFlags::NO_REG_STORE); iter = iter->Parent(); @@ -379,7 +379,7 @@ void VarBinder::InitializeClassBinding(ir::ClassDefinition *classDef) { auto res = scope_->Find(classDef->Ident()->Name()); - ASSERT(res.variable && res.variable->Declaration()->IsLetDecl()); + ASSERT(res.variable && res.variable->Declaration()->Is()); res.variable->AddFlag(VariableFlags::INITIALIZED); } @@ -388,7 +388,7 @@ void VarBinder::InitializeClassIdent(ir::ClassDefinition *classDef) auto res = scope_->Find(classDef->Ident()->Name()); ASSERT(res.variable && - (res.variable->Declaration()->IsConstDecl() || res.variable->Declaration()->IsReadonlyDecl())); + (res.variable->Declaration()->Is() || res.variable->Declaration()->Is())); res.variable->AddFlag(VariableFlags::INITIALIZED); } @@ -535,103 +535,84 @@ void VarBinder::VisitScriptFunctionWithPotentialTypeParams(ir::ScriptFunction *f VisitScriptFunction(func); } +void VarBinder::ResolveDoWhileStatementReference(ir::DoWhileStatement *doWhileStatement) +{ + { + auto loopScopeCtx = LexicalScope::Enter(this, doWhileStatement->Scope()); + ResolveReference(doWhileStatement->Body()); + } + + ResolveReference(doWhileStatement->Test()); +} + +void VarBinder::ResolveWhileStatementReference(ir::WhileStatement *whileStatement) +{ + ResolveReference(whileStatement->Test()); + + auto loopScopeCtx = LexicalScope::Enter(this, whileStatement->Scope()); + ResolveReference(whileStatement->Body()); +} + +void VarBinder::ResolveIdentifierReference(ir::Identifier *ident) +{ + LookupIdentReference(ident); + ResolveReferences(ident); +} + +void VarBinder::ResolveSuperExpressionReference(ir::AstNode *childNode) +{ + VariableScope *varScope = scope_->EnclosingVariableScope(); + varScope->AddFlag(ScopeFlags::USE_SUPER); + ResolveReferences(childNode); +} + void VarBinder::ResolveReference(ir::AstNode *childNode) { switch (childNode->Type()) { - case ir::AstNodeType::IDENTIFIER: { - auto *ident = childNode->AsIdentifier(); - - LookupIdentReference(ident); - ResolveReferences(childNode); - break; - } - case ir::AstNodeType::SUPER_EXPRESSION: { - VariableScope *varScope = scope_->EnclosingVariableScope(); - varScope->AddFlag(ScopeFlags::USE_SUPER); - ResolveReferences(childNode); - break; - } - case ir::AstNodeType::SCRIPT_FUNCTION: { - VisitScriptFunctionWithPotentialTypeParams(childNode->AsScriptFunction()); - break; - } - case ir::AstNodeType::VARIABLE_DECLARATOR: { - BuildVarDeclarator(childNode->AsVariableDeclarator()); - break; - } - case ir::AstNodeType::CLASS_DEFINITION: { - BuildClassDefinition(childNode->AsClassDefinition()); - break; - } - case ir::AstNodeType::CLASS_PROPERTY: { - BuildClassProperty(childNode->AsClassProperty()); - break; - } + case ir::AstNodeType::IDENTIFIER: + return ResolveIdentifierReference(childNode->AsIdentifier()); + case ir::AstNodeType::SUPER_EXPRESSION: + return ResolveSuperExpressionReference(childNode); + case ir::AstNodeType::SCRIPT_FUNCTION: + return VisitScriptFunctionWithPotentialTypeParams(childNode->AsScriptFunction()); + case ir::AstNodeType::VARIABLE_DECLARATOR: + return BuildVarDeclarator(childNode->AsVariableDeclarator()); + case ir::AstNodeType::CLASS_DEFINITION: + return BuildClassDefinition(childNode->AsClassDefinition()); + case ir::AstNodeType::CLASS_PROPERTY: + return BuildClassProperty(childNode->AsClassProperty()); case ir::AstNodeType::BLOCK_STATEMENT: { auto scopeCtx = LexicalScope::Enter(this, childNode->AsBlockStatement()->Scope()); - - ResolveReferences(childNode); - break; + return ResolveReferences(childNode); } case ir::AstNodeType::BLOCK_EXPRESSION: { auto scopeCtx = LexicalScope::Enter(this, childNode->AsBlockExpression()->Scope()); - - ResolveReferences(childNode); - break; + return ResolveReferences(childNode); } case ir::AstNodeType::SWITCH_STATEMENT: { auto scopeCtx = LexicalScope::Enter(this, childNode->AsSwitchStatement()->Scope()); - - ResolveReferences(childNode); - break; - } - case ir::AstNodeType::DO_WHILE_STATEMENT: { - auto *doWhileStatement = childNode->AsDoWhileStatement(); - - { - auto loopScopeCtx = LexicalScope::Enter(this, doWhileStatement->Scope()); - ResolveReference(doWhileStatement->Body()); - } - - ResolveReference(doWhileStatement->Test()); - break; - } - case ir::AstNodeType::WHILE_STATEMENT: { - auto *whileStatement = childNode->AsWhileStatement(); - ResolveReference(whileStatement->Test()); - - auto loopScopeCtx = LexicalScope::Enter(this, whileStatement->Scope()); - ResolveReference(whileStatement->Body()); - - break; - } - case ir::AstNodeType::FOR_UPDATE_STATEMENT: { - BuildForUpdateLoop(childNode->AsForUpdateStatement()); - break; - } + return ResolveReferences(childNode); + } + case ir::AstNodeType::DO_WHILE_STATEMENT: + return ResolveDoWhileStatementReference(childNode->AsDoWhileStatement()); + case ir::AstNodeType::WHILE_STATEMENT: + return ResolveWhileStatementReference(childNode->AsWhileStatement()); + case ir::AstNodeType::FOR_UPDATE_STATEMENT: + return BuildForUpdateLoop(childNode->AsForUpdateStatement()); case ir::AstNodeType::FOR_IN_STATEMENT: { auto *forInStmt = childNode->AsForInStatement(); - BuildForInOfLoop(forInStmt->Scope(), forInStmt->Left(), forInStmt->Right(), forInStmt->Body()); - - break; + return BuildForInOfLoop(forInStmt->Scope(), forInStmt->Left(), forInStmt->Right(), forInStmt->Body()); } case ir::AstNodeType::FOR_OF_STATEMENT: { auto *forOfStmt = childNode->AsForOfStatement(); - BuildForInOfLoop(forOfStmt->Scope(), forOfStmt->Left(), forOfStmt->Right(), forOfStmt->Body()); - break; - } - case ir::AstNodeType::CATCH_CLAUSE: { - BuildCatchClause(childNode->AsCatchClause()); - break; - } - case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: { - BuildTypeAliasDeclaration(childNode->AsTSTypeAliasDeclaration()); - break; - } - default: { - HandleCustomNodes(childNode); - break; + return BuildForInOfLoop(forOfStmt->Scope(), forOfStmt->Left(), forOfStmt->Right(), forOfStmt->Body()); } + case ir::AstNodeType::CATCH_CLAUSE: + return BuildCatchClause(childNode->AsCatchClause()); + case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: + return BuildTypeAliasDeclaration(childNode->AsTSTypeAliasDeclaration()); + default: + return HandleCustomNodes(childNode); } } @@ -642,15 +623,15 @@ void VarBinder::ResolveReferences(const ir::AstNode *parent) LocalVariable *VarBinder::AddMandatoryParam(const std::string_view &name) { - ASSERT(scope_->IsFunctionParamScope()); + ASSERT(scope_->Is()); auto *decl = Allocator()->New(name); auto *param = Allocator()->New(decl, VariableFlags::VAR); - auto &funcParams = scope_->AsFunctionParamScope()->Params(); + auto &funcParams = scope_->As()->Params(); funcParams.insert(funcParams.begin(), param); - scope_->AsFunctionParamScope()->GetFunctionScope()->InsertBinding(decl->Name(), param); + scope_->As()->GetFunctionScope()->InsertBinding(decl->Name(), param); scope_->InsertBinding(decl->Name(), param); return param; @@ -677,7 +658,7 @@ void VarBinder::AddMandatoryParams() auto iter = functionScopes_.begin(); [[maybe_unused]] auto *funcScope = *iter++; - ASSERT(funcScope->IsGlobalScope() || funcScope->IsModuleScope()); + ASSERT(funcScope->Is() || funcScope->Is()); const auto &options = context_->config->options->CompilerOptions(); if (options.isDirectEval) { diff --git a/ets2panda/varbinder/varbinder.h b/ets2panda/varbinder/varbinder.h index fcd83bcdaa..3bde756341 100644 --- a/ets2panda/varbinder/varbinder.h +++ b/ets2panda/varbinder/varbinder.h @@ -256,6 +256,11 @@ protected: virtual void AddCompilableFunction(ir::ScriptFunction *func); private: + void ResolveDoWhileStatementReference(ir::DoWhileStatement *doWhileStatement); + void ResolveWhileStatementReference(ir::WhileStatement *whileStatement); + void ResolveIdentifierReference(ir::Identifier *ident); + void ResolveSuperExpressionReference(ir::AstNode *childNode); + parser::Program *program_ {}; ArenaAllocator *allocator_ {}; public_lib::Context *context_ {}; @@ -307,13 +312,13 @@ public: varbinder->varScope_->CheckDirectEval(varbinder->context_); // NOLINTNEXTLINE(readability-braces-around-statements,readability-misleading-indentation) } else if constexpr (std::is_same_v) { - if (scope->IsLoopScope()) { + if (scope->template Is()) { varbinder->varScope_ = scope; varbinder->varScope_->CheckDirectEval(varbinder->context_); } // NOLINTNEXTLINE(readability-braces-around-statements,readability-misleading-indentation) } else if constexpr (std::is_same_v) { - if (scope->IsLoopDeclarationScope()) { + if (scope->template Is()) { varbinder->varScope_ = scope; varbinder->varScope_->CheckDirectEval(varbinder->context_); } diff --git a/ets2panda/varbinder/variable.cpp b/ets2panda/varbinder/variable.cpp index d845860a74..568462d4a6 100644 --- a/ets2panda/varbinder/variable.cpp +++ b/ets2panda/varbinder/variable.cpp @@ -20,14 +20,14 @@ #include namespace ark::es2panda::varbinder { -LocalVariable::LocalVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) +LocalVariable::LocalVariable(Decl *decl, VariableFlags flags) : TypedVariable(decl, flags) { - if (decl->IsConstDecl() || decl->IsReadonlyDecl()) { + if (decl->Is() || decl->Is()) { flags_ |= VariableFlags::READONLY; } } -LocalVariable::LocalVariable(VariableFlags flags) : Variable(flags) {} +LocalVariable::LocalVariable(VariableFlags flags) : TypedVariable(flags) {} const util::StringView &Variable::Name() const { diff --git a/ets2panda/varbinder/variable.h b/ets2panda/varbinder/variable.h index ce9600fb3d..e8f47969d3 100644 --- a/ets2panda/varbinder/variable.h +++ b/ets2panda/varbinder/variable.h @@ -34,11 +34,6 @@ class Decl; class Scope; class VariableScope; -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DECLARE_CLASSES(type, className) class className; -VARIABLE_TYPES(DECLARE_CLASSES) -#undef DECLARE_CLASSES - class Variable { public: virtual ~Variable() = default; @@ -47,24 +42,24 @@ public: VariableType virtual Type() const = 0; -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DECLARE_CHECKS_CASTS(variableType, className) \ - bool Is##className() const \ - { \ - return Type() == VariableType::variableType; \ - } \ - className *As##className() \ - { \ - ASSERT(Is##className()); \ - return reinterpret_cast(this); \ - } \ - const className *As##className() const \ - { \ - ASSERT(Is##className()); \ - return reinterpret_cast(this); \ + template + bool Is() const + { + return Type() == T::TYPE; + } + + template + const T *As() const + { + ASSERT(Is()); + return reinterpret_cast(this); + } + + template + T *As() + { + return const_cast(const_cast(this)->As()); } - VARIABLE_TYPES(DECLARE_CHECKS_CASTS) -#undef DECLARE_CHECKS_CASTS [[nodiscard]] const Decl *Declaration() const noexcept { @@ -144,16 +139,25 @@ private: Scope *scope_ {}; }; -class LocalVariable : public Variable { +template +class TypedVariable : public Variable { public: - explicit LocalVariable(Decl *decl, VariableFlags flags); - explicit LocalVariable(VariableFlags flags); + static constexpr VariableType TYPE = V; VariableType Type() const override { - return VariableType::LOCAL; + return TYPE; } +protected: + using Variable::Variable; +}; + +class LocalVariable : public TypedVariable { +public: + explicit LocalVariable(Decl *decl, VariableFlags flags); + explicit LocalVariable(VariableFlags flags); + void BindVReg(compiler::VReg vreg) { ASSERT(!LexicalBound()); @@ -190,26 +194,16 @@ private: compiler::VReg vreg_ {}; }; -class GlobalVariable : public Variable { +class GlobalVariable : public TypedVariable { public: - explicit GlobalVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {} - - VariableType Type() const override - { - return VariableType::GLOBAL; - } + explicit GlobalVariable(Decl *decl, VariableFlags flags) : TypedVariable(decl, flags) {} void SetLexical([[maybe_unused]] Scope *scope) override; }; -class ModuleVariable : public Variable { +class ModuleVariable : public TypedVariable { public: - explicit ModuleVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) {} - - VariableType Type() const override - { - return VariableType::MODULE; - } + explicit ModuleVariable(Decl *decl, VariableFlags flags) : TypedVariable(decl, flags) {} compiler::VReg &ModuleReg() { @@ -238,16 +232,11 @@ private: util::StringView exoticName_ {}; }; -class EnumVariable : public Variable { +class EnumVariable : public TypedVariable { public: explicit EnumVariable(Decl *decl, bool backReference = false) - : Variable(decl, VariableFlags::NONE), backReference_(backReference) - { - } - - VariableType Type() const override + : TypedVariable(decl, VariableFlags::NONE), backReference_(backReference) { - return VariableType::ENUM; } void SetValue(EnumMemberResult value) diff --git a/ets2panda/varbinder/variableFlags.h b/ets2panda/varbinder/variableFlags.h index b4dabdd82e..34016ae467 100644 --- a/ets2panda/varbinder/variableFlags.h +++ b/ets2panda/varbinder/variableFlags.h @@ -20,58 +20,44 @@ #include "util/enumbitops.h" namespace ark::es2panda::varbinder { -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DECLARATION_KINDS(_) \ - _(VAR, VarDecl) \ - _(LET, LetDecl) \ - _(CONST, ConstDecl) \ - _(LABEL, LabelDecl) \ - _(READONLY, ReadonlyDecl) \ - _(FUNC, FunctionDecl) \ - _(PARAM, ParameterDecl) \ - _(IMPORT, ImportDecl) \ - _(DYNAMIC_IMPORT, DynamicImportDecl) \ - _(EXPORT, ExportDecl) \ - /* TS */ \ - _(TYPE_ALIAS, TypeAliasDecl) \ - _(NAMESPACE, NameSpaceDecl) \ - _(INTERFACE, InterfaceDecl) \ - _(ENUM_LITERAL, EnumLiteralDecl) \ - _(TYPE_PARAMETER, TypeParameterDecl) \ - _(PROPERTY, PropertyDecl) \ - _(CLASS, ClassDecl) \ - _(METHOD, MethodDecl) \ - _(ENUM, EnumDecl) - enum class DeclType { NONE, -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DECLARE_TYPES(decl_kind, class_name) decl_kind, - DECLARATION_KINDS(DECLARE_TYPES) -#undef DECLARE_TYPES + VAR, + LET, + CONST, + LABEL, + READONLY, + FUNC, + PARAM, + IMPORT, + DYNAMIC_IMPORT, + EXPORT, + // TS + TYPE_ALIAS, + NAMESPACE, + INTERFACE, + ENUM_LITERAL, + TYPE_PARAMETER, + PROPERTY, + CLASS, + METHOD, + ENUM, }; -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define SCOPE_TYPES(_) \ - _(PARAM, ParamScope) \ - _(CATCH_PARAM, CatchParamScope) \ - _(FUNCTION_PARAM, FunctionParamScope) \ - _(CATCH, CatchScope) \ - _(CLASS, ClassScope) \ - _(LOCAL, LocalScope) \ - _(LOCAL_WITH_ALIAS, LocalScopeWithTypeAlias) \ - /* Variable Scopes */ \ - _(LOOP, LoopScope) \ - _(LOOP_DECL, LoopDeclarationScope) \ - _(FUNCTION, FunctionScope) \ - _(GLOBAL, GlobalScope) \ - _(MODULE, ModuleScope) - enum class ScopeType { -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define GEN_SCOPE_TYPES(type, class_name) type, - SCOPE_TYPES(GEN_SCOPE_TYPES) -#undef GEN_SCOPE_TYPES + PARAM, + CATCH_PARAM, + FUNCTION_PARAM, + CATCH, + CLASS, + LOCAL, + LOCAL_WITH_ALIAS, + // Variable Scopes + LOOP, + LOOP_DECL, + FUNCTION, + GLOBAL, + MODULE, }; using ENUMBITOPS_OPERATORS; @@ -97,18 +83,11 @@ enum class ResolveBindingOptions : uint32_t { ALL_NON_TYPE = ALL - TYPE_ALIASES, }; -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define VARIABLE_TYPES(_) \ - _(LOCAL, LocalVariable) \ - _(GLOBAL, GlobalVariable) \ - _(MODULE, ModuleVariable) \ - _(ENUM, EnumVariable) - enum class VariableType { -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define GEN_VARIABLE_TYPES(type, class_name) type, - VARIABLE_TYPES(GEN_VARIABLE_TYPES) -#undef GEN_VARIABLE_TYPES + LOCAL, + GLOBAL, + MODULE, + ENUM, }; enum class VariableKind { -- Gitee