diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 810934b8e53e9efea986fc479d2259ee75030a99..47c8202283b428b9c3f53ebbcf9e96de107a6e6e 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -259,11 +259,16 @@ void CheckGetterSetterTypeConstrains(ETSChecker *checker, ir::ScriptFunction *sc checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const { ETSChecker *checker = GetETSChecker(); + auto *scriptFunc = node->Function(); if (scriptFunc->IsProxy()) { return nullptr; } + if (node->Id()->Variable() == nullptr) { + node->Id()->SetVariable(scriptFunc->Id()->Variable()); + } + // NOTE: aszilagyi. make it correctly check for open function not have body if (!scriptFunc->HasBody() && !(node->IsAbstract() || node->IsNative() || node->IsDeclare() || checker->HasStatus(checker::CheckerStatus::IN_INTERFACE))) { @@ -564,7 +569,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const auto *signature = checker->ResolveConstructExpression(calleeObj, expr->GetArguments(), expr->Start()); checker->CheckObjectLiteralArguments(signature, expr->GetArguments()); - checker->AddUndefinedParamsForDefaultParams(signature, expr->arguments_, checker); + checker->AddUndefinedParamsForDefaultParams(signature, expr, expr->arguments_, checker); checker->ValidateSignatureAccessibility(calleeObj, nullptr, signature, expr->Start()); @@ -923,10 +928,19 @@ static checker::Type *InitAnonymousLambdaCallee(checker::ETSChecker *checker, ir checker::Type *calleeType) { auto *const arrowFunc = callee->AsArrowFunctionExpression()->Function(); - auto origParams = arrowFunc->Params(); - auto signature = ir::FunctionSignature(nullptr, std::move(origParams), arrowFunc->ReturnTypeAnnotation()); - auto *funcType = - checker->Allocator()->New(std::move(signature), ir::ScriptFunctionFlags::NONE); + + ArenaVector params {checker->Allocator()->Adapter()}; + checker->CopyParams(arrowFunc->Params(), params); + + auto *typeAnnotation = arrowFunc->ReturnTypeAnnotation(); + if (typeAnnotation != nullptr) { + typeAnnotation = typeAnnotation->Clone(checker->Allocator(), nullptr); + typeAnnotation->SetTsType(arrowFunc->ReturnTypeAnnotation()->TsType()); + } + + 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()); auto *const funcIface = funcType->Check(checker); checker->Relation()->SetNode(callee); @@ -1087,7 +1101,7 @@ checker::Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, checker::Typ ResolveSignature(checker, expr, calleeType, isFunctionalInterface, isUnionTypeWithFunctionalInterface); checker->CheckObjectLiteralArguments(signature, expr->Arguments()); - checker->AddUndefinedParamsForDefaultParams(signature, expr->Arguments(), checker); + checker->AddUndefinedParamsForDefaultParams(signature, expr, expr->Arguments(), checker); if (!isFunctionalInterface) { checker::ETSObjectType *calleeObj = ChooseCalleeObj(checker, expr, calleeType, isConstructorCall); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index e909286f9379778b42a2def9136e029356ee7fb0..85a5ce781e9f56fd19bcb7e6f9732f171a5b9978 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -17,7 +17,6 @@ #define ES2PANDA_CHECKER_ETS_CHECKER_H #include "checker/checkerContext.h" -#include "varbinder/enumMemberResult.h" #include "varbinder/scope.h" #include "checker/checker.h" #include "checker/ets/primitiveWrappers.h" @@ -29,18 +28,8 @@ #include "ir/ts/tsTypeParameter.h" #include "ir/ts/tsTypeParameterInstantiation.h" #include "lexer/token/tokenType.h" -#include "util/enumbitops.h" #include "util/ustring.h" -#include "utils/bit_utils.h" #include "checker/resolveResult.h" -#include "macros.h" - -#include -#include -#include -#include -#include -#include namespace panda::es2panda::varbinder { class VarBinder; @@ -397,7 +386,8 @@ public: ArenaVector ¶ms, const lexer::SourceRange &pos, bool isStaticReference); ir::MethodDefinition *CreateLambdaInvokeProto(); void CreateLambdaFuncDecl(ir::MethodDefinition *func, varbinder::LocalScope *scope); - void ResolveProxyMethod(ir::MethodDefinition *proxyMethod, ir::ArrowFunctionExpression *lambda); + void ResolveProxyMethod(ir::ClassDefinition *classDefinition, ir::MethodDefinition *proxyMethod, + ir::ArrowFunctionExpression *lambda); void ResolveLambdaObject(ir::ClassDefinition *lambdaObject, Signature *signature, ETSObjectType *functionalInterface, ir::AstNode *refNode); void ResolveLambdaObject(ir::ClassDefinition *lambdaObject, ETSObjectType *functionalInterface, @@ -539,7 +529,7 @@ public: util::StringView GetHashFromSubstitution(const Substitution *substitution); ETSObjectType *GetOriginalBaseType(Type *object); Type *GetTypeFromTypeAnnotation(ir::TypeNode *typeAnnotation); - void AddUndefinedParamsForDefaultParams(const Signature *signature, + void AddUndefinedParamsForDefaultParams(const Signature *signature, ir::AstNode *parent, ArenaVector &arguments, ETSChecker *checker); void SetArrayPreferredTypeForNestedMemberExpressions(ir::MemberExpression *expr, Type *annotationType); @@ -576,6 +566,8 @@ public: ETSEnumInterface *enumType); [[nodiscard]] ETSEnumType::Method CreateEnumValuesMethod(ir::Identifier *itemsArrayIdent, ETSEnumInterface *enumType); + [[nodiscard]] ir::StringLiteral *CreateEnumStringLiteral(ETSEnumInterface *const enumType, + const ir::TSEnumMember *const member); // Dynamic interop template @@ -635,6 +627,11 @@ private: PropertySearchFlags GetInitialSearchFlags(const ir::MemberExpression *memberExpr); const varbinder::Variable *GetTargetRef(const ir::MemberExpression *memberExpr); void BuildClass(util::StringView name, const ClassBuilder &builder); + + template + std::pair CreateScriptFunction(varbinder::FunctionScope *scope, + ClassInitializerBuilder const &builder); + template std::conditional_t CreateClassInitializer( varbinder::ClassScope *classScope, const ClassInitializerBuilder &builder, ETSObjectType *type = nullptr); @@ -643,9 +640,8 @@ private: checker::Type *type); template - ir::MethodDefinition *CreateClassMethod(varbinder::ClassScope *classScope, std::string_view methodName, - panda::es2panda::ir::ModifierFlags modifierFlags, - const MethodBuilder &builder); + ir::MethodDefinition *CreateClassMethod(varbinder::ClassScope *classScope, std::string_view name, + ir::ModifierFlags modifierFlags, const MethodBuilder &builder); template ir::ScriptFunction *CreateDynamicCallIntrinsic(ir::Expression *callee, const ArenaVector &arguments, @@ -663,6 +659,8 @@ private: Signature *invokeSignature, ir::TypeNode *retTypeAnnotation); + void ClassInitializerFromImport(ir::ETSImportDeclaration *import, varbinder::FunctionScope *scope, + ArenaVector *statements); void EmitDynamicModuleClassInitCall(); DynamicCallIntrinsicsMap *DynamicCallIntrinsics(bool isConstruct) diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index c0037fea918477ea3dbf1bd09d75bdbb005f7310..cb5a6a6225b3fd1187218ed79d4d700b9ed3445e 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include #include "checker/ETSchecker.h" #include "varbinder/scope.h" @@ -85,7 +86,6 @@ template ir::ScriptFunction *ETSChecker::CreateDynamicCallIntrinsic(ir::Expression *callee, const ArenaVector &arguments, Language lang) { - auto *name = AllocNode("invoke", Allocator()); auto *paramScope = Allocator()->New(Allocator(), nullptr); auto *scope = Allocator()->New(Allocator(), paramScope); @@ -119,9 +119,9 @@ ir::ScriptFunction *ETSChecker::CreateDynamicCallIntrinsic(ir::Expression *calle info->params.push_back(param->Ident()->Variable()->AsLocalVariable()); } - auto *func = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), nullptr, - ir::ScriptFunctionFlags::METHOD, ir::ModifierFlags::NONE, false, - Language(Language::Id::ETS)); + auto *func = AllocNode( + ir::FunctionSignature(nullptr, std::move(params), nullptr), nullptr, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::METHOD, ir::ModifierFlags::NONE}); func->SetScope(scope); scope->BindNode(func); @@ -129,6 +129,7 @@ ir::ScriptFunction *ETSChecker::CreateDynamicCallIntrinsic(ir::Expression *calle scope->BindParamScope(paramScope); paramScope->BindFunctionScope(scope); + auto *name = AllocNode("invoke", Allocator()); func->SetIdent(name); auto *signature = CreateSignature(info, dynamicType, func); @@ -197,50 +198,60 @@ template Signature *ETSChecker::ResolveDynamicCallExpression &arguments, Language lang, bool is_construct); template -std::conditional_t ETSChecker::CreateClassInitializer( - varbinder::ClassScope *classScope, const ClassInitializerBuilder &builder, ETSObjectType *type) +std::pair ETSChecker::CreateScriptFunction( + varbinder::FunctionScope *scope, ClassInitializerBuilder const &builder) { - varbinder::LocalScope *methodScope = nullptr; - if constexpr (IS_STATIC) { - methodScope = classScope->StaticMethodScope(); - } else { - methodScope = classScope->InstanceMethodScope(); - } - auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), methodScope); - - ArenaVector params(Allocator()->Adapter()); - - auto *paramScope = Allocator()->New(Allocator(), classScope); - auto *scope = Allocator()->New(Allocator(), paramScope); - ArenaVector statements(Allocator()->Adapter()); + ArenaVector params(Allocator()->Adapter()); - ir::ScriptFunction *func = nullptr; - ir::Identifier *id = nullptr; + ir::ScriptFunction *func; + ir::Identifier *id; if constexpr (IS_STATIC) { builder(scope, &statements, nullptr); auto *body = AllocNode(Allocator(), std::move(statements)); body->SetScope(scope); id = AllocNode(compiler::Signatures::CCTOR, Allocator()); - func = - AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::STATIC_BLOCK | ir::ScriptFunctionFlags::EXPRESSION, - ir::ModifierFlags::STATIC, false, Language(Language::Id::ETS)); - func->SetScope(scope); + func = AllocNode( + ir::FunctionSignature(nullptr, std::move(params), nullptr), body, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::STATIC_BLOCK | + ir::ScriptFunctionFlags::EXPRESSION, + ir::ModifierFlags::STATIC}); } else { builder(scope, &statements, ¶ms); auto *body = AllocNode(Allocator(), std::move(statements)); body->SetScope(scope); id = AllocNode(compiler::Signatures::CTOR, Allocator()); - func = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::CONSTRUCTOR | ir::ScriptFunctionFlags::EXPRESSION, - ir::ModifierFlags::PUBLIC, false, Language(Language::Id::ETS)); - func->SetScope(scope); + func = AllocNode( + ir::FunctionSignature(nullptr, std::move(params), nullptr), body, + ir::ScriptFunction::ScriptFunctionData { + ir::ScriptFunctionFlags::CONSTRUCTOR | ir::ScriptFunctionFlags::EXPRESSION, ir::ModifierFlags::PUBLIC}); } + func->SetScope(scope); scope->BindNode(func); func->SetIdent(id); + + return std::make_pair(func, id); +} + +template +std::conditional_t ETSChecker::CreateClassInitializer( + varbinder::ClassScope *classScope, const ClassInitializerBuilder &builder, ETSObjectType *type) +{ + varbinder::LocalScope *methodScope = nullptr; + if constexpr (IS_STATIC) { + methodScope = classScope->StaticMethodScope(); + } else { + methodScope = classScope->InstanceMethodScope(); + } + auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), methodScope); + + auto *paramScope = Allocator()->New(Allocator(), classScope); + auto *scope = Allocator()->New(Allocator(), paramScope); + + auto [func, id] = CreateScriptFunction(scope, builder); + paramScope->BindNode(func); scope->BindParamScope(paramScope); paramScope->BindFunctionScope(scope); @@ -263,12 +274,11 @@ std::conditional_t ET } else { type->AddConstructSignature(signature); - auto *ctor = Allocator()->New(ir::MethodDefinitionKind::CONSTRUCTOR, id, funcExpr, - ir::ModifierFlags::NONE, Allocator(), false); + auto *ctor = + AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, id->Clone(Allocator(), nullptr), + funcExpr, ir::ModifierFlags::NONE, Allocator(), false); auto *funcType = CreateETSFunctionType(signature, id->Name()); ctor->SetTsType(funcType); - funcExpr->SetParent(classScope->Node()->AsClassDeclaration()->Definition()); - func->SetParent(ctor); return ctor; } } @@ -371,10 +381,10 @@ void ETSChecker::BuildDynamicCallClass(bool isConstruct) auto *funcExpr = AllocNode(func); - auto *method = AllocNode(ir::MethodDefinitionKind::METHOD, func->Id(), funcExpr, - ir::ModifierFlags::PUBLIC | ir::ModifierFlags::NATIVE | - ir::ModifierFlags::STATIC, - Allocator(), false); + auto *method = AllocNode( + ir::MethodDefinitionKind::METHOD, func->Id()->Clone(Allocator(), nullptr), funcExpr, + ir::ModifierFlags::PUBLIC | ir::ModifierFlags::NATIVE | ir::ModifierFlags::STATIC, Allocator(), + false); VarBinder()->AsETSBinder()->BuildInternalName(func); VarBinder()->AsETSBinder()->BuildFunctionName(func); @@ -387,56 +397,69 @@ void ETSChecker::BuildDynamicCallClass(bool isConstruct) } } -ir::ClassStaticBlock *ETSChecker::CreateDynamicModuleClassInitializer( - varbinder::ClassScope *classScope, const std::vector &imports) +void ETSChecker::ClassInitializerFromImport(ir::ETSImportDeclaration *import, varbinder::FunctionScope *scope, + ArenaVector *statements) { - return CreateClassInitializer( - classScope, [this, imports](varbinder::FunctionScope *scope, ArenaVector *statements, - [[maybe_unused]] ArenaVector *params) { - for (auto *import : imports) { - auto builtin = compiler::Signatures::Dynamic::LoadModuleBuiltin(import->Language()); - auto [builtin_class_name, builtin_method_name] = util::Helpers::SplitSignature(builtin); + auto builtin = compiler::Signatures::Dynamic::LoadModuleBuiltin(import->Language()); + auto [builtin_class_name, builtin_method_name] = util::Helpers::SplitSignature(builtin); - auto *classId = AllocNode(builtin_class_name, Allocator()); - auto *methodId = AllocNode(builtin_method_name, Allocator()); - auto *callee = AllocNode(classId, methodId, - ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *classId = AllocNode(builtin_class_name, Allocator()); + auto *methodId = AllocNode(builtin_method_name, Allocator()); + auto *callee = + AllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - ArenaVector callParams(Allocator()->Adapter()); - callParams.push_back(import->ResolvedSource()); + ArenaVector callParams(Allocator()->Adapter()); + callParams.push_back(import->ResolvedSource()); - auto *loadCall = AllocNode(callee, std::move(callParams), nullptr, false); + auto *loadCall = AllocNode(callee, std::move(callParams), nullptr, false); - auto *moduleClassId = - AllocNode(compiler::Signatures::DYNAMIC_MODULE_CLASS, Allocator()); - auto *fieldId = AllocNode(import->AssemblerName(), Allocator()); - auto *property = AllocNode( - moduleClassId, fieldId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *moduleClassId = AllocNode(compiler::Signatures::DYNAMIC_MODULE_CLASS, Allocator()); + auto *fieldId = AllocNode(import->AssemblerName(), Allocator()); + auto *property = AllocNode(moduleClassId, fieldId, ir::MemberExpressionKind::PROPERTY_ACCESS, + false, false); - auto *initializer = - AllocNode(property, loadCall, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + auto *initializer = + AllocNode(property, loadCall, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - { - ScopeContext ctx(this, scope); - initializer->Check(this); - } + { + ScopeContext ctx(this, scope); + initializer->Check(this); + } + statements->push_back(AllocNode(initializer)); +} - statements->push_back(AllocNode(initializer)); +ir::ClassStaticBlock *ETSChecker::CreateDynamicModuleClassInitializer( + varbinder::ClassScope *classScope, const std::vector &imports) +{ + return CreateClassInitializer( + classScope, [this, imports](varbinder::FunctionScope *scope, ArenaVector *statements, + [[maybe_unused]] ArenaVector *params) { + for (auto *import : imports) { + ClassInitializerFromImport(import, scope, statements); } }); } template -ir::MethodDefinition *ETSChecker::CreateClassMethod(varbinder::ClassScope *classScope, - const std::string_view methodName, - panda::es2panda::ir::ModifierFlags modifierFlags, - const MethodBuilder &builder) +static void AddMethodToClass(varbinder::ClassScope *classScope, varbinder::Variable *methodVar) +{ + auto *classType = classScope->Node()->AsClassDeclaration()->Definition()->TsType()->AsETSObjectType(); + if constexpr (IS_STATIC) { + classType->AddProperty(methodVar->AsLocalVariable()); + } else { + classType->AddProperty(methodVar->AsLocalVariable()); + } +} + +template +ir::MethodDefinition *ETSChecker::CreateClassMethod(varbinder::ClassScope *classScope, const std::string_view name, + ir::ModifierFlags modifierFlags, const MethodBuilder &builder) { auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), classScope->StaticMethodScope()); ArenaVector params(Allocator()->Adapter()); auto *paramScope = Allocator()->New(Allocator(), classScope); auto *scope = Allocator()->New(Allocator(), paramScope); - auto *id = AllocNode(methodName, Allocator()); + auto *id = AllocNode(name, Allocator()); ArenaVector statements(Allocator()->Adapter()); Type *returnType = nullptr; @@ -446,9 +469,10 @@ ir::MethodDefinition *ETSChecker::CreateClassMethod(varbinder::ClassScope *class auto *body = AllocNode(Allocator(), std::move(statements)); body->SetScope(scope); - auto *func = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::METHOD, modifierFlags, false, - Language(Language::Id::ETS)); + auto *func = AllocNode( + ir::FunctionSignature(nullptr, std::move(params), nullptr), body, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::METHOD, modifierFlags}); + func->SetScope(scope); scope->BindNode(func); func->SetIdent(id); @@ -465,8 +489,9 @@ ir::MethodDefinition *ETSChecker::CreateClassMethod(varbinder::ClassScope *class func->SetSignature(signature); auto *funcExpr = AllocNode(func); - auto *method = AllocNode(ir::MethodDefinitionKind::METHOD, func->Id(), funcExpr, - modifierFlags, Allocator(), false); + auto *method = + AllocNode(ir::MethodDefinitionKind::METHOD, func->Id()->Clone(Allocator(), nullptr), + funcExpr, modifierFlags, Allocator(), false); VarBinder()->AsETSBinder()->BuildInternalName(func); VarBinder()->AsETSBinder()->BuildFunctionName(func); @@ -481,13 +506,9 @@ ir::MethodDefinition *ETSChecker::CreateClassMethod(varbinder::ClassScope *class method->SetTsType(funcType); var->AddFlag(varbinder::VariableFlags::PROPERTY); func->Id()->SetVariable(var); + method->Id()->SetVariable(var); - auto *classType = classScope->Node()->AsClassDeclaration()->Definition()->TsType()->AsETSObjectType(); - if constexpr (IS_STATIC) { - classType->AddProperty(var->AsLocalVariable()); - } else { - classType->AddProperty(var->AsLocalVariable()); - } + AddMethodToClass(classScope, var); return method; } @@ -524,12 +545,12 @@ ir::MethodDefinition *ETSChecker::CreateLambdaObjectClassInvokeMethod(varbinder: scope->Parent()->AsFunctionParamScope(), util::UString(std::string("p") + std::to_string(idx), Allocator()).View(), invokeParam->TsType()); params->push_back(param); - callParams.push_back(param); + callParams.push_back(param->Clone(Allocator(), nullptr)); ++idx; } auto *properyId = AllocNode("jsvalue_lambda", Allocator()); - auto *callee = AllocNode(thisParam, properyId, + auto *callee = AllocNode(thisParam->Clone(Allocator(), nullptr), properyId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); auto *callLambda = AllocNode(callee, std::move(callParams), nullptr, false); @@ -538,9 +559,10 @@ ir::MethodDefinition *ETSChecker::CreateLambdaObjectClassInvokeMethod(varbinder: callLambda->Check(this); } - auto *castToRetTypeExpr = Allocator()->New(callLambda, retTypeAnnotation, false); + auto *castToRetTypeExpr = + AllocNode(callLambda, retTypeAnnotation->Clone(Allocator(), nullptr), false); castToRetTypeExpr->SetTsType(invokeSignature->ReturnType()); - auto *retStatement = Allocator()->New(castToRetTypeExpr); + auto *retStatement = AllocNode(castToRetTypeExpr); statements->push_back(retStatement); *returnType = invokeSignature->ReturnType(); @@ -571,7 +593,9 @@ void ETSChecker::EmitDynamicModuleClassInitCall() initCall->Check(this); } - cctorBody->Statements().push_back(AllocNode(initCall)); + auto *const node = AllocNode(initCall); + node->SetParent(cctorBody); + cctorBody->Statements().push_back(node); } void ETSChecker::BuildDynamicImportClass() @@ -653,8 +677,8 @@ ir::MethodDefinition *ETSChecker::CreateLambdaObjectClassInitializer(varbinder:: auto *fieldId = AllocNode("jsvalue_lambda", Allocator()); auto *property = AllocNode(moduleClassId, fieldId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - auto *initializer = - AllocNode(property, jsvalueParam, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + auto *initializer = AllocNode(property, jsvalueParam->Clone(Allocator(), nullptr), + lexer::TokenType::PUNCTUATOR_SUBSTITUTION); { ScopeContext ctx(this, scope); initializer->Check(this); diff --git a/ets2panda/checker/ets/enum.cpp b/ets2panda/checker/ets/enum.cpp index f9a116f3f27bc4e043e692519b5df6cf72ed1623..08cd8263a67d0b4c1173373c246fa94eaeba65ae 100644 --- a/ets2panda/checker/ets/enum.cpp +++ b/ets2panda/checker/ets/enum.cpp @@ -65,16 +65,16 @@ void AppendParentNames(util::UString &qualifiedName, const ir::AstNode *const no } } -[[nodiscard]] ir::Identifier *MakeQualifiedIdentifier(panda::ArenaAllocator *const allocator, +[[nodiscard]] ir::Identifier *MakeQualifiedIdentifier(ETSChecker *const checker, const ir::TSEnumDeclaration *const enumDecl, const util::StringView &name) { - util::UString qualifiedName(util::StringView("#"), allocator); + util::UString qualifiedName(util::StringView("#"), checker->Allocator()); AppendParentNames(qualifiedName, enumDecl->Parent()); qualifiedName.Append(enumDecl->Key()->Name()); qualifiedName.Append('#'); qualifiedName.Append(name); - return allocator->New(qualifiedName.View(), allocator); + return checker->AllocNode(qualifiedName.View(), checker->Allocator()); } template @@ -88,13 +88,13 @@ template elements.push_back(elementMaker(member->AsTSEnumMember())); } - auto *const arrayExpr = checker->Allocator()->New(std::move(elements), checker->Allocator()); + auto *const arrayExpr = checker->AllocNode(std::move(elements), checker->Allocator()); arrayExpr->SetPreferredType(elementType); arrayExpr->SetTsType(checker->CreateETSArrayType(elementType)); - auto *const arrayIdent = MakeQualifiedIdentifier(checker->Allocator(), enumType->GetDecl(), name); + auto *const arrayIdent = MakeQualifiedIdentifier(checker, enumType->GetDecl(), name); - auto *const arrayClassProp = checker->Allocator()->New( + auto *const arrayClassProp = checker->AllocNode( arrayIdent, arrayExpr, nullptr, ir::ModifierFlags::STATIC | ir::ModifierFlags::PUBLIC | ir::ModifierFlags::CONST, checker->Allocator(), false); arrayClassProp->SetTsType(arrayExpr->TsType()); @@ -118,8 +118,8 @@ template const util::StringView &name, Type *const type) { const auto paramCtx = varbinder::LexicalScope::Enter(varbinder, scope, false); - auto *const paramIdent = checker->Allocator()->New(name, checker->Allocator()); - auto *const param = checker->Allocator()->New(paramIdent, nullptr); + auto *const paramIdent = checker->AllocNode(name, checker->Allocator()); + auto *const param = checker->AllocNode(paramIdent, nullptr); auto *const paramVar = std::get<1>(varbinder->AddParamDecl(param)); paramVar->SetTsType(type); param->Ident()->SetVariable(paramVar); @@ -128,11 +128,11 @@ template return param; } -[[nodiscard]] ir::ETSTypeReference *MakeTypeReference(panda::ArenaAllocator *allocator, const util::StringView &name) +[[nodiscard]] ir::ETSTypeReference *MakeTypeReference(ETSChecker *const checker, const util::StringView &name) { - auto *const ident = allocator->New(name, allocator); - auto *const referencePart = allocator->New(ident); - return allocator->New(referencePart); + auto *const ident = checker->AllocNode(name, checker->Allocator()); + auto *const referencePart = checker->AllocNode(ident); + return checker->AllocNode(referencePart); } [[nodiscard]] ir::ScriptFunction *MakeFunction(ETSChecker *const checker, varbinder::ETSBinder *const varbinder, @@ -145,7 +145,7 @@ template functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); - auto *const bodyBlock = checker->Allocator()->New(checker->Allocator(), std::move(body)); + auto *const bodyBlock = checker->AllocNode(checker->Allocator(), std::move(body)); bodyBlock->SetScope(functionScope); auto flags = ir::ModifierFlags::PUBLIC; @@ -154,9 +154,9 @@ template flags |= ir::ModifierFlags::DECLARE; } - auto *const function = checker->Allocator()->New( + auto *const function = checker->AllocNode( ir::FunctionSignature(nullptr, std::move(params), returnTypeAnnotation), bodyBlock, - ir::ScriptFunctionFlags::METHOD, flags, isDeclare, Language(Language::Id::ETS)); + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::METHOD, flags, isDeclare}); function->SetScope(functionScope); varbinder->AsETSBinder()->BuildInternalName(function); @@ -170,19 +170,21 @@ template void MakeMethodDef(ETSChecker *const checker, varbinder::ETSBinder *const varbinder, ir::Identifier *const ident, ir::ScriptFunction *const function) { - auto *const functionExpr = checker->Allocator()->New(function); - function->SetParent(functionExpr); + auto *const functionExpr = checker->AllocNode(function); + auto *const identClone = ident->Clone(checker->Allocator(), nullptr); + identClone->SetTsType(ident->TsType()); - auto *const methodDef = checker->Allocator()->New( - ir::MethodDefinitionKind::METHOD, ident, functionExpr, ir::ModifierFlags::PUBLIC, checker->Allocator(), false); + auto *const methodDef = + checker->AllocNode(ir::MethodDefinitionKind::METHOD, identClone, functionExpr, + ir::ModifierFlags::PUBLIC, checker->Allocator(), false); methodDef->SetParent(varbinder->Program()->GlobalClass()); - functionExpr->SetParent(methodDef); auto *const methodVar = std::get<1>(varbinder->NewVarDecl( methodDef->Start(), checker->Allocator(), methodDef->Id()->Name(), methodDef)); methodVar->AddFlag(varbinder::VariableFlags::STATIC | varbinder::VariableFlags::SYNTHETIC | varbinder::VariableFlags::METHOD); methodDef->Function()->Id()->SetVariable(methodVar); + methodDef->Id()->SetVariable(methodVar); } [[nodiscard]] ETSFunctionType *MakeProxyFunctionType(ETSChecker *const checker, const util::StringView &name, @@ -224,7 +226,7 @@ ir::Identifier *ETSChecker::CreateEnumNamesArray(ETSEnumInterface const *const e return MakeArray(this, VarBinder()->AsETSBinder(), enumType, "NamesArray", GlobalBuiltinETSStringType(), [this](const ir::TSEnumMember *const member) { auto *const enumNameStringLiteral = - Allocator()->New(member->Key()->AsIdentifier()->Name()); + AllocNode(member->Key()->AsIdentifier()->Name()); enumNameStringLiteral->SetTsType(GlobalBuiltinETSStringType()); return enumNameStringLiteral; }); @@ -236,7 +238,7 @@ ir::Identifier *ETSChecker::CreateEnumValuesArray(ETSEnumType *const enumType) return MakeArray( this, VarBinder()->AsETSBinder(), enumType, "ValuesArray", GlobalIntType(), [this](const ir::TSEnumMember *const member) { - auto *const enumValueLiteral = Allocator()->New(lexer::Number( + auto *const enumValueLiteral = AllocNode(lexer::Number( member->AsTSEnumMember()->Init()->AsNumberLiteral()->Number().GetValue())); enumValueLiteral->SetTsType(GlobalIntType()); return enumValueLiteral; @@ -256,7 +258,7 @@ ir::Identifier *ETSChecker::CreateEnumStringValuesArray(ETSEnumInterface *const .GetValue()), Allocator()) .View(); - auto *const enumValueStringLiteral = Allocator()->New(stringValue); + auto *const enumValueStringLiteral = AllocNode(stringValue); enumValueStringLiteral->SetTsType(GlobalETSStringLiteralType()); return enumValueStringLiteral; }); @@ -264,17 +266,19 @@ ir::Identifier *ETSChecker::CreateEnumStringValuesArray(ETSEnumInterface *const ir::Identifier *ETSChecker::CreateEnumItemsArray(ETSEnumInterface *const enumType) { - auto *const enumTypeIdent = Allocator()->New(enumType->GetName(), Allocator()); - enumTypeIdent->SetTsType(enumType); - return MakeArray( this, VarBinder()->AsETSBinder(), enumType, "ItemsArray", enumType, - [this, enumTypeIdent](const ir::TSEnumMember *const member) { + [this, enumType](const ir::TSEnumMember *const member) { + auto *const enumTypeIdent = AllocNode(enumType->GetName(), Allocator()); + enumTypeIdent->SetTsType(enumType); + auto *const enumMemberIdent = - Allocator()->New(member->AsTSEnumMember()->Key()->AsIdentifier()->Name(), Allocator()); - auto *const enumMemberExpr = Allocator()->New( + AllocNode(member->AsTSEnumMember()->Key()->AsIdentifier()->Name(), Allocator()); + + auto *const enumMemberExpr = AllocNode( enumTypeIdent, enumMemberIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); enumMemberExpr->SetTsType(member->AsTSEnumMember()->Key()->AsIdentifier()->Variable()->TsType()); + return enumMemberExpr; }); } @@ -289,37 +293,41 @@ ETSEnumType::Method ETSChecker::CreateEnumFromIntMethod(ir::Identifier *const na MakeFunctionParam(this, VarBinder()->AsETSBinder(), paramScope, "ordinal", GlobalIntType()); auto *const inArraySizeExpr = [this, namesArrayIdent, inputOrdinalIdent]() { - auto *const lengthIdent = Allocator()->New("length", Allocator()); - auto *const valuesArrayLengthExpr = Allocator()->New( + auto *const lengthIdent = AllocNode("length", Allocator()); + auto *const valuesArrayLengthExpr = AllocNode( namesArrayIdent, lengthIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - auto *const expr = Allocator()->New(inputOrdinalIdent, valuesArrayLengthExpr, - lexer::TokenType::PUNCTUATOR_LESS_THAN); + auto *const expr = AllocNode(inputOrdinalIdent, valuesArrayLengthExpr, + lexer::TokenType::PUNCTUATOR_LESS_THAN); expr->SetOperationType(GlobalIntType()); expr->SetTsType(GlobalETSBooleanType()); return expr; }(); auto *const returnEnumStmt = [this, inputOrdinalIdent, enumType]() { - inputOrdinalIdent->SetTsType(enumType); - return Allocator()->New(inputOrdinalIdent); + auto *const identClone = inputOrdinalIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(enumType); + return AllocNode(identClone); }(); - auto *const ifOrdinalExistsStmt = Allocator()->New(inArraySizeExpr, returnEnumStmt, nullptr); + auto *const ifOrdinalExistsStmt = AllocNode(inArraySizeExpr, returnEnumStmt, nullptr); auto *const throwNoEnumStmt = [this, inputOrdinalIdent, enumType]() { - auto *const exceptionReference = MakeTypeReference(Allocator(), "Exception"); + auto *const exceptionReference = MakeTypeReference(this, "Exception"); util::UString messageString(util::StringView("No enum constant in "), Allocator()); messageString.Append(enumType->GetName()); messageString.Append(" with ordinal value "); - auto *const message = Allocator()->New(messageString.View()); + auto *const identClone = inputOrdinalIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(GlobalIntType()); + + auto *const message = AllocNode(messageString.View()); auto *const newExprArg = - Allocator()->New(message, inputOrdinalIdent, lexer::TokenType::PUNCTUATOR_PLUS); + AllocNode(message, identClone, lexer::TokenType::PUNCTUATOR_PLUS); ArenaVector newExprArgs(Allocator()->Adapter()); newExprArgs.push_back(newExprArg); - auto *const newExpr = Allocator()->New( + auto *const newExpr = AllocNode( exceptionReference, std::move(newExprArgs), GlobalBuiltinExceptionType()->GetDeclNode()->AsClassDefinition()); @@ -327,24 +335,26 @@ ETSEnumType::Method ETSChecker::CreateEnumFromIntMethod(ir::Identifier *const na ResolveConstructExpression(GlobalBuiltinExceptionType(), newExpr->GetArguments(), newExpr->Start())); newExpr->SetTsType(GlobalBuiltinExceptionType()); - return Allocator()->New(newExpr); + return AllocNode(newExpr); }(); + auto *const identClone = inputOrdinalIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(inputOrdinalIdent->TsType()); ArenaVector params(Allocator()->Adapter()); - params.push_back(inputOrdinalIdent); + params.push_back(identClone); ArenaVector body(Allocator()->Adapter()); body.push_back(ifOrdinalExistsStmt); body.push_back(throwNoEnumStmt); body.push_back(returnEnumStmt); - auto *const enumTypeAnnotation = MakeTypeReference(Allocator(), enumType->GetName()); + auto *const enumTypeAnnotation = MakeTypeReference(this, enumType->GetName()); auto *const function = MakeFunction(this, VarBinder()->AsETSBinder(), paramScope, std::move(params), std::move(body), enumTypeAnnotation, enumType->GetDecl()->IsDeclare()); function->AddFlag(ir::ScriptFunctionFlags::THROWS); - auto *const ident = MakeQualifiedIdentifier(Allocator(), enumType->GetDecl(), ETSEnumType::FROM_INT_METHOD_NAME); + auto *const ident = MakeQualifiedIdentifier(this, enumType->GetDecl(), ETSEnumType::FROM_INT_METHOD_NAME); function->SetIdent(ident); function->Scope()->BindInternalName(ident->Name()); @@ -362,25 +372,26 @@ ETSEnumType::Method ETSChecker::CreateEnumToStringMethod(ir::Identifier *const s auto *const inputEnumIdent = MakeFunctionParam(this, VarBinder()->AsETSBinder(), paramScope, "ordinal", enumType); auto *const returnStmt = [this, inputEnumIdent, stringValuesArrayIdent]() { - auto *const arrayAccessExpr = Allocator()->New( + auto *const arrayAccessExpr = AllocNode( stringValuesArrayIdent, inputEnumIdent, ir::MemberExpressionKind::ELEMENT_ACCESS, true, false); arrayAccessExpr->SetTsType(GlobalETSStringLiteralType()); - return Allocator()->New(arrayAccessExpr); + return AllocNode(arrayAccessExpr); }(); ArenaVector body(Allocator()->Adapter()); body.push_back(returnStmt); + auto *const identClone = inputEnumIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(enumType); ArenaVector params(Allocator()->Adapter()); - params.push_back(inputEnumIdent); + params.push_back(identClone); - auto *const stringTypeAnnotation = MakeTypeReference(Allocator(), GlobalBuiltinETSStringType()->Name()); + auto *const stringTypeAnnotation = MakeTypeReference(this, GlobalBuiltinETSStringType()->Name()); auto *const function = MakeFunction(this, VarBinder()->AsETSBinder(), paramScope, std::move(params), std::move(body), stringTypeAnnotation, enumType->GetDecl()->IsDeclare()); - auto *const functionIdent = - MakeQualifiedIdentifier(Allocator(), enumType->GetDecl(), ETSEnumType::TO_STRING_METHOD_NAME); + auto *const functionIdent = MakeQualifiedIdentifier(this, enumType->GetDecl(), ETSEnumType::TO_STRING_METHOD_NAME); function->SetIdent(functionIdent); function->Scope()->BindInternalName(functionIdent->Name()); @@ -400,25 +411,26 @@ ETSEnumType::Method ETSChecker::CreateEnumGetValueMethod(ir::Identifier *const v auto *const inputEnumIdent = MakeFunctionParam(this, VarBinder()->AsETSBinder(), paramScope, "e", enumType); auto *const returnStmt = [this, inputEnumIdent, valuesArrayIdent]() { - auto *const arrayAccessExpr = Allocator()->New( + auto *const arrayAccessExpr = AllocNode( valuesArrayIdent, inputEnumIdent, ir::MemberExpressionKind::ELEMENT_ACCESS, true, false); arrayAccessExpr->SetTsType(GlobalIntType()); - return Allocator()->New(arrayAccessExpr); + return AllocNode(arrayAccessExpr); }(); ArenaVector body(Allocator()->Adapter()); body.push_back(returnStmt); + auto *const identClone = inputEnumIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(enumType); ArenaVector params(Allocator()->Adapter()); - params.push_back(inputEnumIdent); + params.push_back(identClone); - auto *const intTypeAnnotation = Allocator()->New(ir::PrimitiveType::INT); + auto *const intTypeAnnotation = AllocNode(ir::PrimitiveType::INT); auto *const function = MakeFunction(this, VarBinder()->AsETSBinder(), paramScope, std::move(params), std::move(body), intTypeAnnotation, enumType->GetDecl()->IsDeclare()); - auto *const functionIdent = - MakeQualifiedIdentifier(Allocator(), enumType->GetDecl(), ETSEnumType::GET_VALUE_METHOD_NAME); + auto *const functionIdent = MakeQualifiedIdentifier(this, enumType->GetDecl(), ETSEnumType::GET_VALUE_METHOD_NAME); function->SetIdent(functionIdent); function->Scope()->BindInternalName(functionIdent->Name()); @@ -437,26 +449,27 @@ ETSEnumType::Method ETSChecker::CreateEnumGetNameMethod(ir::Identifier *const na auto *const inputEnumIdent = MakeFunctionParam(this, VarBinder()->AsETSBinder(), paramScope, "ordinal", enumType); auto *const returnStmt = [this, inputEnumIdent, namesArrayIdent]() { - auto *const arrayAccessExpr = Allocator()->New( + auto *const arrayAccessExpr = AllocNode( namesArrayIdent, inputEnumIdent, ir::MemberExpressionKind::ELEMENT_ACCESS, true, false); arrayAccessExpr->SetTsType(GlobalBuiltinETSStringType()); - return Allocator()->New(arrayAccessExpr); + return AllocNode(arrayAccessExpr); }(); ArenaVector body(Allocator()->Adapter()); body.push_back(returnStmt); + auto *const identClone = inputEnumIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(enumType); ArenaVector params(Allocator()->Adapter()); - params.push_back(inputEnumIdent); + params.push_back(identClone); - auto *const stringTypeAnnotation = MakeTypeReference(Allocator(), GlobalBuiltinETSStringType()->Name()); + auto *const stringTypeAnnotation = MakeTypeReference(this, GlobalBuiltinETSStringType()->Name()); auto *const function = MakeFunction(this, VarBinder()->AsETSBinder(), paramScope, std::move(params), std::move(body), stringTypeAnnotation, enumType->GetDecl()->IsDeclare()); - auto *const functionIdent = - MakeQualifiedIdentifier(Allocator(), enumType->GetDecl(), ETSEnumType::GET_NAME_METHOD_NAME); + auto *const functionIdent = MakeQualifiedIdentifier(this, enumType->GetDecl(), ETSEnumType::GET_NAME_METHOD_NAME); function->SetIdent(functionIdent); function->Scope()->BindInternalName(functionIdent->Name()); @@ -472,13 +485,10 @@ ETSEnumType::Method ETSChecker::CreateEnumValueOfMethod(ir::Identifier *const na auto *const paramScope = VarBinder()->Allocator()->New(Allocator(), Program()->GlobalScope()); - auto *const inputNameIdent = - MakeFunctionParam(this, VarBinder()->AsETSBinder(), paramScope, "name", GlobalBuiltinETSStringType()); - varbinder::LexicalScope loopDeclScope(VarBinder()); auto *const forLoopIIdent = [this]() { - auto *const ident = Allocator()->New("i", Allocator()); + auto *const ident = AllocNode("i", Allocator()); ident->SetTsType(GlobalIntType()); auto [decl, var] = VarBinder()->NewVarDecl(ident->Start(), ident->Name()); ident->SetVariable(var); @@ -490,24 +500,23 @@ ETSEnumType::Method ETSChecker::CreateEnumValueOfMethod(ir::Identifier *const na }(); auto *const forLoopInitVarDecl = [this, forLoopIIdent]() { - auto *const init = Allocator()->New("0"); + auto *const init = AllocNode("0"); init->SetTsType(GlobalIntType()); - auto *const decl = - Allocator()->New(ir::VariableDeclaratorFlag::LET, forLoopIIdent, init); + auto *const decl = AllocNode(ir::VariableDeclaratorFlag::LET, forLoopIIdent, init); decl->SetTsType(GlobalIntType()); ArenaVector decls(Allocator()->Adapter()); decls.push_back(decl); - return Allocator()->New(ir::VariableDeclaration::VariableDeclarationKind::LET, - Allocator(), std::move(decls), false); + return AllocNode(ir::VariableDeclaration::VariableDeclarationKind::LET, Allocator(), + std::move(decls), false); }(); auto *const forLoopTest = [this, namesArrayIdent, forLoopIIdent]() { - auto *const lengthIdent = Allocator()->New("length", Allocator()); - auto *const arrayLengthExpr = Allocator()->New( + auto *const lengthIdent = AllocNode("length", Allocator()); + auto *const arrayLengthExpr = AllocNode( namesArrayIdent, lengthIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); arrayLengthExpr->SetTsType(GlobalIntType()); - auto *const binaryExpr = Allocator()->New(forLoopIIdent, arrayLengthExpr, - lexer::TokenType::PUNCTUATOR_LESS_THAN); + auto *const binaryExpr = + AllocNode(forLoopIIdent, arrayLengthExpr, lexer::TokenType::PUNCTUATOR_LESS_THAN); binaryExpr->SetOperationType(GlobalIntType()); binaryExpr->SetTsType(GlobalETSBooleanType()); return binaryExpr; @@ -515,30 +524,34 @@ ETSEnumType::Method ETSChecker::CreateEnumValueOfMethod(ir::Identifier *const na auto *const forLoopUpdate = [this, forLoopIIdent]() { auto *const incrementExpr = - Allocator()->New(forLoopIIdent, lexer::TokenType::PUNCTUATOR_PLUS_PLUS, true); + AllocNode(forLoopIIdent, lexer::TokenType::PUNCTUATOR_PLUS_PLUS, true); incrementExpr->SetTsType(GlobalIntType()); return incrementExpr; }(); + auto *const inputNameIdent = + MakeFunctionParam(this, VarBinder()->AsETSBinder(), paramScope, "name", GlobalBuiltinETSStringType()); + auto *const ifStmt = [this, namesArrayIdent, forLoopIIdent, inputNameIdent]() { - auto *const namesArrayElementExpr = Allocator()->New( - namesArrayIdent, forLoopIIdent, ir::MemberExpressionKind::ELEMENT_ACCESS, true, false); + auto *const identClone = namesArrayIdent->Clone(this->Allocator(), nullptr); + identClone->SetTsType(namesArrayIdent->TsType()); + auto *const namesArrayElementExpr = AllocNode( + identClone, forLoopIIdent, ir::MemberExpressionKind::ELEMENT_ACCESS, true, false); namesArrayElementExpr->SetTsType(GlobalBuiltinETSStringType()); - auto *const namesEqualExpr = Allocator()->New(inputNameIdent, namesArrayElementExpr, - lexer::TokenType::PUNCTUATOR_EQUAL); + auto *const namesEqualExpr = + AllocNode(inputNameIdent, namesArrayElementExpr, lexer::TokenType::PUNCTUATOR_EQUAL); namesEqualExpr->SetOperationType(GlobalBuiltinETSStringType()); namesEqualExpr->SetTsType(GlobalETSBooleanType()); - auto *const returnStmt = Allocator()->New(forLoopIIdent); - return Allocator()->New(namesEqualExpr, returnStmt, nullptr); + auto *const returnStmt = AllocNode(forLoopIIdent); + return AllocNode(namesEqualExpr, returnStmt, nullptr); }(); varbinder::LexicalScope loopScope(VarBinder()); loopScope.GetScope()->BindDecls(loopDeclScope.GetScope()); - auto *const forLoop = - Allocator()->New(forLoopInitVarDecl, forLoopTest, forLoopUpdate, ifStmt); + auto *const forLoop = AllocNode(forLoopInitVarDecl, forLoopTest, forLoopUpdate, ifStmt); loopScope.GetScope()->BindNode(forLoop); forLoop->SetScope(loopScope.GetScope()); loopScope.GetScope()->DeclScope()->BindNode(forLoop); @@ -548,40 +561,43 @@ ETSEnumType::Method ETSChecker::CreateEnumValueOfMethod(ir::Identifier *const na messageString.Append(enumType->GetName()); messageString.Append('.'); - auto *const message = Allocator()->New(messageString.View()); + auto *const identClone = inputNameIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(inputNameIdent->TsType()); + auto *const message = AllocNode(messageString.View()); auto *const newExprArg = - Allocator()->New(message, inputNameIdent, lexer::TokenType::PUNCTUATOR_PLUS); + AllocNode(message, identClone, lexer::TokenType::PUNCTUATOR_PLUS); ArenaVector newExprArgs(Allocator()->Adapter()); newExprArgs.push_back(newExprArg); - auto *const exceptionReference = MakeTypeReference(Allocator(), "Exception"); + auto *const exceptionReference = MakeTypeReference(this, "Exception"); - auto *const newExpr = Allocator()->New( + auto *const newExpr = AllocNode( exceptionReference, std::move(newExprArgs), GlobalBuiltinExceptionType()->GetDeclNode()->AsClassDefinition()); newExpr->SetSignature( ResolveConstructExpression(GlobalBuiltinExceptionType(), newExpr->GetArguments(), newExpr->Start())); newExpr->SetTsType(GlobalBuiltinExceptionType()); - return Allocator()->New(newExpr); + return AllocNode(newExpr); }(); ArenaVector body(Allocator()->Adapter()); body.push_back(forLoop); body.push_back(throwStmt); + auto *const identClone = inputNameIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(inputNameIdent->TsType()); ArenaVector params(Allocator()->Adapter()); - params.push_back(inputNameIdent); + params.push_back(identClone); - auto *const enumTypeAnnotation = MakeTypeReference(Allocator(), enumType->GetName()); + auto *const enumTypeAnnotation = MakeTypeReference(this, enumType->GetName()); auto *const function = MakeFunction(this, VarBinder()->AsETSBinder(), paramScope, std::move(params), std::move(body), enumTypeAnnotation, enumType->GetDecl()->IsDeclare()); function->AddFlag(ir::ScriptFunctionFlags::THROWS); - auto *const functionIdent = - MakeQualifiedIdentifier(Allocator(), enumType->GetDecl(), ETSEnumType::VALUE_OF_METHOD_NAME); + auto *const functionIdent = MakeQualifiedIdentifier(this, enumType->GetDecl(), ETSEnumType::VALUE_OF_METHOD_NAME); function->SetIdent(functionIdent); function->Scope()->BindInternalName(functionIdent->Name()); @@ -599,20 +615,18 @@ ETSEnumType::Method ETSChecker::CreateEnumValuesMethod(ir::Identifier *const ite auto *const paramScope = VarBinder()->Allocator()->New(Allocator(), Program()->GlobalScope()); - auto *const returnStmt = Allocator()->New(itemsArrayIdent); + auto *const returnStmt = AllocNode(itemsArrayIdent); ArenaVector body(Allocator()->Adapter()); body.push_back(returnStmt); ArenaVector params(Allocator()->Adapter()); - auto *const enumArrayTypeAnnotation = - Allocator()->New(MakeTypeReference(Allocator(), enumType->GetName())); + auto *const enumArrayTypeAnnotation = AllocNode(MakeTypeReference(this, enumType->GetName())); auto *const function = MakeFunction(this, VarBinder()->AsETSBinder(), paramScope, std::move(params), std::move(body), enumArrayTypeAnnotation, enumType->GetDecl()->IsDeclare()); - auto *const functionIdent = - MakeQualifiedIdentifier(Allocator(), enumType->GetDecl(), ETSEnumType::VALUES_METHOD_NAME); + auto *const functionIdent = MakeQualifiedIdentifier(this, enumType->GetDecl(), ETSEnumType::VALUES_METHOD_NAME); function->SetIdent(functionIdent); function->Scope()->BindInternalName(functionIdent->Name()); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index e6476c47e5aa9b87ce662392da988ef5231198fc..22c98376442ba1ce47115dfe4f0d4a7ebcadc252 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1412,7 +1412,7 @@ void ETSChecker::BuildFunctionalInterfaceName(ir::ETSFunctionType *funcType) void ETSChecker::CreateFunctionalInterfaceForFunctionType(ir::ETSFunctionType *funcType) { - auto *identNode = Allocator()->New(util::StringView("FunctionalInterface"), Allocator()); + auto *identNode = AllocNode(util::StringView("FunctionalInterface"), Allocator()); auto interfaceCtx = varbinder::LexicalScope(VarBinder()); auto *interfaceScope = interfaceCtx.GetScope(); @@ -1448,8 +1448,6 @@ void ETSChecker::CreateFunctionalInterfaceForFunctionType(ir::ETSFunctionType *f ir::MethodDefinition *ETSChecker::CreateInvokeFunction(ir::ETSFunctionType *funcType) { - auto *identNode = Allocator()->New(util::StringView("invoke"), Allocator()); - ArenaVector params(Allocator()->Adapter()); auto *funcParamScope = CopyParams(funcType->Params(), params); @@ -1459,23 +1457,26 @@ ir::MethodDefinition *ETSChecker::CreateInvokeFunction(ir::ETSFunctionType *func functionScope->BindParamScope(funcParamScope); funcParamScope->BindFunctionScope(functionScope); + auto *const typeAnnotation = funcType->ReturnType()->Clone(Allocator(), nullptr); + typeAnnotation->SetTsType(funcType->ReturnType()->TsType()); + ir::ModifierFlags flags = ir::ModifierFlags::ABSTRACT | ir::ModifierFlags::PUBLIC; - auto *func = Allocator()->New( - ir::FunctionSignature(nullptr, std::move(params), funcType->ReturnType()), nullptr, - ir::ScriptFunctionFlags::METHOD, flags, false, Language(Language::Id::ETS)); + auto *func = + AllocNode(ir::FunctionSignature(nullptr, std::move(params), typeAnnotation), nullptr, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::METHOD, flags}); func->SetScope(functionScope); functionScope->BindNode(func); funcParamScope->BindNode(func); - auto *funcExpr = Allocator()->New(func); + auto *identNode = AllocNode(util::StringView("invoke"), Allocator()); func->SetIdent(identNode); - auto *method = Allocator()->New(ir::MethodDefinitionKind::METHOD, identNode, funcExpr, flags, - Allocator(), false); + auto *funcExpr = AllocNode(func); - funcExpr->SetParent(method); - func->SetParent(funcExpr); + auto *identClone = identNode->Clone(Allocator(), nullptr); + auto *method = AllocNode(ir::MethodDefinitionKind::METHOD, identClone, funcExpr, flags, + Allocator(), false); return method; } @@ -1536,10 +1537,10 @@ void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpressio // Create the synthetic lambda class node ArenaVector implements(Allocator()->Adapter()); - auto *identNode = Allocator()->New(util::StringView("LambdaObject"), Allocator()); + auto *identNode = AllocNode(util::StringView("LambdaObject"), Allocator()); auto *lambdaObject = - Allocator()->New(Allocator(), identNode, std::move(properties), - ir::ClassDefinitionModifiers::DECLARATION, Language(Language::Id::ETS)); + AllocNode(Allocator(), identNode, std::move(properties), + ir::ClassDefinitionModifiers::DECLARATION, Language(Language::Id::ETS)); lambda->SetResolvedLambda(lambdaObject); lambda->SetTsType(functionalInterface); lambdaObject->SetScope(classScope); @@ -1560,18 +1561,7 @@ void ETSChecker::CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpressio VarBinder()->AsETSBinder()->BuildLambdaObject(lambda, lambdaObject, proxyMethod->Function()->Signature()); // Resolve the proxy method - ResolveProxyMethod(proxyMethod, lambda); - if (lambda->Function()->IsAsyncFunc()) { - ir::MethodDefinition *asyncImpl = CreateAsyncProxy(proxyMethod, currentClassDef); - ir::ScriptFunction *asyncImplFunc = asyncImpl->Function(); - currentClassDef->Body().push_back(asyncImpl); - ReplaceIdentifierReferencesInProxyMethod(asyncImplFunc->Body(), asyncImplFunc->Params(), - lambda->Function()->Params(), lambda->CapturedVars()); - Signature *implSig = CreateSignature(proxyMethod->Function()->Signature()->GetSignatureInfo(), - GlobalETSObjectType(), asyncImplFunc); - asyncImplFunc->SetSignature(implSig); - VarBinder()->AsETSBinder()->BuildFunctionName(asyncImpl->Function()); - } + ResolveProxyMethod(currentClassDef, proxyMethod, lambda); // Resolve the lambda object ResolveLambdaObject(lambdaObject, functionalInterface, lambda, proxyMethod, saveThis); @@ -1654,14 +1644,19 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, ir lambdaObjectType->AddProperty( invokeFunc->Id()->Variable()->AsLocalVariable()); - // Fill out the type information for the body of the invoke function - auto *resolvedLambdaInvokeFunctionBody = ResolveLambdaObjectInvokeFuncBody(lambdaObject, proxyMethod, isStatic); if (invokeFunc->IsAsyncFunc()) { return; } + + // Fill out the type information for the body of the invoke function + auto *resolvedLambdaInvokeFunctionBody = ResolveLambdaObjectInvokeFuncBody(lambdaObject, proxyMethod, isStatic); + resolvedLambdaInvokeFunctionBody->SetParent(invokeFunc->Body()); invokeFunc->Body()->AsBlockStatement()->Statements().push_back(resolvedLambdaInvokeFunctionBody); + if (resolvedLambdaInvokeFunctionBody->IsExpressionStatement()) { - invokeFunc->Body()->AsBlockStatement()->Statements().push_back(Allocator()->New(nullptr)); + auto *const returnStatement = Allocator()->New(nullptr); + returnStatement->SetParent(invokeFunc->Body()); + invokeFunc->Body()->AsBlockStatement()->Statements().push_back(returnStatement); } } @@ -1675,7 +1670,7 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition // If the proxy method is static, we should call it through the owner class itself if (isStatic) { - fieldIdent = Allocator()->New(proxySignature->Owner()->Name(), Allocator()); + fieldIdent = AllocNode(proxySignature->Owner()->Name(), Allocator()); fieldPropType = proxySignature->Owner(); fieldIdent->SetVariable(proxySignature->Owner()->Variable()); fieldIdent->SetTsType(fieldPropType); @@ -1690,9 +1685,9 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition } // Set the type information for the proxy function call - auto *funcIdent = Allocator()->New(proxyMethod->Function()->Id()->Name(), Allocator()); - auto *callee = Allocator()->New(fieldIdent, funcIdent, - ir::MemberExpressionKind::ELEMENT_ACCESS, false, false); + auto *funcIdent = AllocNode(proxyMethod->Function()->Id()->Name(), Allocator()); + auto *callee = + AllocNode(fieldIdent, funcIdent, ir::MemberExpressionKind::ELEMENT_ACCESS, false, false); callee->SetPropVar(proxySignature->OwnerVar()->AsLocalVariable()); callee->SetObjectType(fieldPropType); callee->SetTsType(proxySignature->OwnerVar()->TsType()); @@ -1707,7 +1702,7 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition } auto *classProp = lambdaBody[i]->AsClassProperty(); - auto *param = Allocator()->New(classProp->Key()->AsIdentifier()->Name(), Allocator()); + auto *param = AllocNode(classProp->Key()->AsIdentifier()->Name(), Allocator()); param->SetVariable(classProp->Key()->AsIdentifier()->Variable()); param->SetIgnoreBox(); param->SetTsType(MaybeBoxedType(param->Variable())); @@ -1717,21 +1712,21 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition // Then we add the lambda functions parameters to the call for (auto const *const it : invokeFunc->Params()) { auto const *const param = it->AsETSParameterExpression(); - auto *const paramIdent = Allocator()->New(param->Ident()->Name(), Allocator()); + auto *const paramIdent = AllocNode(param->Ident()->Name(), Allocator()); paramIdent->SetVariable(param->Variable()); paramIdent->SetTsType(param->Variable()->TsType()); callParams.push_back(paramIdent); } // Create the synthetic call expression to the proxy method - auto *resolvedCall = Allocator()->New(callee, std::move(callParams), nullptr, false); + auto *resolvedCall = AllocNode(callee, std::move(callParams), nullptr, false); resolvedCall->SetTsType(proxySignature->ReturnType()); resolvedCall->SetSignature(proxySignature); if (proxySignature->ReturnType()->IsETSVoidType()) { - return Allocator()->New(resolvedCall); + return AllocNode(resolvedCall); } - return Allocator()->New(resolvedCall); + return AllocNode(resolvedCall); } void ETSChecker::ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject) @@ -1781,15 +1776,16 @@ void ETSChecker::ResolveLambdaObjectCtor(ir::ClassDefinition *lambdaObject) } } -void ETSChecker::ResolveProxyMethod(ir::MethodDefinition *proxyMethod, ir::ArrowFunctionExpression *lambda) +void ETSChecker::ResolveProxyMethod(ir::ClassDefinition *const classDefinition, ir::MethodDefinition *proxyMethod, + ir::ArrowFunctionExpression *lambda) { + auto *const varbinder = VarBinder()->AsETSBinder(); auto *func = proxyMethod->Function(); bool isStatic = func->IsStatic(); auto *currentClassType = Context().ContainingClass(); // Build the proxy method in the binder - VarBinder()->AsETSBinder()->BuildProxyMethod( - func, currentClassType->GetDeclNode()->AsClassDefinition()->InternalName(), isStatic); + varbinder->BuildProxyMethod(func, currentClassType->GetDeclNode()->AsClassDefinition()->InternalName(), isStatic); // If the proxy method is not static, set the implicit 'this' parameters type to the current class if (!isStatic) { @@ -1811,13 +1807,28 @@ void ETSChecker::ResolveProxyMethod(ir::MethodDefinition *proxyMethod, ir::Arrow signature->SetOwner(currentClassType); // Add the proxy method to the current class methods + auto *const variable = func->Id()->Variable()->AsLocalVariable(); if (isStatic) { - currentClassType->AddProperty(func->Id()->Variable()->AsLocalVariable()); + currentClassType->AddProperty(variable); } else { - currentClassType->AddProperty( - func->Id()->Variable()->AsLocalVariable()); + currentClassType->AddProperty(variable); + } + varbinder->BuildFunctionName(func); + + if (lambda->Function()->IsAsyncFunc()) { + ir::MethodDefinition *asyncImpl = CreateAsyncProxy(proxyMethod, classDefinition); + ir::ScriptFunction *asyncImplFunc = asyncImpl->Function(); + + classDefinition->Body().emplace_back(asyncImpl); + asyncImpl->SetParent(classDefinition); + + ReplaceIdentifierReferencesInProxyMethod(asyncImplFunc->Body(), asyncImplFunc->Params(), + lambda->Function()->Params(), lambda->CapturedVars()); + Signature *implSig = CreateSignature(proxyMethod->Function()->Signature()->GetSignatureInfo(), + GlobalETSObjectType(), asyncImplFunc); + asyncImplFunc->SetSignature(implSig); + varbinder->BuildFunctionName(asyncImplFunc); } - VarBinder()->AsETSBinder()->BuildFunctionName(func); } size_t ETSChecker::ComputeProxyMethods(ir::ClassDefinition *klass) @@ -1868,8 +1879,8 @@ ir::ScriptFunction *ETSChecker::CreateProxyFunc(ir::ArrowFunctionExpression *lam funcFlags |= ir::ScriptFunctionFlags::ASYNC; } auto *func = Allocator()->New( - ir::FunctionSignature(nullptr, std::move(params), lambda->Function()->ReturnTypeAnnotation()), body, funcFlags, - GetFlagsForProxyLambda(isStatic), false, Language(Language::Id::ETS)); + ir::FunctionSignature(nullptr, std::move(params), lambda->Function()->ReturnTypeAnnotation()), body, + ir::ScriptFunction::ScriptFunctionData {funcFlags, GetFlagsForProxyLambda(isStatic)}); func->SetScope(scope); if (!func->IsAsyncFunc()) { @@ -1901,23 +1912,22 @@ ir::MethodDefinition *ETSChecker::CreateProxyMethodForLambda(ir::ClassDefinition auto *func = CreateProxyFunc(lambda, captured, isStatic); // Create the synthetic proxy method - auto *funcExpr = Allocator()->New(func); + auto *funcExpr = AllocNode(func); util::UString funcName(util::StringView("lambda$invoke$"), Allocator()); funcName.Append(std::to_string(ComputeProxyMethods(klass))); - auto *identNode = Allocator()->New(funcName.View(), Allocator()); + auto *identNode = AllocNode(funcName.View(), Allocator()); func->SetIdent(identNode); - auto *proxy = Allocator()->New(ir::MethodDefinitionKind::METHOD, identNode, funcExpr, - GetFlagsForProxyLambda(isStatic), Allocator(), false); + + auto *identClone = identNode->Clone(Allocator(), nullptr); + auto *proxy = AllocNode(ir::MethodDefinitionKind::METHOD, identClone, funcExpr, + GetFlagsForProxyLambda(isStatic), Allocator(), false); + klass->Body().push_back(proxy); proxy->SetParent(klass); // Add the proxy method to the current class declarations CreateLambdaFuncDecl(proxy, klass->Scope()->AsClassScope()->InstanceMethodScope()); - // Set the parent nodes - func->SetParent(funcExpr); - funcExpr->SetParent(proxy); - // Create the signature template for the proxy method to be able to save this signatures pointer in the binder // lambdaObjects_ to be able to compute the lambda object invoke functions internal name later auto *proxySignatureInfo = CreateSignatureInfo(); @@ -2026,12 +2036,12 @@ varbinder::FunctionParamScope *ETSChecker::CreateProxyMethodParams(ir::ArrowFunc // "this" should be binded with the parameter of the proxy method if (this->HasStatus(checker::CheckerStatus::IN_INSTANCE_EXTENSION_METHOD) && lambda->CapturedVars()[i]->Name() == varbinder::VarBinder::MANDATORY_PARAM_THIS) { - paramIdent = Allocator()->New(varbinder::VarBinder::MANDATORY_PARAM_THIS, Allocator()); + paramIdent = AllocNode(varbinder::VarBinder::MANDATORY_PARAM_THIS, Allocator()); } else { - paramIdent = Allocator()->New(capturedVar->Name(), Allocator()); + paramIdent = AllocNode(capturedVar->Name(), Allocator()); } - auto *param = Allocator()->New(paramIdent, nullptr); + auto *param = AllocNode(paramIdent, nullptr); auto [_, var] = VarBinder()->AddParamDecl(param); (void)_; var->SetTsType(capturedVar->TsType()); @@ -2046,16 +2056,15 @@ varbinder::FunctionParamScope *ETSChecker::CreateProxyMethodParams(ir::ArrowFunc // Then add the lambda function parameters to the proxy method's parameter vector, and set the type from the // already computed types for the lambda parameters - for (auto const *const it : params) { - auto *const oldParamExprIdent = it->AsETSParameterExpression()->Ident(); - auto *const paramIdent = Allocator()->New(oldParamExprIdent->Name(), Allocator()); - auto *param = Allocator()->New(paramIdent, nullptr); - auto [_, var] = VarBinder()->AddParamDecl(param); + for (auto *const it : params) { + auto *const oldParameter = it->AsETSParameterExpression(); + auto *newParameter = oldParameter->Clone(Allocator(), nullptr); + auto [_, var] = VarBinder()->AddParamDecl(newParameter); (void)_; - var->SetTsType(oldParamExprIdent->Variable()->TsType()); - param->SetVariable(var); - param->SetTsType(oldParamExprIdent->Variable()->TsType()); - proxyParams.push_back(param); + var->SetTsType(oldParameter->Variable()->TsType()); + newParameter->SetVariable(var); + newParameter->SetTsType(oldParameter->Variable()->TsType()); + proxyParams.push_back(newParameter); } return paramCtx.GetScope(); @@ -2135,12 +2144,13 @@ ir::MethodDefinition *ETSChecker::CreateLambdaImplicitCtor(ArenaVectorNew(Allocator(), std::move(statements)); + auto *body = AllocNode(Allocator(), std::move(statements)); body->SetScope(scope); auto *func = - Allocator()->New(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::CONSTRUCTOR, false, Language(Language::Id::ETS)); + AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::CONSTRUCTOR}); func->SetScope(scope); + // Set the scopes scope->BindNode(func); funcParamScope->BindNode(func); @@ -2148,15 +2158,13 @@ ir::MethodDefinition *ETSChecker::CreateLambdaImplicitCtor(ArenaVectorBindFunctionScope(scope); // Create the name for the synthetic constructor - auto *funcExpr = Allocator()->New(func); - auto *key = Allocator()->New("constructor", Allocator()); + auto *funcExpr = AllocNode(func); + auto *key = AllocNode("constructor", Allocator()); func->SetIdent(key); - auto *ctor = Allocator()->New(ir::MethodDefinitionKind::CONSTRUCTOR, key, funcExpr, - ir::ModifierFlags::NONE, Allocator(), false); - // Set the parent nodes - func->SetParent(funcExpr); - funcExpr->SetParent(ctor); + auto *keyClone = key->Clone(Allocator(), nullptr); + auto *ctor = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, keyClone, funcExpr, + ir::ModifierFlags::NONE, Allocator(), false); return ctor; } @@ -2171,8 +2179,8 @@ varbinder::FunctionParamScope *ETSChecker::CreateLambdaCtorImplicitParams(ArenaV // captured variables for (auto *it : properties) { auto *field = it->AsClassProperty()->Key()->AsIdentifier(); - auto *paramField = Allocator()->New(field->Name(), Allocator()); - auto *param = Allocator()->New(paramField, nullptr); + auto *paramField = field->Clone(Allocator(), nullptr); + auto *param = AllocNode(paramField, nullptr); auto [_, var] = VarBinder()->AddParamDecl(param); (void)_; auto *type = MaybeBoxedType(field->Variable()); @@ -2190,15 +2198,15 @@ ir::Statement *ETSChecker::CreateLambdaCtorFieldInit(util::StringView name, varb // Create synthetic field initializers for the lambda class fields // The node structure is the following: this.field0 = field0, where the left hand side refers to the lambda // classes field, and the right hand side is refers to the constructors parameter - auto *thisExpr = Allocator()->New(); - auto *fieldAccessExpr = Allocator()->New(name, Allocator()); - auto *leftHandSide = Allocator()->New( - thisExpr, fieldAccessExpr, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - auto *rightHandSide = Allocator()->New(name, Allocator()); + auto *thisExpr = AllocNode(); + auto *fieldAccessExpr = AllocNode(name, Allocator()); + auto *leftHandSide = AllocNode(thisExpr, fieldAccessExpr, + ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *rightHandSide = AllocNode(name, Allocator()); rightHandSide->SetVariable(var); - auto *initializer = Allocator()->New(leftHandSide, rightHandSide, - lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - return Allocator()->New(initializer); + auto *initializer = + AllocNode(leftHandSide, rightHandSide, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + return AllocNode(initializer); } // Lambda creation for Function references @@ -2291,11 +2299,11 @@ ir::MethodDefinition *ETSChecker::CreateLambdaImplicitCtor(const lexer::SourceRa statements.push_back(CreateLambdaCtorFieldInit(util::StringView("field0"), var)); } - auto *body = Allocator()->New(Allocator(), std::move(statements)); + auto *body = AllocNode(Allocator(), std::move(statements)); body->SetScope(scope); auto *func = - Allocator()->New(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::CONSTRUCTOR, false, Language(Language::Id::ETS)); + AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::CONSTRUCTOR}); func->SetScope(scope); // Bind the scopes scope->BindNode(func); @@ -2304,15 +2312,13 @@ ir::MethodDefinition *ETSChecker::CreateLambdaImplicitCtor(const lexer::SourceRa funcParamScope->BindFunctionScope(scope); // Create the synthetic constructor - auto *funcExpr = Allocator()->New(func); - auto *key = Allocator()->New("constructor", Allocator()); + auto *funcExpr = AllocNode(func); + auto *key = AllocNode("constructor", Allocator()); func->SetIdent(key); - auto *ctor = Allocator()->New(ir::MethodDefinitionKind::CONSTRUCTOR, key, funcExpr, - ir::ModifierFlags::NONE, Allocator(), false); - // Set the parent nodes - func->SetParent(funcExpr); - funcExpr->SetParent(ctor); + auto *keyClone = key->Clone(Allocator(), nullptr); + auto *ctor = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, keyClone, funcExpr, + ir::ModifierFlags::NONE, Allocator(), false); return ctor; } @@ -2327,8 +2333,8 @@ std::tuple ETSChecker::C // since when initializing the lambda class, we don't need to save the instance object which we tried to get the // function reference through if (!isStaticReference) { - auto *paramIdent = Allocator()->New("field0", Allocator()); - auto *param = Allocator()->New(paramIdent, nullptr); + auto *paramIdent = AllocNode("field0", Allocator()); + auto *param = AllocNode(paramIdent, nullptr); paramIdent->SetRange(pos); auto [_, var] = VarBinder()->AddParamDecl(param); (void)_; @@ -2344,18 +2350,17 @@ ir::MethodDefinition *ETSChecker::CreateLambdaInvokeProto() { // Create the template for the synthetic 'invoke' method, which will be used when the function type will be // called - auto *name = Allocator()->New("invoke", Allocator()); auto *paramScope = VarBinder()->Allocator()->New(Allocator(), VarBinder()->GetScope()); auto *scope = VarBinder()->Allocator()->New(Allocator(), paramScope); ArenaVector params(Allocator()->Adapter()); ArenaVector statements(Allocator()->Adapter()); - auto *body = Allocator()->New(Allocator(), std::move(statements)); + auto *body = AllocNode(Allocator(), std::move(statements)); body->SetScope(scope); - auto *func = Allocator()->New(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::METHOD, ir::ModifierFlags::PUBLIC, false, - Language(Language::Id::ETS)); + auto *func = AllocNode( + ir::FunctionSignature(nullptr, std::move(params), nullptr), body, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::METHOD, ir::ModifierFlags::PUBLIC}); func->SetScope(scope); scope->BindNode(func); @@ -2363,14 +2368,14 @@ ir::MethodDefinition *ETSChecker::CreateLambdaInvokeProto() scope->BindParamScope(paramScope); paramScope->BindFunctionScope(scope); - auto *funcExpr = Allocator()->New(func); + auto *name = AllocNode("invoke", Allocator()); func->SetIdent(name); - auto *method = Allocator()->New(ir::MethodDefinitionKind::METHOD, name, funcExpr, - ir::ModifierFlags::PUBLIC, Allocator(), false); + auto *funcExpr = AllocNode(func); - funcExpr->SetParent(method); - func->SetParent(funcExpr); + auto *nameClone = name->Clone(Allocator(), nullptr); + auto *method = AllocNode(ir::MethodDefinitionKind::METHOD, nameClone, funcExpr, + ir::ModifierFlags::PUBLIC, Allocator(), false); return method; } @@ -2509,8 +2514,8 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Si auto paramCtx = varbinder::LexicalScope::Enter( VarBinder(), invokeFunc->Scope()->ParamScope(), false); - auto *paramIdent = Allocator()->New(it->Name(), Allocator()); - auto *param = Allocator()->New(paramIdent, nullptr); + auto *paramIdent = AllocNode(it->Name(), Allocator()); + auto *param = AllocNode(paramIdent, nullptr); auto [_, var] = VarBinder()->AddParamDecl(param); (void)_; var->SetTsType(it->TsType()); @@ -2535,10 +2540,13 @@ void ETSChecker::ResolveLambdaObjectInvoke(ir::ClassDefinition *lambdaObject, Si // Fill out the type information for the body of the invoke function auto *resolvedLambdaInvokeFunctionBody = ResolveLambdaObjectInvokeFuncBody(lambdaObject, signatureRef); - + resolvedLambdaInvokeFunctionBody->SetParent(invokeFunc->Body()); invokeFunc->Body()->AsBlockStatement()->Statements().push_back(resolvedLambdaInvokeFunctionBody); + if (resolvedLambdaInvokeFunctionBody->IsExpressionStatement()) { - invokeFunc->Body()->AsBlockStatement()->Statements().push_back(Allocator()->New(nullptr)); + auto *const returnStatement = Allocator()->New(nullptr); + returnStatement->SetParent(invokeFunc->Body()); + invokeFunc->Body()->AsBlockStatement()->Statements().push_back(returnStatement); } } @@ -2551,7 +2559,7 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition // If this is a static function reference, we have to call the referenced function through the class itself if (isStaticReference) { - fieldIdent = Allocator()->New(signatureRef->Owner()->Name(), Allocator()); + fieldIdent = AllocNode(signatureRef->Owner()->Name(), Allocator()); fieldPropType = signatureRef->Owner(); fieldIdent->SetVariable(signatureRef->Owner()->Variable()); fieldIdent->SetTsType(fieldPropType); @@ -2560,15 +2568,15 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition // reference auto *fieldProp = lambdaBody[0]->AsClassProperty()->Key()->AsIdentifier()->Variable(); fieldPropType = fieldProp->TsType()->AsETSObjectType(); - fieldIdent = Allocator()->New("field0", Allocator()); + fieldIdent = AllocNode("field0", Allocator()); fieldIdent->SetVariable(fieldProp); fieldIdent->SetTsType(fieldPropType); } // Set the type information for the function reference call - auto *funcIdent = Allocator()->New(signatureRef->Function()->Id()->Name(), Allocator()); - auto *callee = Allocator()->New(fieldIdent, funcIdent, - ir::MemberExpressionKind::ELEMENT_ACCESS, false, false); + auto *funcIdent = AllocNode(signatureRef->Function()->Id()->Name(), Allocator()); + auto *callee = + AllocNode(fieldIdent, funcIdent, ir::MemberExpressionKind::ELEMENT_ACCESS, false, false); callee->SetPropVar(signatureRef->OwnerVar()->AsLocalVariable()); callee->SetObjectType(fieldPropType); callee->SetTsType(signatureRef->OwnerVar()->TsType()); @@ -2577,22 +2585,22 @@ ir::Statement *ETSChecker::ResolveLambdaObjectInvokeFuncBody(ir::ClassDefinition auto *invokeFunc = lambdaBody[lambdaBody.size() - 1]->AsMethodDefinition()->Function(); ArenaVector callParams(Allocator()->Adapter()); for (size_t idx = 0; idx != signatureRef->Params().size(); idx++) { - auto *paramIdent = Allocator()->New(signatureRef->Params()[idx]->Name(), Allocator()); + auto *paramIdent = AllocNode(signatureRef->Params()[idx]->Name(), Allocator()); paramIdent->SetVariable(invokeFunc->Params()[idx]->AsETSParameterExpression()->Variable()); paramIdent->SetTsType(invokeFunc->Params()[idx]->AsETSParameterExpression()->Variable()->TsType()); callParams.push_back(paramIdent); } // Create the synthetic call expression to the referenced function - auto *resolvedCall = Allocator()->New(callee, std::move(callParams), nullptr, false); + auto *resolvedCall = AllocNode(callee, std::move(callParams), nullptr, false); resolvedCall->SetTsType(signatureRef->ReturnType()); resolvedCall->SetSignature(signatureRef); if (signatureRef->ReturnType()->IsETSVoidType()) { - return Allocator()->New(resolvedCall); + return AllocNode(resolvedCall); } - return Allocator()->New(resolvedCall); + return AllocNode(resolvedCall); } bool ETSChecker::AreOverrideEquivalent(Signature *const s1, Signature *const s2) @@ -2660,11 +2668,11 @@ ir::MethodDefinition *ETSChecker::CreateAsyncImplMethod(ir::MethodDefinition *as varbinder::FunctionParamScope *paramScope = CopyParams(asyncFunc->Params(), params); // Set impl method return type "Object" because it may return Promise as well as Promise parameter's type - auto *objectId = Allocator()->New(compiler::Signatures::BUILTIN_OBJECT_CLASS, Allocator()); + auto *objectId = AllocNode(compiler::Signatures::BUILTIN_OBJECT_CLASS, Allocator()); objectId->SetReference(); VarBinder()->AsETSBinder()->LookupTypeReference(objectId, false); auto *returnTypeAnn = - Allocator()->New(Allocator()->New(objectId, nullptr, nullptr)); + AllocNode(AllocNode(objectId, nullptr, nullptr)); objectId->SetParent(returnTypeAnn->Part()); returnTypeAnn->Part()->SetParent(returnTypeAnn); auto *asyncFuncRetTypeAnn = asyncFunc->ReturnTypeAnnotation(); @@ -2684,8 +2692,6 @@ ir::MethodDefinition *ETSChecker::CreateAsyncImplMethod(ir::MethodDefinition *as asyncFunc->SetBody(nullptr); returnTypeAnn->SetParent(implMethod->Function()); implMethod->SetParent(asyncMethod->Parent()); - std::for_each(implMethod->Function()->Params().begin(), implMethod->Function()->Params().end(), - [implMethod](ir::Expression *param) { param->SetParent(implMethod->Function()); }); return implMethod; } @@ -2733,14 +2739,12 @@ ir::MethodDefinition *ETSChecker::CreateMethod(const util::StringView &name, ir: varbinder::FunctionParamScope *paramScope, ir::TypeNode *returnType, ir::AstNode *body) { - auto *nameId = Allocator()->New(name, Allocator()); + auto *nameId = AllocNode(name, Allocator()); auto *scope = VarBinder()->Allocator()->New(Allocator(), paramScope); - ir::ScriptFunction *func = - Allocator()->New(ir::FunctionSignature(nullptr, std::move(params), returnType), body, flags, - modifiers, false, Language(Language::Id::ETS)); + auto *func = AllocNode(ir::FunctionSignature(nullptr, std::move(params), returnType), body, + ir::ScriptFunction::ScriptFunctionData {flags, modifiers}); func->SetScope(scope); func->SetIdent(nameId); - body->SetParent(func); if (body->IsBlockStatement()) { body->AsBlockStatement()->SetScope(scope); } @@ -2748,13 +2752,11 @@ ir::MethodDefinition *ETSChecker::CreateMethod(const util::StringView &name, ir: paramScope->BindNode(func); scope->BindParamScope(paramScope); paramScope->BindFunctionScope(scope); - auto *funcExpr = Allocator()->New(func); - auto *method = Allocator()->New(ir::MethodDefinitionKind::METHOD, nameId, funcExpr, modifiers, - Allocator(), false); - funcExpr->SetParent(method); - func->SetParent(funcExpr); - nameId->SetParent(method); + auto *funcExpr = AllocNode(func); + auto *nameClone = nameId->Clone(Allocator(), nullptr); + auto *method = AllocNode(ir::MethodDefinitionKind::METHOD, nameClone, funcExpr, modifiers, + Allocator(), false); return method; } @@ -2842,7 +2844,7 @@ void ETSChecker::TransformTraillingLambda(ir::CallExpression *callExpr) ArenaVector params(Allocator()->Adapter()); auto *funcNode = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), trailingBlock, - ir::ScriptFunctionFlags::ARROW, false, Language(Language::Id::ETS)); + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::ARROW}); funcNode->SetScope(funcScope); funcScope->BindNode(funcNode); funcParamScope->BindNode(funcNode); @@ -2868,8 +2870,9 @@ ArenaVector ETSChecker::ExtendArgumentsWithFakeLamda(ir::CallE auto *body = AllocNode(Allocator(), std::move(statements)); body->SetScope(funcScope); - auto *funcNode = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::ARROW, false, Language(Language::Id::ETS)); + auto *funcNode = + AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::ARROW}); funcNode->SetScope(funcScope); funcScope->BindNode(funcNode); auto *arrowFuncNode = AllocNode(Allocator(), funcNode); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 41e52fafab41dfa69f6e896b7839b31b51e0f803..dcbc09c2907634c82699fa33e63ac7403562248d 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1123,10 +1123,11 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T if (init->IsArrowFunctionExpression()) { typeAnnotation = init->AsArrowFunctionExpression()->CreateTypeAnnotation(this); } else { - typeAnnotation = init->AsTSAsExpression()->TypeAnnotation(); + typeAnnotation = init->AsTSAsExpression()->TypeAnnotation()->Clone(Allocator(), nullptr); } ident->SetTsTypeAnnotation(typeAnnotation); typeAnnotation->SetParent(ident); + annotationType = GetTypeFromTypeAnnotation(typeAnnotation); bindingVar->SetTsType(annotationType); } @@ -2501,7 +2502,9 @@ void ETSChecker::InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunction const auto *const calleeParam = calleeType->Params()[i]->AsETSParameterExpression()->Ident(); auto *const lambdaParam = lambda->Params()[i]->AsETSParameterExpression()->Ident(); if (lambdaParam->TypeAnnotation() == nullptr) { - lambdaParam->SetTsTypeAnnotation(calleeParam->TypeAnnotation()); + auto *const typeAnnotation = calleeParam->TypeAnnotation()->Clone(Allocator(), lambdaParam); + lambdaParam->SetTsTypeAnnotation(typeAnnotation); + typeAnnotation->SetParent(lambdaParam); } } if (lambda->ReturnTypeAnnotation() == nullptr) { @@ -2556,7 +2559,7 @@ bool ETSChecker::TypeInference(Signature *signature, const ArenaVector &arguments, ETSChecker *checker) { @@ -2564,28 +2567,36 @@ void ETSChecker::AddUndefinedParamsForDefaultParams(const Signature *const signa return; } + // Just to avoid extra nested levels + auto const addDefaultLiteral = [&arguments, checker, parent](ir::TypeNode const *const typeAnnotation) -> void { + if (typeAnnotation->IsETSPrimitiveType()) { + if (typeAnnotation->AsETSPrimitiveType()->GetPrimitiveType() == ir::PrimitiveType::BOOLEAN) { + arguments.push_back(checker->Allocator()->New(false)); + } else { + arguments.push_back(checker->Allocator()->New(lexer::Number(0))); + } + arguments.back()->SetParent(parent); + } else { + // A proxy-function is called, so default reference parameters + // are initialized with null instead of undefined + auto *const nullLiteral = checker->Allocator()->New(); + nullLiteral->SetTsType(checker->GlobalETSNullType()); + nullLiteral->SetParent(parent); + arguments.push_back(nullLiteral); + } + }; + uint32_t num = 0; - for (size_t i = arguments.size(); i != signature->Function()->Params().size() - 1; i++) { + for (size_t i = arguments.size(); i != signature->Function()->Params().size() - 1U; ++i) { if (auto const *const param = signature->Function()->Params()[i]->AsETSParameterExpression(); !param->IsRestParameter()) { - auto const *const typeAnn = param->Ident()->TypeAnnotation(); - if (typeAnn->IsETSPrimitiveType()) { - if (typeAnn->AsETSPrimitiveType()->GetPrimitiveType() == ir::PrimitiveType::BOOLEAN) { - arguments.push_back(checker->Allocator()->New(false)); - } else { - arguments.push_back(checker->Allocator()->New(lexer::Number(0))); - } - } else { - // A proxy-function is called, so default reference parameters - // are initialized with null instead of undefined - auto *const nullLiteral = checker->Allocator()->New(); - nullLiteral->SetTsType(checker->GlobalETSNullType()); - arguments.push_back(nullLiteral); - } + addDefaultLiteral(param->Ident()->TypeAnnotation()); num |= (1U << (arguments.size() - 1)); } } + arguments.push_back(checker->Allocator()->New(lexer::Number(num))); + arguments.back()->SetParent(parent); } bool ETSChecker::ExtensionETSFunctionType(checker::Type *type) @@ -2643,25 +2654,27 @@ void ETSChecker::GenerateGetterSetterBody(ETSChecker *checker, ArenaVectorAllocator()->New(field->Key())); + stmts.push_back(checker->AllocNode( + field->Key()->Clone(checker->Allocator(), nullptr)->AsExpression())); return; } - auto *paramIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator()); - paramIdent->SetTsTypeAnnotation(field->TypeAnnotation()->Clone(checker->Allocator())); - paramIdent->TypeAnnotation()->SetParent(paramIdent); + auto *const paramIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator(), nullptr); + auto *const typeAnnotation = field->TypeAnnotation()->Clone(checker->Allocator(), nullptr); + paramIdent->SetTsTypeAnnotation(typeAnnotation); + typeAnnotation->SetParent(paramIdent); auto *paramExpression = checker->AllocNode(paramIdent, nullptr); paramExpression->SetRange(paramIdent->Range()); - auto *const paramVar = std::get<2>(paramScope->AddParamDecl(checker->Allocator(), paramExpression)); - paramIdent->SetVariable(paramVar); + auto *const paramVar = std::get<2>(paramScope->AddParamDecl(checker->Allocator(), paramExpression)); paramExpression->SetVariable(paramVar); params.push_back(paramExpression); auto *assignmentExpression = checker->AllocNode( - field->Key(), paramExpression, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + field->Key()->Clone(Allocator(), nullptr)->AsExpression(), paramExpression->Clone(Allocator(), nullptr), + lexer::TokenType::PUNCTUATOR_SUBSTITUTION); assignmentExpression->SetRange({field->Start(), field->End()}); @@ -2687,16 +2700,16 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty auto *body = checker->AllocNode(checker->Allocator(), std::move(stmts)); auto funcFlags = isSetter ? ir::ScriptFunctionFlags::SETTER : ir::ScriptFunctionFlags::GETTER; - auto *const returnTypeAnn = isSetter ? nullptr : field->TypeAnnotation(); + auto *const returnTypeAnn = isSetter ? nullptr : field->TypeAnnotation()->Clone(checker->Allocator(), nullptr); auto *func = checker->AllocNode(ir::FunctionSignature(nullptr, std::move(params), returnTypeAnn), body, - funcFlags, flags, true, Language(Language::Id::ETS)); + ir::ScriptFunction::ScriptFunctionData {funcFlags, flags, true}); func->SetRange(field->Range()); func->SetScope(functionScope); body->SetScope(functionScope); - auto *methodIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator()); + auto *methodIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator(), nullptr); auto *decl = checker->Allocator()->New( checker->Allocator(), field->Key()->AsIdentifier()->Name(), field->Key()->AsIdentifier()->Variable()->Declaration()->Node()); @@ -2713,7 +2726,7 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty method->Id()->SetMutator(); method->SetRange(field->Range()); - method->Function()->SetIdent(method->Id()); + method->Function()->SetIdent(method->Id()->Clone(checker->Allocator(), nullptr)); method->Function()->AddModifier(method->Modifiers()); method->SetVariable(var); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 8c06deccbc40e0c84799fcc304c753c462a02968..3a7cca64505418fab0e7c2289153087af148571a 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -435,34 +435,51 @@ static void ResolveDeclaredMethodsOfObject(ETSChecker *checker, ETSObjectType *t { for (auto &[_, it] : scope->InstanceMethodScope()->Bindings()) { (void)_; - auto *node = it->Declaration()->Node()->AsMethodDefinition(); + auto *method = it->Declaration()->Node()->AsMethodDefinition(); + auto *function = method->Function(); - if (node->Function()->IsProxy()) { + function->Id()->SetVariable(method->Id()->Variable()); + for (ir::MethodDefinition *const overload : method->Overloads()) { + overload->Function()->Id()->SetVariable(overload->Id()->Variable()); + } + + if (function->IsProxy()) { continue; } - it->AddFlag(checker->GetAccessFlagFromNode(node)); - auto *funcType = checker->BuildMethodSignature(node); + it->AddFlag(checker->GetAccessFlagFromNode(method)); + auto *funcType = checker->BuildMethodSignature(method); it->SetTsType(funcType); funcType->SetVariable(it); - node->SetTsType(funcType); + method->SetTsType(funcType); type->AddProperty(it->AsLocalVariable()); } for (auto &[_, it] : scope->StaticMethodScope()->Bindings()) { (void)_; - if (!it->Declaration()->Node()->IsMethodDefinition() || - it->Declaration()->Node()->AsMethodDefinition()->Function()->IsProxy()) { + if (!it->Declaration()->Node()->IsMethodDefinition()) { continue; } - auto *node = it->Declaration()->Node()->AsMethodDefinition(); - it->AddFlag(checker->GetAccessFlagFromNode(node)); - auto *funcType = checker->BuildMethodSignature(node); + + auto *method = it->Declaration()->Node()->AsMethodDefinition(); + auto *function = method->Function(); + + function->Id()->SetVariable(method->Id()->Variable()); + for (ir::MethodDefinition *const overload : method->Overloads()) { + overload->Function()->Id()->SetVariable(overload->Id()->Variable()); + } + + if (function->IsProxy()) { + continue; + } + + it->AddFlag(checker->GetAccessFlagFromNode(method)); + auto *funcType = checker->BuildMethodSignature(method); it->SetTsType(funcType); funcType->SetVariable(it); - node->SetTsType(funcType); + method->SetTsType(funcType); - if (node->IsConstructor()) { + if (method->IsConstructor()) { type->AddConstructSignature(funcType->CallSignatures()); continue; } @@ -846,6 +863,7 @@ void ETSChecker::CreateAsyncProxyMethods(ir::ClassDefinition *classDef) } } for (auto *it : asyncImpls) { + it->SetParent(classDef); it->Check(this); classDef->Body().push_back(it); } @@ -1492,6 +1510,7 @@ void ETSChecker::TransformProperties(ETSObjectType *classType) ir::MethodDefinition *getter = GenerateDefaultGetterSetter(classProp, scope->AsClassScope(), false, this); classDef->Body().push_back(getter); + getter->SetParent(classDef); classType->AddProperty(getter->Variable()->AsLocalVariable()); auto *const methodScope = scope->AsClassScope()->InstanceMethodScope(); @@ -1509,6 +1528,7 @@ void ETSChecker::TransformProperties(ETSObjectType *classType) if (!classProp->IsReadonly()) { ir::MethodDefinition *const setter = GenerateDefaultGetterSetter(classProp, scope->AsClassScope(), true, this); + setter->SetParent(classDef); classType->AddProperty(setter->Variable()->AsLocalVariable()); prevDecl->Node()->AsMethodDefinition()->AddOverload(setter); @@ -1522,6 +1542,7 @@ void ETSChecker::TransformProperties(ETSObjectType *classType) if (!classProp->IsReadonly()) { ir::MethodDefinition *const setter = GenerateDefaultGetterSetter(classProp, scope->AsClassScope(), true, this); + setter->SetParent(classDef); classType->AddProperty(setter->Variable()->AsLocalVariable()); getter->AddOverload(setter); diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index ea39dcd47ced2ae9e31fc730999c79875efd611f..ff45c96a13bd38d41d479b11396eed04a1ab21ba 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -389,28 +389,40 @@ ETSEnumType *ETSChecker::CreateETSEnumType(ir::TSEnumDeclaration const *const en auto *const namesArrayIdent = CreateEnumNamesArray(enumType); - auto const getNameMethod = CreateEnumGetNameMethod(namesArrayIdent, enumType); + auto *identClone = namesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(namesArrayIdent->TsType()); + auto const getNameMethod = CreateEnumGetNameMethod(identClone, enumType); enumType->SetGetNameMethod(getNameMethod); - auto const valueOfMethod = CreateEnumValueOfMethod(namesArrayIdent, enumType); + identClone = namesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(namesArrayIdent->TsType()); + auto const valueOfMethod = CreateEnumValueOfMethod(identClone, enumType); enumType->SetValueOfMethod(valueOfMethod); - auto const fromIntMethod = CreateEnumFromIntMethod(namesArrayIdent, enumType); + identClone = namesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(namesArrayIdent->TsType()); + auto const fromIntMethod = CreateEnumFromIntMethod(identClone, enumType); enumType->SetFromIntMethod(fromIntMethod); auto *const valuesArrayIdent = CreateEnumValuesArray(enumType); - auto const getValueMethod = CreateEnumGetValueMethod(valuesArrayIdent, enumType); + identClone = valuesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(valuesArrayIdent->TsType()); + auto const getValueMethod = CreateEnumGetValueMethod(identClone, enumType); enumType->SetGetValueMethod(getValueMethod); auto *const stringValuesArrayIdent = CreateEnumStringValuesArray(enumType); - auto const toStringMethod = CreateEnumToStringMethod(stringValuesArrayIdent, enumType); + identClone = stringValuesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(stringValuesArrayIdent->TsType()); + auto const toStringMethod = CreateEnumToStringMethod(identClone, enumType); enumType->SetToStringMethod(toStringMethod); auto *const itemsArrayIdent = CreateEnumItemsArray(enumType); - auto const valuesMethod = CreateEnumValuesMethod(itemsArrayIdent, enumType); + identClone = itemsArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(itemsArrayIdent->TsType()); + auto const valuesMethod = CreateEnumValuesMethod(identClone, enumType); enumType->SetValuesMethod(valuesMethod); for (auto *const member : enumType->GetMembers()) { @@ -444,24 +456,34 @@ ETSStringEnumType *ETSChecker::CreateETSStringEnumType(ir::TSEnumDeclaration con auto *const namesArrayIdent = CreateEnumNamesArray(enumType); - auto const getNameMethod = CreateEnumGetNameMethod(namesArrayIdent, enumType); + auto *identClone = namesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(namesArrayIdent->TsType()); + auto const getNameMethod = CreateEnumGetNameMethod(identClone, enumType); enumType->SetGetNameMethod(getNameMethod); - auto const valueOfMethod = CreateEnumValueOfMethod(namesArrayIdent, enumType); + identClone = namesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(namesArrayIdent->TsType()); + auto const valueOfMethod = CreateEnumValueOfMethod(identClone, enumType); enumType->SetValueOfMethod(valueOfMethod); - auto const fromIntMethod = CreateEnumFromIntMethod(namesArrayIdent, enumType); + identClone = namesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(namesArrayIdent->TsType()); + auto const fromIntMethod = CreateEnumFromIntMethod(identClone, enumType); enumType->SetFromIntMethod(fromIntMethod); auto *const stringValuesArrayIdent = CreateEnumStringValuesArray(enumType); - auto const toStringMethod = CreateEnumToStringMethod(stringValuesArrayIdent, enumType); + identClone = stringValuesArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(stringValuesArrayIdent->TsType()); + auto const toStringMethod = CreateEnumToStringMethod(identClone, enumType); enumType->SetToStringMethod(toStringMethod); enumType->SetGetValueMethod(toStringMethod); auto *const itemsArrayIdent = CreateEnumItemsArray(enumType); - auto const valuesMethod = CreateEnumValuesMethod(itemsArrayIdent, enumType); + identClone = itemsArrayIdent->Clone(Allocator(), nullptr); + identClone->SetTsType(itemsArrayIdent->TsType()); + auto const valuesMethod = CreateEnumValuesMethod(identClone, enumType); enumType->SetValuesMethod(valuesMethod); for (auto *const member : enumType->GetMembers()) { diff --git a/ets2panda/compiler/core/ASTVerifier.cpp b/ets2panda/compiler/core/ASTVerifier.cpp index 405acad229c1357c720e4adf45391f06c60ea615..921d856a990d33e3e3d7fd0282b29760aa0c007f 100644 --- a/ets2panda/compiler/core/ASTVerifier.cpp +++ b/ets2panda/compiler/core/ASTVerifier.cpp @@ -219,7 +219,8 @@ public: ASTVerifier::CheckResult operator()(ASTVerifier::ErrorContext &ctx, const ir::AstNode *ast) { - const auto isEtsScript = ast->IsETSScript(); + const auto isEtsScript = + ast->IsETSScript() || (ast->IsBlockStatement() && ast->AsBlockStatement()->IsProgram()); const auto hasParent = ast->Parent() != nullptr; if (!isEtsScript && !hasParent) { ctx.AddInvariantError("NodeHasParent", "NULL_PARENT", *ast); @@ -361,16 +362,33 @@ public: ASTVerifier::CheckResult operator()(ASTVerifier::ErrorContext &ctx, const ir::AstNode *ast) { + ASSERT(ast != nullptr); + auto result = ASTVerifier::CheckResult::SUCCESS; if (ast->IsETSScript()) { return result; } + ast->Iterate([&](const ir::AstNode *node) { - if (ast != node->Parent()) { + if (ir::AstNode const *parent = node->Parent(); ast != parent) { + // NOTE: Temporary suppress. + // Should be removed after special lowering for lambda-functions will be implemented: #14376 + if ((ast->IsScriptFunction() || ast->IsETSFunctionType()) && parent != nullptr && + parent->IsScriptFunction()) { + return; + } + + // NOTE: Temporary suppress. + // Should be removed after new ENUMs support will be implemented: #14443 + if (ast->IsClassDeclaration() && parent != nullptr && parent->IsETSNewClassInstanceExpression()) { + return; + } + ctx.AddInvariantError("EveryChildHasValidParent", "INCORRECT_PARENT_REF", *node); result = ASTVerifier::CheckResult::FAILED; } }); + return result; } diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index a5bc7da17f8c88a8590f7f614c19c2cde78c9772..dfc46cabf36654d55d80455cc9d1a91f999718ef 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -110,11 +110,15 @@ static void Verify(const parser::Program &program, const CompilerContext &contex using NamedProgram = std::tuple; ArenaVector toCheck {program.Allocator()->Adapter()}; toCheck.push_back(std::make_tuple(program.SourceFilePath(), &program)); + + // collect list of checks for (const auto &externalSource : program.ExternalSources()) { for (const auto *external : externalSource.second) { toCheck.push_back(std::make_tuple(external->SourceFilePath(), external)); } } + + // check for (const auto &it : toCheck) { const auto &sourceName = std::get<0>(it); const auto &linkedProgram = std::get<1>(it); @@ -123,6 +127,20 @@ static void Verify(const parser::Program &program, const CompilerContext &contex verificationCtx.IntroduceNewInvariants(phase->Name()); } } + +static void Report(const CompilerContext &context, ASTVerifierContext &verificationCtx) +{ + if (!context.Options()->verifierWarnings.empty()) { + if (auto errors = verificationCtx.DumpWarningsJSON(); errors != "[]") { + LOG(ERROR, ES2PANDA) << errors; + } + } + if (!context.Options()->verifierErrors.empty()) { + if (auto errors = verificationCtx.DumpAssertsJSON(); errors != "[]") { + ASSERT_PRINT(false, errors); + } + } +} #endif using EmitCb = std::function; @@ -169,21 +187,14 @@ static pandasm::Program *CreateCompiler(const CompilationUnit &unit, const Phase return nullptr; } #ifndef NDEBUG - Verify(program, context, phase, verificationCtx); + if (unit.ext == ScriptExtension::ETS) { + Verify(program, context, phase, verificationCtx); + } #endif } #ifndef NDEBUG - if (!context.Options()->verifierWarnings.empty()) { - if (auto errors = verificationCtx.DumpWarningsJSON(); errors != "[]") { - LOG(ERROR, ES2PANDA) << errors; - } - } - if (!context.Options()->verifierErrors.empty()) { - if (auto errors = verificationCtx.DumpAssertsJSON(); errors != "[]") { - ASSERT_PRINT(false, errors); - } - } + Report(context, verificationCtx); #endif emitter.GenAnnotation(); diff --git a/ets2panda/compiler/lowering/ets/expandBrackets.cpp b/ets2panda/compiler/lowering/ets/expandBrackets.cpp index d8936fe26a9f60761cdbd080b6cac0bcf7a2114d..f5915b3187f19baaa32cad1bc7b456ff4a3204c6 100644 --- a/ets2panda/compiler/lowering/ets/expandBrackets.cpp +++ b/ets2panda/compiler/lowering/ets/expandBrackets.cpp @@ -61,7 +61,7 @@ bool ExpandBracketsPhase::Perform(public_lib::Context *ctx, parser::Program *pro " throw new TypeError(\"Index fractional part should not be different from 0.0\");" "};" "(@@E5);", - parser::DEFAULT_SOURCE_FILE, ident, dimension, exprType, ident->Clone(allocator), newExpression); + parser::DEFAULT_SOURCE_FILE, ident, dimension, exprType, ident->Clone(allocator, nullptr), newExpression); sequenceExpr->SetParent(newExpression->Parent()); InitScopesPhaseETS::RunExternalNode(sequenceExpr, ctx->compilerContext->VarBinder()); checker->VarBinder()->AsETSBinder()->ResolveReferencesForScope(sequenceExpr, scope); diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index 97b56809eb6984326651ea51d1dbcee4b8cfb6e9..35a6278c38eaa18ee5e49ff427a86af58543df26 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -45,8 +45,8 @@ static ir::MethodDefinition *GenerateGetterOrSetter(checker::ETSChecker *const c ArenaVector params(checker->Allocator()->Adapter()); if (isSetter) { - auto paramIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator()); - paramIdent->SetTsTypeAnnotation(field->TypeAnnotation()->Clone(checker->Allocator())); + auto paramIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator(), nullptr); + paramIdent->SetTsTypeAnnotation(field->TypeAnnotation()->Clone(checker->Allocator(), nullptr)); paramIdent->TypeAnnotation()->SetParent(paramIdent); auto *const paramExpression = checker->AllocNode(paramIdent, nullptr); @@ -61,17 +61,17 @@ static ir::MethodDefinition *GenerateGetterOrSetter(checker::ETSChecker *const c auto signature = ir::FunctionSignature(nullptr, std::move(params), isSetter ? nullptr : field->TypeAnnotation()); - auto *func = - isSetter - ? checker->AllocNode(std::move(signature), nullptr, ir::ScriptFunctionFlags::SETTER, - flags, true, Language(Language::Id::ETS)) - : checker->AllocNode(std::move(signature), nullptr, ir::ScriptFunctionFlags::GETTER, - flags, true, Language(Language::Id::ETS)); + auto *func = isSetter ? checker->AllocNode( + std::move(signature), nullptr, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::SETTER, flags, true}) + : checker->AllocNode( + std::move(signature), nullptr, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::GETTER, flags, true}); func->SetRange(field->Range()); func->SetScope(functionScope); - auto methodIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator()); + auto methodIdent = field->Key()->AsIdentifier()->Clone(checker->Allocator(), nullptr); auto *decl = checker->Allocator()->New(field->Key()->AsIdentifier()->Name()); auto var = functionScope->AddDecl(checker->Allocator(), decl, ScriptExtension::ETS); @@ -86,7 +86,7 @@ static ir::MethodDefinition *GenerateGetterOrSetter(checker::ETSChecker *const c method->Id()->SetMutator(); method->SetRange(field->Range()); - method->Function()->SetIdent(method->Id()); + method->Function()->SetIdent(method->Id()->Clone(checker->Allocator(), nullptr)); method->Function()->AddModifier(method->Modifiers()); paramScope->BindNode(func); functionScope->BindNode(func); diff --git a/ets2panda/compiler/lowering/ets/opAssignment.cpp b/ets2panda/compiler/lowering/ets/opAssignment.cpp index 9b4bfa606ba31d881cd882c665d28ff3401a5bc1..8253e18c6adf1e7876d37c14c22793d5a69f84e3 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.cpp +++ b/ets2panda/compiler/lowering/ets/opAssignment.cpp @@ -71,8 +71,21 @@ static lexer::TokenType OpEqualToOp(const lexer::TokenType opEqual) UNREACHABLE(); } -void AdjustBoxingUnboxingFlags(ir::Expression *newExpr, const ir::Expression *oldExpr) +void AdjustBoxingUnboxingFlags(ir::Expression *loweringResult, const ir::Expression *oldExpr) { + ir::AssignmentExpression *newAssignment = nullptr; + if (loweringResult->IsAssignmentExpression()) { + newAssignment = loweringResult->AsAssignmentExpression(); + } else if (loweringResult->IsBlockExpression() && !loweringResult->AsBlockExpression()->Statements().empty()) { + auto *statement = loweringResult->AsBlockExpression()->Statements().back(); + if (statement->IsExpressionStatement() && + statement->AsExpressionStatement()->GetExpression()->IsAssignmentExpression()) { + newAssignment = statement->AsExpressionStatement()->GetExpression()->AsAssignmentExpression(); + } + } else { + UNREACHABLE(); + } + // NOTE: gogabr. make sure that the checker never puts both a boxing and an unboxing flag on the same node. // Then this function will become unnecessary. const ir::BoxingUnboxingFlags oldBoxingFlag {oldExpr->GetBoxingUnboxingFlags() & @@ -80,11 +93,47 @@ void AdjustBoxingUnboxingFlags(ir::Expression *newExpr, const ir::Expression *ol const ir::BoxingUnboxingFlags oldUnboxingFlag {oldExpr->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG}; - if (newExpr->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { - newExpr->SetBoxingUnboxingFlags(oldBoxingFlag); - } else if (newExpr->TsType()->IsETSObjectType()) { - newExpr->SetBoxingUnboxingFlags(oldUnboxingFlag); + if (newAssignment->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + newAssignment->SetBoxingUnboxingFlags(oldBoxingFlag); + } else if (newAssignment->TsType()->IsETSObjectType()) { + newAssignment->SetBoxingUnboxingFlags(oldUnboxingFlag); + } +} + +static ir::OpaqueTypeNode *CreateProxyTypeNode(checker::ETSChecker *checker, ir::Expression *expr) +{ + auto *lcType = expr->TsType(); + if (auto *lcTypeAsPrimitive = checker->ETSBuiltinTypeAsPrimitiveType(lcType); lcTypeAsPrimitive != nullptr) { + lcType = lcTypeAsPrimitive; + } + return checker->AllocNode(lcType); +} + +static std::string GenerateStringForLoweredAssignment(lexer::TokenType opEqual, bool hasProperty, ir::Expression *expr) +{ + std::string leftHand = "@@I5"; + std::string rightHand = "@@I7"; + + if (hasProperty) { + auto const kind = expr->AsMemberExpression()->Kind(); + if (kind == ir::MemberExpressionKind::PROPERTY_ACCESS) { + leftHand += ".@@I6"; + rightHand += ".@@I8"; + } else if (kind == ir::MemberExpressionKind::ELEMENT_ACCESS) { + leftHand += "[@@I6]"; + rightHand += "[@@I8]"; + } else { + UNREACHABLE(); + } } + + return leftHand + " = (" + rightHand + ' ' + std::string {lexer::TokenToString(OpEqualToOp(opEqual))} + + " (@@E9)) as @@T10"; +} + +static ir::Identifier *GetClone(ArenaAllocator *allocator, ir::Identifier *node) +{ + return node != nullptr ? node->Clone(allocator, nullptr) : nullptr; } ir::Expression *HandleOpAssignment(public_lib::Context *ctx, checker::ETSChecker *checker, parser::ETSParser *parser, @@ -136,71 +185,25 @@ ir::Expression *HandleOpAssignment(public_lib::Context *ctx, checker::ETSChecker UNREACHABLE(); } - // Create proxy TypeNode for left hand of assignment expression - auto *lcType = left->TsType(); - if (auto *lcTypeAsPrimitive = checker->ETSBuiltinTypeAsPrimitiveType(lcType); lcTypeAsPrimitive != nullptr) { - lcType = lcTypeAsPrimitive; - } - auto *exprType = checker->AllocNode(lcType); + auto *exprType = CreateProxyTypeNode(checker, left); // Generate ArkTS code string for new lowered assignment expression: - std::string leftHand = "@@I5"; - std::string rightHand = "@@I7"; - - if (ident2 != nullptr) { - if (auto const kind = left->AsMemberExpression()->Kind(); kind == ir::MemberExpressionKind::PROPERTY_ACCESS) { - leftHand += ".@@I6"; - rightHand += ".@@I8"; - } else if (kind == ir::MemberExpressionKind::ELEMENT_ACCESS) { - leftHand += "[@@I6]"; - rightHand += "[@@I8]"; - } else { - UNREACHABLE(); - } - } - - newAssignmentStatements += leftHand + " = (" + rightHand + ' ' + - std::string {lexer::TokenToString(OpEqualToOp(opEqual))} + " (@@E9)) as @@T10"; - // std::cout << "Lowering statements: " << new_assignment_statements << std::endl; + newAssignmentStatements += GenerateStringForLoweredAssignment(opEqual, ident2 != nullptr, left); // Parse ArkTS code string and create and process corresponding AST node(s) auto expressionCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), scope); - auto *loweringResult = parser->CreateFormattedExpression( - newAssignmentStatements, parser::DEFAULT_SOURCE_FILE, ident1, object, ident2, property, - ident1->Clone(allocator), ident2 != nullptr ? ident2->Clone(allocator) : nullptr, ident1->Clone(allocator), - ident2 != nullptr ? ident2->Clone(allocator) : nullptr, right, exprType); + auto *loweringResult = + parser->CreateFormattedExpression(newAssignmentStatements, parser::DEFAULT_SOURCE_FILE, ident1, object, ident2, + property, GetClone(allocator, ident1), GetClone(allocator, ident2), + GetClone(allocator, ident1), GetClone(allocator, ident2), right, exprType); loweringResult->SetParent(assignment->Parent()); InitScopesPhaseETS::RunExternalNode(loweringResult, ctx->compilerContext->VarBinder()); checker->VarBinder()->AsETSBinder()->ResolveReferencesForScope(loweringResult, scope); loweringResult->Check(checker); - // Adjust [un]boxing flag - ir::AssignmentExpression *newAssignment; - if (loweringResult->IsAssignmentExpression()) { - newAssignment = loweringResult->AsAssignmentExpression(); - } else if (loweringResult->IsBlockExpression() && !loweringResult->AsBlockExpression()->Statements().empty() && - loweringResult->AsBlockExpression()->Statements().back()->IsExpressionStatement() && - loweringResult->AsBlockExpression() - ->Statements() - .back() - ->AsExpressionStatement() - ->GetExpression() - ->IsAssignmentExpression()) { - newAssignment = loweringResult->AsBlockExpression() - ->Statements() - .back() - ->AsExpressionStatement() - ->GetExpression() - ->AsAssignmentExpression(); - } else { - UNREACHABLE(); - } - - // NOTE(gogabr): make sure that the checker never puts both a boxing and an unboxing flag on the same node. - // Then this code will become unnecessary. - AdjustBoxingUnboxingFlags(newAssignment, assignment); + AdjustBoxingUnboxingFlags(loweringResult, assignment); return loweringResult; } diff --git a/ets2panda/compiler/lowering/ets/tupleLowering.cpp b/ets2panda/compiler/lowering/ets/tupleLowering.cpp index 5d81de89d92defb083849f27f1ce2981cb5b398c..67132fed0935af2176618ed5b64411a6a99e739e 100644 --- a/ets2panda/compiler/lowering/ets/tupleLowering.cpp +++ b/ets2panda/compiler/lowering/ets/tupleLowering.cpp @@ -81,13 +81,16 @@ static ir::Expression *ConvertTupleUpdate(checker::ETSChecker *const checker, ir // Clone argument of update expression (conversion flag might be added to it, so we need to duplicate it to not make // conversions on 'line 3', that belongs to 'line 1' ) auto *const memberExpr = argument->AsMemberExpression(); - auto *const argumentClone = - checker->AllocNode(memberExpr->Object(), memberExpr->Property(), memberExpr->Kind(), - memberExpr->IsComputed(), memberExpr->IsOptional()); - argumentClone->SetPropVar(memberExpr->PropVar()); - argumentClone->SetParent(memberExpr->Parent()); + auto *const argumentClone = memberExpr->Clone(checker->Allocator(), memberExpr->Parent()); + argumentClone->Object()->SetTsType(memberExpr->Object()->TsType()); + if (argumentClone->Object()->IsIdentifier()) { + argumentClone->Object()->AsIdentifier()->SetVariable(memberExpr->Object()->AsIdentifier()->Variable()); + } + argumentClone->Property()->SetTsType(memberExpr->Property()->TsType()); + if (argumentClone->Property()->IsIdentifier()) { + argumentClone->Property()->AsIdentifier()->SetVariable(memberExpr->Property()->AsIdentifier()->Variable()); + } argumentClone->SetTsType(memberExpr->TsType()); - argumentClone->SetObjectType(memberExpr->ObjType()); // -------------- // Generate temporary symbols @@ -113,20 +116,29 @@ static ir::Expression *ConvertTupleUpdate(checker::ETSChecker *const checker, ir // -------------- // make node: let gensym2 = (gensym)++; - auto *gensymUpdate = checker->AllocNode(gensym, update->OperatorType(), update->IsPrefix()); + auto *identClone = gensym->Clone(checker->Allocator(), nullptr); + identClone->SetTsType(tmpVar->TsType()); + auto *gensymUpdate = + checker->AllocNode(identClone, update->OperatorType(), update->IsPrefix()); auto *const gensym2Assignment = checker->AllocNode(gensym2, gensymUpdate, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); // -------------- // make node: tuple[n] = (gensym as ) as ; - auto *gensymAs = checker->AllocNode(gensym, tupleTypeAtIdxNode, false); + identClone = gensym->Clone(checker->Allocator(), nullptr); + identClone->SetTsType(tmpVar->TsType()); + auto *gensymAs = checker->AllocNode( + identClone, tupleTypeAtIdxNode->Clone(checker->Allocator(), nullptr), false); auto *gensymAsTupleTypeAtIdx = checker->AllocNode(gensymAs, tupleElementTypeNode, false); auto *const tupleAssignment = checker->AllocNode( argument, gensymAsTupleTypeAtIdx, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); // -------------- // make node: gensym2 as ; - auto *const finalTupleNode = checker->AllocNode(gensym2, tupleTypeAtIdxNode, false); + identClone = gensym2->Clone(checker->Allocator(), nullptr); + identClone->SetTsType(tmpVar2->TsType()); + auto *const finalTupleNode = checker->AllocNode( + identClone, tupleTypeAtIdxNode->Clone(checker->Allocator(), nullptr), false); // -------------- // Construct sequence expression order diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index ef64447b6944d8ca51ff118cfb8fa9bacefa6218..f6b9c5f3949eb20ed6418a202af6b4c659691528 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -167,7 +167,7 @@ ir::TSAsExpression *HandleUnionCastToPrimitive(checker::ETSChecker *checker, ir: ir::BinaryExpression *GenInstanceofExpr(checker::ETSChecker *checker, ir::Expression *unionNode, checker::Type *constituentType) { - auto *const lhsExpr = unionNode->Clone(checker->Allocator())->AsExpression(); + auto *const lhsExpr = unionNode->Clone(checker->Allocator(), nullptr)->AsExpression(); lhsExpr->Check(checker); lhsExpr->SetBoxingUnboxingFlags(unionNode->GetBoxingUnboxingFlags()); auto *rhsType = constituentType; @@ -240,7 +240,6 @@ ir::BlockStatement *GenBlockStmtForAssignmentBinary(checker::ETSChecker *checker stmts.push_back(stmt); auto *const localBlockStmt = checker->AllocNode(checker->Allocator(), std::move(stmts)); localBlockStmt->SetScope(localCtx.GetScope()); - stmt->SetParent(localBlockStmt); localBlockStmt->SetRange(stmt->Range()); localCtx.GetScope()->BindNode(localBlockStmt); return localBlockStmt; @@ -329,12 +328,7 @@ ir::BlockStatement *ReplaceBinaryExprInStmt(checker::ETSChecker *checker, ir::Ex clonedBinary->Check(checker); auto *const consequent = GenBlockStmtForAssignmentBinary( checker, varDeclId->AsIdentifier(), ProcessOperandsInBinaryExpr(checker, clonedBinary, uType)); - instanceofTree = checker->Allocator()->New(test, consequent, instanceofTree); - test->SetParent(instanceofTree); - consequent->SetParent(instanceofTree); - if (instanceofTree->Alternate() != nullptr) { - instanceofTree->Alternate()->SetParent(instanceofTree); - } + instanceofTree = checker->AllocNode(test, consequent, instanceofTree); } ASSERT(instanceofTree != nullptr); // Replacing a binary expression with an identifier diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index 736ba8c6cdf4bc7beef7a3a4389db2618998c8e9..3c4e61f9717db87ee81e80fdafda7d6df918f19d 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -400,7 +400,7 @@ void ScopesInitPhase::VisitFunctionExpression(ir::FunctionExpression *funcExpr) auto id = funcExpr->Id(); auto *funcParamScope = func->Scope()->ParamScope(); funcParamScope->BindName(Allocator(), id->Name()); - func->SetIdent(id); + func->SetIdent(id->Clone(Allocator(), nullptr)); } } @@ -734,16 +734,22 @@ void InitScopesPhaseETS::VisitImportNamespaceSpecifier(ir::ImportNamespaceSpecif Iterate(importSpec); } -void InitScopesPhaseETS::DeclareClassMethod(ir::MethodDefinition *method) +// Auxiliary method to avoid extra nested levels and too large function size +void AddOverload(ir::MethodDefinition *overload, varbinder::Variable *variable) noexcept { - const auto methodName = method->Id(); + auto *currentNode = variable->Declaration()->Node(); + currentNode->AsMethodDefinition()->AddOverload(overload); + overload->Id()->SetVariable(variable); +} +void InitScopesPhaseETS::DeclareClassMethod(ir::MethodDefinition *method) +{ ASSERT(VarBinder()->GetScope()->IsClassScope()); - if (method->AsMethodDefinition()->Function()->IsDefaultParamProxy()) { return; } + const auto methodName = method->Id(); auto *const clsScope = VarBinder()->GetScope()->AsClassScope(); if (clsScope->FindLocal(methodName->Name(), varbinder::ResolveBindingOptions::VARIABLES | varbinder::ResolveBindingOptions::DECLARATION) != nullptr) { @@ -758,18 +764,10 @@ void InitScopesPhaseETS::DeclareClassMethod(ir::MethodDefinition *method) } auto *found = targetScope->FindLocal(methodName->Name(), varbinder::ResolveBindingOptions::BINDINGS); - auto addOverload = [](ir::MethodDefinition *overload, varbinder::Variable *of) { - auto *currentNode = of->Declaration()->Node(); - currentNode->AsMethodDefinition()->AddOverload(overload); - overload->Id()->SetVariable(of); - overload->SetParent(currentNode); - }; - if (found == nullptr) { auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), targetScope); - auto [_, var] = VarBinder()->NewVarDecl(methodName->Start(), Allocator(), - methodName->Name(), method); - (void)_; + [[maybe_unused]] auto [_, var] = VarBinder()->NewVarDecl( + methodName->Start(), Allocator(), methodName->Name(), method); var->SetScope(clsScope); var->AddFlag(varbinder::VariableFlags::METHOD); methodName->SetVariable(var); @@ -782,13 +780,13 @@ void InitScopesPhaseETS::DeclareClassMethod(ir::MethodDefinition *method) if (methodName->Name().Is(compiler::Signatures::MAIN) && clsScope->Parent()->IsGlobalScope()) { ThrowSyntaxError("Main overload is not enabled", methodName->Start()); } - addOverload(method, found); + AddOverload(method, found); method->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD); // default params proxy for (auto *overload : method->Overloads()) { ASSERT(overload->Function()->IsDefaultParamProxy()); - addOverload(overload, found); + AddOverload(overload, found); } method->ClearOverloads(); } diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index 4b20f93db346cc953bcf72a36e663d1400b190c3..3075935b3a9af3f5d7a45d91fc64f3b552e27d28 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -484,9 +484,8 @@ public: [[nodiscard]] ir::BlockStatement *GetTopStatement(); [[nodiscard]] const ir::BlockStatement *GetTopStatement() const; - // NOLINTNEXTLINE(google-default-arguments) [[nodiscard]] virtual AstNode *Clone([[maybe_unused]] ArenaAllocator *const allocator, - [[maybe_unused]] AstNode *const parent = nullptr) + [[maybe_unused]] AstNode *const parent) { UNREACHABLE(); } diff --git a/ets2panda/ir/base/classDefinition.cpp b/ets2panda/ir/base/classDefinition.cpp index cfb7ac8dc8e3fad80cfdd96a3f50e5f338dd6d33..94b77be1b6577a18913e0aecb3d66c34b26a1d07 100644 --- a/ets2panda/ir/base/classDefinition.cpp +++ b/ets2panda/ir/base/classDefinition.cpp @@ -117,6 +117,14 @@ void ClassDefinition::Iterate(const NodeTraverser &cb) const } } +void ClassDefinition::SetIdent(ir::Identifier *ident) noexcept +{ + ident_ = ident; + if (ident_ != nullptr) { + ident_->SetParent(this); + } +} + void ClassDefinition::Dump(ir::AstDumper *dumper) const { auto propFilter = [](AstNode *prop) -> bool { diff --git a/ets2panda/ir/base/classDefinition.h b/ets2panda/ir/base/classDefinition.h index 49d1237bf1e0fe3badf2223a99e4d65cd0b3a110..7161da90078b82d2d9b26951094e4ea54a6e31a1 100644 --- a/ets2panda/ir/base/classDefinition.h +++ b/ets2panda/ir/base/classDefinition.h @@ -123,10 +123,7 @@ public: return ident_; } - void SetIdent(ir::Identifier *ident) noexcept - { - ident_ = ident; - } + void SetIdent(ir::Identifier *ident) noexcept; [[nodiscard]] const util::StringView &PrivateId() const noexcept { @@ -156,6 +153,9 @@ public: void SetSuper(Expression *superClass) { superClass_ = superClass; + if (superClass_ != nullptr) { + superClass_->SetParent(this); + } } [[nodiscard]] bool IsGlobal() const noexcept diff --git a/ets2panda/ir/base/classElement.cpp b/ets2panda/ir/base/classElement.cpp index 62b0ebb1003ff02519fe98bdc74c1bd7df759be1..8e41ec34c7b174c3b10275162c65778f9417bb16 100644 --- a/ets2panda/ir/base/classElement.cpp +++ b/ets2panda/ir/base/classElement.cpp @@ -22,12 +22,12 @@ namespace panda::es2panda::ir { Identifier *ClassElement::Id() noexcept { - return key_->IsIdentifier() ? key_->AsIdentifier() : nullptr; + return key_ != nullptr && key_->IsIdentifier() ? key_->AsIdentifier() : nullptr; } const Identifier *ClassElement::Id() const noexcept { - return key_->IsIdentifier() ? key_->AsIdentifier() : nullptr; + return key_ != nullptr && key_->IsIdentifier() ? key_->AsIdentifier() : nullptr; } bool ClassElement::IsPrivateElement() const noexcept diff --git a/ets2panda/ir/base/classProperty.cpp b/ets2panda/ir/base/classProperty.cpp index 9d97cafadaaca1b8a9b4419360f297fc280b21e9..12c6583b73f02fc4efe12432354d63408947ae52 100644 --- a/ets2panda/ir/base/classProperty.cpp +++ b/ets2panda/ir/base/classProperty.cpp @@ -17,15 +17,10 @@ #include "checker/ETSchecker.h" #include "checker/TSchecker.h" -#include "checker/types/ets/etsObjectType.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "ir/srcDump.h" -#include "ir/base/decorator.h" -#include "ir/typeNode.h" -#include "ir/expression.h" -#include "ir/expressions/identifier.h" namespace panda::es2panda::ir { void ClassProperty::TransformChildren(const NodeTransformer &cb) @@ -136,12 +131,11 @@ checker::Type *ClassProperty::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ClassProperty *ClassProperty::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const key = key_->Clone(allocator)->AsExpression(); - auto *const value = value_->Clone(allocator)->AsExpression(); - auto *const typeAnnotation = typeAnnotation_->Clone(allocator, this); + auto *const key = key_->Clone(allocator, nullptr)->AsExpression(); + auto *const value = value_->Clone(allocator, nullptr)->AsExpression(); + auto *const typeAnnotation = typeAnnotation_->Clone(allocator, nullptr); if (auto *const clone = allocator->New(key, value, typeAnnotation, flags_, allocator, isComputed_); clone != nullptr) { diff --git a/ets2panda/ir/base/classProperty.h b/ets2panda/ir/base/classProperty.h index 25ac075f90cbaa9e1067f59b33793e39b4782f2b..0f2c7d5ba3e7209501f2321143cb631403433c6b 100644 --- a/ets2panda/ir/base/classProperty.h +++ b/ets2panda/ir/base/classProperty.h @@ -51,8 +51,7 @@ public: return isStatic ? PrivateFieldKind::STATIC_FIELD : PrivateFieldKind::FIELD; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ClassProperty *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ClassProperty *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/base/decorator.cpp b/ets2panda/ir/base/decorator.cpp index eed3b5f6db795245ea5de04beba6a767083be7d1..4ae382fa2522f2d26eb74ffc4cbcd88a0aa40244 100644 --- a/ets2panda/ir/base/decorator.cpp +++ b/ets2panda/ir/base/decorator.cpp @@ -65,10 +65,9 @@ checker::Type *Decorator::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) Decorator *Decorator::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const expr = expr_ != nullptr ? expr_->Clone(allocator)->AsExpression() : nullptr; + auto *const expr = expr_ != nullptr ? expr_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(expr); clone != nullptr) { if (expr != nullptr) { diff --git a/ets2panda/ir/base/decorator.h b/ets2panda/ir/base/decorator.h index dfbcc9027c1a169d64f2a3ca4333b90588b76964..779e08c90c021fce01569291af01d97c444ff6bb 100644 --- a/ets2panda/ir/base/decorator.h +++ b/ets2panda/ir/base/decorator.h @@ -36,8 +36,7 @@ public: return expr_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] Decorator *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] Decorator *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/base/metaProperty.cpp b/ets2panda/ir/base/metaProperty.cpp index a5208db90f2428856a38f8611feab9b44c39c97d..bf4cb3a214e08eca54977902b3f6ad861ee613e0 100644 --- a/ets2panda/ir/base/metaProperty.cpp +++ b/ets2panda/ir/base/metaProperty.cpp @@ -71,7 +71,6 @@ checker::Type *MetaProperty::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) MetaProperty *MetaProperty::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(kind_); clone != nullptr) { diff --git a/ets2panda/ir/base/metaProperty.h b/ets2panda/ir/base/metaProperty.h index c5eb1bb8448c390cfcb2393bddb5107357585de5..369b6ba66bab9b54992b9b087cd70aa31899cafe 100644 --- a/ets2panda/ir/base/metaProperty.h +++ b/ets2panda/ir/base/metaProperty.h @@ -43,8 +43,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] MetaProperty *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] MetaProperty *Clone(ArenaAllocator *allocator, AstNode *parent) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/ets2panda/ir/base/methodDefinition.cpp b/ets2panda/ir/base/methodDefinition.cpp index 9ab31f5844ea2a82ebc8dc12763a240f4dac9829..3f6be2a26aa24d15fc45f03304c27c7b85c6ddbc 100644 --- a/ets2panda/ir/base/methodDefinition.cpp +++ b/ets2panda/ir/base/methodDefinition.cpp @@ -15,7 +15,6 @@ #include "methodDefinition.h" -#include "varbinder/scope.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" @@ -52,7 +51,7 @@ PrivateFieldKind MethodDefinition::ToPrivateFieldKind(bool const isStatic) const } } -void MethodDefinition::Iterate(const NodeTraverser &cb) const +void MethodDefinition::ResolveReferences(const NodeTraverser &cb) const { cb(key_); cb(value_); @@ -66,6 +65,22 @@ void MethodDefinition::Iterate(const NodeTraverser &cb) const } } +void MethodDefinition::Iterate(const NodeTraverser &cb) const +{ + cb(key_); + cb(value_); + + for (auto *it : overloads_) { + if (it->Parent() == this) { + cb(it); + } + } + + for (auto *it : decorators_) { + cb(it); + } +} + void MethodDefinition::TransformChildren(const NodeTransformer &cb) { key_ = cb(key_)->AsExpression(); @@ -192,11 +207,10 @@ checker::Type *MethodDefinition::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) MethodDefinition *MethodDefinition::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const key = key_ != nullptr ? key_->Clone(allocator)->AsExpression() : nullptr; - auto *const value = value_ != nullptr ? value_->Clone(allocator)->AsExpression() : nullptr; + auto *const key = key_ != nullptr ? key_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const value = value_ != nullptr ? value_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(kind_, key, value, flags_, allocator, isComputed_); clone != nullptr) { diff --git a/ets2panda/ir/base/methodDefinition.h b/ets2panda/ir/base/methodDefinition.h index d3a314df0bfbbeccde183a29cf17a35367026937..bf0f208af96c46172eb182b83fdf0641e3e97c42 100644 --- a/ets2panda/ir/base/methodDefinition.h +++ b/ets2panda/ir/base/methodDefinition.h @@ -45,6 +45,7 @@ public: kind_(kind), overloads_(allocator->Adapter()) { + ASSERT(key_ != nullptr && value_ != nullptr); } // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields @@ -65,16 +66,6 @@ public: return kind_ == MethodDefinitionKind::EXTENSION_METHOD; } - Expression const *Key() const - { - return key_; - } - - Expression const *Value() const - { - return value_; - } - [[nodiscard]] const OverloadsT &Overloads() const noexcept { return overloads_; @@ -104,12 +95,13 @@ public: const ScriptFunction *Function() const; PrivateFieldKind ToPrivateFieldKind(bool isStatic) const override; - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] MethodDefinition *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] MethodDefinition *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; + void ResolveReferences(const NodeTraverser &cb) const; + void Dump(ir::AstDumper *dumper) const override; void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; diff --git a/ets2panda/ir/base/property.cpp b/ets2panda/ir/base/property.cpp index c6811cba023796fca9a5ae456c424d75ddf66dcc..d70ba1108c4dd066706e7287d9a42585739a189e 100644 --- a/ets2panda/ir/base/property.cpp +++ b/ets2panda/ir/base/property.cpp @@ -31,11 +31,10 @@ Property::Property([[maybe_unused]] Tag const tag, Property const &other, Expres value_ = value; } -// NOLINTNEXTLINE(google-default-arguments) Property *Property::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const key = key_ != nullptr ? key_->Clone(allocator)->AsExpression() : nullptr; - auto *const value = value_ != nullptr ? value_->Clone(allocator)->AsExpression() : nullptr; + auto *const key = key_ != nullptr ? key_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const value = value_ != nullptr ? value_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(Tag {}, *this, key, value); clone != nullptr) { if (key != nullptr) { diff --git a/ets2panda/ir/base/property.h b/ets2panda/ir/base/property.h index d643644cfb1c6931e1955b05b4aeade0024680e3..ccfdde132f384de1ccd30baa191da01f4d877a79 100644 --- a/ets2panda/ir/base/property.h +++ b/ets2panda/ir/base/property.h @@ -102,8 +102,7 @@ public: return kind == PropertyKind::GET || kind == PropertyKind::SET; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] Property *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] Property *Clone(ArenaAllocator *allocator, AstNode *parent) override; bool ConvertibleToPatternProperty(); ValidationInfo ValidateExpression(); diff --git a/ets2panda/ir/base/scriptFunction.cpp b/ets2panda/ir/base/scriptFunction.cpp index b033e6749cc8fe68808da58153043f796ae91f6e..8c99eda9f0b1f4347f1d6dde08ffa71058e0cbd5 100644 --- a/ets2panda/ir/base/scriptFunction.cpp +++ b/ets2panda/ir/base/scriptFunction.cpp @@ -15,7 +15,6 @@ #include "scriptFunction.h" -#include "varbinder/scope.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" @@ -24,6 +23,27 @@ namespace panda::es2panda::ir { +ScriptFunction::ScriptFunction(FunctionSignature &&signature, AstNode *body, ScriptFunctionData &&data) + : AstNode(AstNodeType::SCRIPT_FUNCTION, data.flags), + irSignature_(std::move(signature)), + body_(body), + funcFlags_(data.funcFlags), + declare_(data.declare), + lang_(data.lang) +{ + for (auto *param : irSignature_.Params()) { + param->SetParent(this); + } + + if (auto *returnType = irSignature_.ReturnType(); returnType != nullptr) { + returnType->SetParent(this); + } + + if (auto *typeParams = irSignature_.TypeParams(); typeParams != nullptr) { + typeParams->SetParent(this); + } +} + std::size_t ScriptFunction::FormalParamsLength() const noexcept { std::size_t length = 0U; @@ -39,6 +59,12 @@ std::size_t ScriptFunction::FormalParamsLength() const noexcept return length; } +void ScriptFunction::SetIdent(Identifier *id) noexcept +{ + id_ = id; + id_->SetParent(this); +} + void ScriptFunction::TransformChildren(const NodeTransformer &cb) { if (id_ != nullptr) { @@ -61,6 +87,12 @@ void ScriptFunction::Iterate(const NodeTraverser &cb) const } } +void ScriptFunction::SetReturnTypeAnnotation(TypeNode *node) noexcept +{ + irSignature_.SetReturnType(node); + node->SetParent(this); +} + void ScriptFunction::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", "ScriptFunction"}, diff --git a/ets2panda/ir/base/scriptFunction.h b/ets2panda/ir/base/scriptFunction.h index 36e35e5461e0e9b8b7cf6c4d8f4a4b28e538a428..3104009fe127181fd9030f18215c35510bdef928 100644 --- a/ets2panda/ir/base/scriptFunction.h +++ b/ets2panda/ir/base/scriptFunction.h @@ -36,31 +36,25 @@ class TypeNode; class ScriptFunction : public AstNode { public: + // Need to reduce the number of constructor parameters to pass OHOS CI code check + struct ScriptFunctionData { + ir::ScriptFunctionFlags funcFlags = ir::ScriptFunctionFlags::NONE; + ir::ModifierFlags flags = ir::ModifierFlags::NONE; + bool declare = false; + panda::es2panda::Language lang {Language::Id::ETS}; + }; + ScriptFunction() = delete; ~ScriptFunction() override = default; NO_COPY_SEMANTIC(ScriptFunction); NO_MOVE_SEMANTIC(ScriptFunction); - explicit ScriptFunction(FunctionSignature &&signature, AstNode *body, ir::ScriptFunctionFlags funcFlags, - bool declare, Language lang) - : AstNode(AstNodeType::SCRIPT_FUNCTION), - irSignature_(std::move(signature)), - body_(body), - funcFlags_(funcFlags), - declare_(declare), - lang_(lang) - { - } + explicit ScriptFunction(FunctionSignature &&signature, AstNode *body, ScriptFunctionData &&data); explicit ScriptFunction(FunctionSignature &&signature, AstNode *body, ir::ScriptFunctionFlags funcFlags, - ir::ModifierFlags flags, bool declare, Language lang) - : AstNode(AstNodeType::SCRIPT_FUNCTION, flags), - irSignature_(std::move(signature)), - body_(body), - funcFlags_(funcFlags), - declare_(declare), - lang_(lang) + bool declare, Language lang) + : ScriptFunction(std::move(signature), body, {funcFlags, {}, declare, lang}) { } @@ -129,10 +123,7 @@ public: return irSignature_.ReturnType(); } - void SetReturnTypeAnnotation(TypeNode *node) noexcept - { - irSignature_.SetReturnType(node); - } + void SetReturnTypeAnnotation(TypeNode *node) noexcept; [[nodiscard]] bool IsEntryPoint() const noexcept { @@ -254,10 +245,7 @@ public: return funcFlags_; } - void SetIdent(Identifier *id) noexcept - { - id_ = id; - } + void SetIdent(Identifier *id) noexcept; void SetSignature(checker::Signature *signature) noexcept { diff --git a/ets2panda/ir/base/spreadElement.cpp b/ets2panda/ir/base/spreadElement.cpp index f66d00367927fc317b84b8286791c4d5ac87997f..c9d519118ee99bf463612d87d32de69e77149e69 100644 --- a/ets2panda/ir/base/spreadElement.cpp +++ b/ets2panda/ir/base/spreadElement.cpp @@ -42,7 +42,6 @@ SpreadElement::SpreadElement([[maybe_unused]] Tag const tag, SpreadElement const } } -// NOLINTNEXTLINE(google-default-arguments) SpreadElement *SpreadElement::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { diff --git a/ets2panda/ir/base/spreadElement.h b/ets2panda/ir/base/spreadElement.h index 939f60c97555d0ea9f290adb29a3f10ebf7ee7cf..40c8b0dbe6cb8d1a1933c7cf388ab9ad8504798b 100644 --- a/ets2panda/ir/base/spreadElement.h +++ b/ets2panda/ir/base/spreadElement.h @@ -78,8 +78,7 @@ public: optional_ = optional; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] SpreadElement *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] SpreadElement *Clone(ArenaAllocator *allocator, AstNode *parent) override; ValidationInfo ValidateExpression(); [[nodiscard]] bool ConvertibleToRest(bool isDeclaration, bool allowPattern = true); diff --git a/ets2panda/ir/base/templateElement.cpp b/ets2panda/ir/base/templateElement.cpp index 8816ba413cc58502d302ef49f5cb7e747013707e..09a61236abb4273092028aaf38ca63b0df794dc4 100644 --- a/ets2panda/ir/base/templateElement.cpp +++ b/ets2panda/ir/base/templateElement.cpp @@ -58,7 +58,6 @@ checker::Type *TemplateElement::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) TemplateElement *TemplateElement::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(raw_, cooked_); clone != nullptr) { diff --git a/ets2panda/ir/base/templateElement.h b/ets2panda/ir/base/templateElement.h index 85154cdd14255dc18b8e3572d3d5ba44e9bac7aa..45f96e6202073b2f8e28b472abed0b7c5333bd0b 100644 --- a/ets2panda/ir/base/templateElement.h +++ b/ets2panda/ir/base/templateElement.h @@ -44,8 +44,7 @@ public: return cooked_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] TemplateElement *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] TemplateElement *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/base/tsIndexSignature.cpp b/ets2panda/ir/base/tsIndexSignature.cpp index c85adb93c74056577ed34accc8c954f0cd8097b4..a878eeb13a400fcb470413c7fdfa467b696f7e12 100644 --- a/ets2panda/ir/base/tsIndexSignature.cpp +++ b/ets2panda/ir/base/tsIndexSignature.cpp @@ -72,11 +72,10 @@ checker::Type *TSIndexSignature::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) TSIndexSignature *TSIndexSignature::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const param = param_ != nullptr ? param_->Clone(allocator)->AsExpression() : nullptr; - auto *const typeAnnotation = typeAnnotation_->Clone(allocator); + auto *const param = param_ != nullptr ? param_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const typeAnnotation = typeAnnotation_->Clone(allocator, nullptr); if (auto *const clone = allocator->New(param, typeAnnotation, readonly_); clone != nullptr) { if (parent != nullptr) { diff --git a/ets2panda/ir/base/tsIndexSignature.h b/ets2panda/ir/base/tsIndexSignature.h index cff8d5fd215fb78e5d876c5e5f03a42397813caf..9b1b1c1d29b4f5af3c0c05dfa4703f775442be45 100644 --- a/ets2panda/ir/base/tsIndexSignature.h +++ b/ets2panda/ir/base/tsIndexSignature.h @@ -60,8 +60,7 @@ public: [[nodiscard]] TSIndexSignatureKind Kind() const noexcept; - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] TSIndexSignature *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] TSIndexSignature *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/base/tsPropertySignature.cpp b/ets2panda/ir/base/tsPropertySignature.cpp index 4dd052b5d6dedbe87310d771da7c4df6aa0c02a2..49c0ac995c3382d5f0c7f5bb1a14933143734235 100644 --- a/ets2panda/ir/base/tsPropertySignature.cpp +++ b/ets2panda/ir/base/tsPropertySignature.cpp @@ -74,11 +74,10 @@ checker::Type *TSPropertySignature::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) TSPropertySignature *TSPropertySignature::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const key = key_ != nullptr ? key_->Clone(allocator)->AsExpression() : nullptr; - auto *const typeAnnotation = TypeAnnotation()->Clone(allocator); + auto *const key = key_ != nullptr ? key_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const typeAnnotation = TypeAnnotation()->Clone(allocator, nullptr); if (auto *const clone = allocator->New(key, typeAnnotation, computed_, optional_, readonly_); clone != nullptr) { diff --git a/ets2panda/ir/base/tsPropertySignature.h b/ets2panda/ir/base/tsPropertySignature.h index c3a0f73429f7d6bb7dfa5d5fc4eee149dcee43e3..8171be38e4d6550beaaaceb22c50c3d0bd6e7266 100644 --- a/ets2panda/ir/base/tsPropertySignature.h +++ b/ets2panda/ir/base/tsPropertySignature.h @@ -63,8 +63,7 @@ public: return readonly_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] TSPropertySignature *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] TSPropertySignature *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/ets/etsClassLiteral.cpp b/ets2panda/ir/ets/etsClassLiteral.cpp index ad0eabe30565db726b6ce609ef4152c5157c70ad..787e96b37780c004b53ede450dd43332c772ee64 100644 --- a/ets2panda/ir/ets/etsClassLiteral.cpp +++ b/ets2panda/ir/ets/etsClassLiteral.cpp @@ -62,10 +62,9 @@ checker::Type *ETSClassLiteral::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ETSClassLiteral *ETSClassLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const expr = expr_ != nullptr ? expr_->Clone(allocator) : nullptr; + auto *const expr = expr_ != nullptr ? expr_->Clone(allocator, nullptr) : nullptr; if (auto *const clone = allocator->New(expr); clone != nullptr) { if (expr != nullptr) { diff --git a/ets2panda/ir/ets/etsClassLiteral.h b/ets2panda/ir/ets/etsClassLiteral.h index 592f3536fdab61e8af1a6f23c36c7db931883e49..d52bf955f66ec2cf059fc0eef2bb0f707fa553d8 100644 --- a/ets2panda/ir/ets/etsClassLiteral.h +++ b/ets2panda/ir/ets/etsClassLiteral.h @@ -38,8 +38,7 @@ public: explicit ETSClassLiteral(ir::TypeNode *const expr) : Expression(AstNodeType::ETS_CLASS_LITERAL), expr_(expr) {} - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSClassLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSClassLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields friend class checker::ETSAnalyzer; diff --git a/ets2panda/ir/ets/etsFunctionType.cpp b/ets2panda/ir/ets/etsFunctionType.cpp index 0eec9494ff1873f520f4a08759076ad54634a057..7ff4c9b59d3c5df28aa383a330363bf6de21c7bd 100644 --- a/ets2panda/ir/ets/etsFunctionType.cpp +++ b/ets2panda/ir/ets/etsFunctionType.cpp @@ -97,20 +97,20 @@ checker::Type *ETSFunctionType::GetType(checker::ETSChecker *checker) return Check(checker); } -// NOLINTNEXTLINE(google-default-arguments) ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode *const parent) { ArenaVector paramsClone(allocator->Adapter()); for (auto *const param : signature_.Params()) { - paramsClone.emplace_back(param->Clone(allocator)->AsExpression()); + paramsClone.emplace_back(param->Clone(allocator, nullptr)->AsExpression()); } - auto *const typeParamsClone = signature_.TypeParams() != nullptr - ? signature_.TypeParams()->Clone(allocator)->AsTSTypeParameterDeclaration() - : nullptr; + auto *const typeParamsClone = + signature_.TypeParams() != nullptr + ? signature_.TypeParams()->Clone(allocator, nullptr)->AsTSTypeParameterDeclaration() + : nullptr; auto *const returnTypeClone = - signature_.ReturnType() != nullptr ? signature_.ReturnType()->Clone(allocator)->AsTypeNode() : nullptr; + signature_.ReturnType() != nullptr ? signature_.ReturnType()->Clone(allocator, nullptr)->AsTypeNode() : nullptr; if (auto *const clone = allocator->New( FunctionSignature(typeParamsClone, std::move(paramsClone), returnTypeClone), funcFlags_); @@ -123,6 +123,10 @@ ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode returnTypeClone->SetParent(clone); } + for (auto *param : clone->Params()) { + param->SetParent(clone); + } + if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/ets/etsFunctionType.h b/ets2panda/ir/ets/etsFunctionType.h index 42f7323db5f68c696d1a719df092521ba6937f1c..027a6941fc4612f14d8b8baeeb2f67d924e2c098 100644 --- a/ets2panda/ir/ets/etsFunctionType.h +++ b/ets2panda/ir/ets/etsFunctionType.h @@ -109,8 +109,7 @@ public: v->Accept(this); } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSFunctionType *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSFunctionType *Clone(ArenaAllocator *allocator, AstNode *parent) override; private: varbinder::Scope *scope_ {}; diff --git a/ets2panda/ir/ets/etsLaunchExpression.cpp b/ets2panda/ir/ets/etsLaunchExpression.cpp index a492c7c3f23c6b867d27358dcac6bb5403e62d73..0ac08f618599788288766afba71ad35ff2b5ee44 100644 --- a/ets2panda/ir/ets/etsLaunchExpression.cpp +++ b/ets2panda/ir/ets/etsLaunchExpression.cpp @@ -75,18 +75,20 @@ bool ETSLaunchExpression::IsStaticCall() const return expr_->Signature()->HasSignatureFlag(checker::SignatureFlags::STATIC); } -// NOLINTNEXTLINE(google-default-arguments) ETSLaunchExpression *ETSLaunchExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const expr = expr_ != nullptr ? expr_->Clone(allocator) : nullptr; + auto *const expr = expr_ != nullptr ? expr_->Clone(allocator, nullptr) : nullptr; if (auto *const clone = allocator->New(expr); clone != nullptr) { if (expr != nullptr) { expr->SetParent(clone); } + if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/ets/etsLaunchExpression.h b/ets2panda/ir/ets/etsLaunchExpression.h index 5f41d342c81945a35e8e70c640bd38d2c7cb8000..eee51886e92688ef25ccd9806ffbc6c771844bd3 100644 --- a/ets2panda/ir/ets/etsLaunchExpression.h +++ b/ets2panda/ir/ets/etsLaunchExpression.h @@ -44,8 +44,7 @@ public: friend class checker::ETSAnalyzer; friend class compiler::ETSCompiler; - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSLaunchExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSLaunchExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp index 71277d93848ce75adca9d42bbcadc2042662cfce..a5687be6b47da8a2c886c93d844db074b4e0be9f 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp @@ -72,24 +72,27 @@ checker::Type *ETSNewArrayInstanceExpression::Check(checker::ETSChecker *checker return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ETSNewArrayInstanceExpression *ETSNewArrayInstanceExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const typeRef = typeReference_ != nullptr ? typeReference_->Clone(allocator) : nullptr; - auto *const dimension = dimension_ != nullptr ? dimension_->Clone(allocator)->AsExpression() : nullptr; + auto *const typeRef = typeReference_ != nullptr ? typeReference_->Clone(allocator, nullptr) : nullptr; + auto *const dimension = dimension_ != nullptr ? dimension_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(allocator, typeRef, dimension); clone != nullptr) { if (typeRef != nullptr) { typeRef->SetParent(clone); } + if (dimension != nullptr) { dimension->SetParent(clone); } + if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.h b/ets2panda/ir/ets/etsNewArrayInstanceExpression.h index e1f121eaee960d5a1ac0edbecfac12e2509e5c72..5e3dcaee5a4f6dd2c4f3b687e06e3ef3f1a1cf11 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.h +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.h @@ -72,10 +72,12 @@ public: void SetDimension(ir::Expression *dimension) { dimension_ = dimension; + if (dimension_ != nullptr) { + dimension_->SetParent(this); + } } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSNewArrayInstanceExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSNewArrayInstanceExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp b/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp index c85d7639ca48255dc4d9caa5bcc9e3cd9d1b88fd..0a6c95d2147eb240d1f4c446d425b6dcbf0ff55a 100644 --- a/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp @@ -96,15 +96,15 @@ ETSNewClassInstanceExpression::ETSNewClassInstanceExpression(ETSNewClassInstance ArenaAllocator *const allocator) : Expression(static_cast(other)), arguments_(allocator->Adapter()), signature_(other.signature_) { - typeReference_ = other.typeReference_->Clone(allocator, this)->AsExpression(); - classDef_ = other.classDef_->Clone(allocator, this)->AsClassDefinition(); + typeReference_ = + other.typeReference_ != nullptr ? other.typeReference_->Clone(allocator, this)->AsExpression() : nullptr; + classDef_ = other.classDef_ != nullptr ? other.classDef_->Clone(allocator, this)->AsClassDefinition() : nullptr; for (auto *const argument : other.arguments_) { arguments_.emplace_back(argument->Clone(allocator, this)->AsExpression()); } } -// NOLINTNEXTLINE(google-default-arguments) ETSNewClassInstanceExpression *ETSNewClassInstanceExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { diff --git a/ets2panda/ir/ets/etsNewClassInstanceExpression.h b/ets2panda/ir/ets/etsNewClassInstanceExpression.h index 6cbef0d1232afe31ba19868368b88596ad34beda..4df829352a1597312b223aa52e0a7f1dcd1749e6 100644 --- a/ets2panda/ir/ets/etsNewClassInstanceExpression.h +++ b/ets2panda/ir/ets/etsNewClassInstanceExpression.h @@ -85,8 +85,7 @@ public: signature_ = signature; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSNewClassInstanceExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSNewClassInstanceExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp index 4b2bc1500d9ce02d0b8257bc60374f03ae65a900..e9de7f927bbeac14e04eb432f63ecd2d1d0d89a4 100644 --- a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp @@ -90,7 +90,6 @@ ETSNewMultiDimArrayInstanceExpression::ETSNewMultiDimArrayInstanceExpression( } } -// NOLINTNEXTLINE(google-default-arguments) ETSNewMultiDimArrayInstanceExpression *ETSNewMultiDimArrayInstanceExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { @@ -98,6 +97,8 @@ ETSNewMultiDimArrayInstanceExpression *ETSNewMultiDimArrayInstanceExpression::Cl if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.h b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.h index 825aae727d29910e573c58d102a043e7587c9a61..993a655807c7ba8c30798d856f47891fca6c5693 100644 --- a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.h +++ b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.h @@ -81,9 +81,7 @@ public: return signature_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSNewMultiDimArrayInstanceExpression *Clone(ArenaAllocator *allocator, - AstNode *parent = nullptr) override; + [[nodiscard]] ETSNewMultiDimArrayInstanceExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/ets/etsPackageDeclaration.cpp b/ets2panda/ir/ets/etsPackageDeclaration.cpp index 27a44e419c25a17abcac4bbef2d311b10f7f4661..1af22f1a87ff3067bed7179f8d19cc0361b942d5 100644 --- a/ets2panda/ir/ets/etsPackageDeclaration.cpp +++ b/ets2panda/ir/ets/etsPackageDeclaration.cpp @@ -64,10 +64,9 @@ checker::Type *ETSPackageDeclaration::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ETSPackageDeclaration *ETSPackageDeclaration::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto const name = name_ != nullptr ? name_->Clone(allocator, this)->AsExpression() : nullptr; + auto const name = name_ != nullptr ? name_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(name); clone != nullptr) { if (name != nullptr) { name->SetParent(clone); diff --git a/ets2panda/ir/ets/etsPackageDeclaration.h b/ets2panda/ir/ets/etsPackageDeclaration.h index 88d51f0c08ef9f2c1672532ca4b3abb1334fda04..98463a9102685ec3e2b08b86bd4b463fad11f98f 100644 --- a/ets2panda/ir/ets/etsPackageDeclaration.h +++ b/ets2panda/ir/ets/etsPackageDeclaration.h @@ -33,8 +33,7 @@ public: { } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSPackageDeclaration *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSPackageDeclaration *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/ets/etsParameterExpression.cpp b/ets2panda/ir/ets/etsParameterExpression.cpp index 7b808c79c3d5db489990c301f5855ed7d6747d6a..ec2682f77615ce514b8a606bf5f07822c635d310 100644 --- a/ets2panda/ir/ets/etsParameterExpression.cpp +++ b/ets2panda/ir/ets/etsParameterExpression.cpp @@ -32,6 +32,7 @@ ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identO : Expression(AstNodeType::ETS_PARAMETER_EXPRESSION), initializer_(initializer) { ASSERT(identOrSpread != nullptr); + identOrSpread->SetParent(this); if (identOrSpread->IsIdentifier()) { ident_ = identOrSpread->AsIdentifier(); @@ -187,12 +188,12 @@ checker::Type *ETSParameterExpression::Check(checker::ETSChecker *const checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const identOrSpread = spread_ != nullptr ? spread_->Clone(allocator)->AsAnnotatedExpression() - : ident_->Clone(allocator)->AsAnnotatedExpression(); - auto *const initializer = initializer_ != nullptr ? initializer_->Clone(allocator)->AsExpression() : nullptr; + auto *const identOrSpread = spread_ != nullptr ? spread_->Clone(allocator, nullptr)->AsAnnotatedExpression() + : ident_->Clone(allocator, nullptr)->AsAnnotatedExpression(); + auto *const initializer = + initializer_ != nullptr ? initializer_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(identOrSpread, initializer); clone != nullptr) { identOrSpread->SetParent(clone); diff --git a/ets2panda/ir/ets/etsParameterExpression.h b/ets2panda/ir/ets/etsParameterExpression.h index aedc3e7166a1c3079d162b5d2c8793cfc041ced6..ec6fde41a59b2dd9392ffa6f145442ba9419fbad 100644 --- a/ets2panda/ir/ets/etsParameterExpression.h +++ b/ets2panda/ir/ets/etsParameterExpression.h @@ -78,8 +78,7 @@ public: extraValue_ = value; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSParameterExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSParameterExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void Iterate(const NodeTraverser &cb) const override; void TransformChildren(const NodeTransformer &cb) override; diff --git a/ets2panda/ir/ets/etsPrimitiveType.cpp b/ets2panda/ir/ets/etsPrimitiveType.cpp index bfc3562cfad72ea422ce2db83a378064d1a62ae3..be255ddd3abdd8d7de76490791dcce937da28ef5 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.cpp +++ b/ets2panda/ir/ets/etsPrimitiveType.cpp @@ -132,7 +132,6 @@ checker::Type *ETSPrimitiveType::GetType([[maybe_unused]] checker::ETSChecker *c } } -// NOLINTNEXTLINE(google-default-arguments) ETSPrimitiveType *ETSPrimitiveType::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(type_); clone != nullptr) { @@ -140,6 +139,7 @@ ETSPrimitiveType *ETSPrimitiveType::Clone(ArenaAllocator *const allocator, AstNo clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/ets/etsPrimitiveType.h b/ets2panda/ir/ets/etsPrimitiveType.h index b2ad1451dfa0abbb2cc0729962d0a5fa69004057..2fb0d551728ddcd9b49d157b8c885ce960b89b19 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.h +++ b/ets2panda/ir/ets/etsPrimitiveType.h @@ -46,8 +46,7 @@ public: v->Accept(this); } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSPrimitiveType *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSPrimitiveType *Clone(ArenaAllocator *allocator, AstNode *parent) override; private: PrimitiveType type_; diff --git a/ets2panda/ir/ets/etsStructDeclaration.cpp b/ets2panda/ir/ets/etsStructDeclaration.cpp index 37026f4a624b1ec9c717e63a4a15b39a11ebd36d..873c13499fcb7fef5ff579cf848b6d0c4c55926f 100644 --- a/ets2panda/ir/ets/etsStructDeclaration.cpp +++ b/ets2panda/ir/ets/etsStructDeclaration.cpp @@ -75,10 +75,9 @@ checker::Type *ETSStructDeclaration::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ETSStructDeclaration *ETSStructDeclaration::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const def = def_ != nullptr ? def_->Clone(allocator, this)->AsClassDefinition() : nullptr; + auto *const def = def_ != nullptr ? def_->Clone(allocator, nullptr)->AsClassDefinition() : nullptr; if (auto *const clone = allocator->New(def, allocator); clone != nullptr) { for (auto *const decorator : decorators_) { diff --git a/ets2panda/ir/ets/etsStructDeclaration.h b/ets2panda/ir/ets/etsStructDeclaration.h index b7d6176e72ec0af562f262aed793e09b8c883c5b..f16200a8dd5ebc55b09299d331c855666bbbd9c5 100644 --- a/ets2panda/ir/ets/etsStructDeclaration.h +++ b/ets2panda/ir/ets/etsStructDeclaration.h @@ -67,8 +67,7 @@ public: return true; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSStructDeclaration *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSStructDeclaration *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/ets/etsTypeReference.cpp b/ets2panda/ir/ets/etsTypeReference.cpp index b65b9a68d67e56a5f28b6f68eefde831004ba563..0ef5afa775895e3363d376a0c771df4613a57893 100644 --- a/ets2panda/ir/ets/etsTypeReference.cpp +++ b/ets2panda/ir/ets/etsTypeReference.cpp @@ -107,10 +107,9 @@ checker::Type *ETSTypeReference::GetType(checker::ETSChecker *checker) return type; } -// NOLINTNEXTLINE(google-default-arguments) ETSTypeReference *ETSTypeReference::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const partClone = part_ != nullptr ? part_->Clone(allocator)->AsETSTypeReferencePart() : nullptr; + auto *const partClone = part_ != nullptr ? part_->Clone(allocator, nullptr)->AsETSTypeReferencePart() : nullptr; if (auto *const clone = allocator->New(partClone); clone != nullptr) { if (partClone != nullptr) { @@ -123,6 +122,7 @@ ETSTypeReference *ETSTypeReference::Clone(ArenaAllocator *const allocator, AstNo clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/ets/etsTypeReference.h b/ets2panda/ir/ets/etsTypeReference.h index d67d7f49ac4b51c2789cc6f603fe0248791bcace..dfcecf74bbe2f6483a52a11907108d84f483a634 100644 --- a/ets2panda/ir/ets/etsTypeReference.h +++ b/ets2panda/ir/ets/etsTypeReference.h @@ -53,8 +53,7 @@ public: v->Accept(this); } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSTypeReference *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSTypeReference *Clone(ArenaAllocator *allocator, AstNode *parent) override; private: ir::ETSTypeReferencePart *part_; diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index 792e942e8ce8737c4f2060ac5b61480a38a2ef19..21cb3dbbf724b938c32d446aa4aae8d8fa7ab4db 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -110,13 +110,12 @@ checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) return checker->GetReferencedTypeFromBase(baseType, name_); } -// NOLINTNEXTLINE(google-default-arguments) ETSTypeReferencePart *ETSTypeReferencePart::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const nameClone = name_ != nullptr ? name_->Clone(allocator)->AsExpression() : nullptr; + auto *const nameClone = name_ != nullptr ? name_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const typeParamsClone = - typeParams_ != nullptr ? typeParams_->Clone(allocator)->AsTSTypeParameterInstantiation() : nullptr; - auto *const prevClone = prev_ != nullptr ? prev_->Clone(allocator)->AsETSTypeReferencePart() : nullptr; + typeParams_ != nullptr ? typeParams_->Clone(allocator, nullptr)->AsTSTypeParameterInstantiation() : nullptr; + auto *const prevClone = prev_ != nullptr ? prev_->Clone(allocator, nullptr)->AsETSTypeReferencePart() : nullptr; if (auto *const clone = allocator->New(nameClone, typeParamsClone, prevClone); clone != nullptr) { if (nameClone != nullptr) { @@ -135,6 +134,7 @@ ETSTypeReferencePart *ETSTypeReferencePart::Clone(ArenaAllocator *const allocato clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/ets/etsTypeReferencePart.h b/ets2panda/ir/ets/etsTypeReferencePart.h index ab785f6f9cb59cb1e429c112b870040cc4eed2cb..4493d5630783c65c83b9beeabd25ed87f029fc4a 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.h +++ b/ets2panda/ir/ets/etsTypeReferencePart.h @@ -70,8 +70,7 @@ public: v->Accept(this); } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ETSTypeReferencePart *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ETSTypeReferencePart *Clone(ArenaAllocator *allocator, AstNode *parent) override; private: ir::Expression *name_; diff --git a/ets2panda/ir/expressions/arrayExpression.cpp b/ets2panda/ir/expressions/arrayExpression.cpp index 294f8f23ae7d769442d8c22f8aee5a36b4f8f615..653b922f980f3791b8163ece2f192c0e5caed914 100644 --- a/ets2panda/ir/expressions/arrayExpression.cpp +++ b/ets2panda/ir/expressions/arrayExpression.cpp @@ -53,7 +53,6 @@ ArrayExpression::ArrayExpression([[maybe_unused]] Tag const tag, ArrayExpression } } -// NOLINTNEXTLINE(google-default-arguments) ArrayExpression *ArrayExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { diff --git a/ets2panda/ir/expressions/arrayExpression.h b/ets2panda/ir/expressions/arrayExpression.h index 34e834a7765ecab2b31dc9122a7088c3c31175fd..90dfd3e7aa86f1f043c075a51b04a5e7b8df96e0 100644 --- a/ets2panda/ir/expressions/arrayExpression.h +++ b/ets2panda/ir/expressions/arrayExpression.h @@ -119,8 +119,7 @@ public: return true; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ArrayExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ArrayExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; [[nodiscard]] bool ConvertibleToArrayPattern(); [[nodiscard]] ValidationInfo ValidateExpression(); diff --git a/ets2panda/ir/expressions/arrowFunctionExpression.cpp b/ets2panda/ir/expressions/arrowFunctionExpression.cpp index 3e4f53a46ed8095ae3767a5f02a07fc3ba4cf673..cfd25e64417f55e1cee2c950db454f57d68b6a26 100644 --- a/ets2panda/ir/expressions/arrowFunctionExpression.cpp +++ b/ets2panda/ir/expressions/arrowFunctionExpression.cpp @@ -26,7 +26,6 @@ #include "ir/ets/etsTypeReference.h" #include "ir/ets/etsTypeReferencePart.h" #include "ir/expressions/identifier.h" -#include "ir/expressions/thisExpression.h" #include "ir/statements/variableDeclarator.h" namespace panda::es2panda::ir { @@ -86,7 +85,6 @@ ArrowFunctionExpression::ArrowFunctionExpression(ArrowFunctionExpression const & } } -// NOLINTNEXTLINE(google-default-arguments) ArrowFunctionExpression *ArrowFunctionExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(*this, allocator); clone != nullptr) { @@ -105,11 +103,9 @@ ir::TypeNode *ArrowFunctionExpression::CreateReturnNodeFromType(checker::ETSChec Construct a synthetic Node with the correct ts_type_. */ ASSERT(returnType != nullptr); - ir::TypeNode *returnNode = nullptr; - auto *ident = checker->Allocator()->New(util::StringView(""), checker->Allocator()); - ir::ETSTypeReferencePart *part = checker->Allocator()->New(ident); - returnNode = checker->Allocator()->New(part); - part->SetParent(returnNode); + auto *ident = checker->AllocNode(util::StringView(""), checker->Allocator()); + auto *part = checker->AllocNode(ident); + auto *returnNode = checker->AllocNode(part); returnNode->SetTsType(returnType); return returnNode; } @@ -135,14 +131,15 @@ ir::TypeNode *ArrowFunctionExpression::CreateTypeAnnotation(checker::ETSChecker */ returnNode = CreateReturnNodeFromType(checker, Function()->Signature()->ReturnType()); } else { - returnNode = Function()->ReturnTypeAnnotation(); + returnNode = Function()->ReturnTypeAnnotation()->Clone(checker->Allocator(), nullptr); + returnNode->SetTsType(Function()->ReturnTypeAnnotation()->TsType()); } - auto origParams = Function()->Params(); - auto signature = ir::FunctionSignature(nullptr, std::move(origParams), returnNode); - auto *funcType = - checker->Allocator()->New(std::move(signature), ir::ScriptFunctionFlags::NONE); - returnNode->SetParent(funcType); + ArenaVector params {checker->Allocator()->Adapter()}; + checker->CopyParams(Function()->Params(), params); + + auto signature = ir::FunctionSignature(nullptr, std::move(params), returnNode); + auto *funcType = checker->AllocNode(std::move(signature), ir::ScriptFunctionFlags::NONE); return funcType; } } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/expressions/arrowFunctionExpression.h b/ets2panda/ir/expressions/arrowFunctionExpression.h index c1358a17226898a2ebb656b6b9d5b97251dc6fd5..79bc5b379f7f3fd5a3944986f3120bec6fb17408 100644 --- a/ets2panda/ir/expressions/arrowFunctionExpression.h +++ b/ets2panda/ir/expressions/arrowFunctionExpression.h @@ -83,8 +83,7 @@ public: propagateThis_ = true; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ArrowFunctionExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ArrowFunctionExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/assignmentExpression.cpp b/ets2panda/ir/expressions/assignmentExpression.cpp index b4a288a8231c59ed255f5dee3f7c99dddd932a17..bebb7e2b2e3d161c9748e4e67da4da1fea8d2798 100644 --- a/ets2panda/ir/expressions/assignmentExpression.cpp +++ b/ets2panda/ir/expressions/assignmentExpression.cpp @@ -174,16 +174,17 @@ AssignmentExpression::AssignmentExpression([[maybe_unused]] Tag const tag, Assig } } -// NOLINTNEXTLINE(google-default-arguments) AssignmentExpression *AssignmentExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const left = left_ != nullptr ? left_->Clone(allocator)->AsExpression() : nullptr; - auto *const right = right_ != nullptr ? right_->Clone(allocator)->AsExpression() : nullptr; + auto *const left = left_ != nullptr ? left_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const right = right_ != nullptr ? right_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(Tag {}, *this, left, right); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/assignmentExpression.h b/ets2panda/ir/expressions/assignmentExpression.h index ae8eea339769b2ea8d20abf12824dda0f4acba5f..4077716d10ce6512b5da4aeacfcdf22b7081c2b6 100644 --- a/ets2panda/ir/expressions/assignmentExpression.h +++ b/ets2panda/ir/expressions/assignmentExpression.h @@ -112,8 +112,7 @@ public: return target_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] AssignmentExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] AssignmentExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; [[nodiscard]] bool ConvertibleToAssignmentPattern(bool mustBePattern = true); diff --git a/ets2panda/ir/expressions/awaitExpression.cpp b/ets2panda/ir/expressions/awaitExpression.cpp index 5048bd86c4c62fe1875b9616575222fb9a2b907f..bd59fee26901fa9f56dd73e0bbeedb54356cd44a 100644 --- a/ets2panda/ir/expressions/awaitExpression.cpp +++ b/ets2panda/ir/expressions/awaitExpression.cpp @@ -66,18 +66,20 @@ checker::Type *AwaitExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) AwaitExpression *AwaitExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const argument = argument_ != nullptr ? argument_->Clone(allocator)->AsExpression() : nullptr; + auto *const argument = argument_ != nullptr ? argument_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(argument); clone != nullptr) { if (argument != nullptr) { argument->SetParent(clone); } + if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/awaitExpression.h b/ets2panda/ir/expressions/awaitExpression.h index ab1160ad375e45e0d074c89472bd8a47f42346fd..5754b7b9765130257aebd09c9ccf0dcaf1fa5a90 100644 --- a/ets2panda/ir/expressions/awaitExpression.h +++ b/ets2panda/ir/expressions/awaitExpression.h @@ -41,8 +41,7 @@ public: return argument_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] AwaitExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] AwaitExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/binaryExpression.cpp b/ets2panda/ir/expressions/binaryExpression.cpp index 69de43333363cff079a95bbcc10db776dccb20c6..dbbfc271d005740d48664b5e88f71fbc0efe2c40 100644 --- a/ets2panda/ir/expressions/binaryExpression.cpp +++ b/ets2panda/ir/expressions/binaryExpression.cpp @@ -75,25 +75,29 @@ checker::Type *BinaryExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) BinaryExpression *BinaryExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const left = left_ != nullptr ? left_->Clone(allocator)->AsExpression() : nullptr; - auto *const right = right_ != nullptr ? right_->Clone(allocator)->AsExpression() : nullptr; + auto *const left = left_ != nullptr ? left_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const right = right_ != nullptr ? right_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(left, right, operator_); clone != nullptr) { if (operationType_ != nullptr) { clone->SetOperationType(operationType_); } + if (right != nullptr) { right->SetParent(clone); } + if (left != nullptr) { left->SetParent(clone); } + if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/binaryExpression.h b/ets2panda/ir/expressions/binaryExpression.h index c4222f4db9ade7a1937bbe987dde6559c33f6caf..82b484185e9d58618d9ce4fb5b4aef2b20131e75 100644 --- a/ets2panda/ir/expressions/binaryExpression.h +++ b/ets2panda/ir/expressions/binaryExpression.h @@ -142,8 +142,7 @@ public: return operationType_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] BinaryExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] BinaryExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/blockExpression.cpp b/ets2panda/ir/expressions/blockExpression.cpp index 63b795532e49e71648cbe153cfa5cd339bb9dbb7..eaf53644da99ba43f555db33ff619b3159fb3e65 100644 --- a/ets2panda/ir/expressions/blockExpression.cpp +++ b/ets2panda/ir/expressions/blockExpression.cpp @@ -40,7 +40,6 @@ BlockExpression::BlockExpression([[maybe_unused]] Tag const tag, BlockExpression } } -// NOLINTNEXTLINE(google-default-arguments) BlockExpression *BlockExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { diff --git a/ets2panda/ir/expressions/blockExpression.h b/ets2panda/ir/expressions/blockExpression.h index 6c6329ccd290328d853051c071a39ee337e183b7..0180304f97d4540dba35e327ec19420368432ebb 100644 --- a/ets2panda/ir/expressions/blockExpression.h +++ b/ets2panda/ir/expressions/blockExpression.h @@ -41,8 +41,7 @@ public: return statements_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] BlockExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] BlockExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/callExpression.cpp b/ets2panda/ir/expressions/callExpression.cpp index 577a4393b39525a3c6d9355de9ac034bf7bcfa73..630e59b9510f346cd2f700092616e03ed44f8762 100644 --- a/ets2panda/ir/expressions/callExpression.cpp +++ b/ets2panda/ir/expressions/callExpression.cpp @@ -108,27 +108,43 @@ CallExpression::CallExpression(CallExpression const &other, ArenaAllocator *cons isTrailingBlockInNewLine_(other.isTrailingBlockInNewLine_) { callee_ = other.callee_->Clone(allocator, this)->AsExpression(); - typeParams_ = other.typeParams_->Clone(allocator, this); + typeParams_ = other.typeParams_ != nullptr ? other.typeParams_->Clone(allocator, this) : nullptr; for (auto *const argument : other.arguments_) { arguments_.emplace_back(argument->Clone(allocator, this)->AsExpression()); } - if (other.trailingBlock_ != nullptr) { - trailingBlock_ = other.trailingBlock_->Clone(allocator, this)->AsBlockStatement(); - } + trailingBlock_ = + other.trailingBlock_ != nullptr ? other.trailingBlock_->Clone(allocator, this)->AsBlockStatement() : nullptr; } -// NOLINTNEXTLINE(google-default-arguments) CallExpression *CallExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(*this, allocator); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); } + +void CallExpression::SetTypeParams(TSTypeParameterInstantiation *const typeParams) noexcept +{ + typeParams_ = typeParams; + if (typeParams_ != nullptr) { + typeParams_->SetParent(this); + } +} + +void CallExpression::SetTrailingBlock(ir::BlockStatement *const block) noexcept +{ + trailingBlock_ = block; + if (trailingBlock_ != nullptr) { + trailingBlock_->SetParent(this); + } +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/expressions/callExpression.h b/ets2panda/ir/expressions/callExpression.h index cd2e29cb97e968884b92241c1539e0b85ea7ca58..92c87a41e8894a597d9cc92489c49cd3c326ec3b 100644 --- a/ets2panda/ir/expressions/callExpression.h +++ b/ets2panda/ir/expressions/callExpression.h @@ -116,10 +116,7 @@ public: signature_ = signature; } - void SetTypeParams(TSTypeParameterInstantiation *const typeParams) noexcept - { - typeParams_ = typeParams; - } + void SetTypeParams(TSTypeParameterInstantiation *typeParams) noexcept; [[nodiscard]] checker::Type *UncheckedType() const noexcept { @@ -131,10 +128,7 @@ public: uncheckedType_ = type; } - void SetTrailingBlock(ir::BlockStatement *const block) noexcept - { - trailingBlock_ = block; - } + void SetTrailingBlock(ir::BlockStatement *const block) noexcept; [[nodiscard]] ir::BlockStatement *TrailingBlock() const noexcept { @@ -151,8 +145,7 @@ public: return isTrailingBlockInNewLine_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] CallExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] CallExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/chainExpression.cpp b/ets2panda/ir/expressions/chainExpression.cpp index 7513d034fe0a30e3114d33369b798cd9caa48ef4..83f518121259a170040ff308aea9b6dd42df291f 100644 --- a/ets2panda/ir/expressions/chainExpression.cpp +++ b/ets2panda/ir/expressions/chainExpression.cpp @@ -76,10 +76,9 @@ checker::Type *ChainExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ChainExpression *ChainExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const expression = expression_ != nullptr ? expression_->Clone(allocator)->AsExpression() : nullptr; + auto *const expression = expression_ != nullptr ? expression_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(expression); clone != nullptr) { if (expression != nullptr) { diff --git a/ets2panda/ir/expressions/chainExpression.h b/ets2panda/ir/expressions/chainExpression.h index 9c124c9c91ce4a2a818f8823c74efb209a624c42..0ee4506fc97f8aeeca00cdc998a09a0583783b14 100644 --- a/ets2panda/ir/expressions/chainExpression.h +++ b/ets2panda/ir/expressions/chainExpression.h @@ -45,8 +45,7 @@ public: return expression_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ChainExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ChainExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/classExpression.cpp b/ets2panda/ir/expressions/classExpression.cpp index 6caf00999f2954395085a8dabebfe401ab4859b4..7d8e14ddff37d0e6acd3ea057ba32aea108a1330 100644 --- a/ets2panda/ir/expressions/classExpression.cpp +++ b/ets2panda/ir/expressions/classExpression.cpp @@ -62,10 +62,9 @@ checker::Type *ClassExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ClassExpression *ClassExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const def = def_ != nullptr ? def_->Clone(allocator)->AsClassDefinition() : nullptr; + auto *const def = def_ != nullptr ? def_->Clone(allocator, nullptr)->AsClassDefinition() : nullptr; if (auto *const clone = allocator->New(def); clone != nullptr) { if (parent != nullptr) { diff --git a/ets2panda/ir/expressions/classExpression.h b/ets2panda/ir/expressions/classExpression.h index 3277ec23ae89f68e4ca2ee43640cc600fc100ab3..2073d0690d5b9dc859f2c69d0b958c4423b58c70 100644 --- a/ets2panda/ir/expressions/classExpression.h +++ b/ets2panda/ir/expressions/classExpression.h @@ -36,8 +36,7 @@ public: return def_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ClassExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ClassExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/conditionalExpression.cpp b/ets2panda/ir/expressions/conditionalExpression.cpp index c75255d97188df4c7fbe4530b8f751ac084ef92d..839f243ca187870718d816cc0345840383943955 100644 --- a/ets2panda/ir/expressions/conditionalExpression.cpp +++ b/ets2panda/ir/expressions/conditionalExpression.cpp @@ -82,26 +82,30 @@ checker::Type *ConditionalExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ConditionalExpression *ConditionalExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const test = test_ != nullptr ? test_->Clone(allocator)->AsExpression() : nullptr; - auto *const consequent = consequent_ != nullptr ? consequent_->Clone(allocator)->AsExpression() : nullptr; - auto *const alternate = alternate_ != nullptr ? alternate_->Clone(allocator)->AsExpression() : nullptr; + auto *const test = test_ != nullptr ? test_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const consequent = consequent_ != nullptr ? consequent_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const alternate = alternate_ != nullptr ? alternate_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(test, consequent, alternate); clone != nullptr) { if (test != nullptr) { test->SetParent(clone); } + if (consequent != nullptr) { consequent->SetParent(clone); } + if (alternate != nullptr) { alternate->SetParent(clone); } + if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/conditionalExpression.h b/ets2panda/ir/expressions/conditionalExpression.h index f7e3bb822a3bf31d1ef8985ee8921e0fe79b148c..466228c48145db99b5c150fe9cb2b3af3fa3a04a 100644 --- a/ets2panda/ir/expressions/conditionalExpression.h +++ b/ets2panda/ir/expressions/conditionalExpression.h @@ -64,10 +64,10 @@ public: void SetTest(Expression *const test) noexcept { test_ = test; + test_->SetParent(this); } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ConditionalExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ConditionalExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/functionExpression.cpp b/ets2panda/ir/expressions/functionExpression.cpp index 243a94df429a4bdb343ce2627d78015975ed0efc..6a0ad3383027ce5863a25d7e8a0cafb71ad738d7 100644 --- a/ets2panda/ir/expressions/functionExpression.cpp +++ b/ets2panda/ir/expressions/functionExpression.cpp @@ -62,10 +62,10 @@ checker::Type *FunctionExpression::Check([[maybe_unused]] checker::ETSChecker *c return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) FunctionExpression *FunctionExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const func = func_->Clone(allocator)->AsScriptFunction(); + // Note (zelentsov) : need to implement ScriptFunction::Clone + auto *const func = func_; // ->Clone(allocator, nullptr)->AsScriptFunction(); if (auto *const clone = allocator->New(func); clone != nullptr) { func->SetParent(clone); diff --git a/ets2panda/ir/expressions/functionExpression.h b/ets2panda/ir/expressions/functionExpression.h index ae284499ced5dd641e6d70974b0d5e6f3d6b2e09..ce81316c51dfbc190eaecc9ec860bef8fe2ab8a7 100644 --- a/ets2panda/ir/expressions/functionExpression.h +++ b/ets2panda/ir/expressions/functionExpression.h @@ -58,8 +58,7 @@ public: return exprName_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] FunctionExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] FunctionExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/identifier.cpp b/ets2panda/ir/expressions/identifier.cpp index 03d77fb78166ad73d985284bf04b022e10861904..7376be7a24970e69acaf4d9c1a0ead4c3e2c754d 100644 --- a/ets2panda/ir/expressions/identifier.cpp +++ b/ets2panda/ir/expressions/identifier.cpp @@ -15,7 +15,6 @@ #include "identifier.h" -#include "varbinder/scope.h" #include "checker/ETSchecker.h" #include "checker/TSchecker.h" #include "compiler/core/pandagen.h" @@ -36,13 +35,14 @@ Identifier::Identifier([[maybe_unused]] Tag const tag, Identifier const &other, } } -// NOLINTNEXTLINE(google-default-arguments) Identifier *Identifier::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); diff --git a/ets2panda/ir/expressions/identifier.h b/ets2panda/ir/expressions/identifier.h index b91b01311f60a87343d224ad40c97d0e67ae2560..48196b964b056cc3da37e992cd51cfcc14a9c40c 100644 --- a/ets2panda/ir/expressions/identifier.h +++ b/ets2panda/ir/expressions/identifier.h @@ -190,8 +190,7 @@ public: decorators_ = std::move(decorators); } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] Identifier *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] Identifier *Clone(ArenaAllocator *allocator, AstNode *parent) override; bool CanHaveDecorator([[maybe_unused]] bool inTs) const override { diff --git a/ets2panda/ir/expressions/importExpression.cpp b/ets2panda/ir/expressions/importExpression.cpp index 21a048c903dcaf08dab58a2b38a3546ee291101f..37a2df2530b2bb7a183045341cb46a8ca2530738 100644 --- a/ets2panda/ir/expressions/importExpression.cpp +++ b/ets2panda/ir/expressions/importExpression.cpp @@ -61,10 +61,9 @@ checker::Type *ImportExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ImportExpression *ImportExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const source = source_ != nullptr ? source_->Clone(allocator)->AsExpression() : nullptr; + auto *const source = source_ != nullptr ? source_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(source); clone != nullptr) { if (source != nullptr) { diff --git a/ets2panda/ir/expressions/importExpression.h b/ets2panda/ir/expressions/importExpression.h index 4ac17ab18829b21685e1b5da20902fe239257cde..bb3a5fab15804ab1701224e7ec8e1851345483e5 100644 --- a/ets2panda/ir/expressions/importExpression.h +++ b/ets2panda/ir/expressions/importExpression.h @@ -34,8 +34,7 @@ public: return source_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ImportExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ImportExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/literals/bigIntLiteral.cpp b/ets2panda/ir/expressions/literals/bigIntLiteral.cpp index 9b72a6a358ad482b3a68aafd4fc71e28f4862a51..2dd72386fb3890041901a4c4d24ddd5cd5360dbc 100644 --- a/ets2panda/ir/expressions/literals/bigIntLiteral.cpp +++ b/ets2panda/ir/expressions/literals/bigIntLiteral.cpp @@ -56,13 +56,14 @@ checker::Type *BigIntLiteral::Check([[maybe_unused]] checker::ETSChecker *checke return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) BigIntLiteral *BigIntLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(src_); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/literals/bigIntLiteral.h b/ets2panda/ir/expressions/literals/bigIntLiteral.h index 6ac3d773856d79e9b3c2506673822667a22206ef..217e99057d3d88ff02f0cd45548ad19fe3645289 100644 --- a/ets2panda/ir/expressions/literals/bigIntLiteral.h +++ b/ets2panda/ir/expressions/literals/bigIntLiteral.h @@ -35,8 +35,7 @@ public: return src_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] BigIntLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] BigIntLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/literals/booleanLiteral.cpp b/ets2panda/ir/expressions/literals/booleanLiteral.cpp index 40bfa7bc655ee69bfa3c3dfc49ae8096f6ca392d..d6c73467be6377dd445bf9288ecf6296891d95a9 100644 --- a/ets2panda/ir/expressions/literals/booleanLiteral.cpp +++ b/ets2panda/ir/expressions/literals/booleanLiteral.cpp @@ -56,13 +56,13 @@ checker::Type *BooleanLiteral::Check([[maybe_unused]] checker::ETSChecker *check return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) BooleanLiteral *BooleanLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(boolean_); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/literals/booleanLiteral.h b/ets2panda/ir/expressions/literals/booleanLiteral.h index 88f62c6bf7280a0a8810fb478c66b0eaf201f8c5..f3ede215ba13fda9f54b48bf3ab4c0fa6e15b6ec 100644 --- a/ets2panda/ir/expressions/literals/booleanLiteral.h +++ b/ets2panda/ir/expressions/literals/booleanLiteral.h @@ -34,8 +34,7 @@ public: return boolean_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] BooleanLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] BooleanLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/literals/charLiteral.cpp b/ets2panda/ir/expressions/literals/charLiteral.cpp index ce4be05ffc2477b40d3f8b1285826beb78cb5d3c..6ae2efc53f575c00ae98bd1c470a64f4386820fc 100644 --- a/ets2panda/ir/expressions/literals/charLiteral.cpp +++ b/ets2panda/ir/expressions/literals/charLiteral.cpp @@ -59,13 +59,14 @@ checker::Type *CharLiteral::Check([[maybe_unused]] checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) CharLiteral *CharLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(char_); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/literals/charLiteral.h b/ets2panda/ir/expressions/literals/charLiteral.h index 629e1a0d036151a3cbda6cc6a2bb4a19a3733274..003e922b4a9baf73c6b17cb59f788063c57f0d16 100644 --- a/ets2panda/ir/expressions/literals/charLiteral.h +++ b/ets2panda/ir/expressions/literals/charLiteral.h @@ -40,8 +40,7 @@ public: return char_ == other.char_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] CharLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] CharLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/literals/nullLiteral.cpp b/ets2panda/ir/expressions/literals/nullLiteral.cpp index 74c0e578162e27db70a51af734be3e39f602404a..6c45263aba6f17e08e4e3c66675ef4be53fadb15 100644 --- a/ets2panda/ir/expressions/literals/nullLiteral.cpp +++ b/ets2panda/ir/expressions/literals/nullLiteral.cpp @@ -55,13 +55,13 @@ checker::Type *NullLiteral::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) NullLiteral *NullLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/literals/nullLiteral.h b/ets2panda/ir/expressions/literals/nullLiteral.h index 4fb46bb414389a8f35e34285f693b6f90e81dd47..40a5f7b299ff8f582af5cf1221c89ef0aa04fdac 100644 --- a/ets2panda/ir/expressions/literals/nullLiteral.h +++ b/ets2panda/ir/expressions/literals/nullLiteral.h @@ -28,8 +28,7 @@ public: explicit NullLiteral() : Literal(AstNodeType::NULL_LITERAL) {} - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] NullLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] NullLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/literals/numberLiteral.cpp b/ets2panda/ir/expressions/literals/numberLiteral.cpp index dc7e40501b5050e86919f7ca6ca722669a150878..3a832b8da05f2fff804af58e58c6d89b113001dd 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.cpp +++ b/ets2panda/ir/expressions/literals/numberLiteral.cpp @@ -74,13 +74,13 @@ checker::Type *NumberLiteral::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) NumberLiteral *NumberLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(number_); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/literals/numberLiteral.h b/ets2panda/ir/expressions/literals/numberLiteral.h index 0abcbbce6ddbe60216a9803378b4413654f47078..7a4412d2f39fa6844770ff8e2785f87cbe80a1e1 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.h +++ b/ets2panda/ir/expressions/literals/numberLiteral.h @@ -49,8 +49,7 @@ public: [[nodiscard]] bool HasFloatingPoint() const; - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] NumberLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] NumberLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/literals/regExpLiteral.cpp b/ets2panda/ir/expressions/literals/regExpLiteral.cpp index e14f0fad2da61127d333ca7580bc1f299dae8bc2..c05a8ede16ab4120d9d44f93fb657bc4012fe19e 100644 --- a/ets2panda/ir/expressions/literals/regExpLiteral.cpp +++ b/ets2panda/ir/expressions/literals/regExpLiteral.cpp @@ -57,13 +57,13 @@ checker::Type *RegExpLiteral::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) RegExpLiteral *RegExpLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(pattern_, flags_, flagsStr_); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/literals/regExpLiteral.h b/ets2panda/ir/expressions/literals/regExpLiteral.h index 9666670fe75038b2d2f231e7ba3add4555716a7f..9e21afa71f3448a5347108e721de953b45f344d8 100644 --- a/ets2panda/ir/expressions/literals/regExpLiteral.h +++ b/ets2panda/ir/expressions/literals/regExpLiteral.h @@ -44,8 +44,7 @@ public: return flags_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] RegExpLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] RegExpLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/literals/stringLiteral.cpp b/ets2panda/ir/expressions/literals/stringLiteral.cpp index 11bc091825b5792eea11813beff594fc8b514802..8fb5ab112eabebf7186126b0db9ed64905153f76 100644 --- a/ets2panda/ir/expressions/literals/stringLiteral.cpp +++ b/ets2panda/ir/expressions/literals/stringLiteral.cpp @@ -87,13 +87,13 @@ checker::Type *StringLiteral::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) StringLiteral *StringLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(str_); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/literals/stringLiteral.h b/ets2panda/ir/expressions/literals/stringLiteral.h index 081eed374fde1f4fce86bef53f75795b3a9095b7..3183fd6cd3d76fed67ff93a7dc9a7570f9f8b0d1 100644 --- a/ets2panda/ir/expressions/literals/stringLiteral.h +++ b/ets2panda/ir/expressions/literals/stringLiteral.h @@ -41,8 +41,7 @@ public: return str_ == other.str_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] StringLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] StringLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/literals/undefinedLiteral.cpp b/ets2panda/ir/expressions/literals/undefinedLiteral.cpp index 5ba4fd860aa2e4a92cb9ba2447fd0993fdb0181f..3195df4ce886fe8e93cd4a6098ec2ca0c384915f 100644 --- a/ets2panda/ir/expressions/literals/undefinedLiteral.cpp +++ b/ets2panda/ir/expressions/literals/undefinedLiteral.cpp @@ -63,6 +63,7 @@ UndefinedLiteral *UndefinedLiteral::Clone(ArenaAllocator *allocator, AstNode *pa if (parent != nullptr) { clone->SetParent(parent); } + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index ae0ec9e0bf9cc132690194d38d98aaae415f7454..ec8b9340a2c035adbccf46fc476ad52ddb3eb6aa 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -24,18 +24,11 @@ namespace panda::es2panda::ir { MemberExpression::MemberExpression([[maybe_unused]] Tag const tag, MemberExpression const &other, - Expression *const object, Expression *const property) + ArenaAllocator *allocator) : MemberExpression(other) { - object_ = object; - if (object_ != nullptr) { - object_->SetParent(this); - } - - property_ = property; - if (property_ != nullptr) { - property_->SetParent(this); - } + object_ = other.object_ != nullptr ? other.object_->Clone(allocator, this)->AsExpression() : nullptr; + property_ = other.property_ != nullptr ? other.property_->Clone(allocator, this)->AsExpression() : nullptr; } bool MemberExpression::IsPrivateReference() const noexcept @@ -394,24 +387,14 @@ checker::Type *MemberExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) MemberExpression *MemberExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const object = object_ != nullptr ? object_->Clone(allocator)->AsExpression() : nullptr; - auto *const property = property_ != nullptr ? property_->Clone(allocator)->AsExpression() : nullptr; - - if (auto *const clone = - allocator->New(object, property, kind_, computed_, MaybeOptionalExpression::IsOptional()); - clone != nullptr) { - if (object != nullptr) { - object->SetParent(clone); - } - if (property != nullptr) { - property->SetParent(clone); - } + if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/memberExpression.h b/ets2panda/ir/expressions/memberExpression.h index b59a73b4097f5ae6b818081e7af80ca1c5098045..581b342eb2b7542ac30c2ccded7543e5f0edae7f 100644 --- a/ets2panda/ir/expressions/memberExpression.h +++ b/ets2panda/ir/expressions/memberExpression.h @@ -69,7 +69,7 @@ public: { } - explicit MemberExpression(Tag tag, MemberExpression const &other, Expression *object, Expression *property); + explicit MemberExpression(Tag tag, MemberExpression const &other, ArenaAllocator *allocator); // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields friend class compiler::JSCompiler; @@ -172,8 +172,7 @@ public: [[nodiscard]] bool IsPrivateReference() const noexcept; - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] MemberExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] MemberExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; @@ -200,7 +199,9 @@ protected: ignoreBox_ = other.ignoreBox_; propVar_ = other.propVar_; // Note! Probably, we need to do 'Instantiate(...)' but we haven't access to 'Relation()' here... + uncheckedType_ = other.uncheckedType_; objType_ = other.objType_; + tupleConvertedType_ = other.tupleConvertedType_; } private: diff --git a/ets2panda/ir/expressions/newExpression.cpp b/ets2panda/ir/expressions/newExpression.cpp index f56cdeb805147dc9c04dea64b87a01bb9811a501..8fb67ccc9fb8b484177c50868f8f12657e4aaa67 100644 --- a/ets2panda/ir/expressions/newExpression.cpp +++ b/ets2panda/ir/expressions/newExpression.cpp @@ -36,7 +36,6 @@ NewExpression::NewExpression([[maybe_unused]] Tag const tag, NewExpression const } } -// NOLINTNEXTLINE(google-default-arguments) NewExpression *NewExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { diff --git a/ets2panda/ir/expressions/newExpression.h b/ets2panda/ir/expressions/newExpression.h index a1d974cd3fee0d1a0cf847f28f432304e68b5677..883e310a292a25c1e01439089b852581484b2520 100644 --- a/ets2panda/ir/expressions/newExpression.h +++ b/ets2panda/ir/expressions/newExpression.h @@ -53,8 +53,7 @@ public: return arguments_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] NewExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] NewExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/objectExpression.cpp b/ets2panda/ir/expressions/objectExpression.cpp index 6ebf574910a112e74a06bc44f39cc501ccf5d8c0..4ba78c48b3c5ea0b3f2afae22badf44943d95371 100644 --- a/ets2panda/ir/expressions/objectExpression.cpp +++ b/ets2panda/ir/expressions/objectExpression.cpp @@ -65,7 +65,6 @@ ObjectExpression::ObjectExpression([[maybe_unused]] Tag const tag, ObjectExpress } } -// NOLINTNEXTLINE(google-default-arguments) ObjectExpression *ObjectExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { diff --git a/ets2panda/ir/expressions/objectExpression.h b/ets2panda/ir/expressions/objectExpression.h index 0beef0b780c051665b6f3c5622a7d42f1207772e..758a46c1613b7c809d39ac83798dad6f0a3efd00 100644 --- a/ets2panda/ir/expressions/objectExpression.h +++ b/ets2panda/ir/expressions/objectExpression.h @@ -96,8 +96,7 @@ public: return true; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ObjectExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ObjectExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; [[nodiscard]] ValidationInfo ValidateExpression(); [[nodiscard]] bool ConvertibleToObjectPattern(); diff --git a/ets2panda/ir/expressions/omittedExpression.cpp b/ets2panda/ir/expressions/omittedExpression.cpp index 0ab3d1f33203eefd29e3f44e8ed5442c0d3860c3..abbfdd6774d751c50053adf9386671e3a7c31a7b 100644 --- a/ets2panda/ir/expressions/omittedExpression.cpp +++ b/ets2panda/ir/expressions/omittedExpression.cpp @@ -55,7 +55,6 @@ checker::Type *OmittedExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) OmittedExpression *OmittedExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(); clone != nullptr) { diff --git a/ets2panda/ir/expressions/omittedExpression.h b/ets2panda/ir/expressions/omittedExpression.h index 4f1f340b78dfb90e6b0069d7a7b7ece85daf6c68..b29553d7c48099536533db51ccf9aa58696f7414 100644 --- a/ets2panda/ir/expressions/omittedExpression.h +++ b/ets2panda/ir/expressions/omittedExpression.h @@ -30,8 +30,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] OmittedExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] OmittedExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/ets2panda/ir/expressions/sequenceExpression.cpp b/ets2panda/ir/expressions/sequenceExpression.cpp index 3830204255e2be254704e1b1fe96b17c82716c14..d4f37ffaef3de9a5bd586c75dcfea6d72c8be935 100644 --- a/ets2panda/ir/expressions/sequenceExpression.cpp +++ b/ets2panda/ir/expressions/sequenceExpression.cpp @@ -32,7 +32,6 @@ SequenceExpression::SequenceExpression([[maybe_unused]] Tag const tag, SequenceE } } -// NOLINTNEXTLINE(google-default-arguments) SequenceExpression *SequenceExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { diff --git a/ets2panda/ir/expressions/sequenceExpression.h b/ets2panda/ir/expressions/sequenceExpression.h index 98c53be093291a81d397b3d45e3b209a0c983248..4c46022aad2d2a65e6ebf0d5da972434c1c1e54e 100644 --- a/ets2panda/ir/expressions/sequenceExpression.h +++ b/ets2panda/ir/expressions/sequenceExpression.h @@ -47,8 +47,7 @@ public: return sequence_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] SequenceExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] SequenceExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/superExpression.cpp b/ets2panda/ir/expressions/superExpression.cpp index 02e8244316ccb7c986413dbf8c83ae0aaa67a39e..8707b2b35ef2d32a2f3fc1a2ddaa2edc2cefdf83 100644 --- a/ets2panda/ir/expressions/superExpression.cpp +++ b/ets2panda/ir/expressions/superExpression.cpp @@ -57,7 +57,6 @@ checker::Type *SuperExpression::Check([[maybe_unused]] checker::ETSChecker *chec return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) SuperExpression *SuperExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(); clone != nullptr) { diff --git a/ets2panda/ir/expressions/superExpression.h b/ets2panda/ir/expressions/superExpression.h index 29d12a994de0bed32b421f17ac355291e97b3b7e..a3d33a1f187cec7bf7fafa05845850390c612b94 100644 --- a/ets2panda/ir/expressions/superExpression.h +++ b/ets2panda/ir/expressions/superExpression.h @@ -28,8 +28,7 @@ public: explicit SuperExpression() : Expression(AstNodeType::SUPER_EXPRESSION) {} - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] SuperExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] SuperExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/taggedTemplateExpression.cpp b/ets2panda/ir/expressions/taggedTemplateExpression.cpp index 238deecd3736e289f7ab88d65ef9623d3d23ec5c..bd0bce7063074c909906e8c496b07c7733fc3b3b 100644 --- a/ets2panda/ir/expressions/taggedTemplateExpression.cpp +++ b/ets2panda/ir/expressions/taggedTemplateExpression.cpp @@ -81,12 +81,11 @@ checker::Type *TaggedTemplateExpression::Check([[maybe_unused]] checker::ETSChec return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) TaggedTemplateExpression *TaggedTemplateExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const tag = tag_ != nullptr ? tag_->Clone(allocator)->AsExpression() : nullptr; - auto *const quasi = quasi_ != nullptr ? quasi_->Clone(allocator) : nullptr; - auto *const typeParams = typeParams_ != nullptr ? typeParams_->Clone(allocator) : nullptr; + auto *const tag = tag_ != nullptr ? tag_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const quasi = quasi_ != nullptr ? quasi_->Clone(allocator, nullptr) : nullptr; + auto *const typeParams = typeParams_ != nullptr ? typeParams_->Clone(allocator, nullptr) : nullptr; if (auto *const clone = allocator->New(tag, quasi, typeParams); clone != nullptr) { if (tag != nullptr) { diff --git a/ets2panda/ir/expressions/taggedTemplateExpression.h b/ets2panda/ir/expressions/taggedTemplateExpression.h index d8853db8a91e549b4363ff92411fef3cb8398b36..2f70a9451a0a351e1916012e1f636f10c792d9ef 100644 --- a/ets2panda/ir/expressions/taggedTemplateExpression.h +++ b/ets2panda/ir/expressions/taggedTemplateExpression.h @@ -50,8 +50,7 @@ public: return typeParams_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] TaggedTemplateExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] TaggedTemplateExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/templateLiteral.cpp b/ets2panda/ir/expressions/templateLiteral.cpp index 732c96706b0a4377f457ba7407123afc62fb755e..30e37189f82c37e0b08ff1c5cd815d7133d81483 100644 --- a/ets2panda/ir/expressions/templateLiteral.cpp +++ b/ets2panda/ir/expressions/templateLiteral.cpp @@ -39,7 +39,6 @@ TemplateLiteral::TemplateLiteral([[maybe_unused]] Tag const tag, TemplateLiteral } } -// NOLINTNEXTLINE(google-default-arguments) TemplateLiteral *TemplateLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { diff --git a/ets2panda/ir/expressions/templateLiteral.h b/ets2panda/ir/expressions/templateLiteral.h index 046ea69c4f13e5e228751330bf8f09d6872b2433..0b7b58711633734476225f6c6c16da164469c7af 100644 --- a/ets2panda/ir/expressions/templateLiteral.h +++ b/ets2panda/ir/expressions/templateLiteral.h @@ -48,8 +48,7 @@ public: return expressions_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] TemplateLiteral *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] TemplateLiteral *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/thisExpression.cpp b/ets2panda/ir/expressions/thisExpression.cpp index 9598cea01a9637091955cd6b91a2cb479a84da51..7ab66d905ce236004c1411cd436afb457bd92365 100644 --- a/ets2panda/ir/expressions/thisExpression.cpp +++ b/ets2panda/ir/expressions/thisExpression.cpp @@ -63,7 +63,6 @@ checker::Type *ThisExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) ThisExpression *ThisExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const clone = allocator->New(); clone != nullptr) { diff --git a/ets2panda/ir/expressions/thisExpression.h b/ets2panda/ir/expressions/thisExpression.h index 51ab0411293e170091a9ea594be62454044870ef..c1db0af614090524188647b8708224117ca62e87 100644 --- a/ets2panda/ir/expressions/thisExpression.h +++ b/ets2panda/ir/expressions/thisExpression.h @@ -28,8 +28,7 @@ public: explicit ThisExpression() : Expression(AstNodeType::THIS_EXPRESSION) {} - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] ThisExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] ThisExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/unaryExpression.cpp b/ets2panda/ir/expressions/unaryExpression.cpp index 835456d9c4d10eba065554631f9af6119032b3a4..575990650740d907331df70ce4f9bb11883dc1f2 100644 --- a/ets2panda/ir/expressions/unaryExpression.cpp +++ b/ets2panda/ir/expressions/unaryExpression.cpp @@ -15,19 +15,12 @@ #include "unaryExpression.h" -#include "varbinder/variable.h" -#include "checker/types/typeFlag.h" #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "checker/TSchecker.h" #include "checker/ETSchecker.h" #include "ir/astDump.h" #include "ir/srcDump.h" -#include "ir/expressions/identifier.h" -#include "ir/expressions/literals/bigIntLiteral.h" -#include "ir/expressions/literals/numberLiteral.h" -#include "ir/expressions/callExpression.h" -#include "ir/expressions/memberExpression.h" namespace panda::es2panda::ir { void UnaryExpression::TransformChildren(const NodeTransformer &cb) @@ -71,18 +64,20 @@ checker::Type *UnaryExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) UnaryExpression *UnaryExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const argument = argument_ != nullptr ? argument_->Clone(allocator)->AsExpression() : nullptr; + auto *const argument = argument_ != nullptr ? argument_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(argument, operator_); clone != nullptr) { if (argument != nullptr) { argument->SetParent(clone); } + if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/unaryExpression.h b/ets2panda/ir/expressions/unaryExpression.h index bbb261d3a0582bdadd7493c5b0a8c0191c970893..af060bca824a5f0fe3443e10eeb8e9212d99f39a 100644 --- a/ets2panda/ir/expressions/unaryExpression.h +++ b/ets2panda/ir/expressions/unaryExpression.h @@ -58,8 +58,7 @@ public: return argument_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] UnaryExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] UnaryExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/updateExpression.cpp b/ets2panda/ir/expressions/updateExpression.cpp index 5453e7543cf9303ea6550a828cedc953f6978fcd..3e498d2bff7e18fef98be4cb21a1afb447287e22 100644 --- a/ets2panda/ir/expressions/updateExpression.cpp +++ b/ets2panda/ir/expressions/updateExpression.cpp @@ -78,18 +78,20 @@ checker::Type *UpdateExpression::Check(checker::ETSChecker *checker) return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) UpdateExpression *UpdateExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const argument = argument_ != nullptr ? argument_->Clone(allocator)->AsExpression() : nullptr; + auto *const argument = argument_ != nullptr ? argument_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(argument, operator_, prefix_); clone != nullptr) { if (argument != nullptr) { argument->SetParent(clone); } + if (parent != nullptr) { clone->SetParent(parent); } + + clone->SetRange(Range()); return clone; } diff --git a/ets2panda/ir/expressions/updateExpression.h b/ets2panda/ir/expressions/updateExpression.h index 312a73df3306da2da2f1e1a7ae21f1c753dac93c..51539cccf5f8fbb3df53464a7c5e4695c5cafaa0 100644 --- a/ets2panda/ir/expressions/updateExpression.h +++ b/ets2panda/ir/expressions/updateExpression.h @@ -62,8 +62,7 @@ public: return prefix_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] UpdateExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] UpdateExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/expressions/yieldExpression.cpp b/ets2panda/ir/expressions/yieldExpression.cpp index 36ce163da7007580178c8b8e8f8caf8c804930a2..3c8400649d31a0dc6430f52ed4f900d150330cee 100644 --- a/ets2panda/ir/expressions/yieldExpression.cpp +++ b/ets2panda/ir/expressions/yieldExpression.cpp @@ -67,10 +67,9 @@ checker::Type *YieldExpression::Check([[maybe_unused]] checker::ETSChecker *chec return checker->GetAnalyzer()->Check(this); } -// NOLINTNEXTLINE(google-default-arguments) YieldExpression *YieldExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const argument = argument_ != nullptr ? argument_->Clone(allocator)->AsExpression() : nullptr; + auto *const argument = argument_ != nullptr ? argument_->Clone(allocator, nullptr)->AsExpression() : nullptr; if (auto *const clone = allocator->New(argument, delegate_); clone != nullptr) { if (argument != nullptr) { diff --git a/ets2panda/ir/expressions/yieldExpression.h b/ets2panda/ir/expressions/yieldExpression.h index 793843063c900c0ac63c43014cbbd40c37258dbd..c7e2f278f9e50fb0ef497f633b164edb2451a8b8 100644 --- a/ets2panda/ir/expressions/yieldExpression.h +++ b/ets2panda/ir/expressions/yieldExpression.h @@ -46,8 +46,7 @@ public: return argument_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] YieldExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] YieldExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/statements/returnStatement.cpp b/ets2panda/ir/statements/returnStatement.cpp index e6973d5d36bf6576b3a0b35348203d1e52a4b7a8..59a5277dddbbf3a11f13f0a985508691c4859f4a 100644 --- a/ets2panda/ir/statements/returnStatement.cpp +++ b/ets2panda/ir/statements/returnStatement.cpp @@ -96,6 +96,8 @@ void ReturnStatement::SetReturnType(checker::ETSChecker *checker, checker::Type void ReturnStatement::SetArgument(Expression *arg) { argument_ = arg; - arg->SetParent(this); + if (argument_ != nullptr) { + argument_->SetParent(this); + } } } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsArrayType.cpp b/ets2panda/ir/ts/tsArrayType.cpp index b4c9d27caea08b929459d42482688d807dcc4c90..328476307bef27d9f4a754e5288eff7c993e8518 100644 --- a/ets2panda/ir/ts/tsArrayType.cpp +++ b/ets2panda/ir/ts/tsArrayType.cpp @@ -78,10 +78,9 @@ checker::Type *TSArrayType::GetType(checker::ETSChecker *checker) return checker->CreateETSArrayType(elementType); } -// NOLINTNEXTLINE(google-default-arguments) TSArrayType *TSArrayType::Clone(ArenaAllocator *const allocator, AstNode *const parent) { - auto *const elementTypeClone = elementType_ != nullptr ? elementType_->Clone(allocator) : nullptr; + auto *const elementTypeClone = elementType_ != nullptr ? elementType_->Clone(allocator, nullptr) : nullptr; if (auto *const clone = allocator->New(elementTypeClone); clone != nullptr) { if (elementTypeClone != nullptr) { diff --git a/ets2panda/ir/ts/tsArrayType.h b/ets2panda/ir/ts/tsArrayType.h index 12752a30046a61ffc28895d56c02ab5bcfa5b9db..131d10a5d0339925179a21bbef0eb1eb68462377 100644 --- a/ets2panda/ir/ts/tsArrayType.h +++ b/ets2panda/ir/ts/tsArrayType.h @@ -53,8 +53,7 @@ public: v->Accept(this); } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] TSArrayType *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] TSArrayType *Clone(ArenaAllocator *allocator, AstNode *parent) override; private: TypeNode *elementType_; diff --git a/ets2panda/ir/ts/tsAsExpression.cpp b/ets2panda/ir/ts/tsAsExpression.cpp index 051d18b7a501ad7c7ffb506028571cc785f713ef..c28ff0e5cc35808f2ced439a3efbf539dd9e5058 100644 --- a/ets2panda/ir/ts/tsAsExpression.cpp +++ b/ets2panda/ir/ts/tsAsExpression.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,30 +15,24 @@ #include "tsAsExpression.h" -#include "varbinder/scope.h" #include "checker/TSchecker.h" -#include "checker/ets/castingContext.h" -#include "checker/types/ets/etsUnionType.h" +#include "checker/ETSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" -#include "ir/expressions/identifier.h" -#include "ir/expressions/literal.h" -#include "ir/expressions/memberExpression.h" -#include "ir/expressions/objectExpression.h" -#include "ir/expressions/unaryExpression.h" -#include "ir/typeNode.h" -#include "ir/ets/etsFunctionType.h" namespace panda::es2panda::ir { -Expression *TSAsExpression::Expr() +Expression *TSAsExpression::Expr() noexcept { return expression_; } -void TSAsExpression::SetExpr(Expression *expr) +void TSAsExpression::SetExpr(Expression *expr) noexcept { expression_ = expr; - SetStart(expression_->Start()); + if (expression_ != nullptr) { + SetStart(expression_->Start()); + expression_->SetParent(this); + } } void TSAsExpression::TransformChildren(const NodeTransformer &cb) @@ -82,4 +76,33 @@ checker::Type *TSAsExpression::Check(checker::ETSChecker *const checker) { return checker->GetAnalyzer()->Check(this); } + +TSAsExpression *TSAsExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + auto *const expression = expression_ != nullptr ? expression_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *typeAnnotation = TypeAnnotation(); + if (typeAnnotation != nullptr) { + typeAnnotation = typeAnnotation->Clone(allocator, nullptr); + } + + if (auto *const clone = allocator->New(expression, typeAnnotation, isConst_); clone != nullptr) { + if (expression != nullptr) { + expression->SetParent(clone); + } + + if (typeAnnotation != nullptr) { + typeAnnotation->SetParent(clone); + } + + clone->SetTsType(TsType()); + if (parent != nullptr) { + clone->SetParent(parent); + } + + clone->SetRange(Range()); + return clone; + } + + throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsAsExpression.h b/ets2panda/ir/ts/tsAsExpression.h index ba4903adaba877e18f6e07985238cfdfcfec036e..f4a1a25f6b9fe5ab950d27c1d8e0aa48d946723b 100644 --- a/ets2panda/ir/ts/tsAsExpression.h +++ b/ets2panda/ir/ts/tsAsExpression.h @@ -29,6 +29,12 @@ class ETSCompiler; namespace panda::es2panda::ir { class TSAsExpression : public AnnotatedExpression { public: + TSAsExpression() = delete; + ~TSAsExpression() override = default; + + NO_COPY_SEMANTIC(TSAsExpression); + NO_MOVE_SEMANTIC(TSAsExpression); + explicit TSAsExpression(Expression *expression, TypeNode *typeAnnotation, bool isConst) : AnnotatedExpression(AstNodeType::TS_AS_EXPRESSION, typeAnnotation), expression_(expression), isConst_(isConst) { @@ -36,19 +42,22 @@ public: // NOTE (vivienvoros): these friend relationships can be removed once there are getters for private fields friend class checker::ETSAnalyzer; friend class compiler::ETSCompiler; - const Expression *Expr() const + + [[nodiscard]] const Expression *Expr() const noexcept { return expression_; } - Expression *Expr(); - void SetExpr(Expression *expr); + [[nodiscard]] Expression *Expr() noexcept; + void SetExpr(Expression *expr) noexcept; - bool IsConst() const + [[nodiscard]] bool IsConst() const noexcept { return isConst_; } + [[nodiscard]] TSAsExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; + void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/ets2panda/ir/ts/tsInterfaceBody.cpp b/ets2panda/ir/ts/tsInterfaceBody.cpp index ecdb20767258843ee742c126607d2a0c44bd21a3..34392b288281970da3a67f6fb16b19bb0cd3d05a 100644 --- a/ets2panda/ir/ts/tsInterfaceBody.cpp +++ b/ets2panda/ir/ts/tsInterfaceBody.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/ets2panda/ir/ts/tsQualifiedName.cpp b/ets2panda/ir/ts/tsQualifiedName.cpp index d3c4751114aecc79edb26fa7ece0fa23cf5d1dbd..65fe1b15bb654daecdfb2e23028e19f3f0d3b2b5 100644 --- a/ets2panda/ir/ts/tsQualifiedName.cpp +++ b/ets2panda/ir/ts/tsQualifiedName.cpp @@ -24,6 +24,14 @@ #include "ir/expressions/identifier.h" namespace panda::es2panda::ir { +TSQualifiedName::TSQualifiedName([[maybe_unused]] Tag const tag, TSQualifiedName const &other, + ArenaAllocator *allocator) + : Expression(static_cast(other)) +{ + left_ = other.left_ != nullptr ? other.left_->Clone(allocator, this)->AsExpression() : nullptr; + right_ = other.right_ != nullptr ? other.right_->Clone(allocator, this)->AsIdentifier() : nullptr; +} + void TSQualifiedName::Iterate(const NodeTraverser &cb) const { cb(left_); @@ -132,4 +140,18 @@ const ir::TSQualifiedName *TSQualifiedName::ResolveLeftMostQualifiedName() const { return ResolveLeftMostQualifiedNameImpl(this); } + +TSQualifiedName *TSQualifiedName::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + if (auto *const clone = allocator->New(Tag {}, *this, allocator); clone != nullptr) { + if (parent != nullptr) { + clone->SetParent(parent); + } + + clone->SetRange(Range()); + return clone; + } + + throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsQualifiedName.h b/ets2panda/ir/ts/tsQualifiedName.h index a59bf6aa3a2fd7988ad27fd2e8de52b53817ea14..ff2e145f8f224f4ca97f5382a3a7f94add1433c4 100644 --- a/ets2panda/ir/ts/tsQualifiedName.h +++ b/ets2panda/ir/ts/tsQualifiedName.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 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 @@ -20,28 +20,38 @@ namespace panda::es2panda::ir { class TSQualifiedName : public Expression { + struct Tag {}; + public: + TSQualifiedName() = delete; + ~TSQualifiedName() override = default; + + NO_COPY_SEMANTIC(TSQualifiedName); + NO_MOVE_SEMANTIC(TSQualifiedName); + explicit TSQualifiedName(Expression *left, Identifier *right) : Expression(AstNodeType::TS_QUALIFIED_NAME), left_(left), right_(right) { } - const Expression *Left() const + explicit TSQualifiedName(Tag tag, TSQualifiedName const &other, ArenaAllocator *allocator); + + [[nodiscard]] const Expression *Left() const noexcept { return left_; } - Expression *Left() + [[nodiscard]] Expression *Left() noexcept { return left_; } - const Identifier *Right() const + [[nodiscard]] const Identifier *Right() const noexcept { return right_; } - Identifier *Right() + [[nodiscard]] Identifier *Right() noexcept { return right_; } @@ -51,6 +61,8 @@ public: ir::TSQualifiedName *ResolveLeftMostQualifiedName(); const ir::TSQualifiedName *ResolveLeftMostQualifiedName() const; + [[nodiscard]] TSQualifiedName *Clone(ArenaAllocator *allocator, AstNode *parent) override; + void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/ets2panda/ir/ts/tsTypeParameterInstantiation.cpp b/ets2panda/ir/ts/tsTypeParameterInstantiation.cpp index ef538c9bcf72eee3a1a702979bec167a0f0163f1..84496dcd92e2889b2426dc65cc4fa70d628bc348 100644 --- a/ets2panda/ir/ts/tsTypeParameterInstantiation.cpp +++ b/ets2panda/ir/ts/tsTypeParameterInstantiation.cpp @@ -35,7 +35,6 @@ TSTypeParameterInstantiation::TSTypeParameterInstantiation([[maybe_unused]] Tag } } -// NOLINTNEXTLINE(google-default-arguments) TSTypeParameterInstantiation *TSTypeParameterInstantiation::Clone(ArenaAllocator *const allocator, AstNode *const parent) { diff --git a/ets2panda/ir/ts/tsTypeParameterInstantiation.h b/ets2panda/ir/ts/tsTypeParameterInstantiation.h index be57a1c502e38aa4e83c37d498263212135bfbe5..e6c02c9e585dee7d228d5f808e6f26bb259d807d 100644 --- a/ets2panda/ir/ts/tsTypeParameterInstantiation.h +++ b/ets2panda/ir/ts/tsTypeParameterInstantiation.h @@ -42,8 +42,7 @@ public: return params_; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] TSTypeParameterInstantiation *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] TSTypeParameterInstantiation *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/typeNode.cpp b/ets2panda/ir/typeNode.cpp index be22e10ee704a4131e7b904c37bcbe46245b34a3..c90e0234ae5e3f4a3bc3403da01b03c431176bc4 100644 --- a/ets2panda/ir/typeNode.cpp +++ b/ets2panda/ir/typeNode.cpp @@ -20,7 +20,6 @@ namespace panda::es2panda::ir { -// NOLINTNEXTLINE(google-default-arguments) TypeNode *TypeNode::Clone(ArenaAllocator *const allocator, AstNode *const parent) { if (auto *const type = TsType(); type != nullptr) { diff --git a/ets2panda/ir/typeNode.h b/ets2panda/ir/typeNode.h index 7933f9b5e407daaa0898bc2b39b20c5107b542c4..72f4ceb54011618bdab613b38036c72fe9749a47 100644 --- a/ets2panda/ir/typeNode.h +++ b/ets2panda/ir/typeNode.h @@ -47,8 +47,7 @@ public: return nullptr; } - // NOLINTNEXTLINE(google-default-arguments) - [[nodiscard]] TypeNode *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + [[nodiscard]] TypeNode *Clone(ArenaAllocator *allocator, AstNode *parent) override; protected: explicit TypeNode(AstNodeType const type) : Expression(type) {} diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index b91b25f8162a6920f18bda39f0b4fbc7946231e4..ee9438be7f04ef575d1e1a05c7ba002373fd38e0 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -648,7 +648,7 @@ ir::ScriptFunction *ETSParser::AddInitMethod(ArenaVector &globalP auto *initBody = AllocNode(Allocator(), std::move(statements)); initFunc = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), - initBody, functionFlags, false, GetContext().GetLanguge()); + initBody, functionFlags, false, GetContext().GetLanguage()); } initFunc->SetIdent(initIdent); @@ -656,8 +656,9 @@ ir::ScriptFunction *ETSParser::AddInitMethod(ArenaVector &globalP auto *funcExpr = AllocNode(initFunc); - auto *initMethod = AllocNode(ir::MethodDefinitionKind::METHOD, initIdent, funcExpr, - functionModifiers, Allocator(), false); + auto *initMethod = AllocNode(ir::MethodDefinitionKind::METHOD, + initIdent->Clone(Allocator(), nullptr)->AsExpression(), + funcExpr, functionModifiers, Allocator(), false); return std::make_pair(initFunc, initMethod); }; @@ -1017,9 +1018,6 @@ void ETSParser::CreateCCtor(ArenaVector &properties, const lexer: } ArenaVector params(Allocator()->Adapter()); - - auto *id = AllocNode(compiler::Signatures::CCTOR, Allocator()); - ArenaVector statements(Allocator()->Adapter()); // Add the call to special '_$init$_' method containing all the top-level variable initializations (as assignments) @@ -1044,10 +1042,12 @@ void ETSParser::CreateCCtor(ArenaVector &properties, const lexer: } } + auto *id = AllocNode(compiler::Signatures::CCTOR, Allocator()); auto *body = AllocNode(Allocator(), std::move(statements)); - auto *func = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::STATIC_BLOCK | ir::ScriptFunctionFlags::HIDDEN, - ir::ModifierFlags::STATIC, false, GetContext().GetLanguge()); + auto *func = AllocNode( + ir::FunctionSignature(nullptr, std::move(params), nullptr), body, + ir::ScriptFunction::ScriptFunctionData {ir::ScriptFunctionFlags::STATIC_BLOCK | ir::ScriptFunctionFlags::HIDDEN, + ir::ModifierFlags::STATIC, false, GetContext().GetLanguage()}); func->SetIdent(id); auto *funcExpr = AllocNode(func); @@ -1387,16 +1387,16 @@ lexer::SourcePosition ETSParser::InitializeGlobalVariable(ir::Identifier *fieldN ident->SetReference(); ident->SetRange(fieldName->Range()); - auto *assignmentExpression = - AllocNode(ident, initializer, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + auto *assignmentExpression = AllocNode( + ident, initializer->Clone(Allocator(), nullptr)->AsExpression(), lexer::TokenType::PUNCTUATOR_SUBSTITUTION); endLoc = initializer->End(); assignmentExpression->SetRange({fieldName->Start(), endLoc}); - assignmentExpression->SetParent(funcBody); auto expressionStatement = AllocNode(assignmentExpression); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { endLoc = Lexer()->GetToken().End(); } + expressionStatement->SetParent(funcBody); expressionStatement->SetRange({startLoc, endLoc}); funcBody->AsBlockStatement()->Statements().emplace_back(expressionStatement); @@ -1440,7 +1440,8 @@ ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *meth if (className != nullptr) { func->AddFlag(ir::ScriptFunctionFlags::INSTANCE_EXTENSION_METHOD); } - auto *method = AllocNode(methodKind, methodName, funcExpr, modifiers, Allocator(), false); + auto *method = AllocNode(methodKind, methodName->Clone(Allocator(), nullptr)->AsExpression(), + funcExpr, modifiers, Allocator(), false); method->SetRange(funcExpr->Range()); fieldMap_.insert({methodName->Name(), method}); @@ -1489,7 +1490,7 @@ ir::ScriptFunction *ETSParser::ParseFunction(ParserStatus newStatus, ir::Identif functionContext.AddFlag(throwMarker); auto *funcNode = AllocNode(std::move(signature), body, functionContext.Flags(), false, - GetContext().GetLanguge()); + GetContext().GetLanguage()); funcNode->SetRange({startLoc, endLoc}); return funcNode; @@ -1505,6 +1506,9 @@ ir::MethodDefinition *ETSParser::ParseClassMethod(ClassElementDescriptor *desc, } ir::ScriptFunction *func = ParseFunction(desc->newStatus); + if (propName->IsIdentifier()) { + func->SetIdent(propName->AsIdentifier()->Clone(Allocator(), nullptr)); + } auto *funcExpr = AllocNode(func); funcExpr->SetRange(func->Range()); @@ -1517,8 +1521,9 @@ ir::MethodDefinition *ETSParser::ParseClassMethod(ClassElementDescriptor *desc, *propEnd = func->End(); func->AddFlag(ir::ScriptFunctionFlags::METHOD); - auto *method = AllocNode(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(), - desc->isComputed); + auto *method = + AllocNode(desc->methodKind, propName->Clone(Allocator(), nullptr)->AsExpression(), + funcExpr, desc->modifiers, Allocator(), desc->isComputed); method->SetRange(funcExpr->Range()); return method; @@ -1745,7 +1750,6 @@ ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector< lexer::SourcePosition propEnd = methodName->End(); ir::MethodDefinition *method = ParseClassMethod(&desc, properties, methodName, &propEnd); - method->Function()->SetIdent(methodName); method->Function()->AddModifier(desc.modifiers); method->SetRange({desc.propStart, propEnd}); if (desc.methodKind == ir::MethodDefinitionKind::GET) { @@ -1772,7 +1776,7 @@ ir::MethodDefinition *ETSParser::ParseInterfaceGetterSetterMethod(const ir::Modi method->Function()->AddFlag(ir::ScriptFunctionFlags::SETTER); } - method->Function()->SetIdent(method->Id()); + method->Function()->SetIdent(method->Id()->Clone(Allocator(), nullptr)); method->Function()->AddModifier(method->Modifiers()); return method; @@ -1964,7 +1968,7 @@ ir::TSInterfaceDeclaration *ETSParser::ParseInterfaceBody(ir::Identifier *name, const auto isExternal = (GetContext().Status() & ParserStatus::IN_EXTERNAL); auto *interfaceDecl = AllocNode( - Allocator(), name, typeParamDecl, body, std::move(extends), isStatic, isExternal, GetContext().GetLanguge()); + Allocator(), name, typeParamDecl, body, std::move(extends), isStatic, isExternal, GetContext().GetLanguage()); Lexer()->NextToken(); GetContext().Status() &= ~ParserStatus::ALLOW_THIS_TYPE; @@ -2065,7 +2069,7 @@ ir::ClassDefinition *ETSParser::ParseClassDefinition(ir::ClassDefinitionModifier auto *classDefinition = AllocNode( util::StringView(), identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass, - std::move(properties), modifiers, flags, GetContext().GetLanguge()); + std::move(properties), modifiers, flags, GetContext().GetLanguage()); classDefinition->SetRange(bodyRange); @@ -2133,6 +2137,7 @@ ir::ClassProperty *ETSParser::ParseInterfaceField() typeAnnotation = ParseTypeAnnotation(&options); name->SetTsTypeAnnotation(typeAnnotation); + typeAnnotation->SetParent(name); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EQUAL) { ThrowSyntaxError("Initializers are not allowed on interface propertys."); @@ -2144,7 +2149,8 @@ ir::ClassProperty *ETSParser::ParseInterfaceField() fieldModifiers |= ir::ModifierFlags::DECLARE; } - auto *field = AllocNode(name, nullptr, typeAnnotation, fieldModifiers, Allocator(), false); + auto *field = AllocNode(name, nullptr, typeAnnotation->Clone(Allocator(), nullptr), + fieldModifiers, Allocator(), false); field->SetEnd(Lexer()->GetToken().End()); return field; @@ -2181,8 +2187,9 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i functionContext.AddFlag(throwMarker); - auto *func = AllocNode(std::move(signature), body, functionContext.Flags(), flags, true, - GetContext().GetLanguge()); + auto *func = AllocNode( + std::move(signature), body, + ir::ScriptFunction::ScriptFunctionData {functionContext.Flags(), flags, true, GetContext().GetLanguage()}); if ((flags & ir::ModifierFlags::STATIC) == 0 && body == nullptr) { func->AddModifier(ir::ModifierFlags::ABSTRACT); @@ -2196,8 +2203,9 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i func->AddFlag(ir::ScriptFunctionFlags::METHOD); func->SetIdent(name); - auto *method = - AllocNode(ir::MethodDefinitionKind::METHOD, name, funcExpr, flags, Allocator(), false); + auto *method = AllocNode(ir::MethodDefinitionKind::METHOD, + name->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, flags, + Allocator(), false); method->SetRange(funcExpr->Range()); ConsumeSemicolon(method); @@ -3718,7 +3726,10 @@ void ETSParser::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpr Lexer()->NextToken(); // eat ':' TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; - param->SetTsTypeAnnotation(ParseTypeAnnotation(&options)); + if (auto *typeAnnotation = ParseTypeAnnotation(&options); typeAnnotation != nullptr) { + typeAnnotation->SetParent(param); + param->SetTsTypeAnnotation(typeAnnotation); + } } if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { @@ -4196,6 +4207,53 @@ ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExp return asExpression; } +// Extracted from 'ParseNewExpression()' to reduce function's size +ir::ClassDefinition *ETSParser::CreateClassDefinitionForNewExpression(ArenaVector &arguments, + ir::TypeNode *typeReference, + ir::TypeNode *baseTypeReference) +{ + lexer::SourcePosition endLoc = typeReference->End(); + + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { + if (baseTypeReference != nullptr) { + ThrowSyntaxError("Can not use 'new' on primitive types.", baseTypeReference->Start()); + } + + Lexer()->NextToken(); + + while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { + ir::Expression *argument = ParseExpression(); + arguments.push_back(argument); + + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { + Lexer()->NextToken(); + continue; + } + } + + endLoc = Lexer()->GetToken().End(); + Lexer()->NextToken(); + } + + ir::ClassDefinition *classDefinition {}; + + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + ArenaVector implements(Allocator()->Adapter()); + auto modifiers = ir::ClassDefinitionModifiers::ANONYMOUS | ir::ClassDefinitionModifiers::HAS_SUPER; + auto [ctor, properties, bodyRange] = ParseClassBody(modifiers); + + auto newIdent = AllocNode("#0", Allocator()); + classDefinition = AllocNode( + "#0", newIdent, nullptr, nullptr, std::move(implements), ctor, // remove name + typeReference->Clone(Allocator(), nullptr), std::move(properties), modifiers, ir::ModifierFlags::NONE, + Language(Language::Id::ETS)); + + classDefinition->SetRange(bodyRange); + } + + return classDefinition; +} + ir::Expression *ETSParser::ParseNewExpression() { lexer::SourcePosition start = Lexer()->GetToken().Start(); @@ -4242,43 +4300,8 @@ ir::Expression *ETSParser::ParseNewExpression() } ArenaVector arguments(Allocator()->Adapter()); - lexer::SourcePosition endLoc = typeReference->End(); - - if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { - if (baseTypeReference != nullptr) { - ThrowSyntaxError("Can not use 'new' on primitive types.", baseTypeReference->Start()); - } - - Lexer()->NextToken(); - - while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { - ir::Expression *argument = ParseExpression(); - arguments.push_back(argument); - - if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { - Lexer()->NextToken(); - continue; - } - } - - endLoc = Lexer()->GetToken().End(); - Lexer()->NextToken(); - } - - ir::ClassDefinition *classDefinition {}; - - if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { - ArenaVector implements(Allocator()->Adapter()); - auto modifiers = ir::ClassDefinitionModifiers::ANONYMOUS | ir::ClassDefinitionModifiers::HAS_SUPER; - auto [ctor, properties, bodyRange] = ParseClassBody(modifiers); - - auto newIdent = AllocNode("#0", Allocator()); - classDefinition = AllocNode( - "#0", newIdent, nullptr, nullptr, std::move(implements), ctor, // remove name - typeReference, std::move(properties), modifiers, ir::ModifierFlags::NONE, Language(Language::Id::ETS)); - - classDefinition->SetRange(bodyRange); - } + ir::ClassDefinition *classDefinition = + CreateClassDefinitionForNewExpression(arguments, typeReference, baseTypeReference); auto *newExprNode = AllocNode(typeReference, std::move(arguments), classDefinition); diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 4b4afef511257ad239e6150fd9db23e9cc66d76e..01e8b642042571d1417300cb37d2b7f4410bbbde 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -266,6 +266,10 @@ private: ir::AstNode *ParseInnerRest(const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags memberModifiers, ir::Identifier *identNode, const lexer::SourcePosition &startLoc); + + ir::ClassDefinition *CreateClassDefinitionForNewExpression(ArenaVector &arguments, + ir::TypeNode *typeReference, + ir::TypeNode *baseTypeReference); ir::Expression *ParseNewExpression() override; ir::Expression *ParseAsyncExpression(); ir::Expression *ParseAwaitExpression(); diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index a3018356f2b0dc8c995306197b600d68d79f8d2f..9851f05a727fe667ccf38ed487b31a68d0b1eb78 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -462,7 +462,7 @@ ir::Statement *TypedParser::ParseInterfaceDeclaration(bool isStatic) const auto isExternal = (GetContext().Status() & ParserStatus::IN_EXTERNAL); auto *interfaceDecl = AllocNode( - Allocator(), id, typeParamDecl, body, std::move(extends), isStatic, isExternal, GetContext().GetLanguge()); + Allocator(), id, typeParamDecl, body, std::move(extends), isStatic, isExternal, GetContext().GetLanguage()); interfaceDecl->SetRange({interfaceStart, Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -880,7 +880,7 @@ ir::ClassDefinition *TypedParser::ParseClassDefinition(ir::ClassDefinitionModifi auto *classDefinition = AllocNode( privateBinding.View(), identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass, - std::move(properties), modifiers, flags, GetContext().GetLanguge()); + std::move(properties), modifiers, flags, GetContext().GetLanguage()); classDefinition->SetRange(bodyRange); diff --git a/ets2panda/parser/context/parserContext.h b/ets2panda/parser/context/parserContext.h index 926fc510f0f3a3a425aa047e84bd55866d54c64e..5a3c4ce5118a483d24d84b9d7cf5e2bd299b51f5 100644 --- a/ets2panda/parser/context/parserContext.h +++ b/ets2panda/parser/context/parserContext.h @@ -98,7 +98,7 @@ public: program_ = program; } - Language GetLanguge() const + Language GetLanguage() const { return lang_; } diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 5eaa24e774c206db6312bfb73a1e4122b46ab6c1..ab8912e19f5961142947f5e516414528409ab06f 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -325,7 +325,7 @@ ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowF funcNode = AllocNode( ir::FunctionSignature(typeParamDecl, std::move(desc->params), returnTypeAnnotation), body, - arrowFunctionContext->Flags(), false, context_.GetLanguge()); + arrowFunctionContext->Flags(), false, context_.GetLanguage()); funcNode->SetRange({desc->startLoc, endLoc}); auto *arrowFuncNode = AllocNode(Allocator(), funcNode); diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index 5f4d6b623c1ca9ad05b63236f238f0573b00a73c..5410c6540494889aab3787dd2351d92843d51d21 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -466,7 +466,11 @@ ir::MethodDefinition *ParserImpl::ParseClassMethod(ClassElementDescriptor *desc, *propEnd = func->End(); func->AddFlag(ir::ScriptFunctionFlags::METHOD); - auto *method = AllocNode(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(), + + auto *ident = !(propName->IsArrowFunctionExpression() || propName->IsFunctionExpression()) + ? propName->Clone(Allocator(), nullptr)->AsExpression() + : propName; + auto *method = AllocNode(desc->methodKind, ident, funcExpr, desc->modifiers, Allocator(), desc->isComputed); method->SetRange(funcExpr->Range()); @@ -569,8 +573,9 @@ ir::ClassElement *ParserImpl::ParseClassStaticBlock() auto *body = AllocNode(Allocator(), std::move(statements)); auto *func = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, - ir::ScriptFunctionFlags::EXPRESSION | ir::ScriptFunctionFlags::STATIC_BLOCK, - ir::ModifierFlags::STATIC, false, context_.GetLanguge()); + ir::ScriptFunction::ScriptFunctionData { + ir::ScriptFunctionFlags::EXPRESSION | ir::ScriptFunctionFlags::STATIC_BLOCK, + ir::ModifierFlags::STATIC, false, context_.GetLanguage()}); auto *funcExpr = AllocNode(func); auto *staticBlock = AllocNode(funcExpr, Allocator()); @@ -656,7 +661,7 @@ ir::MethodDefinition *ParserImpl::BuildImplicitConstructor(ir::ClassDefinitionMo auto *func = AllocNode(ir::FunctionSignature(nullptr, std::move(params), nullptr), body, ir::ScriptFunctionFlags::CONSTRUCTOR | ir::ScriptFunctionFlags::IMPLICIT_SUPER_CALL_NEEDED, - false, context_.GetLanguge()); + false, context_.GetLanguage()); auto *funcExpr = AllocNode(func); auto *key = AllocNode("constructor", Allocator()); @@ -665,7 +670,8 @@ ir::MethodDefinition *ParserImpl::BuildImplicitConstructor(ir::ClassDefinitionMo func->SetIdent(key); } - auto *ctor = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, key, funcExpr, + auto *ctor = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, + key->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, ir::ModifierFlags::NONE, Allocator(), false); ctor->SetRange({startLoc, lexer_->GetToken().End()}); @@ -763,7 +769,7 @@ ir::ClassDefinition *ParserImpl::ParseClassDefinition(ir::ClassDefinitionModifie ArenaVector implements(Allocator()->Adapter()); auto *classDefinition = AllocNode( privateBinding.View(), identNode, nullptr, superTypeParams, std::move(implements), ctor, superClass, - std::move(properties), modifiers, flags, GetContext().GetLanguge()); + std::move(properties), modifiers, flags, GetContext().GetLanguage()); classDefinition->SetRange(bodyRange); @@ -912,7 +918,7 @@ ir::ScriptFunction *ParserImpl::ParseFunction(ParserStatus newStatus) functionContext.AddFlag(throw_marker); auto *funcNode = AllocNode(std::move(signature), body, functionContext.Flags(), - isDeclare && letDeclare, context_.GetLanguge()); + isDeclare && letDeclare, context_.GetLanguage()); funcNode->SetRange({startLoc, endLoc}); return funcNode; diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 4386ff754fa662041883a3db460aa90a65220c0f..47c1e4c1ed6c75cfd98dd09d082a9ba87c5bffd9 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -2023,8 +2023,8 @@ extern "C" es2panda_AstNode *CreateScriptFunction(es2panda_Context *context, es2 auto irModifierFlags = E2pToIrModifierFlags(modifierFlags); ir::FunctionSignature sig(irTypeParams, std::move(irParams), irReturnTypeAnnotation); - auto func = allocator->New(std::move(sig), nullptr, irFunctionFlags, irModifierFlags, isDeclare, - Language::FromString("ets").value()); + auto func = allocator->New( + std::move(sig), nullptr, ir::ScriptFunction::ScriptFunctionData {irFunctionFlags, irModifierFlags, isDeclare}); return reinterpret_cast(func); } diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index e8521c7c0b4ab6db263b0c1cd4a4363e32f60403..c67367252c325271b4cecb83c54cdae5221a555e 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -47,3 +47,7 @@ struct-init.ets struct-init2.ets struct_implements.ets top_level_03.ets + +# lowering 'expandBrackets' should be repaired #15594 +array-new.ets +array-new-catched.ets diff --git a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt index de27323be467022892a7ff1d56c6205e070690fa..22573f44a8f59d4a7968af5eabf4d90da9800529 100644 --- a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt @@ -11,3 +11,6 @@ parser/ets/import_tests/modules/struct_module.ets parser/ets/import_tests/check_exported_default_struct.ets parser/ets/import_tests/modules/struct_default_module.ets parser/ets/import_tests/check_exported_struct.ets + +# lowering 'expandBrackets' should be repaired #15594 +parser/ets/array_new.ets diff --git a/ets2panda/test/unit/node_creator.h b/ets2panda/test/unit/node_creator.h index f345b56f2873b08a099d0d26400339232fab104b..4a054bcb10917116f0c357fdf07288e220b9962c 100644 --- a/ets2panda/test/unit/node_creator.h +++ b/ets2panda/test/unit/node_creator.h @@ -65,7 +65,9 @@ public: auto varDecl = CreateVarDecl(true, name); ArenaVector tmp {alloc_->Adapter()}; tmp.emplace_back(varDecl); - return alloc_->New(alloc_, std::move(tmp)); + auto *newBlock = alloc_->New(alloc_, std::move(tmp)); + varDecl->SetParent(newBlock); + return newBlock; } ir::ForUpdateStatement *CreateForUpdate() @@ -82,4 +84,4 @@ public: private: ArenaAllocator *const alloc_; }; -} // namespace panda::es2panda::gtests \ No newline at end of file +} // namespace panda::es2panda::gtests diff --git a/ets2panda/util/options.cpp b/ets2panda/util/options.cpp index 7961ee7c144c5dae77f599155b7ad563d25b8c36..4f5e5c1db2e0b62c446d27b21a7067b22227f3f4 100644 --- a/ets2panda/util/options.cpp +++ b/ets2panda/util/options.cpp @@ -190,7 +190,7 @@ bool Options::Parse(int argc, const char **argv) "ForLoopCorrectlyInitializedForAll,VariableHasEnclosingScopeForAll,ModifierAccessValidForAll," "ImportExportAccessValid"); panda::PandArg verifierErrors( - "verifier-errors", "ForLoopCorrectlyInitializedForAll", + "verifier-errors", "ForLoopCorrectlyInitializedForAll,NodeHasParentForAll,EveryChildHasValidParentForAll", "Print errors and stop compilation if AST tree is incorrect. " "Possible values: " "NodeHasParentForAll,EveryChildHasValidParentForAll,VariableHasScopeForAll,NodeHasTypeForAll," diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 06d08f355360f8048f07c6523e8c017e54484f05..b5464f9e2020f3c2c3c66eb9d792028d8ba54ce6 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -275,9 +275,9 @@ void ETSBinder::BuildMethodDefinition(ir::MethodDefinition *methodDef) void ETSBinder::ResolveMethodDefinition(ir::MethodDefinition *methodDef) { - auto *func = methodDef->Function(); - ResolveReferences(methodDef); + methodDef->ResolveReferences([this](auto *childNode) { ResolveReference(childNode); }); + auto *func = methodDef->Function(); if (methodDef->IsStatic() || func->IsStaticBlock()) { return; }