diff --git a/checker/ETSAnalyzer.cpp b/checker/ETSAnalyzer.cpp index 2e05e528f30d1b428c49aef664379507c47a488b..7483849a395084f4d7567fde896656fa4ba7e1f1 100644 --- a/checker/ETSAnalyzer.cpp +++ b/checker/ETSAnalyzer.cpp @@ -16,15 +16,9 @@ #include "binder/binder.h" #include "binder/ETSBinder.h" +#include "checker/ETSchecker.h" +#include "checker/ets/castingContext.h" #include "checker/ets/typeRelationContext.h" -#include "ir/base/catchClause.h" -#include "ir/base/classProperty.h" -#include "ir/base/classStaticBlock.h" -#include "ir/expressions/identifier.h" -#include "ir/expressions/objectExpression.h" -#include "ir/expressions/arrayExpression.h" -#include "ir/statements/blockStatement.h" -#include "ir/statements/returnStatement.h" #include "util/helpers.h" namespace panda::es2panda::checker { @@ -177,58 +171,213 @@ checker::Type *ETSAnalyzer::Check(ir::TSPropertySignature *node) const UNREACHABLE(); } -checker::Type *ETSAnalyzer::Check(ir::TSSignatureDeclaration *node) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TSSignatureDeclaration *node) const { - (void)node; UNREACHABLE(); } // from ets folder checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const { - (void)expr; - UNREACHABLE(); + ETSChecker *checker = GetETSChecker(); + checker->ThrowTypeError("Class literal is not yet supported.", expr->expr_->Start()); + + expr->expr_->Check(checker); + auto *expr_type = expr->expr_->GetType(checker); + + if (expr_type->IsETSVoidType()) { + checker->ThrowTypeError("Invalid .class reference", expr->expr_->Start()); + } + + ArenaVector type_arg_types(checker->Allocator()->Adapter()); + type_arg_types.push_back(expr_type); // TODO(user): Box it if it's a primitive type + + checker::InstantiationContext ctx(checker, checker->GlobalBuiltinTypeType(), type_arg_types, expr->range_.start); + expr->SetTsType(ctx.Result()); + return expr->TsType(); } checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const { - (void)node; - UNREACHABLE(); + ETSChecker *checker = GetETSChecker(); + checker->CreateFunctionalInterfaceForFunctionType(node); + auto *interface_type = + checker->CreateETSObjectType(node->FunctionalInterface()->Id()->Name(), node->FunctionalInterface(), + checker::ETSObjectFlags::FUNCTIONAL_INTERFACE); + interface_type->SetSuperType(checker->GlobalETSObjectType()); + + auto *invoke_func = node->FunctionalInterface()->Body()->Body()[0]->AsMethodDefinition()->Function(); + auto *signature_info = checker->Allocator()->New(checker->Allocator()); + + for (auto *it : invoke_func->Params()) { + auto *const param = it->AsETSParameterExpression(); + if (param->IsRestParameter()) { + auto *rest_ident = param->Ident(); + + ASSERT(rest_ident->Variable()); + signature_info->rest_var = rest_ident->Variable()->AsLocalVariable(); + + ASSERT(param->TypeAnnotation()); + signature_info->rest_var->SetTsType(checker->GetTypeFromTypeAnnotation(param->TypeAnnotation())); + + auto array_type = signature_info->rest_var->TsType()->AsETSArrayType(); + checker->CreateBuiltinArraySignature(array_type, array_type->Rank()); + } else { + auto *param_ident = param->Ident(); + + ASSERT(param_ident->Variable()); + binder::Variable *param_var = param_ident->Variable(); + + ASSERT(param->TypeAnnotation()); + param_var->SetTsType(checker->GetTypeFromTypeAnnotation(param->TypeAnnotation())); + signature_info->params.push_back(param_var->AsLocalVariable()); + ++signature_info->min_arg_count; + } + } + + invoke_func->ReturnTypeAnnotation()->Check(checker); + auto *signature = checker->Allocator()->New(signature_info, + node->ReturnType()->GetType(checker), invoke_func); + signature->SetOwnerVar(invoke_func->Id()->Variable()->AsLocalVariable()); + signature->AddSignatureFlag(checker::SignatureFlags::FUNCTIONAL_INTERFACE_SIGNATURE); + signature->SetOwner(interface_type); + + auto *func_type = checker->CreateETSFunctionType(signature); + invoke_func->SetSignature(signature); + invoke_func->Id()->Variable()->SetTsType(func_type); + interface_type->AddProperty( + invoke_func->Id()->Variable()->AsLocalVariable()); + node->FunctionalInterface()->SetTsType(interface_type); + + auto *this_var = invoke_func->Scope()->ParamScope()->Params().front(); + this_var->SetTsType(interface_type); + checker->BuildFunctionalInterfaceName(node); + + node->ts_type_ = interface_type; + return interface_type; } -checker::Type *ETSAnalyzer::Check(ir::ETSImportDeclaration *node) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSImportDeclaration *node) const { - (void)node; UNREACHABLE(); } checker::Type *ETSAnalyzer::Check(ir::ETSLaunchExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSChecker *checker = GetETSChecker(); + expr->expr_->Check(checker); + auto *const launch_promise_type = + checker->GlobalBuiltinPromiseType() + ->Instantiate(checker->Allocator(), checker->Relation(), checker->GetGlobalTypesHolder()) + ->AsETSObjectType(); + launch_promise_type->AddTypeFlag(checker::TypeFlag::GENERIC); + + // Launch expression returns a Promise type, so we need to insert the expression's type + // as type parameter for the Promise class. + + auto *expr_type = + expr->expr_->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE) && !expr->expr_->TsType()->IsETSVoidType() + ? checker->PrimitiveTypeAsETSBuiltinType(expr->expr_->TsType()) + : expr->expr_->TsType(); + checker::Substitution *substitution = checker->NewSubstitution(); + ASSERT(launch_promise_type->TypeArguments().size() == 1); + substitution->emplace(checker->GetOriginalBaseType(launch_promise_type->TypeArguments()[0]), expr_type); + + expr->SetTsType(launch_promise_type->Substitute(checker->Relation(), substitution)); + return expr->TsType(); } checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSChecker *checker = GetETSChecker(); + + auto *element_type = expr->type_reference_->GetType(checker); + checker->ValidateArrayIndex(expr->dimension_); + + expr->SetTsType(checker->CreateETSArrayType(element_type)); + checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); + return expr->TsType(); } checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSChecker *checker = GetETSChecker(); + checker::Type *callee_type = expr->GetTypeRef()->Check(checker); + + if (!callee_type->IsETSObjectType()) { + checker->ThrowTypeError("This expression is not constructible.", expr->Start()); + } + + auto *callee_obj = callee_type->AsETSObjectType(); + expr->SetTsType(callee_obj); + + if (expr->ClassDefinition() != nullptr) { + if (!callee_obj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT) && callee_obj->GetDeclNode()->IsFinal()) { + checker->ThrowTypeError({"Class ", callee_obj->Name(), " cannot be both 'abstract' and 'final'."}, + callee_obj->GetDeclNode()->Start()); + } + + bool from_interface = callee_obj->HasObjectFlag(checker::ETSObjectFlags::INTERFACE); + auto *class_type = checker->BuildAnonymousClassProperties( + expr->ClassDefinition(), from_interface ? checker->GlobalETSObjectType() : callee_obj); + if (from_interface) { + class_type->AddInterface(callee_obj); + callee_obj = checker->GlobalETSObjectType(); + } + expr->ClassDefinition()->SetTsType(class_type); + checker->CheckClassDefinition(expr->ClassDefinition()); + checker->CheckInnerClassMembers(class_type); + expr->SetTsType(class_type); + } else if (callee_obj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT)) { + checker->ThrowTypeError({callee_obj->Name(), " is abstract therefore cannot be instantiated."}, expr->Start()); + } + + if (callee_type->IsETSDynamicType() && !callee_type->AsETSDynamicType()->HasDecl()) { + auto lang = callee_type->AsETSDynamicType()->Language(); + expr->signature_ = checker->ResolveDynamicCallExpression(expr->GetTypeRef(), expr->GetArguments(), lang, true); + } else { + auto *signature = checker->ResolveConstructExpression(callee_obj, expr->GetArguments(), expr->Start()); + + checker->CheckObjectLiteralArguments(signature, expr->GetArguments()); + checker->ValidateSignatureAccessibility(callee_obj, signature, expr->Start()); + + ASSERT(signature->Function() != nullptr); + + if (signature->Function()->IsThrowing() || signature->Function()->IsRethrowing()) { + checker->CheckThrowingStatements(expr); + } + + if (callee_type->IsETSDynamicType()) { + ASSERT(signature->Function()->IsDynamic()); + auto lang = callee_type->AsETSDynamicType()->Language(); + expr->signature_ = + checker->ResolveDynamicCallExpression(expr->GetTypeRef(), signature->Params(), lang, true); + } else { + ASSERT(!signature->Function()->IsDynamic()); + expr->signature_ = signature; + } + } + + return expr->TsType(); } checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSChecker *checker = GetETSChecker(); + auto *element_type = expr->type_reference_->GetType(checker); + + for (auto *dim : expr->dimensions_) { + checker->ValidateArrayIndex(dim); + element_type = checker->CreateETSArrayType(element_type); + } + + expr->SetTsType(element_type); + expr->signature_ = checker->CreateBuiltinArraySignature(element_type->AsETSArrayType(), expr->dimensions_.size()); + return expr->TsType(); } -checker::Type *ETSAnalyzer::Check(ir::ETSPackageDeclaration *st) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPackageDeclaration *st) const { - (void)st; - UNREACHABLE(); + return nullptr; } checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const diff --git a/checker/SemanticAnalyzer.h b/checker/SemanticAnalyzer.h index 72cfe3735de6e7438ae231ba39f65cf98146e39e..8cc27451f53332c643d0c2cbf5c7139e84b51f76 100644 --- a/checker/SemanticAnalyzer.h +++ b/checker/SemanticAnalyzer.h @@ -17,6 +17,152 @@ #define ES2PANDA_CHECKER_SEMANTICANALYZER_H #include "compiler/core/dynamicContext.h" +#include "ir/opaqueTypeNode.h" +#include "ir/as/namedType.h" +#include "ir/as/prefixAssertionExpression.h" +#include "ir/base/catchClause.h" +#include "ir/base/classDefinition.h" +#include "ir/base/classProperty.h" +#include "ir/base/classStaticBlock.h" +#include "ir/base/decorator.h" +#include "ir/base/metaProperty.h" +#include "ir/base/methodDefinition.h" +#include "ir/base/property.h" +#include "ir/base/scriptFunction.h" +#include "ir/base/spreadElement.h" +#include "ir/base/templateElement.h" +#include "ir/base/tsIndexSignature.h" +#include "ir/base/tsMethodSignature.h" +#include "ir/base/tsPropertySignature.h" +#include "ir/base/tsSignatureDeclaration.h" +#include "ir/ets/etsClassLiteral.h" +#include "ir/ets/etsFunctionType.h" +#include "ir/ets/etsImportDeclaration.h" +#include "ir/ets/etsLaunchExpression.h" +#include "ir/ets/etsNewArrayInstanceExpression.h" +#include "ir/ets/etsNewClassInstanceExpression.h" +#include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" +#include "ir/ets/etsPackageDeclaration.h" +#include "ir/ets/etsParameterExpression.h" +#include "ir/ets/etsPrimitiveType.h" +#include "ir/ets/etsScript.h" +#include "ir/ets/etsStructDeclaration.h" +#include "ir/ets/etsTypeReference.h" +#include "ir/ets/etsTypeReferencePart.h" +#include "ir/ets/etsWildcardType.h" +#include "ir/expressions/arrayExpression.h" +#include "ir/expressions/arrowFunctionExpression.h" +#include "ir/expressions/assignmentExpression.h" +#include "ir/expressions/awaitExpression.h" +#include "ir/expressions/binaryExpression.h" +#include "ir/expressions/callExpression.h" +#include "ir/expressions/chainExpression.h" +#include "ir/expressions/classExpression.h" +#include "ir/expressions/conditionalExpression.h" +#include "ir/expressions/directEvalExpression.h" +#include "ir/expressions/functionExpression.h" +#include "ir/expressions/identifier.h" +#include "ir/expressions/importExpression.h" +#include "ir/expressions/memberExpression.h" +#include "ir/expressions/newExpression.h" +#include "ir/expressions/objectExpression.h" +#include "ir/expressions/omittedExpression.h" +#include "ir/expressions/sequenceExpression.h" +#include "ir/expressions/superExpression.h" +#include "ir/expressions/taggedTemplateExpression.h" +#include "ir/expressions/templateLiteral.h" +#include "ir/expressions/thisExpression.h" +#include "ir/expressions/unaryExpression.h" +#include "ir/expressions/updateExpression.h" +#include "ir/expressions/yieldExpression.h" +#include "ir/expressions/literals/bigIntLiteral.h" +#include "ir/expressions/literals/booleanLiteral.h" +#include "ir/expressions/literals/charLiteral.h" +#include "ir/expressions/literals/nullLiteral.h" +#include "ir/expressions/literals/numberLiteral.h" +#include "ir/expressions/literals/regExpLiteral.h" +#include "ir/expressions/literals/stringLiteral.h" +#include "ir/module/exportAllDeclaration.h" +#include "ir/module/exportDefaultDeclaration.h" +#include "ir/module/exportNamedDeclaration.h" +#include "ir/module/exportSpecifier.h" +#include "ir/module/importDeclaration.h" +#include "ir/module/importDefaultSpecifier.h" +#include "ir/module/importNamespaceSpecifier.h" +#include "ir/module/importSpecifier.h" +#include "ir/statements/assertStatement.h" +#include "ir/statements/blockStatement.h" +#include "ir/statements/breakStatement.h" +#include "ir/statements/classDeclaration.h" +#include "ir/statements/continueStatement.h" +#include "ir/statements/debuggerStatement.h" +#include "ir/statements/doWhileStatement.h" +#include "ir/statements/emptyStatement.h" +#include "ir/statements/expressionStatement.h" +#include "ir/statements/forInStatement.h" +#include "ir/statements/forOfStatement.h" +#include "ir/statements/forUpdateStatement.h" +#include "ir/statements/functionDeclaration.h" +#include "ir/statements/ifStatement.h" +#include "ir/statements/labelledStatement.h" +#include "ir/statements/returnStatement.h" +#include "ir/statements/switchCaseStatement.h" +#include "ir/statements/switchStatement.h" +#include "ir/statements/throwStatement.h" +#include "ir/statements/tryStatement.h" +#include "ir/statements/variableDeclaration.h" +#include "ir/statements/variableDeclarator.h" +#include "ir/statements/whileStatement.h" +#include "ir/ts/tsAnyKeyword.h" +#include "ir/ts/tsArrayType.h" +#include "ir/ts/tsAsExpression.h" +#include "ir/ts/tsBigintKeyword.h" +#include "ir/ts/tsBooleanKeyword.h" +#include "ir/ts/tsClassImplements.h" +#include "ir/ts/tsConditionalType.h" +#include "ir/ts/tsConstructorType.h" +#include "ir/ts/tsEnumDeclaration.h" +#include "ir/ts/tsEnumMember.h" +#include "ir/ts/tsExternalModuleReference.h" +#include "ir/ts/tsFunctionType.h" +#include "ir/ts/tsImportEqualsDeclaration.h" +#include "ir/ts/tsImportType.h" +#include "ir/ts/tsIndexedAccessType.h" +#include "ir/ts/tsInferType.h" +#include "ir/ts/tsInterfaceBody.h" +#include "ir/ts/tsInterfaceDeclaration.h" +#include "ir/ts/tsInterfaceHeritage.h" +#include "ir/ts/tsIntersectionType.h" +#include "ir/ts/tsLiteralType.h" +#include "ir/ts/tsMappedType.h" +#include "ir/ts/tsModuleBlock.h" +#include "ir/ts/tsModuleDeclaration.h" +#include "ir/ts/tsNamedTupleMember.h" +#include "ir/ts/tsNeverKeyword.h" +#include "ir/ts/tsNonNullExpression.h" +#include "ir/ts/tsNullKeyword.h" +#include "ir/ts/tsNumberKeyword.h" +#include "ir/ts/tsObjectKeyword.h" +#include "ir/ts/tsParameterProperty.h" +#include "ir/ts/tsParenthesizedType.h" +#include "ir/ts/tsQualifiedName.h" +#include "ir/ts/tsStringKeyword.h" +#include "ir/ts/tsThisType.h" +#include "ir/ts/tsTupleType.h" +#include "ir/ts/tsTypeAliasDeclaration.h" +#include "ir/ts/tsTypeAssertion.h" +#include "ir/ts/tsTypeLiteral.h" +#include "ir/ts/tsTypeOperator.h" +#include "ir/ts/tsTypeParameterDeclaration.h" +#include "ir/ts/tsTypeParameter.h" +#include "ir/ts/tsTypeParameterInstantiation.h" +#include "ir/ts/tsTypePredicate.h" +#include "ir/ts/tsTypeQuery.h" +#include "ir/ts/tsTypeReference.h" +#include "ir/ts/tsUndefinedKeyword.h" +#include "ir/ts/tsUnionType.h" +#include "ir/ts/tsUnknownKeyword.h" +#include "ir/ts/tsVoidKeyword.h" namespace panda::es2panda::checker { class Checker; diff --git a/checker/TSAnalyzer.cpp b/checker/TSAnalyzer.cpp index f5bfa79b2f493c500b2a5eb57e720362351182ea..528a7c772c63c69111c8c4dd0846965d8be7cceb 100644 --- a/checker/TSAnalyzer.cpp +++ b/checker/TSAnalyzer.cpp @@ -16,12 +16,7 @@ #include "TSAnalyzer.h" #include "checker/TSchecker.h" -#include "ir/base/catchClause.h" -#include "ir/base/methodDefinition.h" -#include "ir/base/scriptFunction.h" -#include "ir/statements/blockStatement.h" -#include "ir/statements/returnStatement.h" -#include "ir/typeNode.h" +#include "checker/ts/destructuringContext.h" #include "util/helpers.h" namespace panda::es2panda::checker { @@ -139,55 +134,84 @@ checker::Type *TSAnalyzer::Check(ir::TSPropertySignature *node) const checker::Type *TSAnalyzer::Check(ir::TSSignatureDeclaration *node) const { - (void)node; - UNREACHABLE(); + TSChecker *checker = GetTSChecker(); + if (node->TsType() != nullptr) { + return node->TsType(); + } + + checker::ScopeContext scope_ctx(checker, node->Scope()); + + auto *signature_info = checker->Allocator()->New(checker->Allocator()); + checker->CheckFunctionParameterDeclarations(node->Params(), signature_info); + + bool is_call_signature = (node->Kind() == ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE); + + if (node->ReturnTypeAnnotation() == nullptr) { + if (is_call_signature) { + checker->ThrowTypeError( + "Call signature, which lacks return-type annotation, implicitly has an 'any' return type.", + node->Start()); + } + + checker->ThrowTypeError( + "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.", + node->Start()); + } + + node->return_type_annotation_->Check(checker); + checker::Type *return_type = node->return_type_annotation_->GetType(checker); + + auto *signature = checker->Allocator()->New(signature_info, return_type); + + checker::Type *placeholder_obj = nullptr; + + if (is_call_signature) { + placeholder_obj = checker->CreateObjectTypeWithCallSignature(signature); + } else { + placeholder_obj = checker->CreateObjectTypeWithConstructSignature(signature); + } + + node->SetTsType(placeholder_obj); + return placeholder_obj; } // from ets folder -checker::Type *TSAnalyzer::Check(ir::ETSClassLiteral *expr) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSClassLiteral *expr) const { - (void)expr; UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::ETSFunctionType *node) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSFunctionType *node) const { - (void)node; UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::ETSImportDeclaration *node) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSImportDeclaration *node) const { - (void)node; UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::ETSLaunchExpression *expr) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSLaunchExpression *expr) const { - (void)expr; UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNewArrayInstanceExpression *expr) const { - (void)expr; UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNewClassInstanceExpression *expr) const { - (void)expr; UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *expr) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNewMultiDimArrayInstanceExpression *expr) const { - (void)expr; UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::ETSPackageDeclaration *st) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSPackageDeclaration *st) const { - (void)st; UNREACHABLE(); } diff --git a/compiler/core/ASTCompiler.h b/compiler/core/ASTCompiler.h index b5bd6661794f22acfc3e000542ef9b1282941eda..03fdde033adf00ef433610758d7e7dbcbdccb6c0 100644 --- a/compiler/core/ASTCompiler.h +++ b/compiler/core/ASTCompiler.h @@ -17,6 +17,152 @@ #define ES2PANDA_COMPILER_CORE_ASTCOMPILER_H #include "compiler/core/dynamicContext.h" +#include "ir/opaqueTypeNode.h" +#include "ir/as/namedType.h" +#include "ir/as/prefixAssertionExpression.h" +#include "ir/base/catchClause.h" +#include "ir/base/classDefinition.h" +#include "ir/base/classProperty.h" +#include "ir/base/classStaticBlock.h" +#include "ir/base/decorator.h" +#include "ir/base/metaProperty.h" +#include "ir/base/methodDefinition.h" +#include "ir/base/property.h" +#include "ir/base/scriptFunction.h" +#include "ir/base/spreadElement.h" +#include "ir/base/templateElement.h" +#include "ir/base/tsIndexSignature.h" +#include "ir/base/tsMethodSignature.h" +#include "ir/base/tsPropertySignature.h" +#include "ir/base/tsSignatureDeclaration.h" +#include "ir/ets/etsClassLiteral.h" +#include "ir/ets/etsFunctionType.h" +#include "ir/ets/etsImportDeclaration.h" +#include "ir/ets/etsLaunchExpression.h" +#include "ir/ets/etsNewArrayInstanceExpression.h" +#include "ir/ets/etsNewClassInstanceExpression.h" +#include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" +#include "ir/ets/etsPackageDeclaration.h" +#include "ir/ets/etsParameterExpression.h" +#include "ir/ets/etsPrimitiveType.h" +#include "ir/ets/etsScript.h" +#include "ir/ets/etsStructDeclaration.h" +#include "ir/ets/etsTypeReference.h" +#include "ir/ets/etsTypeReferencePart.h" +#include "ir/ets/etsWildcardType.h" +#include "ir/expressions/arrayExpression.h" +#include "ir/expressions/arrowFunctionExpression.h" +#include "ir/expressions/assignmentExpression.h" +#include "ir/expressions/awaitExpression.h" +#include "ir/expressions/binaryExpression.h" +#include "ir/expressions/callExpression.h" +#include "ir/expressions/chainExpression.h" +#include "ir/expressions/classExpression.h" +#include "ir/expressions/conditionalExpression.h" +#include "ir/expressions/directEvalExpression.h" +#include "ir/expressions/functionExpression.h" +#include "ir/expressions/identifier.h" +#include "ir/expressions/importExpression.h" +#include "ir/expressions/memberExpression.h" +#include "ir/expressions/newExpression.h" +#include "ir/expressions/objectExpression.h" +#include "ir/expressions/omittedExpression.h" +#include "ir/expressions/sequenceExpression.h" +#include "ir/expressions/superExpression.h" +#include "ir/expressions/taggedTemplateExpression.h" +#include "ir/expressions/templateLiteral.h" +#include "ir/expressions/thisExpression.h" +#include "ir/expressions/unaryExpression.h" +#include "ir/expressions/updateExpression.h" +#include "ir/expressions/yieldExpression.h" +#include "ir/expressions/literals/bigIntLiteral.h" +#include "ir/expressions/literals/booleanLiteral.h" +#include "ir/expressions/literals/charLiteral.h" +#include "ir/expressions/literals/nullLiteral.h" +#include "ir/expressions/literals/numberLiteral.h" +#include "ir/expressions/literals/regExpLiteral.h" +#include "ir/expressions/literals/stringLiteral.h" +#include "ir/module/exportAllDeclaration.h" +#include "ir/module/exportDefaultDeclaration.h" +#include "ir/module/exportNamedDeclaration.h" +#include "ir/module/exportSpecifier.h" +#include "ir/module/importDeclaration.h" +#include "ir/module/importDefaultSpecifier.h" +#include "ir/module/importNamespaceSpecifier.h" +#include "ir/module/importSpecifier.h" +#include "ir/statements/assertStatement.h" +#include "ir/statements/blockStatement.h" +#include "ir/statements/breakStatement.h" +#include "ir/statements/classDeclaration.h" +#include "ir/statements/continueStatement.h" +#include "ir/statements/debuggerStatement.h" +#include "ir/statements/doWhileStatement.h" +#include "ir/statements/emptyStatement.h" +#include "ir/statements/expressionStatement.h" +#include "ir/statements/forInStatement.h" +#include "ir/statements/forOfStatement.h" +#include "ir/statements/forUpdateStatement.h" +#include "ir/statements/functionDeclaration.h" +#include "ir/statements/ifStatement.h" +#include "ir/statements/labelledStatement.h" +#include "ir/statements/returnStatement.h" +#include "ir/statements/switchCaseStatement.h" +#include "ir/statements/switchStatement.h" +#include "ir/statements/throwStatement.h" +#include "ir/statements/tryStatement.h" +#include "ir/statements/variableDeclaration.h" +#include "ir/statements/variableDeclarator.h" +#include "ir/statements/whileStatement.h" +#include "ir/ts/tsAnyKeyword.h" +#include "ir/ts/tsArrayType.h" +#include "ir/ts/tsAsExpression.h" +#include "ir/ts/tsBigintKeyword.h" +#include "ir/ts/tsBooleanKeyword.h" +#include "ir/ts/tsClassImplements.h" +#include "ir/ts/tsConditionalType.h" +#include "ir/ts/tsConstructorType.h" +#include "ir/ts/tsEnumDeclaration.h" +#include "ir/ts/tsEnumMember.h" +#include "ir/ts/tsExternalModuleReference.h" +#include "ir/ts/tsFunctionType.h" +#include "ir/ts/tsImportEqualsDeclaration.h" +#include "ir/ts/tsImportType.h" +#include "ir/ts/tsIndexedAccessType.h" +#include "ir/ts/tsInferType.h" +#include "ir/ts/tsInterfaceBody.h" +#include "ir/ts/tsInterfaceDeclaration.h" +#include "ir/ts/tsInterfaceHeritage.h" +#include "ir/ts/tsIntersectionType.h" +#include "ir/ts/tsLiteralType.h" +#include "ir/ts/tsMappedType.h" +#include "ir/ts/tsModuleBlock.h" +#include "ir/ts/tsModuleDeclaration.h" +#include "ir/ts/tsNamedTupleMember.h" +#include "ir/ts/tsNeverKeyword.h" +#include "ir/ts/tsNonNullExpression.h" +#include "ir/ts/tsNullKeyword.h" +#include "ir/ts/tsNumberKeyword.h" +#include "ir/ts/tsObjectKeyword.h" +#include "ir/ts/tsParameterProperty.h" +#include "ir/ts/tsParenthesizedType.h" +#include "ir/ts/tsQualifiedName.h" +#include "ir/ts/tsStringKeyword.h" +#include "ir/ts/tsThisType.h" +#include "ir/ts/tsTupleType.h" +#include "ir/ts/tsTypeAliasDeclaration.h" +#include "ir/ts/tsTypeAssertion.h" +#include "ir/ts/tsTypeLiteral.h" +#include "ir/ts/tsTypeOperator.h" +#include "ir/ts/tsTypeParameterDeclaration.h" +#include "ir/ts/tsTypeParameter.h" +#include "ir/ts/tsTypeParameterInstantiation.h" +#include "ir/ts/tsTypePredicate.h" +#include "ir/ts/tsTypeQuery.h" +#include "ir/ts/tsTypeReference.h" +#include "ir/ts/tsUndefinedKeyword.h" +#include "ir/ts/tsUnionType.h" +#include "ir/ts/tsUnknownKeyword.h" +#include "ir/ts/tsVoidKeyword.h" namespace panda::es2panda::compiler { class CodeGen; diff --git a/compiler/core/ETSCompiler.cpp b/compiler/core/ETSCompiler.cpp index c7f91c0d7962a2e2b8797f073f71b64e0e9c642f..cd49c329535c15604f7bbf41ea94810ea849e56a 100644 --- a/compiler/core/ETSCompiler.cpp +++ b/compiler/core/ETSCompiler.cpp @@ -15,13 +15,11 @@ #include "ETSCompiler.h" +#include "checker/types/ets/etsDynamicFunctionType.h" +#include "compiler/base/condition.h" #include "compiler/base/lreference.h" #include "compiler/core/ETSGen.h" -#include "ir/base/catchClause.h" -#include "ir/base/classProperty.h" -#include "ir/expressions/identifier.h" -#include "ir/statements/blockStatement.h" -#include "ir/statements/returnStatement.h" +#include "compiler/function/functionBuilder.h" namespace panda::es2panda::compiler { @@ -142,57 +140,149 @@ void ETSCompiler::Compile(const ir::TSPropertySignature *node) const UNREACHABLE(); } -void ETSCompiler::Compile(const ir::TSSignatureDeclaration *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSSignatureDeclaration *node) const { - (void)node; UNREACHABLE(); } // from ets folder void ETSCompiler::Compile(const ir::ETSClassLiteral *expr) const { - (void)expr; - UNREACHABLE(); + ETSGen *etsg = GetETSGen(); + if (expr->expr_->TsType()->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + expr->expr_->Compile(etsg); + etsg->GetType(expr, false); + } else { + ASSERT(expr->expr_->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)); + etsg->SetAccumulatorType(expr->expr_->TsType()); + etsg->GetType(expr, true); + } } -void ETSCompiler::Compile(const ir::ETSFunctionType *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::ETSFunctionType *node) const { - (void)node; UNREACHABLE(); } -void ETSCompiler::Compile(const ir::ETSImportDeclaration *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::ETSImportDeclaration *node) const { - (void)node; UNREACHABLE(); } void ETSCompiler::Compile(const ir::ETSLaunchExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSGen *etsg = GetETSGen(); + compiler::RegScope rs(etsg); + compiler::VReg callee_reg = etsg->AllocReg(); + checker::Signature *signature = expr->expr_->Signature(); + bool is_static = signature->HasSignatureFlag(checker::SignatureFlags::STATIC); + bool is_reference = signature->HasSignatureFlag(checker::SignatureFlags::TYPE); + + if (!is_reference && expr->expr_->Callee()->IsIdentifier()) { + if (!is_static) { + etsg->LoadThis(expr->expr_); + etsg->StoreAccumulator(expr, callee_reg); + } + } else if (!is_reference && expr->expr_->Callee()->IsMemberExpression()) { + if (!is_static) { + expr->expr_->Callee()->AsMemberExpression()->Object()->Compile(etsg); + etsg->StoreAccumulator(expr, callee_reg); + } + } else { + expr->expr_->Callee()->Compile(etsg); + etsg->StoreAccumulator(expr, callee_reg); + } + + if (is_static) { + etsg->LaunchStatic(expr, signature, expr->expr_->Arguments()); + } else if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE)) { + etsg->LaunchThisStatic(expr, callee_reg, signature, expr->expr_->Arguments()); + } else { + etsg->LaunchThisVirtual(expr, callee_reg, signature, expr->expr_->Arguments()); + } + + etsg->SetAccumulatorType(expr->TsType()); } void ETSCompiler::Compile(const ir::ETSNewArrayInstanceExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSGen *etsg = GetETSGen(); + compiler::RegScope rs(etsg); + compiler::TargetTypeContext ttctx(etsg, etsg->Checker()->GlobalIntType()); + + expr->dimension_->Compile(etsg); + + compiler::VReg arr = etsg->AllocReg(); + compiler::VReg dim = etsg->AllocReg(); + etsg->ApplyConversionAndStoreAccumulator(expr, dim, expr->dimension_->TsType()); + etsg->NewArray(expr, arr, dim, expr->TsType()); + etsg->SetVRegType(arr, expr->TsType()); + etsg->LoadAccumulator(expr, arr); +} + +static void CreateDynamicObject(const ir::AstNode *node, compiler::ETSGen *etsg, compiler::VReg &obj_reg, + ir::Expression *name, checker::Signature *signature, + const ArenaVector &arguments) +{ + auto qname_reg = etsg->AllocReg(); + + std::vector parts; + + while (name->IsTSQualifiedName()) { + auto *qname = name->AsTSQualifiedName(); + name = qname->Left(); + parts.push_back(qname->Right()->AsIdentifier()->Name()); + } + + auto *var = name->AsIdentifier()->Variable(); + auto *data = etsg->Binder()->DynamicImportDataForVar(var); + if (data != nullptr) { + auto *import = data->import; + auto *specifier = data->specifier; + ASSERT(import->Language().IsDynamic()); + etsg->LoadAccumulatorDynamicModule(node, import); + if (specifier->IsImportSpecifier()) { + parts.push_back(specifier->AsImportSpecifier()->Imported()->Name()); + } + } else { + name->Compile(etsg); + } + + etsg->StoreAccumulator(node, obj_reg); + + std::stringstream ss; + std::for_each(parts.rbegin(), parts.rend(), [&ss](util::StringView sv) { ss << "." << sv; }); + + etsg->LoadAccumulatorString(node, util::UString(ss.str(), etsg->Allocator()).View()); + etsg->StoreAccumulator(node, qname_reg); + + etsg->CallDynamic(node, obj_reg, qname_reg, signature, arguments); } void ETSCompiler::Compile(const ir::ETSNewClassInstanceExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSGen *etsg = GetETSGen(); + if (expr->TsType()->IsETSDynamicType()) { + auto obj_reg = etsg->AllocReg(); + auto *name = expr->GetTypeRef()->AsETSTypeReference()->Part()->Name(); + CreateDynamicObject(expr, etsg, obj_reg, name, expr->signature_, expr->GetArguments()); + } else { + etsg->InitObject(expr, expr->signature_, expr->GetArguments()); + } + + if (expr->GetBoxingUnboxingFlags() == ir::BoxingUnboxingFlags::NONE) { + etsg->SetAccumulatorType(expr->TsType()); + } } void ETSCompiler::Compile(const ir::ETSNewMultiDimArrayInstanceExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSGen *etsg = GetETSGen(); + etsg->InitObject(expr, expr->signature_, expr->dimensions_); + etsg->SetAccumulatorType(expr->TsType()); } -void ETSCompiler::Compile(const ir::ETSPackageDeclaration *st) const +void ETSCompiler::Compile([[maybe_unused]] const ir::ETSPackageDeclaration *st) const { - (void)st; UNREACHABLE(); } diff --git a/compiler/core/JSCompiler.cpp b/compiler/core/JSCompiler.cpp index a0b4815892d893a6432ee139e5fcea744c7a4b0c..af45f91366841111e9c6e5a4544d6065ff19c6a8 100644 --- a/compiler/core/JSCompiler.cpp +++ b/compiler/core/JSCompiler.cpp @@ -15,18 +15,10 @@ #include "JSCompiler.h" +#include "compiler/base/condition.h" #include "compiler/base/lreference.h" #include "compiler/core/pandagen.h" -#include "ir/base/catchClause.h" -#include "ir/base/classDefinition.h" -#include "ir/base/classProperty.h" -#include "ir/base/classStaticBlock.h" -#include "ir/base/methodDefinition.h" -#include "ir/base/scriptFunction.h" -#include "ir/expressions/functionExpression.h" -#include "ir/expressions/identifier.h" -#include "ir/statements/blockStatement.h" -#include "ir/statements/returnStatement.h" +#include "compiler/function/functionBuilder.h" #include "util/helpers.h" namespace panda::es2panda::compiler { @@ -469,57 +461,48 @@ void JSCompiler::Compile(const ir::TSPropertySignature *node) const UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSSignatureDeclaration *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSSignatureDeclaration *node) const { - (void)node; UNREACHABLE(); } // from ets folder -void JSCompiler::Compile(const ir::ETSClassLiteral *expr) const +void JSCompiler::Compile([[maybe_unused]] const ir::ETSClassLiteral *expr) const { - (void)expr; UNREACHABLE(); } -void JSCompiler::Compile(const ir::ETSFunctionType *expr) const +void JSCompiler::Compile([[maybe_unused]] const ir::ETSFunctionType *expr) const { - (void)expr; UNREACHABLE(); } -void JSCompiler::Compile(const ir::ETSImportDeclaration *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::ETSImportDeclaration *node) const { - (void)node; UNREACHABLE(); } -void JSCompiler::Compile(const ir::ETSLaunchExpression *expr) const +void JSCompiler::Compile([[maybe_unused]] const ir::ETSLaunchExpression *expr) const { - (void)expr; UNREACHABLE(); } -void JSCompiler::Compile(const ir::ETSNewArrayInstanceExpression *expr) const +void JSCompiler::Compile([[maybe_unused]] const ir::ETSNewArrayInstanceExpression *expr) const { - (void)expr; UNREACHABLE(); } -void JSCompiler::Compile(const ir::ETSNewClassInstanceExpression *expr) const +void JSCompiler::Compile([[maybe_unused]] const ir::ETSNewClassInstanceExpression *expr) const { - (void)expr; UNREACHABLE(); } -void JSCompiler::Compile(const ir::ETSNewMultiDimArrayInstanceExpression *expr) const +void JSCompiler::Compile([[maybe_unused]] const ir::ETSNewMultiDimArrayInstanceExpression *expr) const { - (void)expr; UNREACHABLE(); } -void JSCompiler::Compile(const ir::ETSPackageDeclaration *expr) const +void JSCompiler::Compile([[maybe_unused]] const ir::ETSPackageDeclaration *expr) const { - (void)expr; UNREACHABLE(); } diff --git a/ir/base/tsSignatureDeclaration.cpp b/ir/base/tsSignatureDeclaration.cpp index e121ff54f3f7dd46d4c6af1ec1a524223ccc068e..7b61d802e5c13a5c0e7d6c3e9746df814a2a4a03 100644 --- a/ir/base/tsSignatureDeclaration.cpp +++ b/ir/base/tsSignatureDeclaration.cpp @@ -15,13 +15,12 @@ #include "tsSignatureDeclaration.h" -#include "binder/scope.h" -#include "ir/typeNode.h" -#include "ir/astDump.h" -#include "ir/ts/tsTypeParameter.h" -#include "ir/ts/tsTypeParameterDeclaration.h" - +// #include "binder/scope.h" +#include "checker/ETSchecker.h" #include "checker/TSchecker.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" +#include "ir/astDump.h" namespace panda::es2panda::ir { void TSSignatureDeclaration::TransformChildren(const NodeTransformer &cb) @@ -64,50 +63,23 @@ void TSSignatureDeclaration::Dump(ir::AstDumper *dumper) const {"returnType", AstDumper::Optional(return_type_annotation_)}}); } -void TSSignatureDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} - -checker::Type *TSSignatureDeclaration::Check([[maybe_unused]] checker::TSChecker *checker) +void TSSignatureDeclaration::Compile(compiler::PandaGen *pg) const { - if (TsType() != nullptr) { - return TsType(); - } - - checker::ScopeContext scope_ctx(checker, scope_); - - auto *signature_info = checker->Allocator()->New(checker->Allocator()); - checker->CheckFunctionParameterDeclarations(params_, signature_info); - - bool is_call_signature = (Kind() == ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CALL_SIGNATURE); - - if (return_type_annotation_ == nullptr) { - if (is_call_signature) { - checker->ThrowTypeError( - "Call signature, which lacks return-type annotation, implicitly has an 'any' return type.", Start()); - } - - checker->ThrowTypeError( - "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.", Start()); - } - - return_type_annotation_->Check(checker); - checker::Type *return_type = return_type_annotation_->GetType(checker); - - auto *signature = checker->Allocator()->New(signature_info, return_type); - - checker::Type *placeholder_obj = nullptr; + pg->GetAstCompiler()->Compile(this); +} - if (is_call_signature) { - placeholder_obj = checker->CreateObjectTypeWithCallSignature(signature); - } else { - placeholder_obj = checker->CreateObjectTypeWithConstructSignature(signature); - } +void TSSignatureDeclaration::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} - SetTsType(placeholder_obj); - return placeholder_obj; +checker::Type *TSSignatureDeclaration::Check(checker::TSChecker *checker) +{ + return checker->GetAnalyzer()->Check(this); } -checker::Type *TSSignatureDeclaration::Check([[maybe_unused]] checker::ETSChecker *checker) +checker::Type *TSSignatureDeclaration::Check(checker::ETSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ir/base/tsSignatureDeclaration.h b/ir/base/tsSignatureDeclaration.h index a83caebc7735372d34101495cf0be3d29bbcd771..d7d2f0c9fbb03dd87912f300e3aaa85b129833d5 100644 --- a/ir/base/tsSignatureDeclaration.h +++ b/ir/base/tsSignatureDeclaration.h @@ -18,6 +18,10 @@ #include "ir/statement.h" +namespace panda::es2panda::checker { +class TSAnalyzer; +} // namespace panda::es2panda::checker + namespace panda::es2panda::ir { class TSTypeParameterDeclaration; @@ -36,6 +40,8 @@ public: return_type_annotation_(return_type_annotation) { } + // TODO (csabahurton): friend relationship can be removed once there are getters for private fields + friend class checker::TSAnalyzer; bool IsScopeBearer() const override { @@ -70,9 +76,10 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; - checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; - checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; + checker::Type *Check(checker::ETSChecker *checker) override; private: binder::Scope *scope_; diff --git a/ir/ets/etsClassLiteral.cpp b/ir/ets/etsClassLiteral.cpp index 3a2abcd43a8b3b0e876b82545f5ec6305cc9429d..709ce48e45132c54aefb157471085e701ee0cee0 100644 --- a/ir/ets/etsClassLiteral.cpp +++ b/ir/ets/etsClassLiteral.cpp @@ -15,12 +15,10 @@ #include "etsClassLiteral.h" -#include "ir/astNode.h" -#include "ir/astDump.h" -#include "ir/typeNode.h" #include "checker/TSchecker.h" -#include "checker/ets/typeRelationContext.h" #include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" +#include "ir/astDump.h" namespace panda::es2panda::ir { void ETSClassLiteral::TransformChildren(const NodeTransformer &cb) @@ -38,42 +36,24 @@ void ETSClassLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSClassLiteral"}}); } -void ETSClassLiteral::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} - -void ETSClassLiteral::Compile([[maybe_unused]] compiler::ETSGen *etsg) const +void ETSClassLiteral::Compile(compiler::PandaGen *pg) const { - if (expr_->TsType()->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { - expr_->Compile(etsg); - etsg->GetType(this, false); - } else { - ASSERT(expr_->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)); - etsg->SetAccumulatorType(expr_->TsType()); - etsg->GetType(this, true); - } + pg->GetAstCompiler()->Compile(this); } -checker::Type *ETSClassLiteral::Check([[maybe_unused]] checker::TSChecker *checker) +void ETSClassLiteral::Compile(compiler::ETSGen *etsg) const { - return nullptr; + etsg->GetAstCompiler()->Compile(this); } -checker::Type *ETSClassLiteral::Check([[maybe_unused]] checker::ETSChecker *checker) +checker::Type *ETSClassLiteral::Check(checker::TSChecker *checker) { - checker->ThrowTypeError("Class literal is not yet supported.", expr_->Start()); - - expr_->Check(checker); - auto *expr_type = expr_->GetType(checker); - - if (expr_type->IsETSVoidType()) { - checker->ThrowTypeError("Invalid .class reference", expr_->Start()); - } - - ArenaVector type_arg_types(checker->Allocator()->Adapter()); - type_arg_types.push_back(expr_type); // TODO(user): Box it if it's a primitive type + return checker->GetAnalyzer()->Check(this); +} - checker::InstantiationContext ctx(checker, checker->GlobalBuiltinTypeType(), type_arg_types, range_.start); - SetTsType(ctx.Result()); - return TsType(); +checker::Type *ETSClassLiteral::Check(checker::ETSChecker *checker) +{ + return checker->GetAnalyzer()->Check(this); } // NOLINTNEXTLINE(google-default-arguments) diff --git a/ir/ets/etsClassLiteral.h b/ir/ets/etsClassLiteral.h index cc9d4f3651b55c2e01e65e30680a4b4d9cf2ab85..e607ec46656ed4829182d065cb598f67a08a671f 100644 --- a/ir/ets/etsClassLiteral.h +++ b/ir/ets/etsClassLiteral.h @@ -18,6 +18,14 @@ #include "ir/expression.h" +namespace panda::es2panda::checker { +class ETSAnalyzer; +} // namespace panda::es2panda::checker + +namespace panda::es2panda::compiler { +class ETSCompiler; +} // namespace panda::es2panda::compiler + namespace panda::es2panda::ir { class ETSClassLiteral : public Expression { @@ -33,13 +41,17 @@ public: // NOLINTNEXTLINE(google-default-arguments) [[nodiscard]] Expression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + // TODO (csabahurton): these friend relationships can be removed once there are getters for private fields + friend class checker::ETSAnalyzer; + friend class compiler::ETSCompiler; + void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; - void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; - checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; - checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; + checker::Type *Check(checker::ETSChecker *checker) override; private: ir::TypeNode *expr_; diff --git a/ir/ets/etsFunctionType.cpp b/ir/ets/etsFunctionType.cpp index 311491a2117c4116b08f3a87494820ca2b6abb3a..03b550ea5a9c1cb787bd45e0b4896f731c57d532 100644 --- a/ir/ets/etsFunctionType.cpp +++ b/ir/ets/etsFunctionType.cpp @@ -15,20 +15,11 @@ #include "etsFunctionType.h" -#include "binder/scope.h" #include "checker/TSchecker.h" #include "checker/ETSchecker.h" -#include "checker/types/signature.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" -#include "ir/base/spreadElement.h" -#include "ir/base/methodDefinition.h" -#include "ir/base/scriptFunction.h" -#include "ir/expressions/identifier.h" -#include "ir/ts/tsTypeParameter.h" -#include "ir/ts/tsInterfaceDeclaration.h" -#include "ir/ts/tsInterfaceBody.h" -#include "ir/ts/tsTypeParameterDeclaration.h" -#include "ir/ets/etsParameterExpression.h" namespace panda::es2panda::ir { void ETSFunctionType::TransformChildren(const NodeTransformer &cb) @@ -73,11 +64,19 @@ void ETSFunctionType::Dump(ir::AstDumper *dumper) const } } -void ETSFunctionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void ETSFunctionType::Compile(compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} -checker::Type *ETSFunctionType::Check([[maybe_unused]] checker::TSChecker *checker) +void ETSFunctionType::Compile(compiler::ETSGen *etsg) const { - return nullptr; + etsg->GetAstCompiler()->Compile(this); +} + +checker::Type *ETSFunctionType::Check(checker::TSChecker *checker) +{ + return checker->GetAnalyzer()->Check(this); } checker::Type *ETSFunctionType::GetType([[maybe_unused]] checker::TSChecker *checker) @@ -87,60 +86,7 @@ checker::Type *ETSFunctionType::GetType([[maybe_unused]] checker::TSChecker *che checker::Type *ETSFunctionType::Check(checker::ETSChecker *checker) { - checker->CreateFunctionalInterfaceForFunctionType(this); - auto *interface_type = checker->CreateETSObjectType(functional_interface_->Id()->Name(), functional_interface_, - checker::ETSObjectFlags::FUNCTIONAL_INTERFACE); - interface_type->SetSuperType(checker->GlobalETSObjectType()); - - auto *invoke_func = functional_interface_->Body()->Body()[0]->AsMethodDefinition()->Function(); - auto *signature_info = checker->Allocator()->New(checker->Allocator()); - - for (auto *it : invoke_func->Params()) { - auto *const param = it->AsETSParameterExpression(); - if (param->IsRestParameter()) { - auto *rest_ident = param->Ident(); - - ASSERT(rest_ident->Variable()); - signature_info->rest_var = rest_ident->Variable()->AsLocalVariable(); - - ASSERT(param->TypeAnnotation()); - signature_info->rest_var->SetTsType(checker->GetTypeFromTypeAnnotation(param->TypeAnnotation())); - - auto array_type = signature_info->rest_var->TsType()->AsETSArrayType(); - checker->CreateBuiltinArraySignature(array_type, array_type->Rank()); - } else { - auto *param_ident = param->Ident(); - - ASSERT(param_ident->Variable()); - binder::Variable *param_var = param_ident->Variable(); - - ASSERT(param->TypeAnnotation()); - param_var->SetTsType(checker->GetTypeFromTypeAnnotation(param->TypeAnnotation())); - signature_info->params.push_back(param_var->AsLocalVariable()); - ++signature_info->min_arg_count; - } - } - - invoke_func->ReturnTypeAnnotation()->Check(checker); - auto *signature = - checker->Allocator()->New(signature_info, return_type_->GetType(checker), invoke_func); - signature->SetOwnerVar(invoke_func->Id()->Variable()->AsLocalVariable()); - signature->AddSignatureFlag(checker::SignatureFlags::FUNCTIONAL_INTERFACE_SIGNATURE); - signature->SetOwner(interface_type); - - auto *func_type = checker->CreateETSFunctionType(signature); - invoke_func->SetSignature(signature); - invoke_func->Id()->Variable()->SetTsType(func_type); - interface_type->AddProperty( - invoke_func->Id()->Variable()->AsLocalVariable()); - functional_interface_->SetTsType(interface_type); - - auto *this_var = invoke_func->Scope()->ParamScope()->Params().front(); - this_var->SetTsType(interface_type); - checker->BuildFunctionalInterfaceName(this); - - ts_type_ = interface_type; - return interface_type; + return checker->GetAnalyzer()->Check(this); } checker::Type *ETSFunctionType::GetType(checker::ETSChecker *checker) diff --git a/ir/ets/etsFunctionType.h b/ir/ets/etsFunctionType.h index b0b0e646f5a043b879d432d5013d86adcb0b2e2e..d82a745a5911b4fd8e1807a6fc83f67a9aea920f 100644 --- a/ir/ets/etsFunctionType.h +++ b/ir/ets/etsFunctionType.h @@ -18,6 +18,10 @@ #include "ir/typeNode.h" +namespace panda::es2panda::checker { +class ETSAnalyzer; +} // namespace panda::es2panda::checker + namespace panda::es2panda::ir { class TSTypeParameterDeclaration; @@ -35,6 +39,9 @@ public: { } + // TODO (csabahurton): friend relationship can be removed once there are getters for private fields + friend class checker::ETSAnalyzer; + bool IsScopeBearer() const override { return true; @@ -88,10 +95,11 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; - checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; - checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + checker::Type *Check(checker::ETSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::ETSChecker *checker) override; private: diff --git a/ir/ets/etsLaunchExpression.cpp b/ir/ets/etsLaunchExpression.cpp index fbc3336dd6542cee9e8f678517edb8a84a11ce0c..6fc034f167e53f6ad07a1fbbdbce24e174f71679 100644 --- a/ir/ets/etsLaunchExpression.cpp +++ b/ir/ets/etsLaunchExpression.cpp @@ -20,9 +20,7 @@ #include "checker/ETSchecker.h" #include "checker/TSchecker.h" #include "ir/astDump.h" -#include "ir/expressions/identifier.h" #include "ir/expressions/callExpression.h" -#include "ir/expressions/memberExpression.h" namespace panda::es2panda::ir { ETSLaunchExpression::ETSLaunchExpression(CallExpression *expr) @@ -45,71 +43,26 @@ void ETSLaunchExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSLaunchExpression"}, {"expr", expr_}}); } -void ETSLaunchExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void ETSLaunchExpression::Compile(compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} -void ETSLaunchExpression::Compile([[maybe_unused]] compiler::ETSGen *etsg) const +void ETSLaunchExpression::Compile(compiler::ETSGen *etsg) const { #ifdef PANDA_WITH_ETS - compiler::RegScope rs(etsg); - compiler::VReg callee_reg = etsg->AllocReg(); - checker::Signature *signature = expr_->Signature(); - bool is_static = signature->HasSignatureFlag(checker::SignatureFlags::STATIC); - bool is_reference = signature->HasSignatureFlag(checker::SignatureFlags::TYPE); - - if (!is_reference && expr_->Callee()->IsIdentifier()) { - if (!is_static) { - etsg->LoadThis(expr_); - etsg->StoreAccumulator(this, callee_reg); - } - } else if (!is_reference && expr_->Callee()->IsMemberExpression()) { - if (!is_static) { - expr_->Callee()->AsMemberExpression()->Object()->Compile(etsg); - etsg->StoreAccumulator(this, callee_reg); - } - } else { - expr_->Callee()->Compile(etsg); - etsg->StoreAccumulator(this, callee_reg); - } - - if (is_static) { - etsg->LaunchStatic(this, signature, expr_->Arguments()); - } else if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE)) { - etsg->LaunchThisStatic(this, callee_reg, signature, expr_->Arguments()); - } else { - etsg->LaunchThisVirtual(this, callee_reg, signature, expr_->Arguments()); - } - - etsg->SetAccumulatorType(TsType()); + etsg->GetAstCompiler()->Compile(this); #endif // PANDA_WITH_ETS } -checker::Type *ETSLaunchExpression::Check([[maybe_unused]] checker::TSChecker *checker) +checker::Type *ETSLaunchExpression::Check(checker::TSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *ETSLaunchExpression::Check(checker::ETSChecker *checker) { - expr_->Check(checker); - auto *const launch_promise_type = - checker->GlobalBuiltinPromiseType() - ->Instantiate(checker->Allocator(), checker->Relation(), checker->GetGlobalTypesHolder()) - ->AsETSObjectType(); - launch_promise_type->AddTypeFlag(checker::TypeFlag::GENERIC); - - // Launch expression returns a Promise type, so we need to insert the expression's type - // as type parameter for the Promise class. - - auto *expr_type = - expr_->TsType()->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE) && !expr_->TsType()->IsETSVoidType() - ? checker->PrimitiveTypeAsETSBuiltinType(expr_->TsType()) - : expr_->TsType(); - checker::Substitution *substitution = checker->NewSubstitution(); - ASSERT(launch_promise_type->TypeArguments().size() == 1); - substitution->emplace(checker->GetOriginalBaseType(launch_promise_type->TypeArguments()[0]), expr_type); - - SetTsType(launch_promise_type->Substitute(checker->Relation(), substitution)); - return TsType(); + return checker->GetAnalyzer()->Check(this); } bool ETSLaunchExpression::IsStaticCall() const diff --git a/ir/ets/etsLaunchExpression.h b/ir/ets/etsLaunchExpression.h index 9857e8517fd0eaa21182a32bde42c5cd3be3e589..ded2aafac889175e942875f9b942380695ff383f 100644 --- a/ir/ets/etsLaunchExpression.h +++ b/ir/ets/etsLaunchExpression.h @@ -18,6 +18,14 @@ #include "ir/expression.h" +namespace panda::es2panda::checker { +class ETSAnalyzer; +} // namespace panda::es2panda::checker + +namespace panda::es2panda::compiler { +class ETSCompiler; +} // namespace panda::es2panda::compiler + namespace panda::es2panda::ir { class CallExpression; @@ -32,16 +40,19 @@ public: explicit ETSLaunchExpression(CallExpression *expr); + // TODO (csabahurton): these friend relationships can be removed once there are getters for private fields + friend class checker::ETSAnalyzer; + friend class compiler::ETSCompiler; + // NOLINTNEXTLINE(google-default-arguments) [[nodiscard]] Expression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; - void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; - void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; - checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; - checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; + checker::Type *Check(checker::ETSChecker *checker) override; bool IsStaticCall() const; [[nodiscard]] const CallExpression *Call() const noexcept diff --git a/ir/ets/etsNewArrayInstanceExpression.cpp b/ir/ets/etsNewArrayInstanceExpression.cpp index 9483123e2619215984c6f4cebd42a3056fdaf493..9ed5d4304d7333075ffb7f4b3876649efef175c1 100644 --- a/ir/ets/etsNewArrayInstanceExpression.cpp +++ b/ir/ets/etsNewArrayInstanceExpression.cpp @@ -15,10 +15,12 @@ #include "etsNewArrayInstanceExpression.h" +#include "checker/ETSchecker.h" +#include "checker/TSchecker.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "ir/typeNode.h" -#include "compiler/core/ETSGen.h" -#include "checker/ETSchecker.h" namespace panda::es2panda::ir { void ETSNewArrayInstanceExpression::TransformChildren(const NodeTransformer &cb) @@ -39,35 +41,23 @@ void ETSNewArrayInstanceExpression::Dump(ir::AstDumper *dumper) const {{"type", "ETSNewArrayInstanceExpression"}, {"typeReference", type_reference_}, {"dimension", dimension_}}); } -void ETSNewArrayInstanceExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} -void ETSNewArrayInstanceExpression::Compile([[maybe_unused]] compiler::ETSGen *etsg) const +void ETSNewArrayInstanceExpression::Compile(compiler::PandaGen *pg) const { - compiler::RegScope rs(etsg); - compiler::TargetTypeContext ttctx(etsg, etsg->Checker()->GlobalIntType()); - - dimension_->Compile(etsg); - - compiler::VReg arr = etsg->AllocReg(); - compiler::VReg dim = etsg->AllocReg(); - etsg->ApplyConversionAndStoreAccumulator(this, dim, dimension_->TsType()); - etsg->NewArray(this, arr, dim, TsType()); - etsg->SetVRegType(arr, TsType()); - etsg->LoadAccumulator(this, arr); + pg->GetAstCompiler()->Compile(this); } - -checker::Type *ETSNewArrayInstanceExpression::Check([[maybe_unused]] checker::TSChecker *checker) +void ETSNewArrayInstanceExpression::Compile(compiler::ETSGen *etsg) const { - return nullptr; + etsg->GetAstCompiler()->Compile(this); } -checker::Type *ETSNewArrayInstanceExpression::Check([[maybe_unused]] checker::ETSChecker *checker) +checker::Type *ETSNewArrayInstanceExpression::Check(checker::TSChecker *checker) { - auto *element_type = type_reference_->GetType(checker); - checker->ValidateArrayIndex(dimension_); + return checker->GetAnalyzer()->Check(this); +} - SetTsType(checker->CreateETSArrayType(element_type)); - checker->CreateBuiltinArraySignature(TsType()->AsETSArrayType(), 1); - return TsType(); +checker::Type *ETSNewArrayInstanceExpression::Check(checker::ETSChecker *checker) +{ + return checker->GetAnalyzer()->Check(this); } // NOLINTNEXTLINE(google-default-arguments) diff --git a/ir/ets/etsNewArrayInstanceExpression.h b/ir/ets/etsNewArrayInstanceExpression.h index 22a3f89ede5e176f5a3f23efc5062d73bbe4b76d..c15fb4c6e22276304d458b9772e309ae80d497f0 100644 --- a/ir/ets/etsNewArrayInstanceExpression.h +++ b/ir/ets/etsNewArrayInstanceExpression.h @@ -18,6 +18,14 @@ #include "ir/expression.h" +namespace panda::es2panda::checker { +class ETSAnalyzer; +} // namespace panda::es2panda::checker + +namespace panda::es2panda::compiler { +class ETSCompiler; +} // namespace panda::es2panda::compiler + namespace panda::es2panda::ir { class ETSNewArrayInstanceExpression : public Expression { @@ -34,6 +42,9 @@ public: dimension_(dimension) { } + // TODO (csabahurton): these friend relationships can be removed once there are getters for private fields + friend class checker::ETSAnalyzer; + friend class compiler::ETSCompiler; // NOLINTNEXTLINE(google-default-arguments) [[nodiscard]] Expression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; @@ -41,10 +52,10 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; - void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; - checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; - checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; + checker::Type *Check(checker::ETSChecker *checker) override; private: ir::TypeNode *type_reference_; diff --git a/ir/ets/etsNewClassInstanceExpression.cpp b/ir/ets/etsNewClassInstanceExpression.cpp index 60d66c48dbf9ad9dfbd90b17f508b2a475fa19ef..a2a73bcbf4d72c1ad96f9b9355104cf2fb6706ec 100644 --- a/ir/ets/etsNewClassInstanceExpression.cpp +++ b/ir/ets/etsNewClassInstanceExpression.cpp @@ -16,17 +16,9 @@ #include "etsNewClassInstanceExpression.h" #include "compiler/core/ETSGen.h" -#include "ir/base/classDefinition.h" -#include "ir/base/scriptFunction.h" -#include "ir/astDump.h" -#include "ir/ets/etsTypeReference.h" -#include "ir/ets/etsTypeReferencePart.h" -#include "ir/expressions/identifier.h" -#include "ir/statements/variableDeclarator.h" -#include "ir/ts/tsQualifiedName.h" +#include "compiler/core/pandagen.h" #include "checker/TSchecker.h" -#include "checker/ETSchecker.h" -#include "checker/types/ets/types.h" +#include "ir/astDump.h" namespace panda::es2panda::ir { void ETSNewClassInstanceExpression::TransformChildren(const NodeTransformer &cb) @@ -63,125 +55,23 @@ void ETSNewClassInstanceExpression::Dump(ir::AstDumper *dumper) const {"classBody", AstDumper::Optional(class_def_)}}); } -void ETSNewClassInstanceExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} - -void ETSNewClassInstanceExpression::CreateDynamicObject(const ir::AstNode *node, compiler::ETSGen *etsg, - compiler::VReg &obj_reg, ir::Expression *name, - checker::Signature *signature, - const ArenaVector &arguments) +void ETSNewClassInstanceExpression::Compile(compiler::PandaGen *pg) const { - auto qname_reg = etsg->AllocReg(); - - std::vector parts; - - while (name->IsTSQualifiedName()) { - auto *qname = name->AsTSQualifiedName(); - name = qname->Left(); - parts.push_back(qname->Right()->AsIdentifier()->Name()); - } - - auto *var = name->AsIdentifier()->Variable(); - auto *data = etsg->Binder()->DynamicImportDataForVar(var); - if (data != nullptr) { - auto *import = data->import; - auto *specifier = data->specifier; - ASSERT(import->Language().IsDynamic()); - etsg->LoadAccumulatorDynamicModule(node, import); - if (specifier->IsImportSpecifier()) { - parts.push_back(specifier->AsImportSpecifier()->Imported()->Name()); - } - } else { - name->Compile(etsg); - } - - etsg->StoreAccumulator(node, obj_reg); - - std::stringstream ss; - std::for_each(parts.rbegin(), parts.rend(), [&ss](util::StringView sv) { ss << "." << sv; }); - - etsg->LoadAccumulatorString(node, util::UString(ss.str(), etsg->Allocator()).View()); - etsg->StoreAccumulator(node, qname_reg); - - etsg->CallDynamic(node, obj_reg, qname_reg, signature, arguments); + pg->GetAstCompiler()->Compile(this); } -void ETSNewClassInstanceExpression::Compile([[maybe_unused]] compiler::ETSGen *etsg) const +void ETSNewClassInstanceExpression::Compile(compiler::ETSGen *etsg) const { - if (TsType()->IsETSDynamicType()) { - auto obj_reg = etsg->AllocReg(); - auto *name = type_reference_->AsETSTypeReference()->Part()->Name(); - CreateDynamicObject(this, etsg, obj_reg, name, signature_, arguments_); - } else { - etsg->InitObject(this, signature_, arguments_); - } - - if (GetBoxingUnboxingFlags() == ir::BoxingUnboxingFlags::NONE) { - etsg->SetAccumulatorType(TsType()); - } + etsg->GetAstCompiler()->Compile(this); } -checker::Type *ETSNewClassInstanceExpression::Check([[maybe_unused]] checker::TSChecker *checker) +checker::Type *ETSNewClassInstanceExpression::Check(checker::TSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } -checker::Type *ETSNewClassInstanceExpression::Check([[maybe_unused]] checker::ETSChecker *checker) +checker::Type *ETSNewClassInstanceExpression::Check(checker::ETSChecker *checker) { - checker::Type *callee_type = type_reference_->Check(checker); - - if (!callee_type->IsETSObjectType()) { - checker->ThrowTypeError("This expression is not constructible.", Start()); - } - - auto *callee_obj = callee_type->AsETSObjectType(); - SetTsType(callee_obj); - - if (class_def_ != nullptr) { - if (!callee_obj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT) && callee_obj->GetDeclNode()->IsFinal()) { - checker->ThrowTypeError({"Class ", callee_obj->Name(), " cannot be both 'abstract' and 'final'."}, - callee_obj->GetDeclNode()->Start()); - } - - bool from_interface = callee_obj->HasObjectFlag(checker::ETSObjectFlags::INTERFACE); - auto *class_type = checker->BuildAnonymousClassProperties( - class_def_, from_interface ? checker->GlobalETSObjectType() : callee_obj); - if (from_interface) { - class_type->AddInterface(callee_obj); - callee_obj = checker->GlobalETSObjectType(); - } - class_def_->SetTsType(class_type); - checker->CheckClassDefinition(class_def_); - checker->CheckInnerClassMembers(class_type); - SetTsType(class_type); - } else if (callee_obj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT)) { - checker->ThrowTypeError({callee_obj->Name(), " is abstract therefore cannot be instantiated."}, Start()); - } - - if (callee_type->IsETSDynamicType() && !callee_type->AsETSDynamicType()->HasDecl()) { - auto lang = callee_type->AsETSDynamicType()->Language(); - signature_ = checker->ResolveDynamicCallExpression(type_reference_, arguments_, lang, true); - } else { - auto *signature = checker->ResolveConstructExpression(callee_obj, arguments_, Start()); - - checker->CheckObjectLiteralArguments(signature, arguments_); - checker->ValidateSignatureAccessibility(callee_obj, signature, Start()); - - ASSERT(signature->Function() != nullptr); - - if (signature->Function()->IsThrowing() || signature->Function()->IsRethrowing()) { - checker->CheckThrowingStatements(this); - } - - if (callee_type->IsETSDynamicType()) { - ASSERT(signature->Function()->IsDynamic()); - auto lang = callee_type->AsETSDynamicType()->Language(); - signature_ = checker->ResolveDynamicCallExpression(type_reference_, signature->Params(), lang, true); - } else { - ASSERT(!signature->Function()->IsDynamic()); - signature_ = signature; - } - } - - return TsType(); + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ir/ets/etsNewClassInstanceExpression.h b/ir/ets/etsNewClassInstanceExpression.h index 739368683f27562d53318608f96a04063acdf292..6d5da31bc0b60cac0ca9907dda0fc07b2a05066d 100644 --- a/ir/ets/etsNewClassInstanceExpression.h +++ b/ir/ets/etsNewClassInstanceExpression.h @@ -20,9 +20,14 @@ #include "ir/expression.h" namespace panda::es2panda::checker { +class ETSAnalyzer; class Signature; } // namespace panda::es2panda::checker +namespace panda::es2panda::compiler { +class ETSCompiler; +} // namespace panda::es2panda::compiler + namespace panda::es2panda::ir { class ClassDefinition; @@ -37,6 +42,9 @@ public: class_def_(class_definition) { } + // TODO (csabahurton): these friend relationships can be removed once there are getters for private fields + friend class checker::ETSAnalyzer; + friend class compiler::ETSCompiler; ir::ClassDefinition *ClassDefinition() { @@ -63,17 +71,13 @@ public: signature_ = signature; } - static void CreateDynamicObject(const ir::AstNode *node, compiler::ETSGen *etsg, compiler::VReg &obj_reg, - ir::Expression *name, checker::Signature *signature, - const ArenaVector &arguments); - void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; - void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; - checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; - checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; + checker::Type *Check(checker::ETSChecker *checker) override; private: ir::Expression *type_reference_; diff --git a/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp b/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp index d04ddd358e0c67ea12e15fc0614f1007c171bb22..8006b9b7f7d22f80ed843d82baa2e6ae47096889 100644 --- a/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp +++ b/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp @@ -15,12 +15,11 @@ #include "etsNewMultiDimArrayInstanceExpression.h" -#include "binder/ETSBinder.h" -#include "ir/astDump.h" -#include "ir/typeNode.h" -#include "compiler/core/ETSGen.h" #include "checker/ETSchecker.h" -#include "checker/types/signature.h" +#include "checker/TSchecker.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" +#include "ir/astDump.h" namespace panda::es2panda::ir { void ETSNewMultiDimArrayInstanceExpression::TransformChildren(const NodeTransformer &cb) @@ -46,29 +45,22 @@ void ETSNewMultiDimArrayInstanceExpression::Dump(ir::AstDumper *dumper) const {"dimensions", dimensions_}}); } -void ETSNewMultiDimArrayInstanceExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} -void ETSNewMultiDimArrayInstanceExpression::Compile([[maybe_unused]] compiler::ETSGen *etsg) const +void ETSNewMultiDimArrayInstanceExpression::Compile(compiler::PandaGen *pg) const { - etsg->InitObject(this, signature_, dimensions_); - etsg->SetAccumulatorType(TsType()); + pg->GetAstCompiler()->Compile(this); } - -checker::Type *ETSNewMultiDimArrayInstanceExpression::Check([[maybe_unused]] checker::TSChecker *checker) +void ETSNewMultiDimArrayInstanceExpression::Compile(compiler::ETSGen *etsg) const { - return nullptr; + etsg->GetAstCompiler()->Compile(this); } -checker::Type *ETSNewMultiDimArrayInstanceExpression::Check([[maybe_unused]] checker::ETSChecker *checker) +checker::Type *ETSNewMultiDimArrayInstanceExpression::Check(checker::TSChecker *checker) { - auto *element_type = type_reference_->GetType(checker); - - for (auto *dim : dimensions_) { - checker->ValidateArrayIndex(dim); - element_type = checker->CreateETSArrayType(element_type); - } + return checker->GetAnalyzer()->Check(this); +} - SetTsType(element_type); - signature_ = checker->CreateBuiltinArraySignature(element_type->AsETSArrayType(), dimensions_.size()); - return TsType(); +checker::Type *ETSNewMultiDimArrayInstanceExpression::Check(checker::ETSChecker *checker) +{ + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ir/ets/etsNewMultiDimArrayInstanceExpression.h b/ir/ets/etsNewMultiDimArrayInstanceExpression.h index 1cf38efa643435cccf347872aed8957b3912a35d..e7ecee053e27ad92d46e6c9b679a888d3f44dfe3 100644 --- a/ir/ets/etsNewMultiDimArrayInstanceExpression.h +++ b/ir/ets/etsNewMultiDimArrayInstanceExpression.h @@ -19,9 +19,14 @@ #include "ir/expression.h" namespace panda::es2panda::checker { +class ETSAnalyzer; class Signature; } // namespace panda::es2panda::checker +namespace panda::es2panda::compiler { +class ETSCompiler; +} // namespace panda::es2panda::compiler + namespace panda::es2panda::ir { class ETSNewMultiDimArrayInstanceExpression : public Expression { @@ -33,6 +38,9 @@ public: dimensions_(std::move(dimensions)) { } + // TODO (csabahurton): these friend relationships can be removed once there are getters for private fields + friend class checker::ETSAnalyzer; + friend class compiler::ETSCompiler; checker::Signature *Signature() { @@ -47,10 +55,10 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; - void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; - checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; - checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; + checker::Type *Check(checker::ETSChecker *checker) override; private: ir::TypeNode *type_reference_; diff --git a/ir/ets/etsPackageDeclaration.cpp b/ir/ets/etsPackageDeclaration.cpp index cda0cbfbfc31ace7e79f0e47000f08f7d12deeb2..bd32531af7fd356c66db537b6c47e7d6b6d102e8 100644 --- a/ir/ets/etsPackageDeclaration.cpp +++ b/ir/ets/etsPackageDeclaration.cpp @@ -15,9 +15,10 @@ #include "etsPackageDeclaration.h" -#include "ir/astDump.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" +#include "ir/astDump.h" namespace panda::es2panda::ir { void ETSPackageDeclaration::TransformChildren(const NodeTransformer &cb) @@ -35,19 +36,22 @@ void ETSPackageDeclaration::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSPackageDeclaration"}, {"name", name_}}); } -void ETSPackageDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} -void ETSPackageDeclaration::Compile([[maybe_unused]] compiler::ETSGen *etsg) const +void ETSPackageDeclaration::Compile(compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} +void ETSPackageDeclaration::Compile(compiler::ETSGen *etsg) const { - UNREACHABLE(); + etsg->GetAstCompiler()->Compile(this); } -checker::Type *ETSPackageDeclaration::Check([[maybe_unused]] checker::TSChecker *checker) +checker::Type *ETSPackageDeclaration::Check(checker::TSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } -checker::Type *ETSPackageDeclaration::Check([[maybe_unused]] checker::ETSChecker *checker) +checker::Type *ETSPackageDeclaration::Check(checker::ETSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ir/ets/etsPackageDeclaration.h b/ir/ets/etsPackageDeclaration.h index 0a1b6a3eba28738cc44c174194252f9fd531f1c3..aff7ce5fa8243dc90667e93e05e581b33c602e29 100644 --- a/ir/ets/etsPackageDeclaration.h +++ b/ir/ets/etsPackageDeclaration.h @@ -29,10 +29,10 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; - void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; - checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; - checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; + checker::Type *Check(checker::ETSChecker *checker) override; private: ir::Expression *name_; diff --git a/ir/statements/tryStatement.h b/ir/statements/tryStatement.h index 74b955c87aca3f798585faf0c83457db28d74159..af69c1eb9d91f8f33a9ee79f4244c548b90e706b 100644 --- a/ir/statements/tryStatement.h +++ b/ir/statements/tryStatement.h @@ -16,7 +16,7 @@ #ifndef ES2PANDA_IR_STATEMENT_TRY_STATEMENT_H #define ES2PANDA_IR_STATEMENT_TRY_STATEMENT_H -#include "compiler/core/ETSGen.h" +#include "compiler/core/labelPair.h" #include "ir/statement.h" namespace panda::es2panda::compiler {