diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 93f8689a7f952f0eb907b7ba6d60b89f205d14dc..02cb5bc5a84e555715e9b69012e79c35f02669c2 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -141,7 +141,6 @@ libes2panda_sources = [ "checker/types/ets/shortType.cpp", "checker/types/ets/wildcardType.cpp", "checker/types/globalTypesHolder.cpp", - "checker/types/gradualType.cpp", "checker/types/signature.cpp", "checker/types/ts/anyType.cpp", "checker/types/ts/arrayType.cpp", @@ -241,7 +240,6 @@ libes2panda_sources = [ "compiler/lowering/ets/expressionLambdaLowering.cpp", "compiler/lowering/ets/extensionAccessorLowering.cpp", "compiler/lowering/ets/genericBridgesLowering.cpp", - "compiler/lowering/ets/gradualTypeNarrowing.cpp", "compiler/lowering/ets/insertOptionalParametersAnnotation.cpp", "compiler/lowering/ets/interfaceObjectLiteralLowering.cpp", "compiler/lowering/ets/interfacePropertyDeclarations.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 729d0c351967de948d2138e891232149cc3869f4..3aa66c929984c94b155c9e0babcedb280d87a5b8 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -289,7 +289,6 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/expressionLambdaLowering.cpp compiler/lowering/ets/extensionAccessorLowering.cpp compiler/lowering/ets/genericBridgesLowering.cpp - compiler/lowering/ets/gradualTypeNarrowing.cpp compiler/lowering/ets/arrayLiteralLowering.cpp compiler/lowering/ets/boxingForLocals.cpp compiler/lowering/ets/capturedVariables.cpp @@ -597,7 +596,6 @@ set(ES2PANDA_LIB_SRC checker/types/type.cpp checker/types/typeRelation.cpp checker/types/globalTypesHolder.cpp - checker/types/gradualType.cpp checker/types/ets/byteType.cpp checker/types/ets/charType.cpp checker/types/ets/doubleType.cpp diff --git a/ets2panda/ast_verifier/helpers.cpp b/ets2panda/ast_verifier/helpers.cpp index a2179fc411ba0b24db631a82db400ba318fc1b32..cdd88eb8b9c3b620557c3d7ed8c1e086765e54b2 100644 --- a/ets2panda/ast_verifier/helpers.cpp +++ b/ets2panda/ast_verifier/helpers.cpp @@ -19,7 +19,6 @@ #include "checker/types/type.h" #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsUnionType.h" -#include "checker/types/gradualType.h" #include "ir/statements/blockStatement.h" #include "ir/ets/etsModule.h" #include "parser/program/program.h" @@ -55,8 +54,7 @@ bool IsBooleanType(const ir::AstNode *ast) return false; } - auto type = - typedAst->TsType()->IsGradualType() ? typedAst->TsType()->AsGradualType()->GetBaseType() : typedAst->TsType(); + auto type = typedAst->TsType(); if (type->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { return type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); } @@ -79,8 +77,7 @@ bool IsValidTypeForBinaryOp(const ir::AstNode *ast, bool isBitwise) return false; } - auto type = - typedAst->TsType()->IsGradualType() ? typedAst->TsType()->AsGradualType()->GetBaseType() : typedAst->TsType(); + auto type = typedAst->TsType(); if (IsBooleanType(ast)) { return isBitwise; } @@ -115,8 +112,7 @@ bool IsStringType(const ir::AstNode *ast) return false; } - auto type = - typedAst->TsType()->IsGradualType() ? typedAst->TsType()->AsGradualType()->GetBaseType() : typedAst->TsType(); + auto type = typedAst->TsType(); if (type->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { return type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::STRING) || type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_STRING); @@ -155,9 +151,7 @@ const checker::Type *GetClassDefinitionType(const ir::AstNode *ast) if (!tmpNode->IsClassDefinition()) { return nullptr; } - auto *classDefinition = tmpNode->AsClassDefinition(); - return classDefinition->TsType()->IsGradualType() ? classDefinition->TsType()->AsGradualType()->GetBaseType() - : classDefinition->TsType(); + return tmpNode->AsClassDefinition()->TsType(); } const checker::Type *GetTSInterfaceDeclarationType(const ir::AstNode *ast) @@ -169,10 +163,7 @@ const checker::Type *GetTSInterfaceDeclarationType(const ir::AstNode *ast) if (!tmpNode->IsTSInterfaceDeclaration()) { return nullptr; } - auto *tsInterfaceDeclaration = tmpNode->AsTSInterfaceDeclaration(); - return tsInterfaceDeclaration->TsType()->IsGradualType() - ? tsInterfaceDeclaration->TsType()->AsGradualType()->GetBaseType() - : tsInterfaceDeclaration->TsType(); + return tmpNode->AsTSInterfaceDeclaration()->TsType(); } bool ValidateMethodAccessForClass(const ir::AstNode *ast, const ir::AstNode *ownerSignDeclNode, diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index decda894cee4bd5440cc2319ab08bba001cf7d8e..88a8044f43cde2fca76973350b0f463bef975445 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -20,7 +20,6 @@ #include "generated/diagnostic.h" #include "checker/types/globalTypesHolder.h" #include "checker/types/ets/etsTupleType.h" -#include "checker/types/gradualType.h" #include "evaluate/scopedDebugInfoPlugin.h" #include "types/signature.h" #include "compiler/lowering/ets/setJumpTarget.h" @@ -416,9 +415,8 @@ checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const if (expr->PreferredType() != nullptr) { expr->Argument()->SetPreferredType(expr->PreferredType()); } - auto type = expr->Argument()->Check(checker); - Type *exprType = type->MaybeBaseTypeOfGradualType(); + auto const exprType = expr->Argument()->Check(checker); if (exprType->IsETSResizableArrayType()) { return expr->SetTsType(exprType->AsETSObjectType()->TypeArguments().front()); } @@ -431,7 +429,7 @@ checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const return checker->InvalidateType(expr); } - checker::Type *const elementType = exprType->IsETSTupleType() ? type : checker->GetElementTypeOfArray(exprType); + checker::Type *const elementType = exprType->IsETSTupleType() ? exprType : checker->GetElementTypeOfArray(exprType); return expr->SetTsType(elementType); } @@ -509,7 +507,7 @@ static bool CheckArrayElementType(ETSChecker *checker, T *newArrayInstanceExpr) ES2PANDA_ASSERT(checker != nullptr); ES2PANDA_ASSERT(newArrayInstanceExpr != nullptr); - checker::Type *elementType = newArrayInstanceExpr->TypeReference()->GetType(checker)->MaybeBaseTypeOfGradualType(); + checker::Type *elementType = newArrayInstanceExpr->TypeReference()->GetType(checker); ES2PANDA_ASSERT(elementType != nullptr); if (elementType->IsETSPrimitiveType()) { return true; @@ -579,8 +577,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const static checker::Type *CheckInstantiatedNewType(ETSChecker *checker, ir::ETSNewClassInstanceExpression *expr) { - checker::Type *res = expr->GetTypeRef()->Check(checker); - auto calleeType = res->MaybeBaseTypeOfGradualType(); + auto calleeType = expr->GetTypeRef()->Check(checker); FORWARD_TYPE_ERROR(checker, calleeType, expr->GetTypeRef()); if (calleeType->IsETSUnionType()) { @@ -610,7 +607,7 @@ static checker::Type *CheckInstantiatedNewType(ETSChecker *checker, ir::ETSNewCl return checker->GlobalTypeError(); } - return res; + return calleeType; } checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const @@ -623,7 +620,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const auto *calleeType = CheckInstantiatedNewType(checker, expr); FORWARD_TYPE_ERROR(checker, calleeType, expr); - auto *calleeObj = calleeType->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + auto calleeObj = calleeType->AsETSObjectType(); expr->SetTsType(calleeType); auto *signature = checker->ResolveConstructExpression(calleeObj, expr->GetArguments(), expr->Start()); @@ -778,7 +775,7 @@ static void AddSpreadElementTypes(ETSChecker *checker, ir::SpreadElement *const return; } - Type *const spreadArgumentType = element->Argument()->TsType()->MaybeBaseTypeOfGradualType(); + Type *const spreadArgumentType = element->Argument()->TsType(); if (spreadArgumentType->IsETSTupleType()) { for (Type *type : spreadArgumentType->AsETSTupleType()->GetTupleTypesList()) { @@ -1387,8 +1384,7 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const checker::Type *smartType = rightType; auto isLazyImportObject = - leftType->MaybeBaseTypeOfGradualType()->IsETSObjectType() && - leftType->MaybeBaseTypeOfGradualType()->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::LAZY_IMPORT_OBJECT); + leftType->IsETSObjectType() && leftType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::LAZY_IMPORT_OBJECT); if (!leftType->IsTypeError() && !isLazyImportObject) { if (const auto ctx = checker::AssignmentContext(checker->Relation(), relationNode, rightType, leftType, expr->Right()->Start(), @@ -1415,11 +1411,6 @@ static checker::Type *HandleSubstitution(ETSChecker *checker, ir::AssignmentExpr preferredType->AsETSFunctionType()); } } else if (expr->Right()->IsObjectExpression()) { - if (leftType->IsETSObjectType() && leftType->IsGradualType() && - (leftType->HasTypeFlag(TypeFlag::READONLY) || - leftType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::REQUIRED))) { - checker->LogError(diagnostic::DYMANIC_INIT_WITH_OBJEXPR, {leftType}, expr->Right()->Start()); - } expr->Right()->AsObjectExpression()->SetPreferredType(leftType); } else { expr->Right()->SetPreferredType(leftType); @@ -1624,7 +1615,7 @@ static checker::Signature *ResolveSignature(ETSChecker *checker, ir::CallExpress static ETSObjectType *GetCallExpressionCalleeObject(ETSChecker *checker, ir::CallExpression *expr, Type *calleeType) { if (expr->IsETSConstructorCall()) { - return calleeType->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + return calleeType->AsETSObjectType(); } auto callee = expr->Callee(); if (callee->IsMemberExpression()) { @@ -1693,7 +1684,7 @@ static void CheckCallee(ETSChecker *checker, ir::CallExpression *expr) if (memberExpr->Object() == nullptr) { return; } - auto baseType = memberExpr->Object()->TsType()->MaybeBaseTypeOfGradualType(); + auto baseType = memberExpr->Object()->TsType(); if (baseType->IsETSObjectType() && baseType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::READONLY)) { checker->LogError(diagnostic::READONLY_CALL, {}, expr->Start()); expr->SetTsType(checker->GlobalTypeError()); @@ -2055,10 +2046,6 @@ checker::Type *ETSAnalyzer::ResolveMemberExpressionByBaseType(ETSChecker *checke return expr->AdjustType(checker, checker->GlobalETSRelaxedAnyType()); } - if (baseType->IsGradualType()) { - return ResolveMemberExpressionByBaseType(checker, baseType->AsGradualType()->GetBaseType(), expr); - } - if (baseType->IsETSArrayType()) { if (expr->Property()->AsIdentifier()->Name().Is("length")) { return expr->AdjustType(checker, checker->GlobalIntBuiltinType()); @@ -2162,7 +2149,7 @@ checker::Type *ETSAnalyzer::CheckDynamic(ir::ObjectExpression *expr) const static bool ValidatePreferredType(ETSChecker *checker, ir::ObjectExpression *expr) { - auto preferredType = expr->PreferredType()->MaybeBaseTypeOfGradualType(); + auto preferredType = expr->PreferredType(); if (preferredType == nullptr) { checker->LogError(diagnostic::CLASS_COMPOSITE_UNKNOWN_TYPE, {}, expr->Start()); return false; @@ -2487,9 +2474,8 @@ checker::ETSObjectType *ResolveUnionObjectTypeForObjectLiteral(ETSChecker *check std::vector candidateObjectTypes; // Phase 1: Gather all ETSObjectTypes from the union for (auto *constituentType : unionType->ConstituentTypes()) { - auto type = constituentType->MaybeBaseTypeOfGradualType(); - if (type->IsETSObjectType()) { - candidateObjectTypes.push_back(type->AsETSObjectType()); + if (constituentType->IsETSObjectType()) { + candidateObjectTypes.push_back(constituentType->AsETSObjectType()); } } @@ -2518,7 +2504,7 @@ checker::ETSObjectType *ResolveUnionObjectTypeForObjectLiteral(ETSChecker *check static checker::ETSObjectType *ResolveObjectTypeFromPreferredType(ETSChecker *checker, ir::ObjectExpression *expr) { // Assume not null, checked by caller in Check() - checker::Type *preferredType = expr->PreferredType()->MaybeBaseTypeOfGradualType(); + checker::Type *preferredType = expr->PreferredType(); if (preferredType->IsETSAsyncFuncReturnType()) { preferredType = preferredType->AsETSAsyncFuncReturnType()->GetPromiseTypeArg(); @@ -3450,7 +3436,7 @@ checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const // NOTE: Smart casts are not processed correctly within the loops now, thus clear them at this point. auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st, std::nullopt); - checker::Type *const exprType = st->Right()->Check(checker)->MaybeBaseTypeOfGradualType(); + checker::Type *const exprType = st->Right()->Check(checker); checker::Type *elemType = checker->GlobalTypeError(); if (exprType->IsETSStringType()) { @@ -3612,16 +3598,15 @@ bool ETSAnalyzer::CheckInferredFunctionReturnType(ir::ReturnStatement *st, ir::S // Case when function's return type is defined explicitly: if (st->argument_ == nullptr) { ES2PANDA_ASSERT(funcReturnType != nullptr); - if (!funcReturnType->MaybeBaseTypeOfGradualType()->IsETSVoidType() && - funcReturnType != checker->GlobalVoidType() && - !funcReturnType->MaybeBaseTypeOfGradualType()->IsETSAsyncFuncReturnType()) { + if (!funcReturnType->IsETSVoidType() && funcReturnType != checker->GlobalVoidType() && + !funcReturnType->IsETSAsyncFuncReturnType()) { checker->LogError(diagnostic::RETURN_WITHOUT_VALUE, {}, st->Start()); return false; } funcReturnType = checker->GlobalVoidType(); } else { const auto name = containingFunc->Scope()->InternalName().Mutf8(); - if (!CheckArgumentVoidType(funcReturnType->MaybeBaseTypeOfGradualType(), checker, name, st)) { + if (!CheckArgumentVoidType(funcReturnType, checker, name, st)) { return false; } @@ -3633,8 +3618,7 @@ bool ETSAnalyzer::CheckInferredFunctionReturnType(ir::ReturnStatement *st, ir::S } checker::Type *argumentType = st->argument_->Check(checker); - return CheckReturnType(checker, funcReturnType->MaybeBaseTypeOfGradualType(), argumentType, st->argument_, - containingFunc); + return CheckReturnType(checker, funcReturnType, argumentType, st->argument_, containingFunc); } return true; } @@ -4017,11 +4001,12 @@ checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const FORWARD_TYPE_ERROR(checker, stmtType, st); - auto *interfaceType = stmtType->IsGradualType() ? stmtType->AsGradualType()->GetBaseType()->AsETSObjectType() - : stmtType->AsETSObjectType(); + auto *interfaceType = stmtType->AsETSObjectType(); checker->CheckInterfaceAnnotations(st); - interfaceType->SetSuperType(checker->GlobalETSObjectType()); + if (!interfaceType->IsGradual()) { + interfaceType->SetSuperType(checker->GlobalETSObjectType()); + } checker->CheckInvokeMethodsLegitimacy(interfaceType); st->SetTsType(stmtType); @@ -4118,7 +4103,7 @@ static varbinder::Variable *FindNameForImportNamespace(ETSChecker *checker, util checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const { ETSChecker *checker = GetETSChecker(); - checker::Type *baseType = expr->Left()->Check(checker)->MaybeBaseTypeOfGradualType(); + checker::Type *baseType = expr->Left()->Check(checker); if (baseType->IsETSObjectType()) { // clang-format off auto searchName = expr->Right()->Name(); diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index d3127e33aa2eb640069872c868a0be4ba0186073..7df2adc15cb3d0a2748d41d6fe5004e0b19b16ec 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -315,7 +315,7 @@ void CheckIteratorMethodReturnType(ETSChecker *checker, ir::ScriptFunction *scri const lexer::SourcePosition &position, [[maybe_unused]] const std::string &methodName) { - const auto *returnType = scriptFunc->Signature()->ReturnType()->MaybeBaseTypeOfGradualType(); + const auto *returnType = scriptFunc->Signature()->ReturnType(); if (returnType->IsETSTypeParameter()) { returnType = checker->GetApparentType(returnType->AsETSTypeParameter()->GetConstraintType()); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 5aaf2180560f96f9ba72ed83b5af9b65b07164b6..81fed860b6cb35c565669e0d6cccd15630130206 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -201,7 +201,6 @@ public: void CheckObjectLiteralKeys(const ArenaVector &properties); Type *BuildBasicClassProperties(ir::ClassDefinition *classDef); ETSObjectType *BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType); - Type *MaybeGradualType(ir::AstNode *node, ETSObjectType *type); Type *BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl); ETSObjectType *GetSuperType(ETSObjectType *type); ArenaVector GetInterfaces(ETSObjectType *type); @@ -317,7 +316,6 @@ public: ETSResizableArrayType *CreateETSMultiDimResizableArrayType(Type *element, size_t dimSize); ETSResizableArrayType *CreateETSResizableArrayType(Type *element); ETSArrayType *CreateETSArrayType(Type *elementType, bool isCachePolluting = false); - Type *CreateGradualType(Type *baseType, Language lang = Language(Language::Id::JS)); Type *CreateETSUnionType(Span constituentTypes); template Type *CreateETSUnionType(Type *const (&arr)[N]) // NOLINT(modernize-avoid-c-arrays) @@ -340,7 +338,11 @@ public: ETSFunctionType *extensionFunctionType); void AddThisReturnTypeFlagForInterfaceInvoke(ETSObjectType *interface); ETSTypeParameter *CreateTypeParameter(); - ETSObjectType *CreateETSObjectType(ir::AstNode *declNode, ETSObjectFlags flags); + + ETSObjectType *CreateETSObjectType( + ir::AstNode *declNode, ETSObjectFlags flags, + /* this parameter maintanis the behavior of the broken ast-cache logic, avoid it whenever possible */ + std::optional> caches = std::nullopt); ETSObjectType *CreateETSObjectTypeOrBuiltin(ir::AstNode *declNode, ETSObjectFlags flags); std::tuple CreateBuiltinArraySignatureInfo(const ETSArrayType *arrayType, size_t dim); diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index a411f9d429bf07f01adc90396a3a08a1261112b7..2d39801012ab2d928b6e171f2a63d7393f3dfe36 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -57,7 +57,6 @@ #include "varbinder/scope.h" #include "varbinder/declaration.h" #include "checker/ETSchecker.h" -#include "checker/types/gradualType.h" #include "ir/base/catchClause.h" #include "parser/program/program.h" #include "checker/types/ts/objectType.h" @@ -1360,9 +1359,6 @@ static bool IsDefaultValueType(const Type *type, bool isNonReadonlyField) if (type == nullptr) { return false; } - if (type->IsGradualType()) { - return IsDefaultValueType(type->AsGradualType()->GetBaseType(), isNonReadonlyField); - } return (type->IsETSPrimitiveType() || (type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive()) || type->IsETSNeverType() || type->IsETSUndefinedType() || type->IsETSNullType() || (type->PossiblyETSUndefined() && (!type->HasTypeFlag(checker::TypeFlag::GENERIC) || diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 1fd04a4a9e88ed3d4b7489ecfbe585db545fbe43..30beed67882fe7045da8e0e03bc7c32b3476e594 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -27,7 +27,6 @@ #include "checker/types/ets/etsAwaitedType.h" #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsPartialTypeParameter.h" -#include "checker/types/gradualType.h" #include "checker/types/typeError.h" #include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "ir/base/catchClause.h" @@ -85,8 +84,8 @@ bool ETSChecker::IsCompatibleTypeArgument(ETSTypeParameter *typeParam, Type *typ bool ETSChecker::EnhanceSubstitutionForReadonly(const ArenaVector &typeParams, ETSReadonlyType *paramType, Type *argumentType, Substitution *substitution) { - return EnhanceSubstitutionForType(typeParams, paramType->GetUnderlying()->MaybeBaseTypeOfGradualType(), - GetReadonlyType(argumentType), substitution); + return EnhanceSubstitutionForType(typeParams, paramType->GetUnderlying(), GetReadonlyType(argumentType), + substitution); } /* A very rough and imprecise partial type inference */ @@ -118,10 +117,6 @@ bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &typeParam return EnhanceSubstitutionForPartialTypeParam(typeParams, paramType->AsETSPartialTypeParameter(), argumentType, substitution); } - if (paramType->IsGradualType()) { - return EnhanceSubstitutionForType(typeParams, paramType->AsGradualType()->GetBaseType(), argumentType, - substitution); - } if (paramType->IsETSUnionType()) { return EnhanceSubstitutionForUnion(typeParams, paramType->AsETSUnionType(), argumentType, substitution); } @@ -159,8 +154,7 @@ bool ETSChecker::EnhanceSubstitutionForUnion(const ArenaVector &typePara if (!argumentType->IsETSUnionType()) { bool foundValid = false; for (Type *ctype : paramUn->ConstituentTypes()) { - foundValid |= - ValidateTypeSubstitution(typeParams, ctype->MaybeBaseTypeOfGradualType(), argumentType, substitution); + foundValid |= ValidateTypeSubstitution(typeParams, ctype, argumentType, substitution); } return foundValid; } @@ -580,8 +574,7 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, auto &argument = arguments[index]; // #22952: infer optional parameter heuristics - auto const paramType = - GetNonNullishType(substitutedSig->Params()[index]->TsType())->MaybeBaseTypeOfGradualType(); + auto const paramType = GetNonNullishType(substitutedSig->Params()[index]->TsType()); if (argument->IsObjectExpression()) { ES2PANDA_ASSERT(paramType != nullptr); if (!paramType->IsETSObjectType()) { @@ -1103,9 +1096,8 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector static Type *GetParameterTypeOrRestAtIdx(checker::ETSChecker *checker, Signature *sig, const size_t idx) { - return idx < sig->ArgCount() - ? sig->Params().at(idx)->TsType()->MaybeBaseTypeOfGradualType() - : checker->GetElementTypeOfArray(sig->RestVar()->TsType())->MaybeBaseTypeOfGradualType(); + return idx < sig->ArgCount() ? sig->Params().at(idx)->TsType() + : checker->GetElementTypeOfArray(sig->RestVar()->TsType()); } static void InitMostSpecificType(TypeRelation *relation, const ArenaVector &signatures, @@ -1260,7 +1252,7 @@ void ETSChecker::CollectSuitableSignaturesForTypeInference( } for (auto *sig : signatures) { - auto paramType = sig->Params().at(paramIdx)->TsType()->MaybeBaseTypeOfGradualType(); + auto paramType = sig->Params().at(paramIdx)->TsType(); if (paramIdx >= sig->Params().size() || !paramType->IsETSObjectType() || !paramType->AsETSObjectType()->IsGlobalETSObjectType()) { bestSignaturesForParameter.insert({paramIdx, sig}); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 3ed10f6daa0e06b99d331a8c189cb036b546d1fa..313c539f8257d04f9892e4a9076a387a11c857a2 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -18,7 +18,6 @@ #include "checker/ETSchecker.h" #include "checker/types/globalTypesHolder.h" -#include "checker/types/gradualType.h" #include "checker/checkerContext.h" #include "checker/ETSAnalyzerHelpers.h" #include "checker/types/ets/etsEnumType.h" @@ -1720,7 +1719,7 @@ Type *ETSChecker::HandleTypeAlias(ir::Expression *const name, const ir::TSTypePa for (std::size_t idx = 0U; idx < typeAliasNode->TypeParams()->Params().size(); ++idx) { auto *typeAliasTypeName = typeAliasNode->TypeParams()->Params().at(idx)->Name(); - auto *typeAliasType = typeAliasTypeName->Variable()->TsType()->MaybeBaseTypeOfGradualType(); + auto *typeAliasType = typeAliasTypeName->Variable()->TsType(); if (typeAliasType->IsETSTypeParameter()) { ir::TypeNode *typeNode = ResolveTypeNodeForTypeArg(typeAliasNode, typeParams, idx); auto paramType = typeNode->GetType(this); @@ -1793,10 +1792,7 @@ static void BuildExportedFunctionSignature(ETSChecker *checker, varbinder::Varia checker->BuildBasicClassProperties(classDef); } - auto containingClass = classDef->TsType()->IsGradualType() - ? classDef->TsType()->AsGradualType()->GetBaseType()->AsETSObjectType() - : classDef->TsType()->AsETSObjectType(); - SavedCheckerContext scc(checker, checker->Context().Status(), containingClass); + SavedCheckerContext scc(checker, checker->Context().Status(), classDef->TsType()->AsETSObjectType()); auto funcType = checker->BuildMethodSignature(method); funcType->SetVariable(var); var->SetTsType(funcType); @@ -2859,7 +2855,7 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A memberExpression->SetPropVar(field->Key()->Variable()->AsLocalVariable()); memberExpression->SetRange(classDef->Range()); if (memberExpression->ObjType() == nullptr && classDef->TsType() != nullptr) { - memberExpression->SetObjectType(classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType()); + memberExpression->SetObjectType(classDef->TsType()->AsETSObjectType()); } if (!isSetter) { @@ -3328,7 +3324,7 @@ void ETSChecker::CheckTypeParameterVariance(ir::ClassDefinition *classDef) return; } - Context().SetContainingClass(classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType()); + Context().SetContainingClass(classDef->TsType()->AsETSObjectType()); auto checkVariance = [this](VarianceFlag varianceFlag, ir::Expression *expression, Type *type) { Relation()->Result(RelationResult::TRUE); Relation()->SetNode(expression); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 3a2c876796b279d11c1623da93556dec47c02a82..00fd1ca5f6d6eb9dc7a83135de17a3e8f91d7504 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -21,7 +21,6 @@ #include "checker/types/ets/etsTupleType.h" #include "checker/types/ets/etsPartialTypeParameter.h" #include "checker/types/ets/etsAwaitedType.h" -#include "checker/types/gradualType.h" #include "compiler/lowering/phase.h" #include "ir/base/classDefinition.h" #include "ir/base/classElement.h" @@ -140,9 +139,6 @@ ETSObjectType *ETSChecker::GetSuperType(ETSObjectType *type) if (type == GlobalETSObjectType()) { return GlobalETSObjectType(); } - if (type->SuperType() == nullptr) { - return nullptr; - } return type->SuperType(); } @@ -166,7 +162,7 @@ static bool CheckObjectTypeAndSuperType(ETSChecker *checker, ETSObjectType *type if (classDef->Super() == nullptr || !classDef->Super()->IsTypeNode()) { type->AddObjectFlag(ETSObjectFlags::RESOLVED_SUPER); - if (type != checker->GlobalETSObjectType()) { + if (type != checker->GlobalETSObjectType() && !type->IsGradual()) { type->SetSuperType(checker->GlobalETSObjectType()); } return true; @@ -195,7 +191,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) return false; } - auto *superType = classDef->Super()->AsTypeNode()->GetType(this)->MaybeBaseTypeOfGradualType(); + auto *superType = classDef->Super()->AsTypeNode()->GetType(this); if (superType == nullptr) { return true; } @@ -205,7 +201,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) return true; } - ETSObjectType *superObj = superType->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + ETSObjectType *superObj = superType->AsETSObjectType(); // struct node has class definition, too if (superObj->GetDeclNode()->Parent()->IsETSStructDeclaration()) { @@ -216,7 +212,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) LogError(diagnostic::EXTENDING_FINAL, {}, classDef->Super()->Start()); /* It still makes sense to treat superObj as the supertype in future checking */ } - if (GetSuperType(superObj) == nullptr) { + if (GetSuperType(superObj) == nullptr && !superObj->IsGradual()) { superObj = GlobalETSObjectType(); } type->SetSuperType(superObj); @@ -228,7 +224,6 @@ void ETSChecker::ValidateImplementedInterface(ETSObjectType *type, Type *interfa std::unordered_set *extendsSet, const lexer::SourcePosition &pos) { ES2PANDA_ASSERT(interface != nullptr); - interface = interface->MaybeBaseTypeOfGradualType(); if (interface->IsETSObjectType() && interface->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::CLASS)) { LogError(diagnostic::INTERFACE_EXTENDS_CLASS, {}, pos); return; @@ -476,12 +471,12 @@ void ETSChecker::CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type type->AddObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION); } -Type *ETSChecker::MaybeGradualType(ir::AstNode *node, ETSObjectType *type) +static bool IsInInteropDeclProgram(ir::AstNode *node) { - ES2PANDA_ASSERT(node->IsClassDefinition() || node->IsTSInterfaceDeclaration()); - auto isDynamic = node->IsClassDefinition() ? node->AsClassDefinition()->Language().IsDynamic() - : node->AsTSInterfaceDeclaration()->Language().IsDynamic(); - return isDynamic ? CreateGradualType(type) : type; + while (node->Parent() != nullptr) { + node = node->Parent(); + } + return node->AsETSModule()->Program()->IsDeclForDynamicStaticInterop(); } Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl) @@ -493,15 +488,15 @@ Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *inte } checker::ETSObjectType *interfaceType {}; - checker::Type *type {}; if (var->TsType() == nullptr) { interfaceType = CreateETSObjectTypeOrBuiltin(interfaceDecl, checker::ETSObjectFlags::INTERFACE); interfaceType->SetVariable(var); - type = MaybeGradualType(interfaceDecl, interfaceType); - var->SetTsType(type); - } else if (var->TsType()->MaybeBaseTypeOfGradualType()->IsETSObjectType()) { - interfaceType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); - type = MaybeGradualType(interfaceDecl, interfaceType); + var->SetTsType(interfaceType); + if (IsInInteropDeclProgram(interfaceDecl)) { + interfaceType->AddObjectFlag(checker::ETSObjectFlags::GRADUAL); + } + } else if (var->TsType()->IsETSObjectType()) { + interfaceType = var->TsType()->AsETSObjectType(); } else { ES2PANDA_ASSERT(IsAnyError()); return GlobalTypeError(); @@ -521,7 +516,9 @@ Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *inte } GetInterfaces(interfaceType); - interfaceType->SetSuperType(GlobalETSObjectType()); + if (!interfaceType->IsGradual()) { + interfaceType->SetSuperType(GlobalETSObjectType()); + } ctScope.TryCheckConstraints(); // Skip this check if the builtins are not initialized. @@ -531,35 +528,25 @@ Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *inte CheckInterfaceFunctions(interfaceType); } - return type; + return interfaceType; } void ETSChecker::CheckDynamicInheritanceAndImplement(ETSObjectType *const interfaceOrClassType) { auto getTypeString = [](ETSObjectType *type) { return type->IsInterface() ? "interface" : "class"; }; auto extendsOrImplements = [](ETSObjectType *type) { return type->IsInterface() ? "extends" : "implements"; }; - auto isFromDynamicDecl = [](ETSObjectType *type) { - auto declNode = type->GetDeclNode(); - if (declNode->IsTSInterfaceDeclaration()) { - return declNode->AsTSInterfaceDeclaration()->Language().IsDynamic(); - } - if (declNode->IsClassDefinition()) { - return declNode->AsClassDefinition()->Language().IsDynamic(); - } - return false; - }; - if (isFromDynamicDecl(interfaceOrClassType)) { + if (interfaceOrClassType->IsGradual()) { return; } - for (ETSObjectType *interType : interfaceOrClassType->Interfaces()) { - if (isFromDynamicDecl(interType)) { + for (ETSObjectType *itf : interfaceOrClassType->Interfaces()) { + if (itf->IsGradual()) { LogError(diagnostic::INTERFACE_OR_CLASS_CANNOT_IMPL_OR_EXTEND_DYNAMIC, {getTypeString(interfaceOrClassType), interfaceOrClassType->Name(), - extendsOrImplements(interfaceOrClassType), getTypeString(interType), interType->Name()}, + extendsOrImplements(interfaceOrClassType), getTypeString(itf), itf->Name()}, interfaceOrClassType->GetDeclNode()->Start()); } } - if (interfaceOrClassType->SuperType() != nullptr && isFromDynamicDecl(interfaceOrClassType->SuperType())) { + if (interfaceOrClassType->SuperType() != nullptr && interfaceOrClassType->SuperType()->IsGradual()) { LogError(diagnostic::INTERFACE_OR_CLASS_CANNOT_IMPL_OR_EXTEND_DYNAMIC, {getTypeString(interfaceOrClassType), interfaceOrClassType->Name(), "extends", getTypeString(interfaceOrClassType->SuperType()), interfaceOrClassType->SuperType()->Name()}, @@ -580,24 +567,24 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) } checker::ETSObjectType *classType {}; - checker::Type *type {}; if (var->TsType() == nullptr) { classType = CreateETSObjectTypeOrBuiltin(classDef, checker::ETSObjectFlags::CLASS); - type = MaybeGradualType(classDef, classType); classType->SetVariable(var); - var->SetTsType(type); + var->SetTsType(classType); if (classDef->IsAbstract()) { classType->AddObjectFlag(checker::ETSObjectFlags::ABSTRACT); } - } else if (var->TsType()->MaybeBaseTypeOfGradualType()->IsETSObjectType()) { - classType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); - type = MaybeGradualType(classDef, classType); + if (IsInInteropDeclProgram(classDef)) { + classType->AddObjectFlag(checker::ETSObjectFlags::GRADUAL); + } + } else if (var->TsType()->IsETSObjectType()) { + classType = var->TsType()->AsETSObjectType(); } else { ES2PANDA_ASSERT(IsAnyError()); return GlobalTypeError(); } - classDef->SetTsType(type); + classDef->SetTsType(classType); ConstraintCheckScope ctScope(this); if (classDef->TypeParams() != nullptr) { @@ -621,7 +608,7 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) GetInterfaces(classType); } ctScope.TryCheckConstraints(); - return type; + return classType; } ETSObjectType *ETSChecker::BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType) @@ -736,10 +723,6 @@ static void ResolveDeclaredDeclsOfObject(ETSChecker *checker, const ETSObjectTyp void ETSChecker::ResolveDeclaredMembersOfObject(const Type *type) { - if (type->IsGradualType()) { - return ResolveDeclaredMembersOfObject(type->AsGradualType()->GetBaseType()); - } - if (!type->IsETSObjectType() || type->AsETSObjectType()->IsPropertiesInstantiated()) { return; } @@ -1333,7 +1316,7 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) return; } - auto *classType = classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + auto *classType = classDef->TsType()->AsETSObjectType(); if (classType->SuperType() != nullptr) { classType->SuperType()->GetDeclNode()->Check(this); } @@ -1673,7 +1656,7 @@ void ETSChecker::CheckInnerClassMembers(const ETSObjectType *classType) bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) { - auto const expressionType = expr->Check(this)->MaybeBaseTypeOfGradualType(); + auto const expressionType = expr->Check(this); if (expressionType->IsTypeError()) { return false; } @@ -1935,9 +1918,6 @@ void ETSChecker::CheckCyclicConstructorCall(Signature *signature) ETSObjectType *ETSChecker::CheckExceptionOrErrorType(checker::Type *type, const lexer::SourcePosition pos) { - if (type->IsGradualType()) { - return CheckExceptionOrErrorType(type->AsGradualType()->GetBaseType(), pos); - } ES2PANDA_ASSERT(type != nullptr); if (!type->IsETSObjectType() || (!Relation()->IsAssignableTo(type, GlobalBuiltinExceptionType()) && !Relation()->IsAssignableTo(type, GlobalBuiltinErrorType()))) { @@ -2758,10 +2738,6 @@ Type *ETSChecker::GetApparentType(Type *type) }; ES2PANDA_ASSERT(type != nullptr); - if (type->IsGradualType()) { - return cached(type->AsGradualType()->GetBaseType()); - } - if (type->IsETSTypeParameter()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return cached(GetApparentType(type->AsETSTypeParameter()->GetConstraintType())); diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 9fac309638e45f2e2b96e96d35d4a548657e5abe..5ea56002c7a392282b6056e307d387f7af289b5e 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -17,7 +17,6 @@ #include "checker/checkerContext.h" #include "checker/ets/wideningConverter.h" #include "checker/types/globalTypesHolder.h" -#include "checker/types/gradualType.h" #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsPartialTypeParameter.h" #include "ir/base/catchClause.h" @@ -93,10 +92,6 @@ bool ETSChecker::CheckNonNullish(ir::Expression const *expr) Type *ETSChecker::GetNonNullishType(Type *type) { - if (type->IsGradualType()) { - return CreateGradualType(GetNonNullishType(type->AsGradualType()->GetBaseType()), - type->AsGradualType()->Language()); - } if (type->DefinitelyNotETSNullish()) { return type; } @@ -215,8 +210,7 @@ std::pair ETSChecker::RemoveNullishTypes(Type *type) ArenaVector nullishTypes(ProgramAllocator()->Adapter()); ArenaVector notNullishTypes(ProgramAllocator()->Adapter()); - for (auto *ctype : type->AsETSUnionType()->ConstituentTypes()) { - auto constituentType = ctype->MaybeBaseTypeOfGradualType(); + for (auto *constituentType : type->AsETSUnionType()->ConstituentTypes()) { if (constituentType->IsETSUndefinedType() || constituentType->IsETSNullType()) { nullishTypes.push_back(constituentType); } else { @@ -238,9 +232,6 @@ std::pair ETSChecker::RemoveNullishTypes(Type *type) template static bool MatchConstituentOrConstraint(const Type *type, Pred const &pred, Trv const &trv) { - if (type->IsGradualType()) { - return MatchConstituentOrConstraint(type->AsGradualType()->GetBaseType(), pred, trv); - } auto const traverse = [&pred, &trv](const Type *ttype) { return MatchConstituentOrConstraint(ttype, pred, trv); }; @@ -391,7 +382,7 @@ bool Type::IsETSRelaxedAnyType() const TypeFlag::ETS_TYPE_PARAMETER | TypeFlag::WILDCARD | TypeFlag::ETS_NONNULLISH | TypeFlag::ETS_REQUIRED_TYPE_PARAMETER | TypeFlag::ETS_ANY | TypeFlag::ETS_NEVER | TypeFlag::ETS_UNION | TypeFlag::ETS_ARRAY | TypeFlag::FUNCTION | TypeFlag::ETS_PARTIAL_TYPE_PARAMETER | TypeFlag::ETS_TUPLE | - TypeFlag::ETS_ENUM | TypeFlag::ETS_READONLY | TypeFlag::GRADUAL_TYPE | TypeFlag::ETS_AWAITED; + TypeFlag::ETS_ENUM | TypeFlag::ETS_READONLY | TypeFlag::ETS_AWAITED; // Issues if (type->IsETSVoidType()) { // NOTE(vpukhov): #19701 void refactoring @@ -560,10 +551,10 @@ SavedCheckerContext ETSChecker::CreateSavedCheckerContext(varbinder::Variable *c auto *classDef = iter->AsClassDefinition(); Type *containingClass {}; if (classDef->TsType() == nullptr) { - containingClass = BuildBasicClassProperties(classDef)->MaybeBaseTypeOfGradualType(); + containingClass = BuildBasicClassProperties(classDef); ResolveDeclaredMembersOfObject(containingClass); } else { - containingClass = classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + containingClass = classDef->TsType()->AsETSObjectType(); } ES2PANDA_ASSERT(classDef->TsType()); if (!containingClass->IsTypeError()) { diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 15b1e21069f490568c61f57d34f97f45801b2411..99a80c86244ad3e3abdc4254fcfb6395509f53f1 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -19,7 +19,6 @@ #include "checker/types/ets/etsEnumType.h" #include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/globalTypesHolder.h" -#include "checker/types/gradualType.h" #include "checker/types/type.h" #include "ir/statements/annotationDeclaration.h" @@ -130,27 +129,6 @@ ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType, bool isCachePoll return arrayType; } -Type *ETSChecker::CreateGradualType(Type *type, Language const lang) -{ - if (type == nullptr) { - return type; - } - if (type->IsGradualType()) { - return type; - } - if (type->IsETSAnyType()) { - return type; - } - if (type->IsETSUnionType()) { - ArenaVector copied(ProgramAllocator()->Adapter()); - for (auto const &t : type->AsETSUnionType()->ConstituentTypes()) { - copied.push_back(CreateGradualType(t, lang)); - } - return CreateETSUnionType(std::move(copied)); - } - return ProgramAllocator()->New(type); -} - Type *ETSChecker::CreateETSUnionType(Span constituentTypes) { if (constituentTypes.empty()) { @@ -367,30 +345,31 @@ ETSObjectType *ETSChecker::CreateETSObjectTypeOrBuiltin(ir::AstNode *declNode, E return InitializeGlobalBuiltinObjectType(this, globalId.value(), declNode, flags); } -ETSObjectType *ETSChecker::CreateETSObjectType(ir::AstNode *declNode, ETSObjectFlags flags) +ETSObjectType *ETSChecker::CreateETSObjectType( + ir::AstNode *declNode, ETSObjectFlags flags, + /* this parameter maintanis the behavior of the broken ast-cache logic, avoid it whenever possible */ + std::optional> caches) { + auto const allocator = caches.has_value() ? caches->first : ProgramAllocator(); + auto const relation = caches.has_value() ? caches->second : Relation(); + auto const [name, internalName] = GetObjectTypeDeclNames(declNode); - ETSObjectType *objectType = nullptr; + if (declNode->IsClassDefinition() && (declNode->AsClassDefinition()->IsEnumTransformed())) { if (declNode->AsClassDefinition()->IsIntEnumTransformed()) { - objectType = - ProgramAllocator()->New(ProgramAllocator(), name, internalName, declNode, Relation()); - } else if (declNode->AsClassDefinition()->IsStringEnumTransformed()) { - objectType = ProgramAllocator()->New(ProgramAllocator(), name, internalName, declNode, - Relation()); - } else { - ES2PANDA_ASSERT(declNode->AsClassDefinition()->IsDoubleEnumTransformed()); - objectType = ProgramAllocator()->New(ProgramAllocator(), name, internalName, declNode, - Relation()); + return allocator->New(allocator, name, internalName, declNode, relation); + } else if (declNode->AsClassDefinition()->IsDoubleEnumTransformed()) { + return ProgramAllocator()->New(ProgramAllocator(), name, internalName, declNode, + Relation()); } - } else if (internalName == compiler::Signatures::BUILTIN_ARRAY) { - objectType = ProgramAllocator()->New(ProgramAllocator(), name, - std::make_tuple(declNode, flags, Relation())); - } else { - objectType = ProgramAllocator()->New(ProgramAllocator(), name, internalName, - std::make_tuple(declNode, flags, Relation())); + ES2PANDA_ASSERT(declNode->AsClassDefinition()->IsStringEnumTransformed()); + return allocator->New(allocator, name, internalName, declNode, relation); + } + + if (internalName == compiler::Signatures::BUILTIN_ARRAY) { + return allocator->New(allocator, name, std::make_tuple(declNode, flags, relation)); } - return objectType; + return allocator->New(allocator, name, internalName, std::make_tuple(declNode, flags, relation)); } std::tuple ETSChecker::CreateBuiltinArraySignatureInfo(const ETSArrayType *arrayType, diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index d2835dec80367d14eb1aa29ef1050222f0848e85..fc1e4e72841c8ae88eadd16cde3197184d10802b 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -110,8 +110,7 @@ static void CheckInstantiationConstraints(ETSChecker *checker, ArenaVectorRelation(); - for (auto type : typeParams) { - type = type->MaybeBaseTypeOfGradualType(); + for (auto const type : typeParams) { if (!type->IsETSTypeParameter()) { continue; } diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 215712fff1d03a2c2eba0d3b61de02e150ba4629..8b9f73630b7fad2c31ef2f667db6383b3e79f0fa 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -26,8 +26,6 @@ #include "compiler/lowering/util.h" #include "util/nameMangler.h" -#include - namespace ark::es2panda::checker { std::optional ETSChecker::GetUtilityTypeTypeParamNode( @@ -40,11 +38,10 @@ std::optional ETSChecker::GetUtilityTypeTypeParamNode( return typeParams->Params().front(); } -static bool ValidBaseTypeOfRequiredAndPartial(Type *baseType) +static bool ValidBaseTypeOfRequiredAndPartial(Type *type) { - Type *type = baseType->MaybeBaseTypeOfGradualType(); - return type->IsETSObjectType() && (type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE) || - type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::CLASS)); + return type->IsETSObjectType() && + type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE | ETSObjectFlags::CLASS); } Type *ETSChecker::HandleUtilityTypeParameterNode(const ir::TSTypeParameterInstantiation *const typeParams, @@ -231,11 +228,6 @@ Type *ETSChecker::CreatePartialType(Type *const typeToBePartial) return typeToBePartial; } - if (typeToBePartial->IsGradualType()) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return CreatePartialType(typeToBePartial->AsGradualType()->GetBaseType()); - } - if (typeToBePartial->IsETSTypeParameter()) { return CreatePartialTypeParameter(typeToBePartial->AsETSTypeParameter()); } @@ -1113,10 +1105,6 @@ Type *ETSChecker::GetReadonlyType(Type *type) return *found; } - if (type->IsGradualType()) { - return GetReadonlyType(type->AsGradualType()->GetBaseType()); - } - NamedTypeStackElement ntse(this, type); ES2PANDA_ASSERT(type != nullptr); if (type->IsETSArrayType()) { @@ -1205,7 +1193,7 @@ Type *ETSChecker::HandleRequiredType(Type *typeToBeRequired) typeToBeRequired = typeToBeRequired->Clone(this); - MakePropertiesNonNullish(typeToBeRequired->MaybeBaseTypeOfGradualType()->AsETSObjectType()); + MakePropertiesNonNullish(typeToBeRequired->AsETSObjectType()); return typeToBeRequired; } diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 49679056d425bbf4f018bfe93351f7b7a7c7c021..e107167503f9a941bf1b1a6336c0e554d0115abb 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -835,11 +835,6 @@ void ETSObjectType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsGradualType()) { - relation->Result(true); - return; - } - if (CastNumericObject(relation, target)) { return; } @@ -897,6 +892,10 @@ void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) } auto const sourceObj = source->AsETSObjectType(); + if (IsGradual() != sourceObj->IsGradual()) { + relation->Result(false); + return; + } // #23072 - superType_ of the current object is not intialized in recursive generics if (GetConstOriginalBaseType() == checker->GlobalETSObjectType()) { // Fastpath, all objects are subtypes of Object relation->Result(true); @@ -1255,37 +1254,6 @@ static util::StringView GetHashFromSubstitution(const Substitution *substitution return util::UString(ss.str(), allocator).View(); } -static std::pair GetObjectTypeDeclNames(ir::AstNode *node) -{ - if (node->IsClassDefinition()) { - return {node->AsClassDefinition()->Ident()->Name(), node->AsClassDefinition()->InternalName()}; - } - if (node->IsTSInterfaceDeclaration()) { - return {node->AsTSInterfaceDeclaration()->Id()->Name(), node->AsTSInterfaceDeclaration()->InternalName()}; - } - return {node->AsAnnotationDeclaration()->GetBaseName()->Name(), node->AsAnnotationDeclaration()->InternalName()}; -} - -ETSObjectType *ETSObjectType::CreateETSObjectType(ir::AstNode *declNode, ETSObjectFlags flags) -{ - auto const [name, internalName] = GetObjectTypeDeclNames(declNode); - - if (declNode->IsClassDefinition() && (declNode->AsClassDefinition()->IsEnumTransformed())) { - if (declNode->AsClassDefinition()->IsIntEnumTransformed()) { - return Allocator()->New(Allocator(), name, internalName, declNode, GetRelation()); - } - ES2PANDA_ASSERT(declNode->AsClassDefinition()->IsStringEnumTransformed()); - return Allocator()->New(Allocator(), name, internalName, declNode, GetRelation()); - } - if (internalName == compiler::Signatures::BUILTIN_ARRAY) { - return Allocator()->New(Allocator(), name, - std::make_tuple(declNode, flags, GetRelation())); - } - - return Allocator()->New(Allocator(), name, internalName, - std::make_tuple(declNode, flags, GetRelation())); -} - // #22951: remove isExtensionFunctionType flag ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution, bool cache, bool isExtensionFunctionType) @@ -1318,7 +1286,8 @@ ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitut } relation->IncreaseTypeRecursionCount(base); - auto *const copiedType = CreateETSObjectType(declNode_, flags_); + auto checker = relation->GetChecker()->AsETSChecker(); + auto const copiedType = checker->CreateETSObjectType(declNode_, flags_, {{Allocator(), GetRelation()}}); SetCopiedTypeProperties(relation, copiedType, std::move(newTypeArgs), base); if (isExtensionFunctionType) { copiedType->AddObjectFlag(checker::ETSObjectFlags::EXTENSION_FUNCTION); @@ -1360,8 +1329,7 @@ ETSObjectType *ETSObjectType::SubstituteArguments(TypeRelation *relation, ArenaV ES2PANDA_ASSERT(typeArguments_.size() == arguments.size()); for (size_t ix = 0; ix < typeArguments_.size(); ix++) { - substitution.emplace(typeArguments_[ix]->AsETSTypeParameter(), - checker->MaybeBoxType(arguments[ix]->MaybeBaseTypeOfGradualType())); + substitution.emplace(typeArguments_[ix]->AsETSTypeParameter(), checker->MaybeBoxType(arguments[ix])); } return Substitute(relation, &substitution); @@ -1529,20 +1497,28 @@ const ArenaVector &ETSObjectType::ReExports() const return reExports_; } +util::StringView ETSObjectType::AssemblerName() const +{ + if (IsGradual()) { + return "std.core.Object"; // "{Ustd.core.Object,std.core.JSValue}" + } + return internalName_; +} + void ETSObjectType::ToAssemblerType([[maybe_unused]] std::stringstream &ss) const { - ss << internalName_; + ss << AssemblerName(); } void ETSObjectType::ToDebugInfoType(std::stringstream &ss) const { - ss << NameToDescriptor(internalName_); + ss << NameToDescriptor(AssemblerName()); } void ETSObjectType::ToDebugInfoSignatureType(std::stringstream &ss) const { ss << compiler::Signatures::GENERIC_BEGIN; - ss << internalName_; + ss << AssemblerName(); ss << compiler::Signatures::GENERIC_END; } diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 24558f5d5a3dc0c1170a54ad8924ab315e1a02f7..2d9cafe8c9390aca9820d9447a332c61c2d46b88 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -221,7 +221,7 @@ public: bool IsGlobalETSObjectType() const noexcept { - return superType_ == nullptr; + return superType_ == nullptr && !IsGradual(); } bool IsPropertyInherited(const varbinder::Variable *var); @@ -237,10 +237,7 @@ public: return name_; } - util::StringView AssemblerName() const - { - return internalName_; - } + util::StringView AssemblerName() const; ETSObjectFlags ObjectFlags() const { @@ -267,6 +264,11 @@ public: return HasObjectFlag(ETSObjectFlags::INTERFACE); } + bool IsGradual() const + { + return HasObjectFlag(ETSObjectFlags::GRADUAL); + } + bool IsETSStringLiteralType() const { return superType_ != nullptr && superType_->IsETSObjectType() && @@ -366,7 +368,6 @@ public: bool ReplaceArgumentInSignature(std::vector &signatures, Signature *sigToInsert, TypeRelation *relation) const; bool CheckIdenticalFlags(ETSObjectType *other) const; - ETSObjectType *CreateETSObjectType(ir::AstNode *declNode, ETSObjectFlags flags); void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; diff --git a/ets2panda/checker/types/ets/etsObjectTypeConstants.h b/ets2panda/checker/types/ets/etsObjectTypeConstants.h index c627166245b9196579cfbae623d8eaa0bc42b47d..9c4472aaddb775168f86c6667f7ea8951d69f37e 100644 --- a/ets2panda/checker/types/ets/etsObjectTypeConstants.h +++ b/ets2panda/checker/types/ets/etsObjectTypeConstants.h @@ -37,7 +37,7 @@ enum class ETSObjectFlags : std::uint64_t { STRING = 1U << 10U, INCOMPLETE_INSTANTIATION = 1U << 11U, INNER = 1U << 12U, - DYNAMIC = 1U << 13U, + GRADUAL = 1U << 13U, ASYNC_FUNC_RETURN_TYPE = 1U << 14U, CHECKED_INVOKE_LEGITIMACY = 1U << 15U, REQUIRED = 1U << 16U, diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index b68c4d4b00b61b534234a1eedeb387423c717fab..1fee41b8f8ec7dcaa9700b3aee19b68f4eb6818d 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -416,7 +416,7 @@ bool ETSUnionType::ExtractType(checker::ETSChecker *checker, checker::Type *sour bool rc = false; auto it = unionTypes.cbegin(); while (it != unionTypes.cend()) { - auto *constituentType = (*it)->MaybeBaseTypeOfGradualType(); + auto *constituentType = (*it); // Because 'instanceof' expression does not check for type parameters, then for generic types we should // consider that expressions like 'SomeType' and 'SomeType' are identical for smart casting. // We also have to pass through all the union to process cases like 'C|A|B|C|undefined` diff --git a/ets2panda/checker/types/gradualType.cpp b/ets2panda/checker/types/gradualType.cpp deleted file mode 100644 index ccf3f35b6c558b42ac42bcc1b1b6d1710b55c86f..0000000000000000000000000000000000000000 --- a/ets2panda/checker/types/gradualType.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "gradualType.h" - -#include "checker/ETSchecker.h" -#include "checker/ets/conversion.h" - -namespace ark::es2panda::checker { -void GradualType::Identical(TypeRelation *relation, Type *other) -{ - if (other->IsGradualType()) { - baseType_->Identical(relation, other->AsGradualType()->GetBaseType()); - } else { - baseType_->Identical(relation, other); - } -} - -void GradualType::AssignmentTarget(TypeRelation *relation, Type *source) -{ - if (source->IsGradualType()) { - baseType_->AssignmentTarget(relation, source->AsGradualType()->GetBaseType()); - } else { - baseType_->AssignmentTarget(relation, source); - } -} - -bool GradualType::AssignmentSource(TypeRelation *relation, Type *target) -{ - if (target->IsGradualType()) { - return baseType_->AssignmentSource(relation, target->AsGradualType()->GetBaseType()); - } - return baseType_->AssignmentSource(relation, target); -} - -void GradualType::Compare(TypeRelation *relation, Type *other) -{ - if (other->IsGradualType()) { - baseType_->Compare(relation, other->AsGradualType()->GetBaseType()); - } else { - baseType_->Compare(relation, other); - } -} - -void GradualType::Cast(TypeRelation *relation, Type *target) -{ - if (target->IsGradualType()) { - baseType_->Cast(relation, target->AsGradualType()->GetBaseType()); - } else { - baseType_->Cast(relation, target); - } -} - -void GradualType::CastTarget(TypeRelation *relation, Type *source) -{ - if (source->IsGradualType()) { - baseType_->CastTarget(relation, source->AsGradualType()->GetBaseType()); - } else { - baseType_->CastTarget(relation, source); - } -} - -void GradualType::IsSubtypeOf(TypeRelation *relation, Type *target) -{ - if (target->IsGradualType()) { - baseType_->IsSubtypeOf(relation, target->AsGradualType()->GetBaseType()); - } else { - baseType_->IsSubtypeOf(relation, target); - } -} - -void GradualType::IsSupertypeOf(TypeRelation *relation, Type *source) -{ - if (source->IsGradualType()) { - relation->IsSupertypeOf(baseType_, source->AsGradualType()->GetBaseType()); - } else { - baseType_->IsSupertypeOf(relation, source); - } -} - -void GradualType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const -{ - baseType_->ToString(ss); -} - -Type *GradualType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) -{ - auto baseType = baseType_->Instantiate(allocator, relation, globalTypes); - return relation->GetChecker()->AsETSChecker()->CreateGradualType(baseType); -} - -Type *GradualType::Substitute(TypeRelation *relation, const Substitution *substitution) -{ - return baseType_->Substitute(relation, substitution); -} - -void GradualType::ToAssemblerType(std::stringstream &ss) const -{ - baseType_->ToAssemblerType(ss); -} - -void GradualType::ToDebugInfoType(std::stringstream &ss) const -{ - baseType_->ToDebugInfoType(ss); -} - -void GradualType::ToAssemblerTypeWithRank(std::stringstream &ss) const -{ - baseType_->ToAssemblerTypeWithRank(ss); -} - -void GradualType::CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) -{ - // The type of array should be Invariant - relation->CheckVarianceRecursively(baseType_, varianceFlag); -} -} // namespace ark::es2panda::checker \ No newline at end of file diff --git a/ets2panda/checker/types/gradualType.h b/ets2panda/checker/types/gradualType.h deleted file mode 100644 index eb1978e8d64d03011ffa14443c8b8607c8559850..0000000000000000000000000000000000000000 --- a/ets2panda/checker/types/gradualType.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef ES2PANDA_COMPILER_CHECKER_TYPES_GRADUAL_TYPE_H -#define ES2PANDA_COMPILER_CHECKER_TYPES_GRADUAL_TYPE_H - -#include "checker/types/type.h" -#include "ir/astNode.h" - -namespace ark::es2panda::checker { -class GradualType : public Type { -public: - explicit GradualType(checker::Type *baseType) - : Type(TypeFlag::GRADUAL_TYPE), baseType_(baseType), lang_(es2panda::Language(Language::Id::ETS)) - { - } - - explicit GradualType(checker::Type *baseType, Language lang) - : Type(TypeFlag::GRADUAL_TYPE), baseType_(baseType), lang_(lang) - { - } - - void Identical(TypeRelation *relation, Type *other) override; - void AssignmentTarget(TypeRelation *relation, Type *source) override; - bool AssignmentSource(TypeRelation *relation, Type *target) override; - void Compare(TypeRelation *relation, Type *other) override; - void Cast(TypeRelation *relation, Type *target) override; - void CastTarget(TypeRelation *relation, Type *source) override; - void IsSubtypeOf(TypeRelation *relation, Type *target) override; - void IsSupertypeOf(TypeRelation *relation, Type *source) override; - void ToString(std::stringstream &ss, bool precise) const override; - void ToAssemblerType(std::stringstream &ss) const override; - void ToDebugInfoType(std::stringstream &ss) const override; - void ToAssemblerTypeWithRank(std::stringstream &ss) const override; - Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; - void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; - - const Type *GetBaseType() const - { - auto baseType = baseType_; - while (baseType->IsGradualType()) { - baseType = baseType->AsGradualType()->BaseType(); - } - return baseType; - } - - Type *GetBaseType() - { - auto baseType = baseType_; - while (baseType->IsGradualType()) { - baseType = baseType->AsGradualType()->BaseType(); - } - return baseType; - } - - Type *BaseType() - { - return baseType_; - } - - Type *BaseType() const - { - return baseType_; - } - - es2panda::Language Language() const - { - return lang_; - } - -private: - Type *baseType_; - es2panda::Language lang_; -}; -} // namespace ark::es2panda::checker - -#endif \ No newline at end of file diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index 0aaeab306651b74f0c87a99d36bc33cd095b239f..156647880f74fdebb640b7fed537af14ff57d541 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -117,7 +117,7 @@ Signature *Signature::Copy(ArenaAllocator *allocator, TypeRelation *relation, Gl SignatureInfo *copiedInfo = allocator->New(signatureInfo_, allocator); ES2PANDA_ASSERT(copiedInfo != nullptr); for (size_t idx = 0U; idx < signatureInfo_->params.size(); ++idx) { - auto *const paramType = signatureInfo_->params[idx]->TsType()->MaybeBaseTypeOfGradualType(); + auto *const paramType = signatureInfo_->params[idx]->TsType(); if (paramType->HasTypeFlag(TypeFlag::GENERIC) && paramType->IsETSObjectType()) { copiedInfo->params[idx]->SetTsType(paramType->Instantiate(allocator, relation, globalTypes)); auto originalTypeArgs = paramType->AsETSObjectType()->GetOriginalBaseType()->TypeArguments(); diff --git a/ets2panda/checker/types/type.cpp b/ets2panda/checker/types/type.cpp index 694499259016b06b0bea17986aa1a3dc766f89e3..cc2f70dcd833c6de018bd81374c9036a23c7e4ca 100644 --- a/ets2panda/checker/types/type.cpp +++ b/ets2panda/checker/types/type.cpp @@ -18,7 +18,6 @@ #include "checker/types/typeFlag.h" #include "checker/types/typeRelation.h" #include "checker/types/ets/etsObjectType.h" -#include "checker/types/gradualType.h" #include "checker/checker.h" namespace ark::es2panda::checker { @@ -167,13 +166,4 @@ bool IsTypeError(Type const *tp) return tp != nullptr && tp->IsTypeError(); } -Type *Type::MaybeBaseTypeOfGradualType() -{ - auto res = this; - while (res->IsGradualType()) { - res = res->AsGradualType()->GetBaseType(); - } - return res; -} - } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index b0a50a0b51d31f85953003e00e86e147ff312481..96526b30895dee5d6d15d583175ebe40929b0212 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -33,7 +33,6 @@ class ETSAsyncFuncReturnType; class ETSChecker; class ETSTypeParameter; class ETSEnumType; -class GradualType; // CC-OFFNXT(G.PRE.02) name part // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -181,8 +180,6 @@ public: return IsETSArrayType() || IsETSResizableArrayType() || IsETSReadonlyArrayType() || IsETSTupleType(); } - Type *MaybeBaseTypeOfGradualType(); - TypeFlag TypeFlags() const { return typeFlags_; diff --git a/ets2panda/checker/types/typeFlag.h b/ets2panda/checker/types/typeFlag.h index 9245b2a7e555d13ce6afbaecc5a089be94c76614..8dd323f0a9a47166f11a13a05f4c9902361580ca 100644 --- a/ets2panda/checker/types/typeFlag.h +++ b/ets2panda/checker/types/typeFlag.h @@ -72,7 +72,7 @@ enum class TypeFlag : uint64_t { GENERIC = 1ULL << 45ULL, // ETS Generic ETS_INT_ENUM = 1ULL << 46ULL, // ETS Enum ETS_STRING_ENUM = 1ULL << 47ULL, // ETS string-type Enumeration - GRADUAL_TYPE = 1ULL << 48ULL, // gradual type + /* Unused: 1ULL << 48ULL, */ // unused GETTER = 1ULL << 49ULL, // ETS Getter SETTER = 1ULL << 50ULL, // ETS Setter ETS_EXTENSION_FUNC_HELPER = 1ULL << 51ULL, // ETS Extension Function Helper diff --git a/ets2panda/checker/types/typeMapping.h b/ets2panda/checker/types/typeMapping.h index 0ab8b04c640a65123ddad29a541726fe15ad6b5e..0314e1e6482e9fc4639e58f6dc998d313ab834b8 100644 --- a/ets2panda/checker/types/typeMapping.h +++ b/ets2panda/checker/types/typeMapping.h @@ -72,7 +72,6 @@ _(TypeFlag::ETS_TUPLE, ETSTupleType) \ _(TypeFlag::ETS_PARTIAL_TYPE_PARAMETER, ETSPartialTypeParameter) \ _(TypeFlag::TYPE_ERROR, TypeError) \ - _(TypeFlag::GRADUAL_TYPE, GradualType) \ _(TypeFlag::ETS_TYPE_ALIAS, ETSTypeAliasType) #define OBJECT_TYPE_MAPPING(_) \ diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 758d0da822c177409ececbccb60d5b0feb82d623..7f7059aeca6aa6abed070a929196666e520f5724 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -495,17 +495,6 @@ static void CompileLogical(compiler::ETSGen *etsg, const ir::BinaryExpression *e etsg->SetAccumulatorType(expr->TsType()); } -static void CompileAnyInstanceOf(compiler::ETSGen *etsg, const VReg lhs, const ir::Expression *expr) -{ - RegScope rs(etsg); - VReg objReg = etsg->AllocReg(); - expr->Compile(etsg); - etsg->StoreAccumulator(expr, objReg); - etsg->LoadAccumulator(expr, lhs); - etsg->EmitAnyIsinstance(expr, objReg); - etsg->SetAccumulatorType(etsg->Checker()->GlobalETSBooleanType()); -} - static void CompileInstanceof(compiler::ETSGen *etsg, const ir::BinaryExpression *expr) { ES2PANDA_ASSERT(expr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF); @@ -516,12 +505,7 @@ static void CompileInstanceof(compiler::ETSGen *etsg, const ir::BinaryExpression expr->Left()->Compile(etsg); etsg->ApplyConversionAndStoreAccumulator(expr->Left(), lhs, expr->OperationType()); - auto target = expr->Right()->TsType(); - if (target->IsETSAnyType() && target->AsETSAnyType()->IsRelaxed()) { - CompileAnyInstanceOf(etsg, lhs, expr->Right()); - } else { - etsg->IsInstance(expr, lhs, target); - } + etsg->IsInstance(expr, lhs, expr->Right()->TsType()); ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->TsType())); } @@ -697,29 +681,6 @@ bool IsCastCall(checker::Signature *signature) (signature->Params().size() == 1) && signature->Params()[0]->TsType()->IsETSPrimitiveType()); } -void ETSCompiler::CompileAny(const ir::CallExpression *expr, const ir::Expression *callee, - compiler::VReg &calleeReg) const -{ - ETSGen *etsg = GetETSGen(); - auto memberExpr = callee->AsMemberExpression(); - memberExpr->Object()->Compile(etsg); - compiler::VReg objReg = etsg->AllocReg(); - etsg->StoreAccumulator(expr, objReg); - auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); - if (expr->Signature()->Function() != nullptr && expr->Signature()->Function()->IsStatic()) { - auto name = expr->Signature()->Function()->IsDefaultExported() ? compiler::Signatures::DEFAULT - : memberExpr->Property()->AsIdentifier()->Name(); - etsg->LoadPropertyByNameAny(memberExpr, objReg, name); - etsg->StoreAccumulator(expr, calleeReg); - etsg->CallAny(callee->AsMemberExpression()->Object(), Span(expr->Arguments()), - calleeReg); - } else { - etsg->CallAnyThis(expr, memberExpr->Property()->AsIdentifier()->Name(), - Span(expr->Arguments()), objReg); - } - etsg->EmitAnyCheckCast(expr, expr->TsType()); -} - void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, checker::Signature *signature) const { @@ -774,9 +735,7 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const ConvertRestArguments(const_cast(etsg->Checker()->AsETSChecker()), expr, signature); - if (expr->IsDynamicCall()) { - CompileAny(expr, callee, calleeReg); - } else if (callee->IsIdentifier()) { + if (callee->IsIdentifier()) { if (!isStatic) { etsg->LoadThis(expr); etsg->StoreAccumulator(expr, calleeReg); @@ -850,17 +809,6 @@ void ETSCompiler::Compile(const ir::Identifier *expr) const etsg->SetAccumulatorType(smartType); } -static void LoadETSAnyTypeFromMemberExpr(compiler::ETSGen *etsg, const ir::MemberExpression *expr, - compiler::VReg objReg) -{ - if (expr->Property()->TsType()->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { - etsg->LoadByIndexAny(expr, objReg); - } else { - etsg->LoadByValueAny(expr, objReg); - } - etsg->EmitAnyCheckCast(expr, expr->TsType()); -} - bool ETSCompiler::CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression *expr) { if (!expr->IsComputed()) { @@ -886,8 +834,6 @@ bool ETSCompiler::CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpres auto indexValue = *expr->GetTupleIndexValue(); auto *tupleElementType = objectType->AsETSTupleType()->GetTypeAtIndex(indexValue); etsg->LoadTupleElement(expr, objReg, tupleElementType, indexValue); - } else if (objectType->IsETSAnyType()) { - LoadETSAnyTypeFromMemberExpr(etsg, expr, objReg); } else { ES2PANDA_ASSERT(objectType->IsETSArrayType()); etsg->LoadArrayElement(expr, objReg); @@ -900,28 +846,6 @@ bool ETSCompiler::CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpres return true; } -bool ETSCompiler::CompileAny(compiler::ETSGen *etsg, const ir::MemberExpression *expr) const -{ - if (!etsg->Checker()->GetApparentType(expr->Object()->TsType())->IsETSAnyType()) { - return false; - } - auto ottctx = compiler::TargetTypeContext(etsg, expr->Object()->TsType()); - etsg->CompileAndCheck(expr->Object()); - - compiler::VReg objReg = etsg->AllocReg(); - etsg->StoreAccumulator(expr, objReg); - - auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); - if (expr->Property()->Variable()->Declaration() != nullptr && - expr->Property()->Variable()->Declaration()->Node()->IsDefaultExported()) { - etsg->LoadPropertyByNameAny(expr, objReg, compiler::Signatures::DEFAULT); - } else { - etsg->LoadPropertyByNameAny(expr, objReg, expr->Property()->AsIdentifier()->Name()); - } - etsg->EmitAnyCheckCast(expr, expr->TsType()); - return true; -} - void ETSCompiler::Compile(const ir::MemberExpression *expr) const { ETSGen *etsg = GetETSGen(); @@ -932,10 +856,6 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const return; } - if (CompileAny(etsg, expr)) { - return; - } - if (HandleArrayTypeLengthProperty(expr, etsg)) { return; } @@ -1656,7 +1576,8 @@ void ETSCompiler::CompileCast(const ir::TSAsExpression *expr, checker::Type cons case checker::TypeFlag::ETS_UNION: case checker::TypeFlag::ETS_ANY: case checker::TypeFlag::ETS_NULL: - case checker::TypeFlag::ETS_UNDEFINED: { + case checker::TypeFlag::ETS_UNDEFINED: + case checker::TypeFlag::ETS_VOID: { etsg->CastToReftype(expr, targetType, expr->isUncheckedCast_); break; } @@ -1734,17 +1655,9 @@ void ETSCompiler::Compile(const ir::TSNonNullExpression *expr) const void ETSCompiler::Compile([[maybe_unused]] const ir::TSTypeAliasDeclaration *st) const {} -void ETSCompiler::Compile(const ir::TSQualifiedName *expr) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSQualifiedName *expr) const { - ES2PANDA_ASSERT(expr->Left()->IsMemberExpression()); - - ETSGen *etsg = GetETSGen(); - expr->Left()->Compile(etsg); - - compiler::VReg objReg = etsg->AllocReg(); - etsg->StoreAccumulator(expr->Left(), objReg); - etsg->LoadPropertyByNameAny(expr->Left(), objReg, expr->Right()->AsIdentifier()->Name()); - etsg->EmitAnyCheckCast(expr, expr->Right()->AsIdentifier()->Variable()->TsType()); + ES2PANDA_UNREACHABLE(); } } // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/core/ETSCompiler.h b/ets2panda/compiler/core/ETSCompiler.h index 868ce81e497e15dbcb51d9a6dd65191d2249dc58..d09df63fd6c3d2e54a7fcc92214db24f5469d466 100644 --- a/ets2panda/compiler/core/ETSCompiler.h +++ b/ets2panda/compiler/core/ETSCompiler.h @@ -35,7 +35,6 @@ public: private: void GetDynamicNameParts(const ir::CallExpression *expr, ArenaVector &parts) const; - void CompileAny(const ir::CallExpression *expr, const ir::Expression *callee, compiler::VReg &calleeReg) const; void CompileCastPrimitives(const ir::Expression *expr, checker::Type const *targetType) const; void CompileCast(const ir::TSAsExpression *expr, checker::Type const *targetType) const; void EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, checker::Signature *signature) const; @@ -45,7 +44,6 @@ private: void CompileTupleCreation(const ir::ArrayExpression *tupleInitializer) const; static bool CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression *expr); - bool CompileAny(compiler::ETSGen *etsg, const ir::MemberExpression *expr) const; ETSGen *GetETSGen() const; }; diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 44062c41cc13294f29efe3e31854726d9f54fa0d..f278b3ae3603a322615b53bfb6a07b3f660e7f65 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -360,9 +360,9 @@ public: Ra().Emit(node, objectReg, propReg); } - void EmitAnyIsinstance(const ir::AstNode *node, VReg objReg) + void EmitAnyIsinstance(const ir::AstNode *node, VReg typeReg) { - Sa().Emit(node, objReg); + Sa().Emit(node, typeReg); } void CallExact(const ir::AstNode *node, checker::Signature *signature, diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index 69cac80ef67b34d00ffd74ca0d32bea6084cbfc5..533858140318458728d94d75366ec0dd1a279a44 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -46,7 +46,7 @@ #include "checker/types/signature.h" #include "checker/ETSchecker.h" #include "checker/types/type.h" -#include "checker/types/gradualType.h" +#include "checker/types/ets/types.h" #include "checker/types/ets/etsPartialTypeParameter.h" #include "public/public.h" #include "util/nameMangler.h" @@ -161,9 +161,6 @@ private: static pandasm::Type PandasmTypeWithRank(ETSEmitter *emitter, checker::Type const *type) { - if (type->IsGradualType()) { - return PandasmTypeWithRank(emitter, type->AsGradualType()->GetBaseType()); - } if (type->IsETSTypeParameter()) { return PandasmTypeWithRank(emitter, type->AsETSTypeParameter()->GetConstraintType()); } @@ -639,10 +636,7 @@ void ETSEmitter::GenInterfaceRecord(const ir::TSInterfaceDeclaration *interfaceD interfaceRecord.metadata->SetAttributeValue(Signatures::EXTENDS_ATTRIBUTE, Signatures::BUILTIN_OBJECT); - auto *baseType = interfaceDecl->TsType()->IsGradualType() - ? interfaceDecl->TsType()->AsGradualType()->GetBaseType()->AsETSObjectType() - : interfaceDecl->TsType()->AsETSObjectType(); - for (auto *it : baseType->Interfaces()) { + for (auto *it : interfaceDecl->TsType()->AsETSObjectType()->Interfaces()) { auto *declNode = it->GetDeclNode(); ES2PANDA_ASSERT(declNode->IsTSInterfaceDeclaration()); interfaceRecord.metadata->SetAttributeValue( @@ -719,7 +713,6 @@ void ETSEmitter::GenClassRecord(const ir::ClassDefinition *classDef, bool extern uint32_t accessFlags = GetAccessFlags(classDef); classRecord.metadata->SetAccessFlags(accessFlags); classRecord.sourceFile = std::string {Context()->parserProgram->VarBinder()->Program()->RelativeFilePath()}; - for (const auto *prop : classDef->Body()) { if (prop->IsClassProperty()) { GenClassField(prop->AsClassProperty(), classRecord, external); @@ -734,15 +727,13 @@ void ETSEmitter::GenClassRecord(const ir::ClassDefinition *classDef, bool extern return; } - auto *baseType = classDef->TsType()->IsGradualType() - ? classDef->TsType()->AsGradualType()->GetBaseType()->AsETSObjectType() - : classDef->TsType()->AsETSObjectType(); - if (baseType->SuperType() != nullptr) { + auto const type = classDef->TsType()->AsETSObjectType(); + if (type->SuperType() != nullptr) { classRecord.metadata->SetAttributeValue(Signatures::EXTENDS_ATTRIBUTE, - AddDependence(ToAssemblerType(baseType->SuperType()->GetDeclNode()))); + AddDependence(ToAssemblerType(type->SuperType()->GetDeclNode()))); } - for (auto *it : baseType->Interfaces()) { + for (auto *it : type->Interfaces()) { classRecord.metadata->SetAttributeValue( Signatures::IMPLEMENTS_ATTRIBUTE, AddDependence(ToAssemblerType(it->GetDeclNode()->AsTSInterfaceDeclaration()))); diff --git a/ets2panda/compiler/core/ETSfunction.cpp b/ets2panda/compiler/core/ETSfunction.cpp index af91c7d094e4199a180f9de1fe3eb7c738dc8815..39cc8e6600ec879ace54119b94fdb62ee693296a 100644 --- a/ets2panda/compiler/core/ETSfunction.cpp +++ b/ets2panda/compiler/core/ETSfunction.cpp @@ -33,7 +33,6 @@ #include "ir/ts/tsEnumDeclaration.h" #include "ir/ts/tsEnumMember.h" #include "checker/types/ets/types.h" -#include "checker/types/gradualType.h" namespace ark::es2panda::compiler { // #22952: this should have been done in lowering @@ -41,8 +40,7 @@ void ETSFunction::CallImplicitCtor(ETSGen *etsg) { RegScope rs(etsg); auto *type = etsg->ContainingObjectType()->SuperType(); - auto superType = - type->IsGradualType() ? type->AsGradualType()->GetBaseType()->AsETSObjectType() : type->AsETSObjectType(); + auto superType = type->AsETSObjectType(); if (superType == nullptr) { etsg->CallExact(etsg->RootNode(), Signatures::BUILTIN_OBJECT_CTOR, etsg->GetThisReg()); return; diff --git a/ets2panda/compiler/lowering/ets/dynamicImport.cpp b/ets2panda/compiler/lowering/ets/dynamicImport.cpp index 7d27f20b77c92701cf0412e84a5ef2419dec6516..4622facfe7afe2981d358cfd19b5af9328b1d301 100644 --- a/ets2panda/compiler/lowering/ets/dynamicImport.cpp +++ b/ets2panda/compiler/lowering/ets/dynamicImport.cpp @@ -25,20 +25,22 @@ namespace ark::es2panda::compiler { using AstNodePtr = ir::AstNode *; -static constexpr std::string_view LAZY_IMPORT_OBJECT_SUFFIX = "%%lazyImportObject-"; +static constexpr std::string_view LAZY_IMPORT_OBJECT_PREFIX = "%%lazy_import-"; static constexpr std::string_view FIELD_NAME = "value"; +static size_t &LazyImportsCount() +{ + thread_local size_t counter = 0; + return counter; +} + static checker::Type *CreateModuleObjectType(public_lib::Context *ctx, ir::ETSImportDeclaration *importDecl); -ir::ClassDeclaration *GetOrCreateLazyImportObjectClass(ark::ArenaAllocator *allocator, - ir::ETSImportDeclaration *importDecl, parser::Program *program) +static ir::ClassDeclaration *GetOrCreateLazyImportObjectClass(ark::ArenaAllocator *allocator, parser::Program *program) { - auto checker = program->Checker()->AsETSChecker(); auto globalClass = program->GlobalClass(); - auto varbinder = checker->VarBinder()->AsETSBinder(); - auto sourceProgram = checker->SelectEntryOrExternalProgram(varbinder, importDecl->DeclPath()); - const std::string classNameStr = std::string(LAZY_IMPORT_OBJECT_SUFFIX) + sourceProgram->ModuleName().Mutf8(); + const std::string classNameStr = std::string(LAZY_IMPORT_OBJECT_PREFIX) + std::to_string(LazyImportsCount()++); const util::UString className(classNameStr, allocator); const auto nameView = className.View().Mutf8(); @@ -184,6 +186,7 @@ static checker::Type *CreateModuleObjectType(public_lib::Context *ctx, ir::ETSIm ImportNamespaceObjectTypeAddReExportType(ctx, program->VarBinder()->AsETSBinder(), importDecl, moduleObjectType); SetPropertiesForModuleObject(ctx, moduleObjectType, importPath, nullptr); moduleObjectType->AddObjectFlag(checker::ETSObjectFlags::LAZY_IMPORT_OBJECT); + moduleObjectType->AddObjectFlag(checker::ETSObjectFlags::GRADUAL); return moduleObjectType; } @@ -221,7 +224,7 @@ static void BuildLazyImportObject(public_lib::Context *ctx, ir::ETSImportDeclara return; } - auto *classDecl = GetOrCreateLazyImportObjectClass(allocator, importDecl, program); + auto *classDecl = GetOrCreateLazyImportObjectClass(allocator, program); FillVarMapForImportSpecifiers(importDecl->Specifiers(), classDecl->Definition(), varMap); const auto className = classDecl->Definition()->Ident()->Name(); @@ -234,10 +237,8 @@ static void BuildLazyImportObject(public_lib::Context *ctx, ir::ETSImportDeclara auto *objType = CreateModuleObjectType(ctx, importDecl)->AsETSObjectType(); moduleMap.insert({className, objType}); - auto moduleType = checker->CreateGradualType(objType, Language::Id::JS); - auto parser = ctx->parser->AsETSParser(); - auto *typeAnnotation = allocator->New(moduleType, allocator); + auto *typeAnnotation = allocator->New(objType, allocator); auto *classProp = parser->CreateFormattedClassFieldDefinition(std::string {FIELD_NAME} + ": @@T1", typeAnnotation) ->AsClassProperty(); typeAnnotation->SetParent(classProp); @@ -264,9 +265,10 @@ static void BuildLazyImportObject(public_lib::Context *ctx, ir::ETSImportDeclara classDecl->Check(checker); } -static ir::MemberExpression *CreateTripleMemberExpr(ArenaAllocator *allocator, const util::StringView &left, +static ir::MemberExpression *CreateTripleMemberExpr(public_lib::Context *ctx, const util::StringView &left, const util::StringView &middle, const util::StringView &right) { + auto allocator = ctx->allocator; auto *leftId = allocator->New(left, allocator); auto *middleId = allocator->New(middle, allocator); auto *expr = util::NodeAllocator::ForceSetParent( @@ -276,12 +278,25 @@ static ir::MemberExpression *CreateTripleMemberExpr(ArenaAllocator *allocator, c allocator, expr, rightId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); } +static bool IsInTypeExpressionPattern(ir::AstNode *node) +{ + while (node->IsIdentifier() || node->IsTSQualifiedName() || node->IsETSTypeReferencePart()) { + node = node->Parent(); + } + if (!node->IsETSTypeReference()) { + return true; + } + node = node->Parent(); + return node->IsETSNewClassInstanceExpression() || + (node->IsBinaryExpression() && + node->AsBinaryExpression()->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF); +} + static AstNodePtr TransformIdentifier(ir::Identifier *ident, public_lib::Context *ctx, const ArenaUnorderedMap &varMap) { auto checker = ctx->GetChecker()->AsETSChecker(); auto varBinder = checker->VarBinder()->AsETSBinder(); - auto allocator = checker->ProgramAllocator(); if (ident->Variable()->Declaration() != nullptr && ident->Variable()->Declaration()->Node() != nullptr && (ident->Variable()->Declaration()->Node()->IsImportNamespaceSpecifier() || ident->Variable()->Declaration()->Node()->IsImportDefaultSpecifier())) { @@ -301,9 +316,12 @@ static AstNodePtr TransformIdentifier(ir::Identifier *ident, public_lib::Context if (varIt == varMap.end()) { return ident; } + if (!IsInTypeExpressionPattern(ident)) { + return ident; + } auto *memberExpr = - CreateTripleMemberExpr(allocator, varIt->second->Ident()->Name(), FIELD_NAME, ident->Variable()->Name()); + CreateTripleMemberExpr(ctx, varIt->second->Ident()->Name(), FIELD_NAME, ident->Variable()->Name()); memberExpr->SetParent(parent); // Ensure that it will not be incorrectly converted to ArrowType. if (parent->IsCallExpression() && parent->AsCallExpression()->Callee() == ident) { @@ -313,8 +331,9 @@ static AstNodePtr TransformIdentifier(ir::Identifier *ident, public_lib::Context return memberExpr; } -AstNodePtr TransformTsQualifiedName(ir::TSQualifiedName *qualifiedName, public_lib::Context *ctx, - const ArenaUnorderedMap &varMap) +static AstNodePtr TransformTsQualifiedName( + ir::TSQualifiedName *qualifiedName, public_lib::Context *ctx, + const ArenaUnorderedMap &varMap) { auto checker = ctx->GetChecker()->AsETSChecker(); auto varBinder = checker->VarBinder()->AsETSBinder(); @@ -332,9 +351,13 @@ AstNodePtr TransformTsQualifiedName(ir::TSQualifiedName *qualifiedName, public_l if (varIt == varMap.end()) { return qualifiedName; } + if (!IsInTypeExpressionPattern(moduleId)) { + return moduleId; + } + const auto parent = qualifiedName->Parent(); auto *newIdent = allocator->New(qualifiedName->Right()->AsIdentifier()->Name(), allocator); - auto *memberExpr = CreateTripleMemberExpr(allocator, varIt->second->Ident()->Name(), FIELD_NAME, newIdent->Name()); + auto *memberExpr = CreateTripleMemberExpr(ctx, varIt->second->Ident()->Name(), FIELD_NAME, newIdent->Name()); memberExpr->SetParent(parent); // Ensure that it will not be incorrectly converted to ArrowType. if (parent->IsCallExpression() && parent->AsCallExpression()->Callee() == qualifiedName) { @@ -344,8 +367,9 @@ AstNodePtr TransformTsQualifiedName(ir::TSQualifiedName *qualifiedName, public_l return memberExpr; } -AstNodePtr TransformMemberExpression(ir::MemberExpression *memberExpr, public_lib::Context *ctx, - const ArenaUnorderedMap &varMap) +static AstNodePtr TransformMemberExpression( + ir::MemberExpression *memberExpr, public_lib::Context *ctx, + const ArenaUnorderedMap &varMap) { auto checker = ctx->GetChecker()->AsETSChecker(); auto varBinder = checker->VarBinder()->AsETSBinder(); @@ -364,7 +388,7 @@ AstNodePtr TransformMemberExpression(ir::MemberExpression *memberExpr, public_li } const auto parent = memberExpr->Parent(); auto *newIdent = allocator->New(memberExpr->Property()->AsIdentifier()->Name(), allocator); - auto *res = CreateTripleMemberExpr(allocator, varIt->second->Ident()->Name(), FIELD_NAME, newIdent->Name()); + auto *res = CreateTripleMemberExpr(ctx, varIt->second->Ident()->Name(), FIELD_NAME, newIdent->Name()); res->SetParent(parent); // Ensure that it will not be incorrectly converted to ArrowType. @@ -376,8 +400,51 @@ AstNodePtr TransformMemberExpression(ir::MemberExpression *memberExpr, public_li return res; } +static ir::AstNode *LowerDynamicObjectLiteralExpression(public_lib::Context *ctx, ir::ObjectExpression *objExpr) +{ + auto parser = ctx->parser->AsETSParser(); + auto checker = ctx->GetChecker()->AsETSChecker(); + auto varBinder = checker->VarBinder()->AsETSBinder(); + auto allocator = checker->ProgramAllocator(); + + ArenaVector blockStatements(allocator->Adapter()); + auto gensym = Gensym(allocator); + // NOTE(vpukhov): semantics should aligned with the static one + blockStatements.push_back(parser->CreateFormattedStatement( + "let @@I1 = ESValue.instantiateEmptyObject().unwrap() as @@T2;", gensym->Clone(allocator, nullptr), + allocator->New(checker->GlobalETSRelaxedAnyType(), allocator))); + + std::stringstream initStringSS; + std::vector initStringParams; + auto appendParameter = [&initStringParams](ir::AstNode *arg) { + initStringParams.push_back(arg); + return initStringParams.size(); + }; + + for (auto property : objExpr->Properties()) { + initStringSS << "@@I" << appendParameter(gensym->Clone(allocator, nullptr)) << "." + << property->AsProperty()->Key()->DumpEtsSrc() << "= @@E" + << appendParameter(property->AsProperty()->Value()) << ";"; + } + if (!objExpr->Properties().empty()) { + blockStatements.push_back(parser->CreateFormattedStatement(initStringSS.str(), initStringParams)); + } + blockStatements.push_back( + parser->CreateFormattedStatement("@@I1 as @@T2;", gensym->Clone(allocator, nullptr), + allocator->New(objExpr->TsType(), allocator))); + auto *blockExpr = util::NodeAllocator::ForceSetParent(allocator, std::move(blockStatements)); + blockExpr->SetParent(objExpr->Parent()); + CheckLoweredNode(varBinder, checker, blockExpr); + return blockExpr; +} + bool DynamicImport::PerformForModule(public_lib::Context *ctx, parser::Program *program) { + if (program == ctx->parserProgram && + ctx->config->options->GetCompilationMode() != CompilationMode::GEN_ABC_FOR_EXTERNAL_SOURCE) { + LazyImportsCount() = 0; + } + auto dynamicImports = program->VarBinder()->AsETSBinder()->DynamicImports(); if (dynamicImports.empty()) { return true; @@ -405,6 +472,21 @@ bool DynamicImport::PerformForModule(public_lib::Context *ctx, parser::Program * }, Name()); + program->Ast()->TransformChildrenRecursively( + [ctx](ir::AstNode *ast) -> AstNodePtr { + if (ast->IsObjectExpression()) { + auto *exprType = ast->AsObjectExpression()->TsType(); + if (exprType == nullptr || !exprType->IsETSObjectType()) { // broken AST invariants + return ast; + } + return exprType->AsETSObjectType()->IsGradual() + ? LowerDynamicObjectLiteralExpression(ctx, ast->AsObjectExpression()) + : ast; + } + return ast; + }, + Name()); + return true; } } // namespace ark::es2panda::compiler \ No newline at end of file diff --git a/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp b/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp deleted file mode 100644 index edb6d6935041acddfd5e82b2dd2ab426f33d4a53..0000000000000000000000000000000000000000 --- a/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "gradualTypeNarrowing.h" - -#include "checker/ETSchecker.h" -#include "checker/types/ets/etsTupleType.h" -#include "checker/types/gradualType.h" -#include "varbinder/ETSBinder.h" -#include "es2panda.h" -#include "ir/astNode.h" -#include "ir/opaqueTypeNode.h" -#include "ir/typed.h" -#include "util/language.h" - -namespace ark::es2panda::compiler { - -checker::Type *GradualTypeNarrowing::TransformType(checker::Type *type, - const std::function &func) -{ - if (type->IsETSFunctionType()) { - auto funcType = type->AsETSFunctionType(); - for (auto sig : funcType->CallSignaturesOfMethodOrArrow()) { - sig->SetReturnType(TransformType(sig->ReturnType(), func)); - for (auto var : sig->Params()) { - var->SetTsType(TransformType(var->TsType(), func)); - } - - if (sig->RestVar() != nullptr) { - sig->RestVar()->SetTsType(TransformType(sig->RestVar()->TsType(), func)); - } - } - } - - if (type->IsETSUnionType()) { - auto unionType = type->AsETSUnionType(); - ArenaVector types {checker_->ProgramAllocator()->Adapter()}; - for (auto ctype : unionType->ConstituentTypes()) { - types.push_back(TransformType(ctype, func)); - } - type = checker_->CreateETSUnionType(std::move(types)); - } - - if (type->IsETSArrayType()) { - auto arrayType = type->AsETSArrayType(); - arrayType->SetElementType(TransformType(arrayType->ElementType(), func)); - } - - if (type->IsETSResizableArrayType()) { - auto arrayType = type->AsETSResizableArrayType(); - arrayType->SetElementType(TransformType(arrayType->ElementType(), func)); - } - - if (type->IsETSTupleType()) { - auto tupleType = type->AsETSTupleType(); - ArenaVector types {checker_->ProgramAllocator()->Adapter()}; - for (auto ctype : tupleType->GetTupleTypesList()) { - types.push_back(TransformType(ctype, func)); - } - type = checker_->ProgramAllocator()->New(checker_, std::move(types)); - } - - return func(type); -} - -void GradualTypeNarrowing::NarrowGradualType(ir::AstNode *node) -{ - auto typedNode = node->AsTyped(); - auto typeTransformFunc = [this](checker::Type *type) -> checker::TypePtr { - if (type->IsGradualType() || (type->IsETSObjectType() && type->AsETSObjectType()->GetDeclNode() != nullptr && - type->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType() != nullptr && - type->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType()->IsGradualType())) { - return this->checker_->GlobalETSRelaxedAnyType(); - } - return type; - }; - - if (typedNode->TsType() != nullptr) { - typedNode->SetTsType(TransformType(typedNode->TsType(), typeTransformFunc)); - } - if (typedNode->IsBinaryExpression()) { - typedNode->AsBinaryExpression()->SetOperationType( - TransformType(typedNode->AsBinaryExpression()->OperationType(), typeTransformFunc)); - } - - auto var = node->Variable(); - if (var != nullptr && var->TsType() != nullptr) { - var->SetTsType(TransformType(var->TsType(), typeTransformFunc)); - } -} - -ir::AstNode *GradualTypeNarrowing::ProcessGradualTypeNode(ir::ETSTypeReference *node) -{ - auto type = node->GetType(checker_); - if (!type->IsGradualType()) { - return node; - } - - // Only narrow explicit type annotation of gradual to T or to Any - if (!node->Part()->Name()->IsIdentifier() || - !(node->Part()->Name()->AsIdentifier()->Name() == compiler::Signatures::GRADUAL_TYPE_NAME)) { - return node; - } - auto loweredNode = context_->AllocNode(checker_->GlobalETSAnyType(), context_->Allocator()); - loweredNode->SetRange(node->Range()); - loweredNode->SetParent(node->Parent()); - loweredNode->SetTsType(checker_->GlobalETSRelaxedAnyType()); - return loweredNode; -} - -bool GradualTypeNarrowing::PerformForModule(public_lib::Context *ctx, parser::Program *program) -{ - context_ = ctx; - checker_ = ctx->GetChecker()->AsETSChecker(); - - auto dynamicImports = program->VarBinder()->AsETSBinder()->DynamicImports(); - if (dynamicImports.empty()) { - return true; - } - - program->Ast()->TransformChildrenRecursively( - // CC-OFFNXT(G.FMT.14-CPP) project code style - [this](ir::AstNode *ast) -> checker::AstNodePtr { - if (ast->IsETSTypeReference()) { - return ProcessGradualTypeNode(ast->AsETSTypeReference()); - } - return ast; - }, - Name()); - - program->Ast()->IterateRecursively([this](ir::AstNode *ast) { - if (ast->IsTyped()) { - NarrowGradualType(ast); - } - }); - return true; -} -} // namespace ark::es2panda::compiler \ No newline at end of file diff --git a/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.h b/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.h deleted file mode 100644 index e4a09c4ab960a0760129e82eb57b03cb9ff406df..0000000000000000000000000000000000000000 --- a/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ES2PANDA_GRADUAL_TYPE_NARROWING_H -#define ES2PANDA_GRADUAL_TYPE_NARROWING_H - -#include "compiler/lowering/phase.h" -#include "ir/typeNode.h" - -namespace ark::es2panda::compiler { - -class GradualTypeNarrowing : public PhaseForBodies { -public: - std::string_view Name() const override - { - return "GradualTypeNarrowing"; - } - - bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; - -private: - checker::Type *TransformType(checker::Type *type, const std::function &func); - void NarrowGradualType(ir::AstNode *node); - ir::AstNode *ProcessGradualTypeNode(ir::ETSTypeReference *node); - - public_lib::Context *context_ {nullptr}; - checker::ETSChecker *checker_ {nullptr}; -}; -} // namespace ark::es2panda::compiler - -#endif \ No newline at end of file diff --git a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp index 7a4a9db9dda99a3d44b33cfd1cd3a90203fe0ad6..ee5076286e62c273e3b2ac5adc30c5b076c034a2 100644 --- a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp @@ -36,13 +36,13 @@ std::string_view InterfaceObjectLiteralLowering::Name() const static inline bool IsInterfaceType(const checker::Type *type) { return type != nullptr && type->IsETSObjectType() && - type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::INTERFACE) && !type->IsGradualType(); + type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::INTERFACE); } static inline bool IsAbstractClassType(const checker::Type *type) { return type != nullptr && type->IsETSObjectType() && - type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT) && !type->IsGradualType(); + type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT); } static ir::AstNode *CreateAnonClassImplCtor(public_lib::Context *ctx, ArenaVector &readonlyFields) @@ -238,7 +238,7 @@ static void GenerateAnonClassTypeFromInterface(public_lib::Context *ctx, ir::TSI auto *classDecl = checker->BuildClass(anonClassName.View(), classBodyBuilder); RefineSourceRanges(classDecl); auto *classDef = classDecl->Definition(); - auto *classType = classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + auto *classType = classDef->TsType()->AsETSObjectType(); classDef->SetAnonymousModifier(); classDecl->SetRange(ifaceNode->Range()); @@ -297,7 +297,7 @@ static void GenerateAnonClassTypeFromAbstractClass(public_lib::Context *ctx, ir: } RefineSourceRanges(classDecl); auto *classDef = classDecl->Definition(); - if (classDef->TsType()->IsGradualType()) { + if (classDef->TsType()->AsETSObjectType()->IsGradual()) { return; } auto *classType = classDef->TsType()->AsETSObjectType(); @@ -391,7 +391,7 @@ static void HandleInterfaceLowering(public_lib::Context *ctx, ir::ObjectExpressi static bool CheckInterfaceShouldGenerateAnonClass(ir::TSInterfaceDeclaration *interfaceDecl) { - if (interfaceDecl->TsType() != nullptr && interfaceDecl->TsType()->IsGradualType()) { + if (interfaceDecl->TsType() != nullptr && interfaceDecl->TsType()->AsETSObjectType()->IsGradual()) { return false; } for (auto it : interfaceDecl->Body()->Body()) { @@ -432,7 +432,8 @@ static void TransfromInterfaceDecl(public_lib::Context *ctx, parser::Program *pr if (ast->IsTSInterfaceDeclaration() && CheckInterfaceShouldGenerateAnonClass(ast->AsTSInterfaceDeclaration())) { GenerateAnonClassTypeFromInterface(ctx, ast->AsTSInterfaceDeclaration()); } else if (ast->IsClassDefinition() && ast != program->GlobalClass() && - ast->AsClassDefinition()->IsAbstract() && !ast->AsClassDefinition()->TsType()->IsGradualType() && + ast->AsClassDefinition()->IsAbstract() && + !ast->AsClassDefinition()->TsType()->AsETSObjectType()->IsGradual() && CheckAbstractClassShouldGenerateAnonClass(ast->AsClassDefinition())) { GenerateAnonClassTypeFromAbstractClass(ctx, ast->AsClassDefinition()); } @@ -447,7 +448,7 @@ static void TransfromInterfaceLiteral(public_lib::Context *ctx, parser::Program } auto objExpr = ast->AsObjectExpression(); if ((IsInterfaceType(objExpr->TsType()) || IsAbstractClassType(objExpr->TsType())) && - !objExpr->TsType()->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType()->IsGradualType()) { + !objExpr->TsType()->AsETSObjectType()->IsGradual()) { HandleInterfaceLowering(ctx, ast->AsObjectExpression()); } }); diff --git a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp index 16d194cd48bef0f4c9aac06486e5f1c41323d4f1..bfe3da4967cc6f31694a9c3854d69bbf638bc42c 100644 --- a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp +++ b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp @@ -79,8 +79,7 @@ static ir::AstNode *ProcessIndexGetAccess(public_lib::Context *ctx, ir::MemberEx bool ObjectIndexLowering::PerformForModule(public_lib::Context *ctx, parser::Program *program) { const auto isGetSetExpression = [](const ir::MemberExpression *const memberExpr) { - return memberExpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS && memberExpr->ObjType() != nullptr && - !memberExpr->Object()->TsType()->IsGradualType(); + return memberExpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS && memberExpr->ObjType() != nullptr; }; program->Ast()->TransformChildrenRecursively( @@ -114,10 +113,9 @@ bool ObjectIndexLowering::PostconditionForModule([[maybe_unused]] public_lib::Co const parser::Program *program) { return !program->Ast()->IsAnyChild([](const ir::AstNode *ast) { - if (ast->IsMemberExpression()) { - const auto *const memberExpr = ast->AsMemberExpression(); - if (memberExpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS && memberExpr->ObjType() != nullptr && - !memberExpr->Object()->TsType()->IsGradualType()) { + if (ast->IsMemberExpression() && + ast->AsMemberExpression()->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS) { + if (auto const *const objectType = ast->AsMemberExpression()->ObjType(); objectType != nullptr) { return true; } } diff --git a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp index a899908b80b42d70310d2c1488be2cbfbd1340e8..44908b804d152f93995b8784e68c7581690b6096 100644 --- a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp @@ -300,42 +300,6 @@ static ir::AstNode *HandleObjectLiteralLowering(public_lib::Context *ctx, ir::Ob return loweringResult; } -static ir::AstNode *HandleDynamicObjectLiteralLowering(public_lib::Context *ctx, ir::ObjectExpression *objExpr) -{ - auto parser = ctx->parser->AsETSParser(); - auto checker = ctx->GetChecker()->AsETSChecker(); - auto varBinder = checker->VarBinder()->AsETSBinder(); - auto allocator = checker->ProgramAllocator(); - - std::stringstream ss; - ArenaVector blockStatements(allocator->Adapter()); - std::vector args; - auto gensym = Gensym(allocator); - blockStatements.push_back(parser->CreateFormattedStatement("let @@I1:ESValue = ESValue.instantiateEmptyObject();", - gensym->Clone(allocator, nullptr))); - size_t counter = 0; - for (auto property : objExpr->Properties()) { - auto appendArgument = [&](auto &&arg) { - args.push_back(std::forward(arg)); - return ++counter; - }; - - const size_t genSymId = appendArgument(gensym->Clone(allocator, nullptr)); - const size_t valueId = appendArgument(property->AsProperty()->Value()); - - ss << "@@I" << genSymId << ".setProperty('" << property->AsProperty()->Key()->DumpEtsSrc() - << "', ESValue.wrap(@@E" << valueId << "));"; - } - if (!objExpr->Properties().empty()) { - blockStatements.push_back(parser->CreateFormattedStatement(ss.str(), args)); - } - blockStatements.push_back(parser->CreateFormattedStatement("@@I1.unwrap();", gensym->Clone(allocator, nullptr))); - auto *blockExpr = util::NodeAllocator::ForceSetParent(allocator, std::move(blockStatements)); - blockExpr->SetParent(objExpr->Parent()); - CheckLoweredNode(varBinder, checker, blockExpr); - return blockExpr; -} - bool ObjectLiteralLowering::PerformForModule(public_lib::Context *ctx, parser::Program *program) { program->Ast()->TransformChildrenRecursively( @@ -348,9 +312,7 @@ bool ObjectLiteralLowering::PerformForModule(public_lib::Context *ctx, parser::P return ast; } if (exprType->IsETSObjectType()) { - return exprType->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType()->IsGradualType() - ? HandleDynamicObjectLiteralLowering(ctx, ast->AsObjectExpression()) - : HandleObjectLiteralLowering(ctx, ast->AsObjectExpression()); + return HandleObjectLiteralLowering(ctx, ast->AsObjectExpression()); } } return ast; diff --git a/ets2panda/compiler/lowering/ets/relaxedAnyLowering.cpp b/ets2panda/compiler/lowering/ets/relaxedAnyLowering.cpp index 78d661f3919288262311963853feb85035d9a3ff..45c06c1cec15a30aef3ae3a4a309806aa903d4c8 100644 --- a/ets2panda/compiler/lowering/ets/relaxedAnyLowering.cpp +++ b/ets2panda/compiler/lowering/ets/relaxedAnyLowering.cpp @@ -29,25 +29,40 @@ static bool IsLoweringCandidate(checker::ETSChecker *checker, checker::Type *typ if (type->IsETSMethodType() || type->IsETSExtensionFuncHelperType()) { return false; // synthetic types don't represent values } - if (type->IsGradualType()) { - return false; // should be removed after Gradual type refactoring + if (type->IsETSObjectType() && type->AsETSObjectType()->IsGradual()) { + return true; // enum-BaseEnum case } return type->IsETSAnyType() || !checker->Relation()->IsSupertypeOf(checker->GlobalETSUnionUndefinedNullObject(), type); } +static ir::Expression *InsertTypeGuard(public_lib::Context *ctx, checker::Type *type, ir::Expression *expr) +{ + auto checker = ctx->GetChecker()->AsETSChecker(); + auto allocator = ctx->Allocator(); + + if (type == nullptr || type->IsTypeError()) { // #29049: type errors should not appear here + return expr; + } + if (type->IsETSMethodType()) { // bug, should not be the case of gradual types + type = type->AsETSFunctionType()->MethodToArrow(checker); + } + if (checker->Relation()->IsIdenticalTo(type, checker->GlobalETSAnyType())) { + return expr; + } + return util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(type, allocator), false); +} + static ir::Expression *CreateIntrin(public_lib::Context *ctx, std::string_view id, checker::Type *type, ArenaVector &&args) { auto checker = ctx->GetChecker()->AsETSChecker(); auto allocator = ctx->Allocator(); - ir::Expression *result = util::NodeAllocator::ForceSetParent(allocator, id, std::move(args)); - if (type != nullptr && !type->IsTypeError() && // #29049: type errors should not appear here - !checker->Relation()->IsIdenticalTo(type, checker->GlobalETSAnyType())) { - result = util::NodeAllocator::ForceSetParent( - allocator, result, allocator->New(type, allocator), false); - } + auto result = InsertTypeGuard( + ctx, type, util::NodeAllocator::ForceSetParent(allocator, id, std::move(args))); + result->Check(checker); return result; } @@ -100,26 +115,83 @@ static ir::AstNode *TransformCallExpression(public_lib::Context *ctx, ir::CallEx auto checker = ctx->GetChecker()->AsETSChecker(); auto const callee = node->Callee(); - if (!IsLoweringCandidate(checker, callee->TsType())) { - return node; - } - - auto args = ArenaVector({}, ctx->Allocator()->Adapter()); - args.reserve(node->Arguments().size() + 2U); - if (callee->IsMemberExpression()) { + if (!IsLoweringCandidate(checker, callee->AsMemberExpression()->Object()->TsType())) { + return node; + } auto prop = callee->AsMemberExpression()->Property(); prop = callee->AsMemberExpression()->IsComputed() ? prop : IdentifierToLiteral(ctx, prop->AsIdentifier()); + + auto args = ArenaVector({}, ctx->Allocator()->Adapter()); + args.reserve(node->Arguments().size() + 2U); args.insert(args.end(), {callee->AsMemberExpression()->Object(), prop}); args.insert(args.end(), node->Arguments().begin(), node->Arguments().end()); return CreateIntrin(ctx, "anycallthis", node->TsType(), std::move(args)); } + if (!IsLoweringCandidate(checker, callee->TsType())) { + return node; + } + + auto args = ArenaVector({}, ctx->Allocator()->Adapter()); + args.reserve(node->Arguments().size() + 1U); args.insert(args.begin(), callee); args.insert(args.end(), node->Arguments().begin(), node->Arguments().end()); return CreateIntrin(ctx, "anycall", node->TsType(), std::move(args)); } +static ir::Expression *TransformTypeExpressionPattern(public_lib::Context *ctx, ir::Expression *expr) +{ + ir::Expression *typeref = expr->IsETSTypeReference() ? expr->AsETSTypeReference()->Part()->Name() : expr; + + std::vector names; + while (typeref->IsTSQualifiedName()) { + names.push_back(typeref->AsTSQualifiedName()->Right()); + typeref = typeref->AsTSQualifiedName()->Left(); + } + names.push_back(typeref->AsMemberExpression()->Property()->AsIdentifier()); + + ir::Expression *val = typeref->AsMemberExpression()->Object(); + for (auto it = names.rbegin(); it != names.rend(); ++it) { + val = CreateIntrin(ctx, "anyldbyname", nullptr, val, IdentifierToLiteral(ctx, *it)); + } + return val; +} + +static bool IsTypeExpressionType(checker::Type *type) +{ + return type->IsETSObjectType(); +} + +static ir::AstNode *TransformNewExpression(public_lib::Context *ctx, ir::ETSNewClassInstanceExpression *node) +{ + auto checker = ctx->GetChecker()->AsETSChecker(); + + auto const typeNode = node->GetTypeRef(); + if (!IsLoweringCandidate(checker, typeNode->TsType()) || !IsTypeExpressionType(typeNode->TsType())) { + return node; + } + + auto args = ArenaVector({}, ctx->Allocator()->Adapter()); + args.reserve(node->GetArguments().size() + 2U); + + args.insert(args.begin(), TransformTypeExpressionPattern(ctx, typeNode)); + args.insert(args.end(), node->GetArguments().begin(), node->GetArguments().end()); + return CreateIntrin(ctx, "anycallnew", node->TsType(), std::move(args)); +} + +static ir::AstNode *TransformInstanceofExpression(public_lib::Context *ctx, ir::BinaryExpression *node) +{ + ES2PANDA_ASSERT(node->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF); + auto checker = ctx->GetChecker()->AsETSChecker(); + + auto const typeNode = node->Right(); + if (!IsLoweringCandidate(checker, typeNode->TsType()) || !IsTypeExpressionType(typeNode->TsType())) { + return node; + } + return CreateIntrin(ctx, "anyisinstance", nullptr, node->Left(), TransformTypeExpressionPattern(ctx, typeNode)); +} + static ir::AstNode *LowerOperationIfNeeded(public_lib::Context *ctx, ir::AstNode *node) { auto const setParent = [node](ir::AstNode *res) { @@ -129,6 +201,12 @@ static ir::AstNode *LowerOperationIfNeeded(public_lib::Context *ctx, ir::AstNode return res; }; + if (node->IsETSNewClassInstanceExpression()) { + return setParent(TransformNewExpression(ctx, node->AsETSNewClassInstanceExpression())); + } + if (node->IsBinaryExpression() && node->AsBinaryExpression()->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF) { + return setParent(TransformInstanceofExpression(ctx, node->AsBinaryExpression())); + } if (node->IsCallExpression()) { return setParent(TransformCallExpression(ctx, node->AsCallExpression())); } diff --git a/ets2panda/compiler/lowering/ets/setterLowering.cpp b/ets2panda/compiler/lowering/ets/setterLowering.cpp index 50f2d01a2c3b19e2b987d947ed4d9a4e30032d4b..581e89696ed410653a571d36674b17798dc57fa7 100644 --- a/ets2panda/compiler/lowering/ets/setterLowering.cpp +++ b/ets2panda/compiler/lowering/ets/setterLowering.cpp @@ -53,7 +53,7 @@ static bool IsSetterCallOrSetExpression(const ir::Expression *const expr) // set expressions, but not get expressions const auto isSetExpression = [](const ir::MemberExpression *const possibleSetExpr) { return possibleSetExpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS && - possibleSetExpr->ObjType() != nullptr && !possibleSetExpr->Object()->TsType()->IsGradualType(); + possibleSetExpr->ObjType() != nullptr; }; return isSetExpression(memberExpr); diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 1fd456e7849dbcdf8a0699f4213d31afedc101d8..1ba5618ea9e3791934b5ad407f30ee315bc008e3 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -42,7 +42,6 @@ #include "compiler/lowering/ets/expressionLambdaLowering.h" #include "compiler/lowering/ets/extensionAccessorLowering.h" #include "compiler/lowering/ets/genericBridgesLowering.h" -#include "compiler/lowering/ets/gradualTypeNarrowing.h" #include "compiler/lowering/ets/insertOptionalParametersAnnotation.h" #include "compiler/lowering/ets/interfaceObjectLiteralLowering.h" #include "compiler/lowering/ets/interfacePropertyDeclarations.h" @@ -164,7 +163,6 @@ std::vector GetETSPhaseList() new OptionalArgumentsLowering, // #22952 could be moved to earlier phase new GenericBridgesPhase, new TypeFromLowering, - new GradualTypeNarrowing, new PrimitiveConversionPhase, new UnboxPhase, // pluginsAfterLowerings has to come at the very end, nothing should go after it diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index f4326fe372f78483d5e26acb2ad6a71b34e10afb..088e6902c3b340ef3af2a859321d0d8a39981496 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -19,7 +19,6 @@ #include "ir/expressions/identifier.h" #include "checker/checker.h" #include "checker/ETSAnalyzer.h" -#include "checker/types/gradualType.h" #include "parser/JsdocHelper.h" namespace ark::es2panda::compiler { @@ -377,11 +376,8 @@ void CheckLoweredNode(varbinder::ETSBinder *varBinder, checker::ETSChecker *chec newStatus |= checker::CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK; } - auto classType = containingClass == nullptr ? nullptr - : containingClass->TsType()->IsGradualType() - ? containingClass->TsType()->AsGradualType()->GetBaseType()->AsETSObjectType() - : containingClass->TsType()->AsETSObjectType(); - auto checkerCtx = checker::SavedCheckerContext(checker, newStatus, classType); + auto checkerCtx = checker::SavedCheckerContext( + checker, newStatus, containingClass == nullptr ? nullptr : containingClass->TsType()->AsETSObjectType()); auto scopeCtx = checker::ScopeContext(checker, scope); node->Check(checker); diff --git a/ets2panda/ir/ets/etsIntrinsicNode.cpp b/ets2panda/ir/ets/etsIntrinsicNode.cpp index 9024106ab3d9fe693127fbfa675a62341b23a60b..82944360eb56d240c4070ac3267b852246a0f105 100644 --- a/ets2panda/ir/ets/etsIntrinsicNode.cpp +++ b/ets2panda/ir/ets/etsIntrinsicNode.cpp @@ -468,6 +468,38 @@ public: } }; +class ETSIntrinsicAnyCallNew final : public EtsIntrinsicInfo { +public: + util::StringView Name() const override + { + return "anycallnew"; + } + + checker::Type *Check(checker::ETSChecker *checker, ETSIntrinsicNode *intrin) const override + { + CheckParams(checker, intrin); + if (intrin->Arguments().size() < 1U) { + return InvalidateIntrinsic(checker, intrin); + } + return intrin->SetTsType(checker->GlobalETSAnyType()); + } + + void CompileImpl(compiler::ETSGen *etsg, ETSIntrinsicNode const *intrin) const override + { + auto const [callee] = Args<1U>(intrin); + auto args = + Span {intrin->Arguments().data(), intrin->Arguments().size()}.SubSpan(1); + + compiler::RegScope rs(etsg); + auto const calleeReg = etsg->AllocReg(); + + callee->Compile(etsg); + etsg->StoreAccumulator(intrin, calleeReg); + + etsg->CallAnyNew(intrin, args, calleeReg); + } +}; + class ETSIntrinsicAnyCallThis final : public EtsIntrinsicInfo { public: util::StringView Name() const override @@ -522,12 +554,16 @@ public: compiler::RegScope rs(etsg); auto const objReg = etsg->AllocReg(); + auto const typeReg = etsg->AllocReg(); obj->Compile(etsg); etsg->StoreAccumulator(intrin, objReg); type->Compile(etsg); - etsg->EmitAnyIsinstance(intrin, objReg); + etsg->StoreAccumulator(intrin, typeReg); + + etsg->LoadAccumulator(intrin, objReg); + etsg->EmitAnyIsinstance(intrin, typeReg); } }; @@ -550,6 +586,7 @@ EtsIntrinsicInfo::InfosMap EtsIntrinsicInfo::InitIntrinsicInfos() registerIntrin(std::make_unique()); registerIntrin(std::make_unique()); registerIntrin(std::make_unique()); + registerIntrin(std::make_unique()); registerIntrin(std::make_unique()); registerIntrin(std::make_unique()); return infos; diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index fb40b130edcf5cd68f3a806b2dda6263a7aed827..0c0ba03bf0c70adf557f798ec5730076bc938437 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -242,20 +242,6 @@ checker::Type *ETSTypeReferencePart::HandleInternalTypes(checker::ETSChecker *co return nullptr; } -checker::Type *ETSTypeReferencePart::HandlerResultType(checker::ETSChecker *checker, checker::Type *baseType) -{ - if (checker->IsDeclForDynamicStaticInterop() && baseType->IsETSTypeParameter()) { - return checker->CreateGradualType(baseType); - } - if (baseType->IsGradualType()) { - return checker->CreateGradualType(HandlerResultType(checker, baseType->MaybeBaseTypeOfGradualType())); - } - if (baseType->IsETSObjectType()) { - checker::InstantiationContext ctx(checker, baseType->AsETSObjectType(), TypeParams(), Start()); - return ctx.Result(); - } - return baseType; -} checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) { @@ -276,7 +262,12 @@ checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) if (TsType() == nullptr) { checker::Type *baseType = checker->GetReferencedTypeBase(name); ES2PANDA_ASSERT(baseType != nullptr); - SetTsType(HandlerResultType(checker, baseType)); + if (baseType->IsETSObjectType()) { + checker::InstantiationContext ctx(checker, baseType->AsETSObjectType(), TypeParams(), Start()); + SetTsType(ctx.Result()); + } else { + SetTsType(baseType); + } } } else { checker::Type *baseType = Previous()->GetType(checker); diff --git a/ets2panda/ir/ets/etsTypeReferencePart.h b/ets2panda/ir/ets/etsTypeReferencePart.h index 40af6ab2b6e6690d97ee297a0d4452ca6e3f6c9b..9fe657e9302608ebbc02c8b032041c5127466597 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.h +++ b/ets2panda/ir/ets/etsTypeReferencePart.h @@ -95,7 +95,6 @@ public: void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; checker::VerifiedType Check(checker::ETSChecker *checker) override; - checker::Type *HandlerResultType(checker::ETSChecker *checker, checker::Type *baseType); checker::Type *GetType([[maybe_unused]] checker::ETSChecker *checker) override; ir::Identifier *GetIdent(); diff --git a/ets2panda/ir/expressions/callExpression.cpp b/ets2panda/ir/expressions/callExpression.cpp index 4be13e81f78eadcac19dd71382540f7e53d3a6fb..51a4a751d18c87986f245ca0095bfda1015b4edf 100644 --- a/ets2panda/ir/expressions/callExpression.cpp +++ b/ets2panda/ir/expressions/callExpression.cpp @@ -187,11 +187,4 @@ bool CallExpression::IsExtensionAccessorCall() return (Signature() != nullptr) && (Signature()->Function()->IsExtensionAccessor()); } -bool CallExpression::IsDynamicCall() const noexcept -{ - return Callee()->IsMemberExpression() && Callee()->AsMemberExpression()->PropVar() != nullptr && - (Callee()->AsMemberExpression()->Object()->TsType()->IsETSAnyType() || - Callee()->AsMemberExpression()->Object()->TsType()->IsGradualType()); -} - } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/expressions/callExpression.h b/ets2panda/ir/expressions/callExpression.h index d75f1a2426655aee660839cfce19bb3adc417715..7a273b79b0eaec7ccbd67dbc4073a7f00df5180e 100644 --- a/ets2panda/ir/expressions/callExpression.h +++ b/ets2panda/ir/expressions/callExpression.h @@ -166,8 +166,6 @@ public: return callee_->IsThisExpression() || callee_->IsSuperExpression(); } - bool IsDynamicCall() const noexcept; - [[nodiscard]] CallExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index 984599ecf5cd79eae996eb6d9ff3e15e95d1a98a..9bd788ce380e17b04d77aaabf94dca4f03ff28bf 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -482,31 +482,6 @@ static void CastTupleElementFromClassMemberType(checker::ETSChecker *checker, tupleElementAccessor->Start(), checker::TypeRelationFlag::NO_THROW}); } -checker::Type *MemberExpression::HandleComputedInGradualType(checker::ETSChecker *checker, checker::Type *baseType) -{ - property_->Check(checker); - if (baseType->IsETSObjectType()) { - util::StringView searchName; - if (property_->IsLiteral()) { - searchName = util::StringView {property_->AsLiteral()->ToString()}; - } - auto found = baseType->AsETSObjectType()->GetProperty(searchName, checker::PropertySearchFlags::SEARCH_ALL); - if (found == nullptr) { - // Try to find indexer method - checker::Type *indexType = CheckIndexAccessMethod(checker); - if (indexType != nullptr) { - return indexType; - } - checker->LogError(diagnostic::PROPERTY_NONEXISTENT, {searchName, baseType->AsETSObjectType()->Name()}, - property_->Start()); - return nullptr; - } - return found->TsType(); - } - ES2PANDA_UNREACHABLE(); - return nullptr; -} - checker::Type *MemberExpression::CheckComputed(checker::ETSChecker *checker, checker::Type *baseType) { if (baseType->IsETSRelaxedAnyType()) { @@ -514,13 +489,6 @@ checker::Type *MemberExpression::CheckComputed(checker::ETSChecker *checker, che return checker->GlobalETSRelaxedAnyType(); } - if (baseType->IsETSObjectType() && baseType->AsETSObjectType()->GetDeclNode() != nullptr && - baseType->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType() != nullptr && - baseType->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType()->IsGradualType()) { - SetObjectType(baseType->AsETSObjectType()); - return HandleComputedInGradualType(checker, baseType); - } - if (baseType->IsETSArrayType()) { auto *dflt = baseType->AsETSArrayType()->ElementType(); if (!checker->ValidateArrayIndex(property_)) { diff --git a/ets2panda/ir/expressions/memberExpression.h b/ets2panda/ir/expressions/memberExpression.h index 4c72e652feabf12e3d22dd1f36bbfe9ed09b86f7..4906dc35d2e626cb0f2167e051c71fd7247dcb8f 100644 --- a/ets2panda/ir/expressions/memberExpression.h +++ b/ets2panda/ir/expressions/memberExpression.h @@ -251,7 +251,6 @@ private: checker::Type *TraverseUnionMember(checker::ETSChecker *checker, checker::ETSUnionType *unionType); bool CheckArrayIndexValue(checker::ETSChecker *checker) const; - checker::Type *HandleComputedInGradualType(checker::ETSChecker *checker, checker::Type *baseType); checker::Type *CheckIndexAccessMethod(checker::ETSChecker *checker); checker::Type *ResolveReturnTypeFromSignature(checker::ETSChecker *checker, bool isSetter, ArenaVector &arguments, diff --git a/ets2panda/lsp/src/isolated_declaration.cpp b/ets2panda/lsp/src/isolated_declaration.cpp index 77f06d2da7ae35876a82c166d868c86a8942a97d..4b4e179d01adc92e2fece7d4f5e2dd90d3fb775f 100644 --- a/ets2panda/lsp/src/isolated_declaration.cpp +++ b/ets2panda/lsp/src/isolated_declaration.cpp @@ -214,7 +214,6 @@ std::optional HandleETSSpecificTypes(const checker::Type *checkerTy return checkerType->ToString(); case checker::TypeFlag::ETS_OBJECT: - case checker::TypeFlag::GRADUAL_TYPE: return HandleObjectType(checkerType, checker); case checker::TypeFlag::ETS_ARRAY: diff --git a/ets2panda/test/benchmarks/bench_1-max.txt b/ets2panda/test/benchmarks/bench_1-max.txt index 81e3099f82e7696cbb68e727ae0288f68b6eb4ce..7d80c6fbb753a65820a831ff419f5286fe23da0e 100644 --- a/ets2panda/test/benchmarks/bench_1-max.txt +++ b/ets2panda/test/benchmarks/bench_1-max.txt @@ -24,7 +24,6 @@ :@phases/InsertOptionalParametersAnnotation : time=17.38ms mem=0.74MB :@phases/AmbientLowering : time=17.22ms mem=0.00MB :@phases/ExpressionLambdaConstruction : time=17.15ms mem=0.00MB -:@phases/GradualTypeNarrowing : time=16.99ms mem=1.88MB :@phases/DefaultParametersInConstructorLowering : time=16.67ms mem=0.52MB :@phases/ObjectIndexLowering : time=3.65ms mem=0.71MB :@phases/CreateGenericBridges : time=3.36ms mem=0.00MB diff --git a/ets2panda/test/benchmarks/etsstdlib-max.txt b/ets2panda/test/benchmarks/etsstdlib-max.txt index ab8a25fbeba5dce556305e95ec236cb135547251..84cf0c190f1a972ae2e156019a0883818631be65 100644 --- a/ets2panda/test/benchmarks/etsstdlib-max.txt +++ b/ets2panda/test/benchmarks/etsstdlib-max.txt @@ -9,7 +9,6 @@ :@phases/ConstantExpressionLowering : time=363.29ms mem=0.28MB :@phases/LambdaObjectConversion : time=328.18ms mem=22.00MB :@phases/TopLevelStatements : time=277.34ms mem=83.00MB -:@phases/GradualTypeNarrowing : time=198.37ms mem=19.00MB :@phases/ResolveIdentifiers : time=123.95ms mem=5.13MB :@phases/OpAssignmentLowering : time=116.33ms mem=18.00MB :@phases/InterfaceObjectLiteralLowering : time=76.22ms mem=7.00MB diff --git a/ets2panda/test/unit/any_ins_test/CMakeLists.txt b/ets2panda/test/unit/any_ins_test/CMakeLists.txt index b41cb7c83f96c685476aeab6d72e7298d17fdc7e..03cb6d4c35c0d5e7192dc38103ef45c20560270c 100644 --- a/ets2panda/test/unit/any_ins_test/CMakeLists.txt +++ b/ets2panda/test/unit/any_ins_test/CMakeLists.txt @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - -ets2panda_add_gtest(any_ins_test - CPP_SOURCES any_ins_test.cpp -) +# 29387 +# ets2panda_add_gtest(any_ins_test +# CPP_SOURCES any_ins_test.cpp +# ) diff --git a/ets2panda/test/unit/dynamic/dynamic_call_test.cpp b/ets2panda/test/unit/dynamic/dynamic_call_test.cpp index 6adab4bdb4eaf0428ffe92f575d89453feb327fd..259a8d67923d8628bfb40e23572b7f1f43bc5c93 100644 --- a/ets2panda/test/unit/dynamic/dynamic_call_test.cpp +++ b/ets2panda/test/unit/dynamic/dynamic_call_test.cpp @@ -160,27 +160,6 @@ TEST_F(DynamicCall, JoinDynCallMember) AssertNameEq(callName, {"c", "d"}); } -TEST_F(DynamicCall, JoinDynStaticCallMember) -{ - auto strExpr = "A.b.c.d.e()"; - auto [program, obj, first] = ParseDynExpr(strExpr); - - auto bObj = obj->AsMemberExpression()->Object()->AsMemberExpression()->Object(); - ASSERT_EQ(bObj->AsMemberExpression()->Property()->AsIdentifier()->Name(), "c"); - auto staticType = - Allocator()->New(Allocator(), "", "", nullptr, checker::ETSObjectFlags::NO_OPTS); - bObj->AsMemberExpression()->Object()->SetTsType(staticType); - - auto [squeezedObj, name] = checker::DynamicCall::SqueezeExpr(Allocator(), obj->AsMemberExpression()); - AssertNameEq(name, {"d", "e"}); - ASSERT_EQ(squeezedObj, bObj); - - auto varbinder = program->VarBinder()->AsETSBinder(); - AddDynImport("A", varbinder, first->AsIdentifier()); - auto [finalObj, callName] = checker::DynamicCall::ResolveCall(varbinder, obj); - AssertNameEq(callName, {"d", "e"}); -} - TEST_F(DynamicCall, TsQualifiedName) { auto strExpr = "new A.b.c.d()";