diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index c4886adedc621a9df388f1d15361cad5a8c333ed..0a418ecf30dc060364de4119a4223cc3b877f2b1 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -209,7 +209,6 @@ libes2panda_sources = [ "compiler/lowering/ets/boxingForLocals.cpp", "compiler/lowering/ets/capturedVariables.cpp", "compiler/lowering/ets/cfgBuilderPhase.cpp", - "compiler/lowering/ets/constStringToCharLowering.cpp", "compiler/lowering/ets/constantExpressionLowering.cpp", "compiler/lowering/ets/declareOverloadLowering.cpp", "compiler/lowering/ets/defaultParametersInConstructorLowering.cpp", @@ -217,6 +216,7 @@ libes2panda_sources = [ "compiler/lowering/ets/dynamicImportLowering.cpp", "compiler/lowering/ets/enumLowering.cpp", "compiler/lowering/ets/enumPostCheckLowering.cpp", + "compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp", "compiler/lowering/ets/expandBrackets.cpp", "compiler/lowering/ets/expressionLambdaLowering.cpp", "compiler/lowering/ets/extensionAccessorLowering.cpp", @@ -248,6 +248,7 @@ libes2panda_sources = [ "compiler/lowering/ets/topLevelStmts/importExportDecls.cpp", "compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp", "compiler/lowering/ets/typeFromLowering.cpp", + "compiler/lowering/ets/unboxLowering.cpp", "compiler/lowering/ets/unionLowering.cpp", "compiler/lowering/phase.cpp", "compiler/lowering/plugin_phase.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index b4a4c0c06b73873ec47fd9dabdcbe518b9ad1974..08ba487893db25f1c87ae5f07bac8c34931671d9 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -274,7 +274,6 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/ambientLowering.cpp compiler/lowering/ets/asyncMethodLowering.cpp compiler/lowering/ets/bigintLowering.cpp - compiler/lowering/ets/constStringToCharLowering.cpp compiler/lowering/ets/recordLowering.cpp compiler/lowering/ets/resizableArrayLowering.cpp compiler/lowering/ets/restArgsLowering.cpp @@ -293,7 +292,9 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/typeFromLowering.cpp compiler/lowering/ets/enumLowering.cpp compiler/lowering/ets/enumPostCheckLowering.cpp + compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp compiler/lowering/ets/setJumpTarget.cpp + compiler/lowering/ets/unboxLowering.cpp ir/astDump.cpp ir/srcDump.cpp ir/astNode.cpp diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 65b83520da3abbcd620558c3ab298e998563f9d8..dcf6d5b49bb661a8a106ea99b474615fe11fa5e3 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1018,7 +1018,7 @@ checker::Type *ETSAnalyzer::GetSmartType(ir::AssignmentExpression *expr, checker if (expr->Left()->IsIdentifier() && expr->Target() != nullptr) { // Now try to define the actual type of Identifier so that smart cast can be used in further checker // processing - smartType = checker->ResolveSmartType(rightType, leftType); + smartType = checker->ResolveSmartType(rightType, leftType, expr->Right()->IsLiteral()); auto const *const variable = expr->Target(); // Add/Remove/Modify smart cast for identifier @@ -1488,6 +1488,45 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const return expr->TsType(); } +static bool IsNumericType(ETSChecker *checker, Type *type) +{ + return checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), type); +} + +static Type *BiggerNumericType(ETSChecker *checker, Type *t1, Type *t2) +{ + ES2PANDA_ASSERT(IsNumericType(checker, t1)); + ES2PANDA_ASSERT(IsNumericType(checker, t2)); + + auto *rel = checker->Relation(); + + if (rel->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), t2)) { + return checker->GlobalDoubleBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalFloatBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalFloatBuiltinType(), t2)) { + return checker->GlobalFloatBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalLongBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalLongBuiltinType(), t2)) { + return checker->GlobalLongBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalIntBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalIntBuiltinType(), t2)) { + return checker->GlobalIntBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalShortBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalShortBuiltinType(), t2)) { + return checker->GlobalShortBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalByteBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalByteBuiltinType(), t2)) { + return checker->GlobalByteBuiltinType(); + } + ES2PANDA_UNREACHABLE(); +} + checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const { if (expr->TsType() != nullptr) { @@ -1525,21 +1564,10 @@ checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const if (checker->IsTypeIdenticalTo(consequentType, alternateType)) { expr->SetTsType(checker->GetNonConstantType(consequentType)); + } else if (IsNumericType(GetETSChecker(), consequentType) && IsNumericType(GetETSChecker(), alternateType)) { + expr->SetTsType(BiggerNumericType(GetETSChecker(), consequentType, alternateType)); } else { - // If possible and required update number literal type to the proper value (identical to left-side type) - if (alternate->IsNumberLiteral() && - checker->AdjustNumberLiteralType(alternate->AsNumberLiteral(), alternateType, consequentType)) { - expr->SetTsType(consequentType); - } else if (consequent->IsNumberLiteral() && - checker->AdjustNumberLiteralType(consequent->AsNumberLiteral(), consequentType, alternateType)) { - expr->SetTsType(alternateType); - } else { - expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType})); - if (expr->TsType()->IsETSReferenceType()) { - checker->MaybeBoxExpression(expr->Consequent()); - checker->MaybeBoxExpression(expr->Alternate()); - } - } + expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType})); } return expr->TsType(); @@ -1646,7 +1674,7 @@ checker::Type *ETSAnalyzer::ResolveMemberExpressionByBaseType(ETSChecker *checke if (baseType->IsETSArrayType()) { if (expr->Property()->AsIdentifier()->Name().Is("length")) { - return expr->AdjustType(checker, checker->GlobalIntType()); + return expr->AdjustType(checker, checker->GlobalIntBuiltinType()); } return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); @@ -2056,8 +2084,6 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const auto argType = expr->argument_->Check(checker); const auto isCondExpr = expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(argType, true, true, isCondExpr); - auto unboxedOperandType = - isCondExpr ? checker->MaybeUnboxConditionalInRelation(argType) : checker->MaybeUnboxInRelation(argType); if (argType != nullptr && argType->IsETSBigIntType() && argType->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL)) { switch (expr->OperatorType()) { @@ -2090,11 +2116,6 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const } } - if ((argType != nullptr) && argType->IsETSObjectType() && (unboxedOperandType != nullptr) && - unboxedOperandType->IsETSPrimitiveType()) { - expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedOperandType)); - } - SetTsTypeForUnaryExpression(checker, expr, operandType); checker->Context().CheckUnarySmartCastCondition(expr); @@ -2146,11 +2167,6 @@ checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const return expr->SetTsType(checker->GlobalTypeError()); } - if (operandType->IsETSObjectType()) { - expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedType) | - checker->GetBoxingFlag(unboxedType)); - } - return expr->SetTsType(operandType); } @@ -2166,7 +2182,9 @@ checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - expr->SetTsType(checker->CreateETSBooleanType(expr->Value())); + auto type = checker->GlobalETSBooleanBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); } return expr->TsType(); } @@ -2175,7 +2193,9 @@ checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - expr->SetTsType(checker->Allocator()->New(expr->Char())); + auto type = checker->GlobalCharBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); } return expr->TsType(); } @@ -2192,23 +2212,52 @@ checker::Type *ETSAnalyzer::Check(ir::NullLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const { ETSChecker *checker = GetETSChecker(); + if (expr->TsType() != nullptr) { + return expr->TsType(); + } if (expr->Number().IsInt()) { - expr->SetTsType(checker->CreateIntType(expr->Number().GetInt())); + auto type = checker->GlobalIntBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); return expr->TsType(); } if (expr->Number().IsLong()) { - expr->SetTsType(checker->CreateLongType(expr->Number().GetLong())); + auto type = checker->GlobalLongBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); return expr->TsType(); } if (expr->Number().IsFloat()) { - expr->SetTsType(checker->CreateFloatType(expr->Number().GetFloat())); + auto type = checker->GlobalFloatBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); return expr->TsType(); } - expr->SetTsType(checker->CreateDoubleType(expr->Number().GetDouble())); - return expr->TsType(); + if (expr->Number().IsDouble()) { + auto type = checker->GlobalDoubleBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); + return expr->TsType(); + } + + if (expr->Number().IsShort()) { + auto type = checker->GlobalShortBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); + return expr->TsType(); + } + + if (expr->Number().IsByte()) { + auto type = checker->GlobalByteBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); + return expr->TsType(); + } + + return checker->GlobalTypeError(); } checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const @@ -2366,6 +2415,21 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const return ReturnTypeForStatement(st); } +static void ProcessRequiredFields(ArenaUnorderedMap &fieldMap, + ir::AnnotationUsage *st, ETSChecker *checker) +{ + for (const auto &entry : fieldMap) { + if (entry.second->Value() == nullptr) { + checker->LogError(diagnostic::ANNOT_FIELD_NO_VAL, {entry.first}, st->Start()); + continue; + } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto *clone = entry.second->Clone(checker->Allocator(), st); + st->AddProperty(clone); + clone->Check(checker); + } +} + checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const { if (st->Expr()->TsType() != nullptr) { @@ -2401,7 +2465,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const checker->CheckMultiplePropertiesAnnotation(st, st->GetBaseName()->Name(), fieldMap); } - checker->ProcessRequiredFields(fieldMap, st, checker); + ProcessRequiredFields(fieldMap, st, checker); return ReturnTypeForStatement(st); } @@ -2463,7 +2527,7 @@ static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, relation->SetNode(ident); if (auto ctx = checker::AssignmentContext(checker->Relation(), ident, elemType, iterType, ident->Start(), std::nullopt, TypeRelationFlag::NO_THROW); - !ctx.IsAssignable()) { + !ctx.IsAssignable() && !relation->IsLegalBoxedPrimitiveConversion(iterType, elemType)) { checker->LogError(diagnostic::ITERATOR_ELEMENT_TYPE_MISMATCH, {elemType, iterType}, st->Start()); return false; } @@ -2474,7 +2538,7 @@ static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, const auto variable = ident->Variable(); if (variable != nullptr) { // Set smart type for variable of 'for-of' statement - const auto smartType = checker->ResolveSmartType(elemType, variable->TsType()); + const auto smartType = checker->ResolveSmartType(elemType, variable->TsType(), false); checker->Context().SetSmartCast(variable, smartType); } @@ -2769,6 +2833,7 @@ checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const checker::TypeRelationFlag::NONE); auto *comparedExprType = checker->CheckSwitchDiscriminant(st->Discriminant()); + // may have no meaning to unbox comparedExprType auto unboxedDiscType = (st->Discriminant()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U ? checker->MaybeUnboxInRelation(comparedExprType) : comparedExprType; @@ -2895,7 +2960,7 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const // NOTE: T_S and K_o_t_l_i_n don't act in such way, but we can try - why not? :) auto *smartType = variableType; if (auto *const initType = st->Init() != nullptr ? st->Init()->TsType() : nullptr; initType != nullptr) { - smartType = checker->ResolveSmartType(initType, variableType); + smartType = checker->ResolveSmartType(initType, variableType, st->Init()->IsLiteral()); // Set smart type for identifier if it differs from annotated type // Top-level and captured variables are not processed here! if (!checker->Relation()->IsIdenticalTo(variableType, smartType)) { diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index a663a854b8ac789038fa15cacd90ec302ac30914..b9368223e89181f544f83cdfbf0fe83d7df003b7 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -522,7 +522,7 @@ void ProcessExclamationMark(ETSChecker *checker, ir::UnaryExpression *expr, chec return; } - auto exprRes = operandType->ResolveConditionExpr(); + auto exprRes = IsConstantTestValue(expr->Argument()); if (std::get<0>(exprRes)) { auto tsType = checker->CreateETSBooleanType(!std::get<1>(exprRes)); tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); @@ -559,7 +559,8 @@ void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, break; } - expr->Argument()->SetTsType(expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType))); + expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType)); + expr->Argument()->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType)); break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { @@ -618,7 +619,8 @@ bool CheckArgumentVoidType(checker::Type *&funcReturnType, ETSChecker *checker, ir::ReturnStatement *st) { if (name.find(compiler::Signatures::ETS_MAIN_WITH_MANGLE_BEGIN) != std::string::npos) { - if (!funcReturnType->IsETSVoidType() && !funcReturnType->IsIntType()) { + if (!funcReturnType->IsETSVoidType() && + !checker->Relation()->IsSupertypeOf(checker->GlobalIntBuiltinType(), funcReturnType)) { checker->LogError(diagnostic::MAIN_BAD_RETURN, {}, st->Start()); } } @@ -813,4 +815,28 @@ void CheckAllConstPropertyInitialized(checker::ETSChecker *checker, ir::ETSModul } } } + +// NOLINTBEGIN(readability-else-after-return) +std::tuple IsConstantTestValue(ir::Expression const *expr) +{ + if (expr->IsNullLiteral() || expr->IsUndefinedLiteral()) { + return {true, false}; + } else if (expr->IsBooleanLiteral()) { + return {true, expr->AsBooleanLiteral()->Value()}; + } else if (expr->IsStringLiteral()) { + return {true, expr->AsStringLiteral()->Str().Length() != 0}; + } else if (expr->IsCharLiteral()) { + return {true, expr->AsCharLiteral()->Char() != 0}; + } else if (expr->IsBigIntLiteral()) { + return {true, expr->AsBigIntLiteral()->Str() != "0"}; + } else if (expr->IsNumberLiteral()) { + auto num = expr->AsNumberLiteral()->Number(); + return {true, !num.IsZero()}; + } else if (expr->TsType()->IsETSEnumType() && expr->TsType()->IsConstantType()) { + // NOTE(gogabr): Should handle enum constants + return {false, false}; + } + return {false, false}; +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ETSAnalyzerHelpers.h b/ets2panda/checker/ETSAnalyzerHelpers.h index 979d6413ac63d58a4c73e16aabef6a38c793068f..1b5e9a814fc68d4f4d8abf4cae5a5ce2956b439e 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.h +++ b/ets2panda/checker/ETSAnalyzerHelpers.h @@ -63,7 +63,10 @@ void CastPossibleTupleOnRHS(ETSChecker *checker, ir::AssignmentExpression *expr) void ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, ir::ReturnStatement *st, ir::Expression *stArgument); bool CheckReturnTypeNecessity(ir::MethodDefinition *node); + void CheckAllConstPropertyInitialized(checker::ETSChecker *checker, ir::ETSModule *pkg); + +std::tuple IsConstantTestValue(ir::Expression const *expr); } // namespace ark::es2panda::checker #endif // ES2PANDA_CHECKER_ETSANALYZERHELPERS_H diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 24b38be959d852698d06721db05a4e06faa36b93..93db5d483b3b84a2511e4495a77aca3102a42f7d 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -376,41 +376,80 @@ Type *ETSChecker::GlobalByteType() const return GetGlobalTypesHolder()->GlobalByteType(); } +Type *ETSChecker::GlobalByteBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalByteBuiltinType(); +} + Type *ETSChecker::GlobalShortType() const { return GetGlobalTypesHolder()->GlobalShortType(); } +Type *ETSChecker::GlobalShortBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalShortBuiltinType(); +} + Type *ETSChecker::GlobalIntType() const { return GetGlobalTypesHolder()->GlobalIntType(); } +Type *ETSChecker::GlobalIntBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); +} + Type *ETSChecker::GlobalLongType() const { return GetGlobalTypesHolder()->GlobalLongType(); } +Type *ETSChecker::GlobalLongBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalLongBuiltinType(); +} + Type *ETSChecker::GlobalFloatType() const { return GetGlobalTypesHolder()->GlobalFloatType(); } +Type *ETSChecker::GlobalFloatBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalFloatBuiltinType(); +} + Type *ETSChecker::GlobalDoubleType() const { return GetGlobalTypesHolder()->GlobalDoubleType(); } +Type *ETSChecker::GlobalDoubleBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalDoubleBuiltinType(); +} + Type *ETSChecker::GlobalCharType() const { return GetGlobalTypesHolder()->GlobalCharType(); } +Type *ETSChecker::GlobalCharBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalCharBuiltinType(); +} Type *ETSChecker::GlobalETSBooleanType() const { return GetGlobalTypesHolder()->GlobalETSBooleanType(); } +Type *ETSChecker::GlobalETSBooleanBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); +} + Type *ETSChecker::GlobalVoidType() const { return GetGlobalTypesHolder()->GlobalETSVoidType(); @@ -574,6 +613,22 @@ ETSObjectType *ETSChecker::GlobalBuiltinBoxType(Type *contents) } } +void ETSChecker::SetFlagsForLegalBoxedPrimitiveConversion(TypeRelation *relation, Type *source, Type *target) +{ + if ((relation->GetTypeRelationFlags() & TypeRelationFlag::OVERLOADING_CONTEXT) != 0 || + (relation->GetTypeRelationFlags() & TypeRelationFlag::ONLY_CHECK_BOXING_UNBOXING) != 0) { + return; + } + Type *sourceUnboxedType = MaybeUnboxType(source); + relation->GetNode()->AddBoxingUnboxingFlags(GetUnboxingFlag(sourceUnboxedType)); + if (target->IsETSUnionType()) { + auto *boxedPrimitive = target->AsETSUnionType()->FindUnboxableType(); + relation->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(boxedPrimitive)); + } else { + relation->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(target)); + } +} + GlobalArraySignatureMap &ETSChecker::GlobalArrayTypes() { return globalArraySignatures_; @@ -631,13 +686,13 @@ Type *ETSChecker::SelectGlobalIntegerTypeForNumeric(Type *type) { switch (ETSType(type)) { case checker::TypeFlag::FLOAT: { - return GlobalIntType(); + return GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); } case checker::TypeFlag::DOUBLE: { - return GlobalLongType(); + return GetGlobalTypesHolder()->GlobalLongBuiltinType(); } default: { - return type; + return MaybeBoxType(type); } } } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 7be80417df068573172f5f4621a4a33d0a529e1a..2e0c049eabad076c95c2dab1fa37705446a146dd 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -24,6 +24,7 @@ #include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/ets/types.h" #include "checker/resolveResult.h" +#include "checker/types/globalTypesHolder.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/visitor/AstVisitor.h" #include "util/helpers.h" @@ -129,6 +130,15 @@ public: Type *GlobalETSBigIntType() const; Type *GlobalWildcardType() const; + Type *GlobalByteBuiltinType() const; + Type *GlobalShortBuiltinType() const; + Type *GlobalIntBuiltinType() const; + Type *GlobalLongBuiltinType() const; + Type *GlobalFloatBuiltinType() const; + Type *GlobalDoubleBuiltinType() const; + Type *GlobalCharBuiltinType() const; + Type *GlobalETSBooleanBuiltinType() const; + ETSObjectType *GlobalETSObjectType() const; ETSUnionType *GlobalETSNullishType() const; ETSUnionType *GlobalETSNullishObjectType() const; @@ -196,8 +206,7 @@ public: void ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set *extendsSet, const lexer::SourcePosition &pos); void ResolveDeclaredMembersOfObject(const Type *type); - lexer::Number ExtractNumericValue(Type const *const indexType); - std::optional GetTupleElementAccessValue(const Type *type); + std::optional GetTupleElementAccessValue(const ir::Expression *expr); bool ValidateArrayIndex(ir::Expression *expr, bool relaxed = false); bool ValidateTupleIndex(const ETSTupleType *tuple, ir::MemberExpression *expr, bool reportError = true); bool ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple, ir::MemberExpression *expr); @@ -348,6 +357,8 @@ public: checker::Type *CheckBinaryOperatorMulDivMod( std::tuple op, bool isEqualOp, std::tuple types); + + bool CheckType(const checker::Type *type, ETSChecker *checker); checker::Type *CheckBinaryOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType); checker::Type *CheckBinaryBitwiseOperatorForIntEnums(const checker::Type *const leftType, @@ -379,15 +390,13 @@ public: checker::Type *rightType); checker::Type *CheckBinaryOperatorNullishCoalescing(ir::Expression *left, ir::Expression *right, lexer::SourcePosition pos); + bool CheckIfNumeric(Type *type); bool AdjustNumberLiteralType(ir::NumberLiteral *literal, Type *literalType, Type *otherType); Type *HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); - Type *HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); + void SetUnboxingFlagsForBinaryExpression(std::tuple types, + std::tuple nodes, bool isBoxed); void FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression); - template - Type *PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); - - Type *HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); template Type *PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); @@ -475,6 +484,7 @@ public: Signature *ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpression *callExpr, ArenaVector const &signatures, ArenaVector &arguments); + Signature *MakeSignatureInvocable(Signature *sig, ir::CallExpression *callExpr); Signature *ResolveCallExpressionAndTrailingLambda(ArenaVector &signatures, ir::CallExpression *callExpr, const lexer::SourcePosition &pos, TypeRelationFlag reportFlag = TypeRelationFlag::NONE); @@ -495,8 +505,8 @@ public: Signature *CheckEveryAbstractSignatureIsOverridden(ETSFunctionType *target, ETSFunctionType *source); static Signature *GetSignatureFromMethodDefinition(const ir::MethodDefinition *methodDef); bool CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload, - const ir::MethodDefinition *currentFunc, bool omitSameAsm = false); - static bool CmpAssemblerTypesWithRank(Signature const *const sig1, Signature const *const sig2) noexcept; + const ir::MethodDefinition *currentFunc, bool omitSameAsm = false, + TypeRelationFlag relationFlags = TypeRelationFlag::NO_RETURN_TYPE_CHECK); static bool HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept; static bool HasSameAssemblySignatures(ETSFunctionType const *const func1, ETSFunctionType const *const func2) noexcept; @@ -562,9 +572,6 @@ public: bool IsNullLikeOrVoidExpression(const ir::Expression *expr) const; bool IsConstantExpression(ir::Expression *expr, Type *type); void ValidateUnaryOperatorOperand(varbinder::Variable *variable); - bool ValidateAnnotationPropertyType(checker::Type *tsType); - void ProcessRequiredFields(ArenaUnorderedMap &fieldMap, - ir::AnnotationUsage *st, ETSChecker *checker) const; void CheckFunctionSignatureAnnotations(const ArenaVector ¶ms, ir::TSTypeParameterDeclaration *typeParams, ir::TypeNode *returnTypeAnnotation); @@ -587,6 +594,7 @@ public: checker::Type *unboxedR); Type *ApplyUnaryOperatorPromotion(Type *type, bool createConst = true, bool doPromotion = true, bool isCondExpr = false); + Type *GetUnaryOperatorPromotedType(Type *type, const bool doPromotion = true, const bool isCondExpr = false); Type *HandleBooleanLogicalOperators(Type *leftType, Type *rightType, lexer::TokenType tokenType); bool HandleLogicalPotentialResult(ir::Expression *left, ir::Expression *right, ir::BinaryExpression *expr, @@ -628,6 +636,7 @@ public: void AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType); ir::BoxingUnboxingFlags GetBoxingFlag(Type *boxingType); ir::BoxingUnboxingFlags GetUnboxingFlag(Type const *unboxingType) const; + void SetFlagsForLegalBoxedPrimitiveConversion(TypeRelation *relation, Type *source, Type *target); Type *MaybeBoxExpression(ir::Expression *expr); Type *MaybeUnboxExpression(ir::Expression *expr); Type *MaybeBoxType(Type *type) const; @@ -639,7 +648,6 @@ public: bool CompareIdentifiersValuesAreDifferent(ir::Expression *compareValue, const std::string &caseValue); void CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase, const lexer::SourcePosition &pos); - std::string GetStringFromLiteral(ir::Expression *caseTest) const; varbinder::Variable *FindVariableInFunctionScope(util::StringView name); std::pair FindVariableInClassOrEnclosing( util::StringView name, const ETSObjectType *classType); @@ -755,7 +763,8 @@ public: static NamedAccessMeta FormNamedAccessMetadata(varbinder::Variable const *prop); // Smart cast support - [[nodiscard]] checker::Type *ResolveSmartType(checker::Type *sourceType, checker::Type *targetType); + [[nodiscard]] checker::Type *ResolveSmartType(checker::Type *sourceType, checker::Type *targetType, + bool narrowingAllowed); [[nodiscard]] std::pair CheckTestNullishCondition(Type *testedType, Type *actualType, bool strict); [[nodiscard]] std::pair CheckTestObjectCondition(ETSObjectType *testedType, Type *actualType, bool strict); @@ -866,6 +875,11 @@ public: return overloadSigContainer_; } + void ClearApparentTypes() noexcept + { + apparentTypes_.clear(); + } + void CleanUp() override { Checker::CleanUp(); @@ -968,15 +982,6 @@ private: bool ComputeSuperType(ETSObjectType *type); - template - UType HandleModulo(UType leftValue, UType rightValue); - - template - Type *HandleBitWiseArithmetic(Type *leftValue, Type *rightValue, lexer::TokenType operationType); - - template - typename TargetType::UType GetOperand(Type *type); - template ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const; Signature *GetMostSpecificSignature(ArenaVector &compatibleSignatures, diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index 7c9a9142ba7166f3d60cf3132387f7c6e2cc3e82..59cf64d557ad3a6284952f83864521590c5d3bf8 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -44,6 +44,7 @@ #include "ir/ets/etsNewClassInstanceExpression.h" #include "ir/ets/etsStructDeclaration.h" #include "ir/ts/tsInterfaceDeclaration.h" +#include "checker/ETSAnalyzerHelpers.h" #include "checker/types/globalTypesHolder.h" #include "varbinder/variable.h" #include "varbinder/declaration.h" @@ -282,7 +283,7 @@ void AliveAnalyzer::AnalyzeDoLoop(const ir::DoWhileStatement *doWhile) status_ = Or(status_, ResolveContinues(doWhile)); AnalyzeNode(doWhile->Test()); ES2PANDA_ASSERT(doWhile->Test()->TsType() && doWhile->Test()->TsType()->IsConditionalExprType()); - const auto exprRes = doWhile->Test()->TsType()->ResolveConditionExpr(); + const auto exprRes = IsConstantTestValue(doWhile->Test()); status_ = And(status_, static_cast(!std::get<0>(exprRes) || !std::get<1>(exprRes))); status_ = Or(status_, ResolveBreaks(doWhile)); } @@ -292,7 +293,7 @@ void AliveAnalyzer::AnalyzeWhileLoop(const ir::WhileStatement *whileStmt) SetOldPendingExits(PendingExits()); AnalyzeNode(whileStmt->Test()); ES2PANDA_ASSERT(whileStmt->Test()->TsType() && whileStmt->Test()->TsType()->IsConditionalExprType()); - const auto exprRes = whileStmt->Test()->TsType()->ResolveConditionExpr(); + const auto exprRes = IsConstantTestValue(whileStmt->Test()); status_ = And(status_, static_cast(!std::get<0>(exprRes) || std::get<1>(exprRes))); AnalyzeStat(whileStmt->Body()); status_ = Or(status_, ResolveContinues(whileStmt)); @@ -311,7 +312,7 @@ void AliveAnalyzer::AnalyzeForLoop(const ir::ForUpdateStatement *forStmt) AnalyzeNode(forStmt->Test()); ES2PANDA_ASSERT(forStmt->Test()->TsType() && forStmt->Test()->TsType()->IsConditionalExprType()); condType = forStmt->Test()->TsType(); - std::tie(resolveType, res) = forStmt->Test()->TsType()->ResolveConditionExpr(); + std::tie(resolveType, res) = IsConstantTestValue(forStmt->Test()); status_ = From(!resolveType || res); } else { status_ = LivenessStatus::ALIVE; diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index b0b3e32efd5af3ce71e4525bf4e8fca6e88a970f..ba6cb5e75335ab546789d1d6a896688103992f54 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -16,7 +16,9 @@ #include "arithmetic.h" #include "checker/types/ts/nullType.h" +#include "checker/types/globalTypesHolder.h" #include "lexer/token/token.h" +#include "checker/types/ets/etsEnumType.h" namespace ark::es2panda::checker { @@ -48,20 +50,6 @@ static void LogOperatorCannotBeApplied(ETSChecker *checker, BinaryArithmOperands LogOperatorCannotBeApplied(checker, ops.expr->OperatorType(), ops.typeL, ops.typeR, ops.expr->Start()); } -static inline void UnboxOperands(ETSChecker *checker, BinaryArithmOperands const &ops) -{ - auto const unbox = [checker](ir::Expression *expr, Type *type, Type *reducedType) { - if (type != reducedType) { - expr->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(reducedType)); - } - if (reducedType->IsETSEnumType()) { - expr->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - } - }; - unbox(ops.expr->Left(), ops.typeL, ops.reducedL); - unbox(ops.expr->Right(), ops.typeR, ops.reducedR); -} - static inline void RepairTypeErrorsInOperands(Type **left, Type **right) { if (IsTypeError(*left)) { @@ -87,11 +75,31 @@ static inline void RepairTypeErrorWithDefault(Type **type, Type *dflt) } } -static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) +static bool CheckOpArgsTypeEq(ETSChecker *checker, Type *left, Type *right, Type *type) +{ + return ((left != nullptr) && (right != nullptr) && checker->IsTypeIdenticalTo(left, type) && + checker->IsTypeIdenticalTo(right, type)); +} + +static bool FindOpArgsType(ETSChecker *checker, Type *left, Type *right, Type *target) +{ + return (checker->Relation()->IsSupertypeOf(target, left) || checker->Relation()->IsSupertypeOf(target, right)); +} + +bool ETSChecker::CheckIfNumeric(Type *type) { - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); + if (type == nullptr) { + return false; + } + if (type->IsETSPrimitiveType()) { + return type->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); + } + auto *unboxed = MaybeUnboxInRelation(type); + return (unboxed != nullptr) && unboxed->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); +} +static Type *EffectivePrimitiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) +{ if (left->IsDoubleType() || right->IsDoubleType()) { return checker->GlobalDoubleType(); } @@ -101,7 +109,10 @@ static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *rig if (left->IsLongType() || right->IsLongType()) { return checker->GlobalLongType(); } - return checker->GlobalIntType(); + if (left->IsCharType() && right->IsCharType()) { + return checker->GlobalCharType(); + } + return checker->GlobalIntType(); // return int in case of primitive types by default } static Type *TryConvertToPrimitiveType(ETSChecker *checker, Type *type) @@ -113,32 +124,71 @@ static Type *TryConvertToPrimitiveType(ETSChecker *checker, Type *type) if (type->IsETSIntEnumType()) { return checker->GlobalIntType(); } + if (type->IsETSStringEnumType()) { return checker->GlobalETSStringLiteralType(); } return checker->MaybeUnboxInRelation(type); } -static std::pair BinaryCoerceToPrimitives(ETSChecker *checker, Type *left, Type *right, - bool const promote) +static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) +{ + ES2PANDA_ASSERT(checker->CheckIfNumeric(left) && checker->CheckIfNumeric(right)); + + auto bothBoxed = left->IsETSUnboxableObject() && right->IsETSUnboxableObject(); + if (!bothBoxed) { + return EffectivePrimitiveTypeOfNumericOp(checker, left, right); + } + + auto globalTypesHolder = checker->GetGlobalTypesHolder(); + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalDoubleBuiltinType())) { + return globalTypesHolder->GlobalDoubleBuiltinType(); + } + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalFloatBuiltinType())) { + return globalTypesHolder->GlobalFloatBuiltinType(); + } + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalLongBuiltinType())) { + return globalTypesHolder->GlobalLongBuiltinType(); + } + return globalTypesHolder->GlobalIntegerBuiltinType(); // return Int for Byte, Short, Int +} + +static Type *BinaryGetPromotedType(ETSChecker *checker, Type *left, Type *right, bool const promote) { Type *const unboxedL = TryConvertToPrimitiveType(checker, left); Type *const unboxedR = TryConvertToPrimitiveType(checker, right); if (unboxedL == nullptr || unboxedR == nullptr) { - return {nullptr, false}; + return nullptr; } - bool const bothConst = unboxedL->IsConstantType() && unboxedR->IsConstantType(); + Type *typeL = left; + Type *typeR = right; + + bool const bothBoxed = !typeL->IsETSPrimitiveType() && !typeR->IsETSPrimitiveType(); if (!promote) { - return {unboxedR, bothConst}; + return typeR; } - if (unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - return {EffectiveTypeOfNumericOp(checker, unboxedL, unboxedR), bothConst}; + if (!bothBoxed) { + if (unboxedL->IsETSEnumType() || unboxedR->IsETSEnumType()) { + return nullptr; + } + if (!typeL->IsETSPrimitiveType()) { + typeL = checker->MaybeUnboxType(typeL); + } + if (!typeR->IsETSPrimitiveType()) { + typeR = checker->MaybeUnboxType(typeR); + } + } + + if (checker->CheckIfNumeric(typeL) && checker->CheckIfNumeric(typeR)) { + return EffectiveTypeOfNumericOp(checker, typeL, typeR); } - return {unboxedR, bothConst}; + if (checker->CheckIfNumeric(typeR)) { + return typeR; + } + return typeL; } Type *ETSChecker::NegateNumericType(Type *type, ir::Expression *node) @@ -186,26 +236,6 @@ Type *ETSChecker::NegateNumericType(Type *type, ir::Expression *node) return result; } -Type *ETSChecker::HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - if (left->IsDoubleType() || right->IsDoubleType()) { - return PerformRelationOperationOnTypes(left, right, operationType); - } - - if (left->IsFloatType() || right->IsFloatType()) { - return PerformRelationOperationOnTypes(left, right, operationType); - } - - if (left->IsLongType() || right->IsLongType()) { - return PerformRelationOperationOnTypes(left, right, operationType); - } - - return PerformRelationOperationOnTypes(left, right, operationType); -} - bool ETSChecker::CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::TokenType op) { if ((left == nullptr) || (right == nullptr)) { @@ -250,6 +280,20 @@ bool ETSChecker::CheckBinaryPlusMultDivOperandsForUnionType(const Type *leftType return true; } +void ETSChecker::SetUnboxingFlagsForBinaryExpression(std::tuple types, + std::tuple nodes, bool isBoxed) +{ + auto [leftType, rightType, unboxedL, unboxedR] = types; + auto [left, right] = nodes; + if (isBoxed) { + FlagExpressionWithUnboxing(leftType, nullptr, left); + FlagExpressionWithUnboxing(rightType, nullptr, right); + } else { + FlagExpressionWithUnboxing(leftType, unboxedL, left); + FlagExpressionWithUnboxing(rightType, unboxedR, right); + } +} + checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( std::tuple op, bool isEqualOp, std::tuple types) @@ -264,17 +308,12 @@ checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( return GlobalTypeError(); } - checker::Type *tsType {}; - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); if (!CheckBinaryPlusMultDivOperandsForUnionType(leftType, rightType, left, right)) { return GlobalTypeError(); } - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (promotedType == nullptr || !CheckIfNumeric(leftType) || !CheckIfNumeric(rightType)) { auto type = CheckBinaryOperatorForIntEnums(leftType, rightType); if (type != nullptr) { return type; @@ -283,31 +322,32 @@ checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( return GlobalTypeError(); } - if (bothConst) { - tsType = HandleArithmeticOperationOnTypes(leftType, rightType, operationType); - } + return promotedType; +} - return (tsType != nullptr) ? tsType : promotedType; +bool ETSChecker::CheckType(const checker::Type *type, [[maybe_unused]] ETSChecker *checker) +{ + return type->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || + Relation()->IsSupertypeOf(GetGlobalTypesHolder()->GlobalNumericBuiltinType(), type); } checker::Type *ETSChecker::CheckBinaryOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType) { - if (leftType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - rightType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (CheckType(leftType, this) && CheckType(rightType, this)) { if (leftType->IsETSIntEnumType() && rightType->IsETSIntEnumType()) { - return GlobalIntType(); + return GlobalIntBuiltinType(); } if (leftType->IsFloatType() || rightType->IsFloatType()) { - return GlobalFloatType(); + return GlobalFloatBuiltinType(); } if (leftType->IsDoubleType() || rightType->IsDoubleType()) { - return GlobalDoubleType(); + return GlobalDoubleBuiltinType(); } if (leftType->IsLongType() || rightType->IsLongType()) { - return GlobalLongType(); + return GlobalLongBuiltinType(); } - return GlobalIntType(); + return GlobalIntBuiltinType(); } return nullptr; } @@ -315,21 +355,20 @@ checker::Type *ETSChecker::CheckBinaryOperatorForIntEnums(const checker::Type *c checker::Type *ETSChecker::CheckBinaryBitwiseOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType) { - if (leftType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - rightType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (CheckType(leftType, this) && CheckType(rightType, this)) { if (leftType->IsETSIntEnumType() && rightType->IsETSIntEnumType()) { - return GlobalIntType(); + return GlobalIntBuiltinType(); } if (leftType->IsFloatType() || rightType->IsFloatType()) { - return GlobalIntType(); + return GlobalIntBuiltinType(); } if (leftType->IsDoubleType() || rightType->IsDoubleType()) { - return GlobalLongType(); + return GlobalLongBuiltinType(); } if (leftType->IsLongType() || rightType->IsLongType()) { - return GlobalLongType(); + return GlobalLongBuiltinType(); } - return GlobalIntType(); + return GlobalIntBuiltinType(); } return nullptr; } @@ -374,29 +413,20 @@ checker::Type *ETSChecker::CheckBinaryOperatorPlus( if (!CheckBinaryPlusMultDivOperandsForUnionType(leftType, rightType, left, right)) { return GlobalTypeError(); } + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (promotedType == nullptr || !CheckIfNumeric(rightType) || !CheckIfNumeric(leftType)) { auto type = CheckBinaryOperatorPlusForEnums(leftType, rightType); if (type != nullptr) { return type; } LogError(diagnostic::BINOP_NONARITHMETIC_TYPE, {}, pos); - return GlobalTypeError(); - } - - if (bothConst) { - return HandleArithmeticOperationOnTypes(leftType, rightType, operationType); } return promotedType; } -static checker::Type *GetBitwiseCompatibleType(ETSChecker *checker, Type *const type) +[[maybe_unused]] static checker::Type *GetBitwiseCompatibleType(ETSChecker *checker, Type *const type) { switch (checker->ETSType(type)) { case TypeFlag::BYTE: { @@ -430,8 +460,8 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( auto [left, right, operationType, pos] = op; auto [leftType, rightType, unboxedL, unboxedR] = types; - RepairTypeErrorWithDefault(&leftType, GlobalIntType()); - RepairTypeErrorWithDefault(&rightType, GlobalIntType()); + RepairTypeErrorWithDefault(&leftType, GlobalIntBuiltinType()); + RepairTypeErrorWithDefault(&rightType, GlobalIntBuiltinType()); RepairTypeErrorWithDefault(&unboxedL, GlobalIntType()); RepairTypeErrorWithDefault(&unboxedR, GlobalIntType()); @@ -440,15 +470,10 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( return GlobalTypeError(); } - auto promotedLeftType = ApplyUnaryOperatorPromotion(unboxedL, false, !isEqualOp); - auto promotedRightType = ApplyUnaryOperatorPromotion(unboxedR, false, !isEqualOp); - - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedLeftType == nullptr || !promotedLeftType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - promotedRightType == nullptr || - !promotedRightType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + auto promotedLeftType = GetUnaryOperatorPromotedType(leftType, !isEqualOp); + auto promotedRightType = GetUnaryOperatorPromotedType(rightType, !isEqualOp); + if (promotedLeftType == nullptr || promotedRightType == nullptr || !CheckIfNumeric(promotedLeftType) || + !CheckIfNumeric(promotedRightType)) { auto type = CheckBinaryBitwiseOperatorForIntEnums(leftType, rightType); if (type != nullptr) { return type; @@ -457,10 +482,22 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( return GlobalTypeError(); } - if (promotedLeftType->HasTypeFlag(TypeFlag::CONSTANT) && promotedRightType->HasTypeFlag(TypeFlag::CONSTANT)) { - return HandleBitwiseOperationOnTypes(promotedLeftType, promotedRightType, operationType); + auto isPrim = promotedLeftType->IsETSPrimitiveType(); + auto unboxedProm = MaybeUnboxType(promotedLeftType); + if (unboxedProm->IsFloatType() || unboxedProm->IsIntType()) { + return isPrim ? GlobalIntType() : GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); + } + + if (unboxedProm->IsLongType() || unboxedProm->IsDoubleType()) { + return isPrim ? GlobalLongType() : GetGlobalTypesHolder()->GlobalLongBuiltinType(); + } + + if (unboxedProm->IsByteType() || unboxedProm->IsShortType() || unboxedProm->IsCharType()) { + return promotedLeftType; } - return GetBitwiseCompatibleType(this, promotedLeftType); + + ES2PANDA_UNREACHABLE(); + return nullptr; } checker::Type *ETSChecker::CheckBinaryOperatorBitwise( @@ -481,19 +518,12 @@ checker::Type *ETSChecker::CheckBinaryOperatorBitwise( return GlobalTypeError(); } - if (unboxedL != nullptr && unboxedL->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) && unboxedR != nullptr && - unboxedR->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return HandleBooleanLogicalOperators(unboxedL, unboxedR, operationType); + if (CheckOpArgsTypeEq(this, unboxedL, unboxedR, GlobalETSBooleanType())) { + return GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); } - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); + if (promotedType == nullptr || !CheckIfNumeric(rightType) || !CheckIfNumeric(leftType)) { auto type = CheckBinaryBitwiseOperatorForIntEnums(leftType, rightType); if (type != nullptr) { return type; @@ -501,12 +531,22 @@ checker::Type *ETSChecker::CheckBinaryOperatorBitwise( LogError(diagnostic::OP_NONNUMERIC, {}, pos); return GlobalTypeError(); } + SetUnboxingFlagsForBinaryExpression(types, {left, right}, promotedType->IsETSUnboxableObject()); + + auto isPrim = promotedType->IsETSPrimitiveType(); + auto unboxedProm = MaybeUnboxType(promotedType); + if (unboxedProm->IsFloatType() || unboxedProm->IsIntType()) { + return isPrim ? GlobalIntType() : GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); + } - if (bothConst) { - return HandleBitwiseOperationOnTypes(leftType, rightType, operationType); + if (unboxedProm->IsLongType() || unboxedProm->IsDoubleType()) { + return isPrim ? GlobalLongType() : GetGlobalTypesHolder()->GlobalLongBuiltinType(); } - return SelectGlobalIntegerTypeForNumeric(promotedType); + if (unboxedProm->IsByteType() || unboxedProm->IsShortType() || unboxedProm->IsCharType()) { + return promotedType; + } + return nullptr; } checker::Type *ETSChecker::CheckBinaryOperatorLogical(ir::Expression *left, ir::Expression *right, @@ -540,25 +580,39 @@ checker::Type *ETSChecker::CheckBinaryOperatorLogical(ir::Expression *left, ir:: return GetNonConstantType(leftType); } - if (IsTypeIdenticalTo(unboxedL, unboxedR)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return GetNonConstantType(unboxedL); - } - if (unboxedL != nullptr && unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && unboxedR != nullptr && unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return EffectiveTypeOfNumericOp(this, unboxedL, unboxedR); + SetUnboxingFlagsForBinaryExpression({leftType, rightType, unboxedL, unboxedR}, {left, right}, + (leftType->IsETSUnboxableObject() || rightType->IsETSUnboxableObject())); + return EffectiveTypeOfNumericOp(this, leftType, rightType); } return CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)}); } +static bool ContainsNumbers(ETSChecker *checker, Type *tp) +{ + auto isSubtypeOfNumeric = [checker](Type *tp2) { + return checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), tp2); + }; + if (isSubtypeOfNumeric(tp)) { + return true; + } + if (tp->IsETSUnionType()) { + for (auto *constituent : tp->AsETSUnionType()->ConstituentTypes()) { + if (isSubtypeOfNumeric(constituent)) { + return true; + } + } + } + + return false; +} + +// CC-OFFNXT(huge_cyclomatic_complexity) solid logic bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, checker::Type *const rightType) { - auto isGlobalObjectType {[](checker::Type *const type) -> bool { + auto isGlobalObjectType {[&](checker::Type *const type) -> bool { return type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType(); }}; @@ -568,6 +622,18 @@ bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, che return true; } + // Any two types that can be numeric are comparable + if (ContainsNumbers(this, leftType) && ContainsNumbers(this, rightType)) { + return true; + } + + // Boolean and any type that can be numeric or char are not comparable + if ((FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalNumericBuiltinType()) || + FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalCharBuiltinType())) && + FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType())) { + return false; + } + // NOTE (mxlgv): Skip for unions. Required implementation of the specification section: // 7.25.6 Reference Equality Based on Actual Type (Union Equality Operators) if (leftType->IsETSUnionType()) { @@ -594,6 +660,11 @@ bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, che } } + if (FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalIntegerBuiltinType()) && + (leftType->IsETSEnumType() || rightType->IsETSEnumType())) { + return true; + } + // 7.24.5 Enumeration Relational Operators return leftType->IsETSEnumType() == rightType->IsETSEnumType(); } @@ -665,13 +736,6 @@ static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOper return checker->CreateETSUnionType({typeL, typeR}); } - if (typeL->IsETSEnumType() && typeR->IsETSEnumType()) { - if (checker->Relation()->IsIdenticalTo(typeL, typeR)) { - return typeL; - } - return nullptr; - } - if (typeL->IsETSReferenceType() && typeR->IsETSReferenceType()) { checker->Relation()->SetNode(expr->Left()); if (!checker->CheckValidEqualReferenceType(typeL, typeR)) { @@ -697,8 +761,6 @@ static Type *CheckBinaryOperatorEqual(ETSChecker *checker, BinaryArithmOperands { [[maybe_unused]] auto const [expr, typeL, typeR, reducedL, reducedR] = ops; - expr->Left()->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - expr->Right()->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); if (typeL->IsTypeError()) { // both are errors return checker->GlobalTypeError(); } @@ -709,12 +771,13 @@ static Type *CheckBinaryOperatorEqual(ETSChecker *checker, BinaryArithmOperands if (reducedL->IsETSBooleanType() && reducedR->IsETSBooleanType()) { if (reducedL->IsConstantType() && reducedR->IsConstantType()) { - bool res = reducedL->AsETSBooleanType()->GetValue() == reducedR->AsETSBooleanType()->GetValue(); - res = ((expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EQUAL) == res); - return checker->CreateETSBooleanType(res); + return checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); + } + if (checker->CheckIfNumeric(typeL) && checker->CheckIfNumeric(typeR) && typeL->IsETSUnboxableObject() && + typeR->IsETSUnboxableObject()) { + return typeL; } - UnboxOperands(checker, ops); - return checker->GlobalETSBooleanType(); + return reducedL; } return HandelReferenceBinaryEquality(checker, ops); @@ -763,15 +826,14 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres return {GlobalETSBooleanType(), leftType}; } - auto *const promotedType = std::get<0>(BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp)); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); if (leftType->IsETSUnionType() || rightType->IsETSUnionType()) { return {GlobalETSBooleanType(), CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)})}; } - if (promotedType != nullptr && (unboxedL->IsETSBooleanType() != unboxedR->IsETSBooleanType())) { + if (promotedType != nullptr && unboxedL != nullptr && unboxedR != nullptr && + unboxedL->IsETSBooleanType() != unboxedR->IsETSBooleanType()) { LogOperatorCannotBeApplied(this, operationType, leftType, rightType, pos); return {GlobalETSBooleanType(), leftType}; } @@ -783,7 +845,7 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres return {GlobalETSBooleanType(), GlobalETSBooleanType()}; } - return {GlobalETSBooleanType(), promotedType}; + return {GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(), promotedType}; } std::tuple ETSChecker::CheckBinaryOperatorInstanceOf(lexer::SourcePosition pos, checker::Type *leftType, @@ -903,6 +965,7 @@ struct TypeParams { Type *unboxedR; }; +// CC-OFFNXT(G.FUN.01, huge_method) solid logic static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, const BinaryOperatorParams &binaryParams, const TypeParams &typeParams) @@ -913,6 +976,7 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, checker::Type *const leftType = typeParams.leftType; checker::Type *const rightType = typeParams.rightType; checker::Type *tsType {}; + BinaryArithmOperands ops = GetBinaryOperands(checker, binaryParams.expr->AsBinaryExpression()); BinaryArithmOperands opsRepaired = RepairTypeErrorsInOperands(ops); @@ -927,8 +991,8 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - if (Type *res = CheckBinaryOperatorEqual(checker, opsRepaired); res != nullptr) { - return {checker->GlobalETSBooleanType(), res}; + if (auto res = CheckBinaryOperatorEqual(checker, opsRepaired); res != nullptr) { + return {checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(), res}; } [[fallthrough]]; } @@ -956,123 +1020,66 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, return {tsType, tsType}; } -namespace { -bool IsStringEnum(const ir::Expression *expr) +static void TryAddValueOfFlagToStringEnumOperand(ir::Expression *op, const ir::Expression *otherOp) { - if (expr == nullptr) { - return false; + auto type = op->TsType(); + auto otherType = otherOp->TsType(); + if (type->IsETSStringEnumType() && (otherType->IsETSStringType() || otherType->IsETSStringEnumType())) { + op->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } - - auto type = expr->TsType(); - if (type == nullptr) { - return false; - } - - return type->IsETSStringEnumType(); } -bool IsIntEnum(const ir::Expression *expr) +static void TryAddValueOfFlagToIntEnumOperand(ir::Expression *op) { - if (expr == nullptr) { - return false; + if (op->TsType()->IsETSIntEnumType()) { + op->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } - - auto type = expr->TsType(); - if (type == nullptr) { - return false; - } - - return type->IsETSIntEnumType(); } -bool CheckNumericOperatorContext(ir::Expression *expression, lexer::TokenType op) +static void CheckEnumInOperatorContext(ir::Expression *expression, lexer::TokenType opType, ir::Expression *left, + ir::Expression *right, ETSChecker *checker) { - const bool isMultiplicative = op == lexer::TokenType::PUNCTUATOR_MULTIPLY || - op == lexer::TokenType::PUNCTUATOR_DIVIDE || op == lexer::TokenType::PUNCTUATOR_MOD; - const bool isAdditive = op == lexer::TokenType::PUNCTUATOR_PLUS || op == lexer::TokenType::PUNCTUATOR_MINUS; - const bool isShift = op == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || - op == lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT || - op == lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT; - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - const bool isBitwise = op == lexer::TokenType::PUNCTUATOR_BITWISE_AND || - op == lexer::TokenType::PUNCTUATOR_BITWISE_OR || - op == lexer::TokenType::PUNCTUATOR_BITWISE_XOR; - const bool isConditionalAndOr = - op == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || op == lexer::TokenType::PUNCTUATOR_LOGICAL_OR; - - if (IsIntEnum(expression)) { - if (isMultiplicative || isAdditive || isShift || isRelational || isEquality || isBitwise || - isConditionalAndOr) { - expression->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - } - return true; - } - return false; -} + auto [lType, rType] = std::tuple {left->TsType(), right->TsType()}; -void CheckStringOperatorContext(ir::Expression *expression, checker::Type *otherType, lexer::TokenType op) -{ - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - if (IsStringEnum(expression) && (otherType->IsETSStringType() || otherType->IsETSStringEnumType())) { - if (op == lexer::TokenType::PUNCTUATOR_PLUS || isRelational || isEquality) { - expression->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + switch (opType) { + case lexer::TokenType::PUNCTUATOR_GREATER_THAN: + case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_LESS_THAN: + case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_EQUAL: + case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { + if (lType->IsETSEnumType() && rType->IsETSEnumType() && !checker->Relation()->IsIdenticalTo(lType, rType)) { + checker->LogError(diagnostic::BINOP_INCOMPARABLE, {}, expression->Start()); + return; + } + [[fallthrough]]; } - } -} - -bool CheckRelationalOperatorsBetweenEnums(ir::Expression *left, ir::Expression *right, lexer::TokenType op) -{ - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - - if (((IsStringEnum(left) && IsStringEnum(right)) || - (IsIntEnum(left) && IsIntEnum(right)))) { // NOTE(psiket) In case of int enums it has been already checked in - // the CheckNumericOperatorContext function - if (isRelational || isEquality) { - left->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - right->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - return true; + case lexer::TokenType::PUNCTUATOR_PLUS: { + TryAddValueOfFlagToStringEnumOperand(left, right); + TryAddValueOfFlagToStringEnumOperand(right, left); + [[fallthrough]]; } - } - return false; -} - -void CheckNeedToGenerateGetValueForBinaryExpression(ir::Expression *expression) -{ - if (!expression->IsBinaryExpression()) { - return; - } - - auto binaryExpression = expression->AsBinaryExpression(); - auto op = binaryExpression->OperatorType(); - auto leftExp = binaryExpression->Left(); - auto rightExp = binaryExpression->Right(); - - // Numeric Operator Context - auto leftIsIntEnum = CheckNumericOperatorContext(leftExp, op); - auto rightIsIntEnum = CheckNumericOperatorContext(rightExp, op); - if (leftIsIntEnum || rightIsIntEnum) { - return; - } - - // String Operator Context - CheckStringOperatorContext(leftExp, rightExp->TsType(), op); - CheckStringOperatorContext(rightExp, leftExp->TsType(), op); - - // Relational operators if both are enumeration Types - if (CheckRelationalOperatorsBetweenEnums(leftExp, rightExp, op)) { - return; + case lexer::TokenType::PUNCTUATOR_MULTIPLY: + case lexer::TokenType::PUNCTUATOR_DIVIDE: + case lexer::TokenType::PUNCTUATOR_MOD: + case lexer::TokenType::PUNCTUATOR_MINUS: + case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: + case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: + case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: + case lexer::TokenType::PUNCTUATOR_BITWISE_AND: + case lexer::TokenType::PUNCTUATOR_BITWISE_OR: + case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: + case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: + case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { + TryAddValueOfFlagToIntEnumOperand(left); + TryAddValueOfFlagToIntEnumOperand(right); + break; + } + default: + // NOTE(dkofanov): What about the '+=' operation? + break; } } -} // namespace std::tuple ETSChecker::CheckArithmeticOperations( ir::Expression *expr, std::tuple op, @@ -1088,16 +1095,23 @@ std::tuple ETSChecker::CheckArithmeticOperations( if (rightType->IsETSUnionType()) { rightType = GetNonConstantType(rightType); } + CheckEnumInOperatorContext(expr, operationType, left, right, this); auto checkMap = GetCheckMap(); if (checkMap.find(operationType) != checkMap.end()) { auto check = checkMap[operationType]; auto tsType = check(this, std::make_tuple(left, right, operationType, pos), isEqualOp, std::make_tuple(leftType, rightType, unboxedL, unboxedR)); + if (tsType == nullptr) { + return {leftType, rightType}; + } + if (tsType->IsETSPrimitiveType()) { + tsType = MaybeBoxType(tsType); + expr->AddBoxingUnboxingFlags(GetBoxingFlag(tsType)); + } return {tsType, tsType}; } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return CheckBinaryOperatorHelper(this, {left, right, expr, operationType, pos, isEqualOp}, {leftType, rightType, unboxedL, unboxedR}); } @@ -1146,8 +1160,6 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, return {leftType, leftType}; } - CheckNeedToGenerateGetValueForBinaryExpression(expr); - const bool isLogicalExtendedOperator = (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) || (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR); Type *unboxedL = @@ -1167,46 +1179,6 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, std::make_tuple(leftType, rightType, unboxedL, unboxedR)); } -Type *ETSChecker::HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - if (left->IsDoubleType() || right->IsDoubleType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - if (left->IsFloatType() || right->IsFloatType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - if (left->IsLongType() || right->IsLongType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - return PerformArithmeticOperationOnTypes(left, right, operationType); -} - -Type *ETSChecker::HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - if (left->IsDoubleType() || right->IsDoubleType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - if (left->IsFloatType() || right->IsFloatType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - if (left->IsLongType() || right->IsLongType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - return HandleBitWiseArithmetic(left, right, operationType); -} - void ETSChecker::FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression) { if (type->IsETSEnumType()) { diff --git a/ets2panda/checker/ets/arithmetic.h b/ets2panda/checker/ets/arithmetic.h index 9e08b1e46e32a4fae19e8436d5f7be1a5c9d491e..6ca03978bb6127cf14ad560447bfb15a78af169d 100644 --- a/ets2panda/checker/ets/arithmetic.h +++ b/ets2panda/checker/ets/arithmetic.h @@ -18,167 +18,9 @@ #include "checker/ETSchecker.h" #include "checker/ETSAnalyzer.h" +#include "checker/types/globalTypesHolder.h" namespace ark::es2panda::checker { - -template -typename TargetType::UType ETSChecker::GetOperand(Type *type) -{ - switch (ETSType(type)) { - case TypeFlag::BYTE: { - return type->AsByteType()->GetValue(); - } - case TypeFlag::CHAR: { - return type->AsCharType()->GetValue(); - } - case TypeFlag::SHORT: { - return type->AsShortType()->GetValue(); - } - case TypeFlag::INT: { - return type->AsIntType()->GetValue(); - } - case TypeFlag::LONG: { - return type->AsLongType()->GetValue(); - } - case TypeFlag::FLOAT: { - return type->AsFloatType()->GetValue(); - } - case TypeFlag::DOUBLE: { - return type->AsDoubleType()->GetValue(); - } - case TypeFlag::ETS_BOOLEAN: { - return type->AsETSBooleanType()->GetValue(); - } - default: { - ES2PANDA_UNREACHABLE(); - } - } -} - -template -Type *ETSChecker::PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - using UType = typename TargetType::UType; - - UType leftValue = GetOperand(left); - UType rightValue = GetOperand(right); - - bool result {}; - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_LESS_THAN: { - result = leftValue < rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { - result = leftValue <= rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { - result = leftValue > rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: { - result = leftValue >= rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: - case lexer::TokenType::PUNCTUATOR_EQUAL: { - result = leftValue == rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: - case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - result = leftValue != rightValue; - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return CreateETSBooleanType(result); -} - -template -Type *ETSChecker::PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - using UType = typename TargetType::UType; - - UType leftValue = GetOperand(left); - UType rightValue = GetOperand(right); - auto result = leftValue; - auto isForbiddenZeroDivision = [&rightValue]() { return std::is_integral::value && rightValue == 0; }; - - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_PLUS: - case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL: { - result = leftValue + rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MINUS: - case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL: { - result = leftValue - rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_DIVIDE: - case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: { - if (isForbiddenZeroDivision()) { - return nullptr; - } - result = leftValue / rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MULTIPLY: - case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL: { - result = leftValue * rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MOD: - case lexer::TokenType::PUNCTUATOR_MOD_EQUAL: { - if (isForbiddenZeroDivision()) { - return nullptr; - } - result = HandleModulo(leftValue, rightValue); - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return Allocator()->New(result); -} - -template <> -inline IntType::UType ark::es2panda::checker::ETSChecker::HandleModulo(IntType::UType leftValue, - IntType::UType rightValue) -{ - ES2PANDA_ASSERT(rightValue != 0); - return leftValue % rightValue; -} - -template <> -inline LongType::UType ark::es2panda::checker::ETSChecker::HandleModulo(LongType::UType leftValue, - LongType::UType rightValue) -{ - ES2PANDA_ASSERT(rightValue != 0); - return leftValue % rightValue; -} - -template <> -inline FloatType::UType ark::es2panda::checker::ETSChecker::HandleModulo(FloatType::UType leftValue, - FloatType::UType rightValue) -{ - return std::fmod(leftValue, rightValue); -} - -template <> -inline DoubleType::UType ark::es2panda::checker::ETSChecker::HandleModulo( - DoubleType::UType leftValue, DoubleType::UType rightValue) -{ - return std::fmod(leftValue, rightValue); -} - template inline IntegerUType CastIfFloat(FloatOrIntegerUType num) { @@ -188,61 +30,6 @@ inline IntegerUType CastIfFloat(FloatOrIntegerUType num) return num; } } - -template -Type *ETSChecker::HandleBitWiseArithmetic(Type *left, Type *right, lexer::TokenType operationType) -{ - using IntegerUType = typename IntegerType::UType; - using UnsignedUType = std::make_unsigned_t; - - UnsignedUType result = 0; - UnsignedUType unsignedLeftValue = CastIfFloat(GetOperand(left)); - UnsignedUType unsignedRightValue = CastIfFloat(GetOperand(right)); - - auto mask = std::numeric_limits::digits - 1U; - auto shift = unsignedRightValue & mask; - - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: - case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL: { - result = unsignedLeftValue & unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: - case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL: { - result = unsignedLeftValue | unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL: { - result = unsignedLeftValue ^ unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL: { - static_assert(sizeof(UnsignedUType) == 4 || sizeof(UnsignedUType) == 8); - result = unsignedLeftValue << shift; - break; - } - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL: { - static_assert(sizeof(IntegerUType) == 4 || sizeof(IntegerUType) == 8); - result = static_cast(unsignedLeftValue) >> shift; // NOLINT(hicpp-signed-bitwise) - break; - } - case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL: { - static_assert(sizeof(UnsignedUType) == 4 || sizeof(UnsignedUType) == 8); - result = unsignedLeftValue >> shift; - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return Allocator()->New(result); -} } // namespace ark::es2panda::checker #endif diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index 21d8514aec1e1865bdeb90cc3e207b7dc22abd31..59cddd1ff90e8cd7ea39bebbd048255419412e81 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -1343,8 +1343,10 @@ bool AssignAnalyzer::VariableHasDefaultValue(const ir::AstNode *node) ES2PANDA_UNREACHABLE(); } + bool isPrimitive = type->IsETSPrimitiveType(); + bool isBoxedPrimitive = type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive(); return type != nullptr && - (type->IsETSPrimitiveType() || + ((isPrimitive || isBoxedPrimitive) || (type->PossiblyETSUndefined() && (!type->HasTypeFlag(checker::TypeFlag::GENERIC) || (isNonReadonlyField && !CHECK_GENERIC_NON_READONLY_PROPERTIES)))); } diff --git a/ets2panda/checker/ets/castingContext.cpp b/ets2panda/checker/ets/castingContext.cpp index 0f1c377aaa3d61389ec083ad314ea99ca5704da2..1f8d508164838fc6e2c8af4656ee87123d25add5 100644 --- a/ets2panda/checker/ets/castingContext.cpp +++ b/ets2panda/checker/ets/castingContext.cpp @@ -39,11 +39,8 @@ CastingContext::CastingContext(TypeRelation *relation, const diagnostic::Diagnos } } - if (isLegalBoxedPrimitiveConversion && !relation->IsTrue()) { - auto *const checker = relation->GetChecker()->AsETSChecker(); - Type *sourceUnboxedType = checker->MaybeUnboxType(data.source); - relation->GetNode()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(sourceUnboxedType)); - relation->GetNode()->AddBoxingUnboxingFlags(checker->GetBoxingFlag(data.target)); + if (isLegalBoxedPrimitiveConversion) { + relation->Result(true); } uncheckedCast_ = relation->UncheckedCast(); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index c314bd252b34e69beea444e7aef3df52d019fd3d..b9925d61d0e3fd53087f4d0f6df600dbb0d0f0d2 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -16,6 +16,7 @@ #include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/ets/etsTupleType.h" #include "generated/signatures.h" +#include "checker/ets/wideningConverter.h" #include "varbinder/ETSBinder.h" #include "checker/ETSchecker.h" #include "checker/ets/function_helpers.h" @@ -341,11 +342,13 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, // #22952: infer optional parameter heuristics auto const paramType = GetNonNullishType(substitutedSig->Params()[index]->TsType()); if (argument->IsObjectExpression()) { - if (paramType->IsETSObjectType()) { - // No chance to check the argument at this point - continue; + if (!paramType->IsETSObjectType()) { + return false; } - return false; + if (paramType->AsETSObjectType()->IsBoxedPrimitive()) { + return false; + } + argument->AsObjectExpression()->SetPreferredType(paramType); } if (argument->IsMemberExpression()) { @@ -392,7 +395,7 @@ bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, i // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) Type *argumentType = argument->Check(this); - flags |= TypeRelationFlag::ONLY_CHECK_WIDENING; + flags |= (TypeRelationFlag::ONLY_CHECK_WIDENING); auto const invocationCtx = checker::InvocationContext(Relation(), argument, argumentType, targetType, argument->Start(), @@ -404,12 +407,13 @@ bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, i bool ETSChecker::IsValidRestArgument(ir::Expression *const argument, Signature *const substitutedSig, const TypeRelationFlag flags, const std::size_t index) { + auto *restParam = substitutedSig->RestVar()->TsType(); if (argument->IsObjectExpression()) { + argument->AsObjectExpression()->SetPreferredType(restParam->AsETSArrayType()->ElementType()); // Object literals should be checked separately afterwards after call resolution return true; } const auto argumentType = argument->Check(this); - auto *restParam = substitutedSig->RestVar()->TsType(); if (restParam->IsETSTupleType()) { return false; } @@ -585,6 +589,7 @@ std::array GetFlagVariants() }; } +// CC-OFFNXT(huge_method) solid logic ArenaVector ETSChecker::CollectSignatures(ArenaVector &signatures, const ir::TSTypeParameterInstantiation *typeArguments, const ArenaVector &arguments, @@ -594,12 +599,20 @@ ArenaVector ETSChecker::CollectSignatures(ArenaVector std::vector argTypeInferenceRequired = FindTypeInferenceArguments(arguments); Signature *notVisibleSignature = nullptr; + if (signatures.size() > 1) { + resolveFlags |= TypeRelationFlag::OVERLOADING_CONTEXT; + } + auto collectSignatures = [&](TypeRelationFlag relationFlags) { for (auto *sig : signatures) { if (notVisibleSignature != nullptr && !IsSignatureAccessible(sig, Context().ContainingClass(), Relation())) { continue; } + if (sig->HasSignatureFlag(SignatureFlags::BRIDGE)) { + // Bridges are never invoked direcly + continue; + } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *concreteSig = ValidateSignature(std::make_tuple(sig, typeArguments, relationFlags), arguments, pos, argTypeInferenceRequired, signatures.size() == 1); @@ -757,6 +770,8 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector return true; }; + auto isGeneric = [](const Signature *sig) { return sig->TypeParams().empty(); }; + Signature *result = nullptr; size_t currentMinLength = SIZE_MAX; @@ -780,8 +795,14 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector if (candidateLength < currentLength) { result = candidate; // Shorter parameter count wins currentMinLength = result->Function()->Params().size(); - } else if (candidateLength == currentLength) { - // Ambiguous resolution for same-length params + } else if (candidateLength >= currentLength) { + continue; + } else if (!isGeneric(candidate) && isGeneric(result)) { + result = candidate; + } else if (isGeneric(candidate) && !isGeneric(result)) { + continue; + } else { + // Ambiguous resolution for same-length params, same genericity if (result->Owner() == candidate->Owner()) { result = nullptr; } @@ -797,16 +818,45 @@ static Type *GetParatmeterTypeOrRestAtIdx(checker::ETSChecker *checker, Signatur : checker->GetElementTypeOfArray(sig->RestVar()->TsType()); } -static void InitMostSpecificType(checker::ETSChecker *checker, const ArenaVector &signatures, +static void InitMostSpecificType(TypeRelation *relation, const ArenaVector &signatures, [[maybe_unused]] Type *&mostSpecificType, [[maybe_unused]] Signature *&prevSig, const size_t idx) { + // Attempt to choose the widest type of available ones + SavedTypeRelationFlagsContext ctx {relation, TypeRelationFlag::WIDENING | TypeRelationFlag::ONLY_CHECK_WIDENING}; + auto checker = relation->GetChecker()->AsETSChecker(); for (auto *sig : signatures) { - if (Type *sigType = GetParatmeterTypeOrRestAtIdx(checker, sig, idx); - sigType->IsETSObjectType() && !sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { + Type *sigType = GetParatmeterTypeOrRestAtIdx(checker, sig, idx); + relation->Result(false); + + if (sigType->IsETSObjectType()) { + if (sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { + continue; + } + if (!sigType->AsETSObjectType()->IsBoxedPrimitive()) { + // Found "non-primitive" ref type + mostSpecificType = sigType; + prevSig = sig; + return; + } + relation->SetNode(prevSig->Function()->Params()[idx]->AsETSParameterExpression()); + if (relation->IsLegalBoxedPrimitiveConversion(sigType, mostSpecificType)) { + mostSpecificType = sigType; + prevSig = sig; + continue; + } + } + if (sigType->IsETSFunctionType() && relation->IsSupertypeOf(sigType, mostSpecificType)) { mostSpecificType = sigType; prevSig = sig; - return; + continue; + } + relation->Result(false); + WideningConverter(checker, relation, sigType, mostSpecificType); + if (relation->IsTrue()) { + mostSpecificType = sigType; + prevSig = sig; + continue; } } } @@ -817,17 +867,34 @@ void ETSChecker::SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature { auto [pos, idx, sig] = info; Type *sigType = GetParatmeterTypeOrRestAtIdx(this, sig, idx); + if (prevSig->Function()->Params()[idx]->IsETSParameterExpression()) { + Relation()->SetNode(prevSig->Function()->Params()[idx]->AsETSParameterExpression()); + } const bool isClassType = sigType->IsETSObjectType() && !sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE); if (isClassType == lookForClassType) { if (Relation()->IsIdenticalTo(sigType, mostSpecificType)) { + Relation()->SetNode(nullptr); return; } + if (isClassType && sigType->AsETSObjectType()->IsBoxedPrimitive() && mostSpecificType->IsETSObjectType() && + mostSpecificType->AsETSObjectType()->IsBoxedPrimitive()) { + TypeRelationFlag flags = TypeRelationFlag::NO_THROW | TypeRelationFlag::UNBOXING | + TypeRelationFlag::BOXING | TypeRelationFlag::WIDENING; + Relation()->SetFlags(flags); + if (Relation()->IsLegalBoxedPrimitiveConversion(mostSpecificType, sigType)) { + Relation()->Result(true); + mostSpecificType = sigType; + prevSig = sig; + return; + } + } if (Relation()->IsAssignableTo(sigType, mostSpecificType)) { mostSpecificType = sigType; prevSig = sig; } else if (sigType->IsETSObjectType() && mostSpecificType->IsETSObjectType() && - !Relation()->IsAssignableTo(mostSpecificType, sigType)) { + !Relation()->IsAssignableTo(mostSpecificType, sigType) && + !Relation()->IsLegalBoxedPrimitiveConversion(sigType, mostSpecificType)) { auto funcName = sig->Function()->Id()->Name(); LogError(diagnostic::AMBIGUOUS_CALL, {funcName, funcName, funcName, prevSig, funcName, sig}, pos); } @@ -864,7 +931,9 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter Type *mostSpecificType = signatures.front()->Params().at(i)->TsType(); Signature *prevSig = signatures.front(); - InitMostSpecificType(this, signatures, mostSpecificType, prevSig, i); + // NOTE: first we choose the some signature with possibly widest argumetns' types + // Then we search for the most specific signature + InitMostSpecificType(Relation(), signatures, mostSpecificType, prevSig, i); for (auto *sig : signatures) { SearchAmongMostSpecificTypes(mostSpecificType, prevSig, std::make_tuple(pos, i, sig), true); } @@ -1012,6 +1081,31 @@ void ETSChecker::UpdateDeclarationFromSignature(ir::CallExpression *expr, checke callIdentifier->SetVariable(newVar); } +Signature *ETSChecker::MakeSignatureInvocable(Signature *sig, ir::CallExpression *callExpr) +{ + if (sig == nullptr) { + return nullptr; + } + std::size_t const argumentCount = callExpr->Arguments().size(); + std::size_t const parameterCount = sig->Params().size(); + auto count = std::min(parameterCount, argumentCount); + for (std::size_t idx = 0; idx < count; ++idx) { + // Kludge to make promise code compile + if (callExpr->Arguments().at(idx)->IsArrowFunctionExpression()) { + continue; + } + + auto ctx = checker::AssignmentContext( + Relation(), callExpr->Arguments().at(idx), callExpr->Arguments().at(idx)->TsType(), + sig->Params().at(idx)->TsType(), callExpr->Arguments().at(idx)->Start(), + {{diagnostic::INVALID_ASSIGNMNENT, {sig->Params().at(idx)->TsType(), sig->Params().at(idx)->TsType()}}}); + if (!ctx.IsAssignable()) { + return nullptr; + } + } + return sig; +} + Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVector &signatures, ir::CallExpression *callExpr, const lexer::SourcePosition &pos, @@ -1021,6 +1115,7 @@ Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVectorTypeParams(), callExpr->Arguments(), pos, "call", reportFlag); + sig = MakeSignatureInvocable(sig, callExpr); UpdateDeclarationFromSignature(callExpr, sig); return sig; } @@ -1040,6 +1135,7 @@ Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVectorTypeParams(), callExpr->Arguments(), pos, "call", reportFlag); + sig = MakeSignatureInvocable(sig, callExpr); if (sig != nullptr) { EnsureValidCurlyBrace(callExpr); } @@ -1164,7 +1260,8 @@ checker::Type *ETSChecker::BuildMethodSignature(ir::MethodDefinition *method) } bool ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload, - const ir::MethodDefinition *const currentFunc, bool omitSameAsm) + const ir::MethodDefinition *const currentFunc, bool omitSameAsm, + TypeRelationFlag relationFlags) { // Don't necessary to check overload for invalid functions if (func->Name().Is(ERROR_LITERAL)) { @@ -1172,7 +1269,7 @@ bool ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType return false; } - SavedTypeRelationFlagsContext savedFlagsCtx(Relation(), TypeRelationFlag::NO_RETURN_TYPE_CHECK); + SavedTypeRelationFlagsContext savedFlagsCtx(Relation(), relationFlags); Relation()->SignatureIsIdenticalTo(func->CallSignatures()[0], overload->CallSignatures()[0]); if (Relation()->IsTrue() && func->CallSignatures()[0]->GetSignatureInfo()->restVar == @@ -2122,30 +2219,23 @@ size_t &ETSChecker::ConstraintCheckScopesCount() return constraintCheckScopesCount_; } -bool ETSChecker::CmpAssemblerTypesWithRank(Signature const *const sig1, Signature const *const sig2) noexcept +bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept { - for (size_t ix = 0U; ix < sig1->Params().size(); ++ix) { - std::stringstream s1; - std::stringstream s2; - sig1->Params()[ix]->TsType()->ToAssemblerTypeWithRank(s1); - sig2->Params()[ix]->TsType()->ToAssemblerTypeWithRank(s2); - if (s1.str() != s2.str()) { - return false; - break; - } + if (sig1->ReturnType()->ToAssemblerTypeWithRank() != sig2->ReturnType()->ToAssemblerTypeWithRank()) { + return false; } - return true; -} -bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept -{ if (sig1->ArgCount() != sig2->ArgCount()) { return false; } - if (!CmpAssemblerTypesWithRank(sig1, sig2)) { - return false; + for (size_t ix = 0U; ix < sig1->Params().size(); ++ix) { + if (sig1->Params()[ix]->TsType()->ToAssemblerTypeWithRank() != + sig2->Params()[ix]->TsType()->ToAssemblerTypeWithRank()) { + return false; + } } + auto *rv1 = sig1->RestVar(); auto *rv2 = sig2->RestVar(); if (rv1 == nullptr && rv2 == nullptr) { @@ -2154,11 +2244,8 @@ bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature if (rv1 == nullptr || rv2 == nullptr) { // exactly one of them is null return false; } - std::stringstream s1; - std::stringstream s2; - rv1->TsType()->ToAssemblerTypeWithRank(s1); - rv2->TsType()->ToAssemblerTypeWithRank(s2); - return s1.str() == s2.str(); + + return (rv1->TsType()->ToAssemblerTypeWithRank() == rv2->TsType()->ToAssemblerTypeWithRank()); } bool ETSChecker::HasSameAssemblySignatures(ETSFunctionType const *const func1, diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index b144fbcb545aabf51a7b6b2ef4a99d486a9a6766..f5412482ab4873eced049428c912c3a909b4c14f 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -16,6 +16,8 @@ #include "checker/ETSchecker.h" #include "checker/types/globalTypesHolder.h" +#include "checker/checkerContext.h" +#include "checker/ETSAnalyzerHelpers.h" #include "checker/types/ets/etsTupleType.h" #include "checker/ets/typeRelationContext.h" #include "checker/ets/typeConverter.h" @@ -367,6 +369,27 @@ checker::Type *ETSChecker::ApplyConditionalOperatorPromotion(checker::ETSChecker ES2PANDA_UNREACHABLE(); } +Type *ETSChecker::GetUnaryOperatorPromotedType(Type *type, const bool doPromotion, const bool isCondExpr) +{ + auto globalTypesHolder = GetGlobalTypesHolder(); + + if (doPromotion) { + if (type == globalTypesHolder->GlobalByteBuiltinType() || type == globalTypesHolder->GlobalShortBuiltinType() || + type == globalTypesHolder->GlobalCharBuiltinType() || + type == globalTypesHolder->GlobalIntegerBuiltinType()) { + return globalTypesHolder->GlobalIntegerBuiltinType(); + } + + Type *unboxedType = isCondExpr ? MaybeUnboxConditionalInRelation(type) : MaybeUnboxInRelation(type); + + if (type->IsIntType() || type->IsByteType() || type->IsShortType() || type->IsCharType()) { + return CreateIntTypeFromType(unboxedType); + } + } + + return type; +} + Type *ETSChecker::ApplyUnaryOperatorPromotion(Type *type, const bool createConst, const bool doPromotion, const bool isCondExpr) { @@ -403,7 +426,7 @@ bool ETSChecker::IsNullLikeOrVoidExpression(const ir::Expression *expr) const std::tuple ETSChecker::IsResolvedAndValue(const ir::Expression *expr, Type *type) const { auto [isResolve, isValue] = - IsNullLikeOrVoidExpression(expr) ? std::make_tuple(true, false) : type->ResolveConditionExpr(); + IsNullLikeOrVoidExpression(expr) ? std::make_tuple(true, false) : IsConstantTestValue(expr); const Type *tsType = expr->TsType(); if (tsType->DefinitelyNotETSNullish() && !type->IsETSPrimitiveOrEnumType()) { @@ -453,15 +476,6 @@ Type *ETSChecker::HandleBooleanLogicalOperators(Type *leftType, Type *rightType, bool ETSChecker::HandleLogicalPotentialResult(ir::Expression *left, ir::Expression *right, ir::BinaryExpression *expr, checker::Type *leftType) { - if (leftType->IsConstantType() && leftType->IsETSBooleanType()) { - if (expr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) { - expr->SetResult(leftType->AsETSBooleanType()->GetValue() ? right : left); - return true; - } - expr->SetResult(leftType->AsETSBooleanType()->GetValue() ? left : right); - return true; - } - if (!leftType->IsETSPrimitiveType() && !leftType->PossiblyETSValueTyped()) { expr->SetResult(expr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND ? right : left); return true; @@ -534,7 +548,6 @@ checker::Type *ETSChecker::CheckArrayElements(ir::ArrayExpression *init) for (auto *typeFromTuple : elementType->AsETSTupleType()->GetTupleTypesList()) { elementTypes.emplace_back(typeFromTuple); } - continue; } @@ -542,22 +555,30 @@ checker::Type *ETSChecker::CheckArrayElements(ir::ArrayExpression *init) elementType = elementType->AsETSArrayType()->ElementType(); } - elementTypes.push_back(GetNonConstantType(elementType)); + elementTypes.emplace_back(elementType); } if (elementTypes.empty()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return Allocator()->New(GlobalETSObjectType()); } - auto const isNumeric = [](checker::Type *ct) { return ct->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); }; - auto const isChar = [](checker::Type *ct) { return ct->HasTypeFlag(TypeFlag::CHAR); }; - auto *const arrayElementType = - std::all_of(elementTypes.begin(), elementTypes.end(), isNumeric) - ? std::all_of(elementTypes.begin(), elementTypes.end(), isChar) ? GlobalCharType() : GlobalDoubleType() - : CreateETSUnionType(std::move(elementTypes)); + auto const isNumericLiteral = [this](checker::Type *&ct) { + auto const rc = + ct->IsConstantType() && Relation()->IsSupertypeOf(GetGlobalTypesHolder()->GlobalNumericBuiltinType(), ct); + ct = GetNonConstantType(ct); + return rc; + }; + auto const isChar = [this](checker::Type *ct) { + return Relation()->IsSupertypeOf(GetGlobalTypesHolder()->GlobalCharBuiltinType(), ct); + }; + auto const elementType = std::all_of(elementTypes.begin(), elementTypes.end(), isNumericLiteral) + ? std::all_of(elementTypes.begin(), elementTypes.end(), isChar) + ? GlobalCharBuiltinType() + : GlobalDoubleBuiltinType() + : CreateETSUnionType(std::move(elementTypes)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return CreateETSResizableArrayType(arrayElementType); + return CreateETSResizableArrayType(elementType); } void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::ArrowFunctionExpression *init) @@ -995,7 +1016,7 @@ checker::Type *ETSChecker::GetExtensionAccessorReturnType(ir::MemberExpression * // Smart cast support //==============================================================================// -checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker::Type *targetType) +checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker::Type *targetType, bool narrowingAllowed) { // For left-hand variable of primitive type leave it as is. if (targetType->IsETSPrimitiveType()) { @@ -1035,7 +1056,7 @@ checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker:: // Because now we have logging of errors we have to continue analyze incorrect program, for // this case we change typeError to source type. if (targetType->IsETSUnionType()) { - auto component = targetType->AsETSUnionType()->GetAssignableType(this, sourceType); + auto component = targetType->AsETSUnionType()->GetAssignableType(this, sourceType, narrowingAllowed); return component->IsTypeError() ? MaybeBoxType(sourceType) : component; } @@ -1809,7 +1830,9 @@ void ETSChecker::ConcatConstantString(util::UString &target, Type *type) { switch (ETSType(type)) { case TypeFlag::ETS_OBJECT: { - ES2PANDA_ASSERT(type->IsETSStringType()); + if (!type->IsETSStringType()) { + break; + } target.Append(type->AsETSStringType()->GetValue()); break; } @@ -2123,7 +2146,7 @@ void ETSChecker::CheckItemCasesConstant(ArenaVector c if (caseTest == nullptr) { continue; } - auto *caseType = caseTest->TsType(); + auto *caseType = MaybeUnboxType(caseTest->TsType()); if (caseType->HasTypeFlag(TypeFlag::TYPE_ERROR)) { continue; } @@ -2201,7 +2224,7 @@ void ETSChecker::CheckItemCasesDuplicate(ArenaVector } if (caseTest->IsLiteral() && compareCaseTest->IsLiteral() && - GetStringFromLiteral(caseTest) != GetStringFromLiteral(compareCaseTest)) { + caseTest->AsLiteral()->ToString() != compareCaseTest->AsLiteral()->ToString()) { continue; } @@ -2231,7 +2254,7 @@ bool ETSChecker::CompareIdentifiersValuesAreDifferent(ir::Expression *compareVal return caseValue != compareCaseValue; } - return caseValue != GetStringFromLiteral(compareValue); + return caseValue != compareValue->ToString(); } void ETSChecker::CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase, @@ -2255,23 +2278,6 @@ void ETSChecker::CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expr } } -std::string ETSChecker::GetStringFromLiteral(ir::Expression *caseTest) const -{ - switch (caseTest->Type()) { - case ir::AstNodeType::CHAR_LITERAL: { - return std::to_string(caseTest->AsCharLiteral()->Char()); - } - case ir::AstNodeType::STRING_LITERAL: - case ir::AstNodeType::NULL_LITERAL: - case ir::AstNodeType::UNDEFINED_LITERAL: - case ir::AstNodeType::NUMBER_LITERAL: { - return util::Helpers::LiteralToPropName(caseTest).Mutf8(); - } - default: - ES2PANDA_UNREACHABLE(); - } -} - bool ETSChecker::IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare) { return target->Declaration()->Type() == compare->Declaration()->Type(); @@ -2624,6 +2630,7 @@ ir::ClassProperty *ETSChecker::ClassPropToImplementationProp(ir::ClassProperty * return classProp; } +// CC-OFFNXT(huge_method) solid logic void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, ArenaVector ¶ms, ir::ClassProperty *const field, varbinder::FunctionParamScope *paramScope, bool isSetter) @@ -2685,6 +2692,7 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto ident = AllocNode(paramExpression->Ident()->Name(), Allocator()); ident->SetVariable(paramExpression->Variable()); + ident->SetTsTypeAnnotation(nullptr); auto *assignmentExpression = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) AllocNode(memberExpression, ident, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); @@ -2720,6 +2728,7 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); + auto classCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), classScope); ArenaVector params(checker->Allocator()->Adapter()); ArenaVector stmts(checker->Allocator()->Adapter()); @@ -2775,7 +2784,6 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty paramScope->BindNode(func); functionScope->BindNode(func); - auto classCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), classScope); checker->VarBinder()->AsETSBinder()->ResolveMethodDefinition(method); functionScope->BindName(classScope->Node()->AsClassDefinition()->InternalName()); @@ -2894,6 +2902,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin getter->Variable()->TsType()->AsETSFunctionType()->AddCallSignature( setter->TsType()->AsETSFunctionType()->CallSignatures()[0]); getter->AddOverload(setter); + setter->SetParent(getter); } } diff --git a/ets2panda/checker/ets/narrowingConverter.h b/ets2panda/checker/ets/narrowingConverter.h index f42051d88b9042d717680e29e899a2d0f472c87b..483c72aa61fa3d8c2697c8e01a6bce10505eca9a 100644 --- a/ets2panda/checker/ets/narrowingConverter.h +++ b/ets2panda/checker/ets/narrowingConverter.h @@ -173,27 +173,49 @@ private: using SType = typename SourceType::UType; using TType = typename TargetType::UType; + // in case of + // let d: Char; + // const s: Short = -129 + // d = s + // we have to check for NumberLiteral too, because after ConstantExpressionLowering src will look like + // let d: Char; + // const s: Short = -129 + // d = -129 + // And NumberLiteral "-129" will have type Short. It should be CTE: value out of range + // NOTE: The same situation with CharLiteral + // NOTE: After complete removing primitive types refactor is needed + if (!Source()->HasTypeFlag(TypeFlag::CONSTANT) && !Relation()->GetNode()->IsNumberLiteral() && + !Relation()->GetNode()->IsCharLiteral()) { + Relation()->Result(true); + return; + } + + SType value; if (Source()->HasTypeFlag(TypeFlag::CONSTANT)) { - SType value = reinterpret_cast(Source())->GetValue(); - if (!Relation()->InCastingContext() && Source()->HasTypeFlag(TypeFlag::ETS_FLOATING_POINT) && - Target()->HasTypeFlag(TypeFlag::ETS_INTEGRAL)) { - auto narrowedValue = CalculateNarrowedValue(Target(), Source(), value); - if (narrowedValue != value) { - Relation()->Result(RelationResult::ERROR); - return; - } - } + value = reinterpret_cast(Source())->GetValue(); + } else if (Relation()->GetNode()->IsNumberLiteral()) { + // NumberLiteral + value = Relation()->GetNode()->AsNumberLiteral()->Number().GetValueAndCastTo(); + } else { + // CharLiteral + value = static_cast(Relation()->GetNode()->AsCharLiteral()->Char()); + } - if (Relation()->InCastingContext() || util::Helpers::IsTargetFitInSourceRange(value)) { - Relation()->Result(true); + if (!Relation()->InCastingContext() && Source()->HasTypeFlag(TypeFlag::ETS_FLOATING_POINT) && + Target()->HasTypeFlag(TypeFlag::ETS_INTEGRAL)) { + auto narrowedValue = CalculateNarrowedValue(Target(), Source(), value); + if (narrowedValue != value) { + Relation()->Result(RelationResult::ERROR); return; } + } - Relation()->Result(RelationResult::ERROR); + if (Relation()->InCastingContext() || util::Helpers::IsTargetFitInSourceRange(value)) { + Relation()->Result(true); return; } - Relation()->Result(true); + Relation()->Result(RelationResult::ERROR); } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 4c1bd6ba8b6eaa8d9b5b34e2d8fbc379fa430a56..35ac9d8ae205a5326567fb0f4ace24dbafc3a494 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1467,37 +1467,6 @@ void ETSChecker::CheckInnerClassMembers(const ETSObjectType *classType) } } -lexer::Number ETSChecker::ExtractNumericValue(Type const *const indexType) -{ - TypeFlag typeKind = ETSType(indexType); - lexer::Number resNum; - switch (typeKind) { - case TypeFlag::BYTE: { - resNum = lexer::Number(indexType->AsByteType()->GetValue()); - break; - } - case TypeFlag::SHORT: { - resNum = lexer::Number(indexType->AsShortType()->GetValue()); - break; - } - case TypeFlag::INT: { - resNum = lexer::Number(indexType->AsIntType()->GetValue()); - break; - } - case TypeFlag::FLOAT: { - resNum = lexer::Number(indexType->AsFloatType()->GetValue()); - break; - } - case TypeFlag::DOUBLE: { - resNum = lexer::Number(indexType->AsDoubleType()->GetValue()); - break; - } - default: - break; - } - return resNum; -} - bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) { auto const expressionType = expr->Check(this); @@ -1510,28 +1479,8 @@ bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) expr->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedExpressionType)); } - Type const *const indexType = ApplyUnaryOperatorPromotion(expressionType); - - if (relaxed && indexType != nullptr) { - lexer::Number resNum = ExtractNumericValue(indexType); - double value = resNum.GetDouble(); - double intpart; - if (std::modf(value, &intpart) != 0.0) { - LogError(diagnostic::INDEX_NONINTEGRAL_FLOAT, {}, expr->Start()); - return false; - } - bool tildeFlag = false; - if (expr->IsUnaryExpression() && - expr->AsUnaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_TILDE) { - tildeFlag = true; - } - if ((tildeFlag && value > 0) || (!tildeFlag && value < 0)) { - LogError(diagnostic::NEGATIVE_INDEX, {}, expr->Start()); - return false; - } - } - - if (indexType == nullptr || + if (Type const *const indexType = ApplyUnaryOperatorPromotion(expressionType); + indexType == nullptr || (!indexType->HasTypeFlag(relaxed ? (TypeFlag::ETS_ARRAY_INDEX | TypeFlag::ETS_FLOATING_POINT) : TypeFlag::ETS_ARRAY_INDEX))) { std::stringstream message(""); @@ -1541,11 +1490,51 @@ bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) return false; } + if (!relaxed || !expressionType->IsConstantType()) { + return true; + } + + ASSERT(expr->IsNumberLiteral()); + double value = expr->AsNumberLiteral()->Number().GetDouble(); + + double intPart; + if (std::modf(value, &intPart) != 0.0) { + LogError(diagnostic::INDEX_NONINTEGRAL_FLOAT, {}, expr->Start()); + return false; + } + + if (intPart < 0.0) { + LogError(diagnostic::NEGATIVE_INDEX, {}, expr->Start()); + return false; + } + return true; } -std::optional ETSChecker::GetTupleElementAccessValue(const Type *const type) +std::optional ETSChecker::GetTupleElementAccessValue(const ir::Expression *expr) { + auto checkLongValBounds = [this](int64_t val, const lexer::SourcePosition &p) -> std::optional { + if (val < 0) { + LogError(diagnostic::TUPLE_INDEX_OOB, {}, p); + return std::nullopt; + } + return static_cast(val); + }; + + if (expr->IsNumberLiteral()) { + auto num = expr->AsNumberLiteral()->Number(); + if (num.IsInt()) { + return checkLongValBounds(num.GetInt(), expr->Start()); + } + if (num.IsLong()) { + return checkLongValBounds(num.GetLong(), expr->Start()); + } + ES2PANDA_UNREACHABLE(); + } + + // Below code should be unreachable after removing primitives + auto type = expr->TsType(); + ES2PANDA_ASSERT(type->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); switch (ETSType(type)) { @@ -1574,14 +1563,9 @@ std::optional ETSChecker::GetTupleElementAccessValue(const Type *co bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberExpression *const expr, const bool reportError) { - auto const expressionType = expr->Property()->Check(this); - auto const *const unboxedExpressionType = MaybeUnboxInRelation(expressionType); - - if (expressionType->IsETSObjectType() && (unboxedExpressionType != nullptr)) { - expr->Property()->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedExpressionType)); - } + auto const exprType = expr->Property()->Check(this); + auto const *const unboxedExpressionType = MaybeUnboxInRelation(exprType); - const auto *const exprType = expr->Property()->TsType(); ES2PANDA_ASSERT(exprType != nullptr); if (!exprType->HasTypeFlag(TypeFlag::CONSTANT)) { @@ -1594,14 +1578,13 @@ bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberE return false; } - if (!exprType->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX | TypeFlag::LONG)) { - if (reportError) { - LogError(diagnostic::TUPLE_INDEX_NOT_INT, {}, expr->Property()->Start()); - } + if (!Relation()->IsSupertypeOf(GlobalIntBuiltinType(), exprType) && + !Relation()->IsSupertypeOf(GlobalLongBuiltinType(), exprType)) { + LogError(diagnostic::TUPLE_INDEX_NOT_INT, {}, expr->Property()->Start()); return false; } - auto exprValue = GetTupleElementAccessValue(exprType); + auto exprValue = GetTupleElementAccessValue(expr->Property()); if (!exprValue.has_value() || (*exprValue >= tuple->GetTupleSize())) { if (reportError) { LogError(diagnostic::TUPLE_INDEX_OOB, {}, expr->Property()->Start()); @@ -1614,6 +1597,13 @@ bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberE bool ETSChecker::ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple, ir::MemberExpression *const expr) { + if (expr->Property() == nullptr || expr->Property()->Variable() == nullptr || + expr->Property()->Variable()->Declaration() == nullptr || + expr->Property()->Variable()->Declaration()->Node() == nullptr || + expr->Property()->Variable()->Declaration()->Node()->AsClassElement() == nullptr) { + LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Start()); + return false; + } auto *value = expr->Property()->Variable()->Declaration()->Node()->AsClassElement()->Value(); if (value == nullptr) { LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Property()->Start()); @@ -1631,7 +1621,7 @@ bool ETSChecker::ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple return false; } - auto exprValue = GetTupleElementAccessValue(exprType); + auto exprValue = GetTupleElementAccessValue(expr); if (!exprValue.has_value() || (*exprValue >= tuple->GetTupleSize())) { LogError(diagnostic::TUPLE_INDEX_OOB, {}, expr->Property()->Start()); return false; @@ -1917,6 +1907,9 @@ static bool ShouldRemoveStaticSearchFlag(const ir::MemberExpression *const membe if (object->IsMemberExpression()) { object = object->AsMemberExpression()->Property(); } + if (object->IsTypeNode()) { + return false; + } if (!object->IsIdentifier() || (object->AsIdentifier()->Variable() == nullptr) || object->AsIdentifier()->Variable()->HasFlag(varbinder::VariableFlags::INITIALIZED)) { return true; @@ -1957,6 +1950,9 @@ const varbinder::Variable *ETSChecker::GetTargetRef(const ir::MemberExpression * if (memberExpr->Object()->IsMemberExpression()) { return memberExpr->Object()->AsMemberExpression()->PropVar(); } + if (memberExpr->Object()->IsTypeNode() && memberExpr->Object()->TsType()->IsETSObjectType()) { + return memberExpr->Object()->TsType()->Variable(); + } return nullptr; } @@ -2466,21 +2462,7 @@ Type *ETSChecker::GetApparentType(Type *type) Type const *ETSChecker::GetApparentType(Type const *type) const { - if (auto it = apparentTypes_.find(type); LIKELY(it != apparentTypes_.end())) { - return it->second; - } - // Relaxed for some types - if (type->IsETSTypeParameter()) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return GetApparentType(type->AsETSTypeParameter()->GetConstraintType()); - } - if (type->IsETSArrayType()) { - return type; - } - if (type->IsETSUnionType() || type->IsETSNonNullishType() || type->IsETSPartialTypeParameter()) { - ASSERT_PRINT(false, std::string("Type ") + type->ToString() + " was not found in apparent_types_"); - } - return type; + return const_cast(const_cast(this)->GetApparentType(const_cast(type))); } ETSObjectType *ETSChecker::GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target) diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index e65e3567b01c32a7576334264a34e49faf516847..9ce7252c380f70ebd38826fe0eaabffd5403eafa 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -387,6 +387,9 @@ Type *ETSChecker::GetNonConstantType(Type *type) } if (!type->IsETSPrimitiveType()) { + if (type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive()) { + type->RemoveTypeFlag(TypeFlag::CONSTANT); + } return type; } @@ -1076,21 +1079,69 @@ void ETSChecker::CheckStandardAnnotation(ir::AnnotationUsage *anno) } } +static auto IsNonArrayLiteral(ir::Expression *init) +{ + if ((init == nullptr) || init->IsLiteral()) { + return true; + } + + if (init->TsType()->IsETSEnumType() && init->TsType()->AsETSEnumType()->NodeIsEnumLiteral(init)) { + init->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + return true; + } + return false; +} + +static auto IsValidAnnotationPropInitializer(ir::Expression *init) +{ + if (IsNonArrayLiteral(init)) { + return true; + } + + if (init->IsArrayExpression()) { + for (auto elem : init->AsArrayExpression()->Elements()) { + if (!IsValidAnnotationPropInitializer(elem)) { + return false; + } + } + return true; + } + return false; +} + +static bool ValidateAnnotationPropertyType(checker::Type *type, ETSChecker *checker) +{ + if (type == nullptr || type->IsTypeError()) { + ES2PANDA_ASSERT(checker->IsAnyError()); + return false; + } + + if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { + return ValidateAnnotationPropertyType(checker->GetElementTypeOfArray(type), checker); + } + auto relation = checker->Relation(); + return type->IsETSEnumType() || type->IsETSStringType() || + (type->IsETSObjectType() && (relation->IsSupertypeOf(checker->GlobalETSBooleanBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalByteBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalShortBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalIntBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalLongBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalFloatBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), type))); +} + void ETSChecker::CheckAnnotationPropertyType(ir::ClassProperty *property) { // typeAnnotation check - if (!ValidateAnnotationPropertyType(property->TsType())) { + if (!ValidateAnnotationPropertyType(property->TsType(), this)) { LogError(diagnostic::ANNOT_FIELD_INVALID_TYPE, {}, property->Start()); } - // The type of the Initializer has been check in the parser, - // except for the enumeration type, because it is a member expression, - // so here is an additional check to the enumeration type. - if (property->Value() != nullptr && - ((property->Value()->IsMemberExpression() && !property->TsType()->IsETSEnumType()) || - property->Value()->IsIdentifier())) { - LogError(diagnostic::ANNOTATION_FIELD_NONLITERAL, {}, property->Value()->Start()); + if (IsValidAnnotationPropInitializer(property->Value())) { + return; } + + LogError(diagnostic::ANNOTATION_FIELD_NONLITERAL, {}, property->Value()->Start()); } void ETSChecker::CheckSinglePropertyAnnotation(ir::AnnotationUsage *st, ir::AnnotationDeclaration *annoDecl) @@ -1108,20 +1159,6 @@ void ETSChecker::CheckSinglePropertyAnnotation(ir::AnnotationUsage *st, ir::Anno CheckAnnotationPropertyType(param); } -void ETSChecker::ProcessRequiredFields(ArenaUnorderedMap &fieldMap, - ir::AnnotationUsage *st, ETSChecker *checker) const -{ - for (const auto &entry : fieldMap) { - if (entry.second->Value() == nullptr) { - checker->LogError(diagnostic::ANNOT_FIELD_NO_VAL, {entry.first}, st->Start()); - continue; - } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *clone = entry.second->Clone(checker->Allocator(), st); - st->AddProperty(clone); - } -} - void ETSChecker::CheckMultiplePropertiesAnnotation(ir::AnnotationUsage *st, util::StringView const &baseName, ArenaUnorderedMap &fieldMap) { @@ -1452,6 +1489,7 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, // #22952: infer optional parameter heuristics auto nonNullishParam = param->IsOptional() ? GetNonNullishType(parameterType) : parameterType; if (!nonNullishParam->IsETSFunctionType()) { + arrowFuncExpr->Check(this); return true; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index 039b1ce024f0c488a8b6cd9453a88ec82250a60f..6b94d2fe42cf663cf21a1e8c1f02e319b7176d85 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -78,19 +78,7 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParame result_ = paramType; return; } - - if (paramType->IsETSPrimitiveType()) { - checker_->Relation()->SetNode(it); - - auto *const boxedTypeArg = checker_->MaybeBoxInRelation(paramType); - if (boxedTypeArg != nullptr) { - paramType = boxedTypeArg->Instantiate(checker_->Allocator(), checker_->Relation(), - checker_->GetGlobalTypesHolder()); - } else { - ES2PANDA_UNREACHABLE(); - } - } - + ES2PANDA_ASSERT(!paramType->IsETSPrimitiveType()); typeArgTypes.push_back(paramType); } } @@ -137,10 +125,10 @@ static void CheckInstantiationConstraints(ETSChecker *checker, ArenaVectorIsETSReferenceType() || typeArg->IsETSVoidType()); + auto maybeIrrelevantTypeArg = typeArg->IsETSVoidType() ? checker->GlobalETSUndefinedType() : typeArg; auto constraint = typeParam->GetConstraintType()->Substitute(relation, substitution); - if (!relation->IsAssignableTo(typeArg, constraint)) { - // NOTE(vpukhov): refine message - checker->LogError(diagnostic::INIT_NOT_ASSIGNABLE, {typeArg, constraint}, pos); + if (!relation->IsSupertypeOf(constraint, maybeIrrelevantTypeArg)) { + checker->LogError(diagnostic::TYPEARG_TYPEPARAM_SUBTYPING, {typeArg, constraint}, pos); } } } diff --git a/ets2panda/checker/ets/typeRelationContext.h b/ets2panda/checker/ets/typeRelationContext.h index ef6c5017f9cb026520b83ba5f7166d0b5855baeb..9a97781e878973eb81190d8a6cbf14d4c7b1ef65 100644 --- a/ets2panda/checker/ets/typeRelationContext.h +++ b/ets2panda/checker/ets/typeRelationContext.h @@ -55,9 +55,7 @@ public: if (!relation->IsAssignableTo(source, target)) { if (relation->IsLegalBoxedPrimitiveConversion(target, source)) { - Type *sourceUnboxedType = etsChecker->MaybeUnboxType(source); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetUnboxingFlag(sourceUnboxedType)); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetBoxingFlag(target)); + relation->Result(true); } if (((flags_ & TypeRelationFlag::UNBOXING) != 0) && !relation->IsTrue() && source->IsETSObjectType() && !target->IsETSObjectType()) { @@ -107,6 +105,9 @@ public: relation->SetFlags(flags_ | initialFlags); if (!relation->IsAssignableTo(source, target)) { + if (relation->IsLegalBoxedPrimitiveConversion(target, source)) { + relation->Result(true); + } if (((flags_ & TypeRelationFlag::UNBOXING) != 0U) && !relation->IsTrue() && source->IsETSObjectType() && !target->IsETSObjectType()) { etsChecker->CheckUnboxedSourceTypeWithWideningAssignable(relation, source, target); diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index c8d7e269c934a2c9ce648b4a110e2f879706fb87..2530894b03e64c062144799c9324cd716940dc2c 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -180,21 +180,6 @@ void ETSChecker::ValidateResolvedIdentifier(ir::Identifier *const ident) } } -bool ETSChecker::ValidateAnnotationPropertyType(checker::Type *type) -{ - if (type == nullptr || type->IsTypeError()) { - ES2PANDA_ASSERT(IsAnyError()); - return false; - } - - if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { - return ValidateAnnotationPropertyType(MaybeUnboxType(GetElementTypeOfArray(type))); - } - - return type->HasTypeFlag(TypeFlag::ETS_NUMERIC | TypeFlag::ETS_ENUM | TypeFlag::ETS_BOOLEAN) || - type->IsETSStringType(); -} - void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable) { if (IsVariableGetterSetter(variable)) { diff --git a/ets2panda/checker/types/ets/byteType.h b/ets2panda/checker/types/ets/byteType.h index a92f1f637d46d3611ba579ca23e7acc4cd63d9ca..a622ebc4e27e1b8bf50171ba47e1b301816d9c7e 100644 --- a/ets2panda/checker/types/ets/byteType.h +++ b/ets2panda/checker/types/ets/byteType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_BYTE; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/charType.cpp b/ets2panda/checker/types/ets/charType.cpp index 044657176938dfc8ba8914c7faeea14277b7dc57..73a36a05703144e5cae91cb20a51e17066e144ba 100644 --- a/ets2panda/checker/types/ets/charType.cpp +++ b/ets2panda/checker/types/ets/charType.cpp @@ -37,11 +37,6 @@ void CharType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *s bool CharType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) { if (relation->InAssignmentContext()) { - if (target->IsETSStringType()) { - conversion::Boxing(relation, this); - relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); - return relation->Result(true); - } relation->GetChecker()->AsETSChecker()->CheckUnboxedTypeWidenable(relation, target, this); if (!relation->IsTrue()) { return false; @@ -72,11 +67,6 @@ void CharType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSStringType()) { - conversion::String(relation, this); - return; - } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { conversion::Boxing(relation, this); diff --git a/ets2panda/checker/types/ets/charType.h b/ets2panda/checker/types/ets/charType.h index 9ddb9054ff1173910324d71e2ccdb1a65e3854e6..793a64ea4ed52a5ed44f86b1a6439623f9e55375 100644 --- a/ets2panda/checker/types/ets/charType.h +++ b/ets2panda/checker/types/ets/charType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_CHAR; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != '\0'}; - } - private: UType value_ {'\0'}; }; diff --git a/ets2panda/checker/types/ets/doubleType.h b/ets2panda/checker/types/ets/doubleType.h index e7e7dde792299f53ba775bea89d0a674dab337d2..fa3d5de326b61b66c9a6eaa2f745f8d82e7044a4 100644 --- a/ets2panda/checker/types/ets/doubleType.h +++ b/ets2panda/checker/types/ets/doubleType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,12 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_DOUBLE; } - std::tuple ResolveConditionExpr() const override - { - // isNan = !(value_ == value_) - return {IsConstantType(), (value_ != 0) && (value_ == value_)}; - } - private: UType value_ {0.0}; }; diff --git a/ets2panda/checker/types/ets/etsArrayType.cpp b/ets2panda/checker/types/ets/etsArrayType.cpp index 2f0573d664103a80b83e96d590b62ca7d01da44c..79d9cc398389767328cfa2ccc2d9a51868e91f81 100644 --- a/ets2panda/checker/types/ets/etsArrayType.cpp +++ b/ets2panda/checker/types/ets/etsArrayType.cpp @@ -111,7 +111,7 @@ void ETSArrayType::AssignmentTarget(TypeRelation *relation, Type *source) source->AsETSArrayType()->ElementType()->IsETSPrimitiveOrEnumType()) { return; } - relation->IsAssignableTo(source->AsETSArrayType()->ElementType(), element_); + relation->IsSupertypeOf(element_, source->AsETSArrayType()->ElementType()); } } diff --git a/ets2panda/checker/types/ets/etsArrayType.h b/ets2panda/checker/types/ets/etsArrayType.h index 9794adb54f0f11e1a5cc0dfb2a2ffc7b528fdde4..c9dd00904fffa7d09046075fde8e94a49ff87db8 100644 --- a/ets2panda/checker/types/ets/etsArrayType.h +++ b/ets2panda/checker/types/ets/etsArrayType.h @@ -38,11 +38,6 @@ public: element_ = element; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp index 46308e495d546fec72639801ef3c8588619a8f9a..599a503b4334018bdc4681681d7e1e475927ad0c 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp @@ -39,6 +39,15 @@ void ETSAsyncFuncReturnType::Identical(TypeRelation *relation, Type *other) relation->Result(false); } +void ETSAsyncFuncReturnType::IsSupertypeOf(TypeRelation *relation, Type *source) +{ + GetPromiseTypeArg()->IsSupertypeOf(relation, source); + if (relation->IsTrue()) { + return; + } + promiseType_->IsSupertypeOf(relation, source); +} + bool ETSAsyncFuncReturnType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) { return false; diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h index e1ede4842b6fe35b3dc6ac4d712bf8e26ed064f2..1cdc68d3896d5743b7f045773b0ed792dcb57333 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h @@ -33,6 +33,7 @@ public: void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; diff --git a/ets2panda/checker/types/ets/etsBooleanType.h b/ets2panda/checker/types/ets/etsBooleanType.h index 421ae63e3b29b5ff3b070f1b25c482a73f8343ef..2bc7ccaddca17d8268de62ba33e7fbaa7a3aa371 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.h +++ b/ets2panda/checker/types/ets/etsBooleanType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -51,11 +51,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_BOOLEAN; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_}; - } - private: UType value_ {false}; }; diff --git a/ets2panda/checker/types/ets/etsEnumType.h b/ets2panda/checker/types/ets/etsEnumType.h index a5c6bdf33d7a3e767413365b6105f75f9114285b..414a2e61024caa2bfe4ad00d8ae760d70e68c037 100644 --- a/ets2panda/checker/types/ets/etsEnumType.h +++ b/ets2panda/checker/types/ets/etsEnumType.h @@ -19,6 +19,10 @@ #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsObjectTypeConstants.h" #include "checker/types/typeFlag.h" +#include "ir/base/classProperty.h" +#include "ir/expressions/arrayExpression.h" +#include "ir/expressions/literals/stringLiteral.h" +#include "ir/expressions/memberExpression.h" namespace ark::es2panda::checker { @@ -27,8 +31,10 @@ public: explicit ETSEnumType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, ir::AstNode *declNode, TypeRelation *relation) : ETSObjectType(allocator, name, internalName, - std::make_tuple(declNode, ETSObjectFlags::CLASS | ETSObjectFlags::ENUM_OBJECT, relation)) + std::make_tuple(declNode, ETSObjectFlags::CLASS | ETSObjectFlags::ENUM_OBJECT, relation)), + memberNameToOrdinal_(allocator->Adapter()) { + InitElementsShortcuts(declNode->AsClassDefinition()); } NO_COPY_SEMANTIC(ETSEnumType); @@ -37,14 +43,79 @@ public: ETSEnumType() = delete; ~ETSEnumType() override = default; - static constexpr std::string_view const TO_STRING_METHOD_NAME {"toString"}; - static constexpr std::string_view const VALUE_OF_METHOD_NAME {"valueOf"}; - static constexpr std::string_view const GET_NAME_METHOD_NAME {"getName"}; - static constexpr std::string_view const GET_VALUE_OF_METHOD_NAME {"getValueOf"}; - static constexpr std::string_view const FROM_VALUE_METHOD_NAME {"fromValue"}; - static constexpr std::string_view const VALUES_METHOD_NAME {"values"}; - static constexpr std::string_view const GET_ORDINAL_METHOD_NAME {"getOrdinal"}; - static constexpr std::string_view const DOLLAR_GET_METHOD_NAME {"$_get"}; + static constexpr std::string_view TO_STRING_METHOD_NAME {"toString"}; + static constexpr std::string_view VALUE_OF_METHOD_NAME {"valueOf"}; + static constexpr std::string_view GET_NAME_METHOD_NAME {"getName"}; + static constexpr std::string_view GET_VALUE_OF_METHOD_NAME {"getValueOf"}; + static constexpr std::string_view FROM_VALUE_METHOD_NAME {"fromValue"}; + static constexpr std::string_view VALUES_METHOD_NAME {"values"}; + static constexpr std::string_view GET_ORDINAL_METHOD_NAME {"getOrdinal"}; + static constexpr std::string_view DOLLAR_GET_METHOD_NAME {"$_get"}; + + static constexpr std::string_view STRING_VALUES_ARRAY_NAME {"#StringValuesArray"}; + static constexpr std::string_view VALUES_ARRAY_NAME {"#ValuesArray"}; + static constexpr std::string_view NAMES_ARRAY_NAME {"#NamesArray"}; + + auto *Underlying() + { + ES2PANDA_ASSERT(membersValues_->TsType() != nullptr); + return membersValues_->TsType()->AsETSArrayType()->ElementType(); + } + + auto GetOrdinalFromMemberName(std::string_view name) const + { + return memberNameToOrdinal_.at(name); + } + + auto GetValueLiteralFromOrdinal(size_t ord) const + { + ES2PANDA_ASSERT(ord < membersValues_->Elements().size()); + return membersValues_->Elements()[ord]; + } + + bool NodeIsEnumLiteral(ir::Expression *node) const + { + ES2PANDA_ASSERT(node->TsType() == this); + if (!node->IsMemberExpression()) { + return false; + } + + auto mobj = node->AsMemberExpression()->Object(); + if (mobj->TsType() == this) { + // No need to search properties since enum-literals are the only enum-type properties + // NOTE(dkofanov): For some reason, 'enumLowering' changes 'CLASS' to 'ENUM_LITERAL', instead of 'ENUM'. + // ES2PANDA_ASSERT(mobj->Variable()->HasFlag(varbinder::VariableFlags::ENUM_LITERAL)); + ES2PANDA_ASSERT(GetDeclNode()->AsClassDefinition()->IsEnumTransformed()); + return true; + } + return false; + } + +private: + void InitElementsShortcuts(ir::ClassDefinition *declNode) + { + Span membersNames {}; + for (auto elem : declNode->Body()) { + auto elemName = elem->AsClassElement()->Key()->AsIdentifier()->Name(); + if (elemName == NAMES_ARRAY_NAME) { + membersNames = Span(elem->AsClassProperty()->Value()->AsArrayExpression()->Elements()); + } else if (elemName == VALUES_ARRAY_NAME) { + membersValues_ = elem->AsClassProperty()->Value()->AsArrayExpression(); // int-enum + } else if ((elemName == STRING_VALUES_ARRAY_NAME) && (membersValues_ == nullptr)) { + membersValues_ = elem->AsClassProperty()->Value()->AsArrayExpression(); // string-enum + } + } + auto membersValues = Span {membersValues_->Elements()}; + ES2PANDA_ASSERT(membersValues.size() == membersNames.size()); + for (size_t i = 0; i < membersNames.size(); i++) { + memberNameToOrdinal_.insert({membersNames[i]->AsStringLiteral()->Str(), i}); + ES2PANDA_ASSERT(membersValues[i]->IsStringLiteral() || membersValues[i]->IsNumberLiteral()); + } + } + +private: + ArenaMap memberNameToOrdinal_; + ir::ArrayExpression *membersValues_; }; class ETSIntEnumType : public ETSEnumType { @@ -91,4 +162,4 @@ public: } // namespace ark::es2panda::checker -#endif \ No newline at end of file +#endif diff --git a/ets2panda/checker/types/ets/etsFunctionType.h b/ets2panda/checker/types/ets/etsFunctionType.h index f59b65c709b186655a85fb231952f2884b628baa..49d1a17d3a2acc6ea40f0311302d716dc274272d 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.h +++ b/ets2panda/checker/types/ets/etsFunctionType.h @@ -134,11 +134,6 @@ public: void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void SetHelperSignature(Signature *signature) noexcept { helperSignature_ = signature; diff --git a/ets2panda/checker/types/ets/etsNeverType.h b/ets2panda/checker/types/ets/etsNeverType.h index 06904ce0581c2dcf74cc495f1c17e960a04cbbf0..7e998eb6b619f7962aea4e1d931ca1b2edff1889 100644 --- a/ets2panda/checker/types/ets/etsNeverType.h +++ b/ets2panda/checker/types/ets/etsNeverType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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 @@ -38,11 +38,6 @@ public: TypeFacts GetTypeFacts() const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsNullishTypes.h b/ets2panda/checker/types/ets/etsNullishTypes.h index 195332ffd27cb4541ca6d7ee6bdd31beb21f0027..ff11033e5d4d7c2a2af967e67bd0cc3fea8ce87a 100644 --- a/ets2panda/checker/types/ets/etsNullishTypes.h +++ b/ets2panda/checker/types/ets/etsNullishTypes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -37,11 +37,6 @@ public: void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; class ETSUndefinedType : public Type { @@ -60,11 +55,6 @@ public: void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 1bbd08c26226a2d7de6cbe8e6cea02b237d58f03..6e4fcf43d111954e46fb95551537f23f8fac204f 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -492,6 +492,9 @@ bool ETSObjectType::IsBoxedPrimitive() const if (this->IsETSDynamicType()) { return false; } + if (this->IsETSEnumType()) { + return false; + } return this->IsETSUnboxableObject(); } @@ -624,6 +627,12 @@ bool ETSObjectType::TryCastUnboxable(TypeRelation *const relation, Type *const t conversion::WideningReference(relation, this, target->AsETSObjectType()); return true; } + + if (target->IsETSEnumType()) { + auto unboxedThis = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(this); + return relation->IsCastableTo(unboxedThis, target); + } + conversion::Forbidden(relation); return true; } diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 9a174689dd7925c03ca8557b5caf2c2a044d2338..3c6b6081b0119943a520d8a015228b69505c135d 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -397,11 +397,6 @@ public: return allocator_; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - [[nodiscard]] static std::uint32_t GetPrecedence(checker::ETSChecker *checker, ETSObjectType const *type) noexcept; bool IsPropertiesInstantiated() const diff --git a/ets2panda/checker/types/ets/etsResizableArrayType.cpp b/ets2panda/checker/types/ets/etsResizableArrayType.cpp index 25fcd72aba950af51699942f1241bbfff595af9a..2d4da551f1d4d5186d9a7bcf1bf3b34b3e0b7384 100644 --- a/ets2panda/checker/types/ets/etsResizableArrayType.cpp +++ b/ets2panda/checker/types/ets/etsResizableArrayType.cpp @@ -24,4 +24,11 @@ ETSResizableArrayType *ETSResizableArrayType::Substitute(TypeRelation *relation, return copiedType; } -} // namespace ark::es2panda::checker \ No newline at end of file +void ETSResizableArrayType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const +{ + if (element_ != nullptr) { + ss << element_->ToString() << "[]"; + } +} + +} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsResizableArrayType.h b/ets2panda/checker/types/ets/etsResizableArrayType.h index 43babf404a36dcfdbce983333683b9a94a0666bd..8b041760eb698d6264cdfe1e2318117d0eed3a5f 100644 --- a/ets2panda/checker/types/ets/etsResizableArrayType.h +++ b/ets2panda/checker/types/ets/etsResizableArrayType.h @@ -76,10 +76,12 @@ public: ETSResizableArrayType *Substitute(TypeRelation *relation, const Substitution *substitution) override; + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; + private: Type *element_; }; } // namespace ark::es2panda::checker -#endif \ No newline at end of file +#endif diff --git a/ets2panda/checker/types/ets/etsStringType.cpp b/ets2panda/checker/types/ets/etsStringType.cpp index 648af3cc0137a144315bc3974bc6f456b31ed8b4..ef98c512f8887eff0ba6f19d14f95fa89d0d081b 100644 --- a/ets2panda/checker/types/ets/etsStringType.cpp +++ b/ets2panda/checker/types/ets/etsStringType.cpp @@ -40,17 +40,7 @@ void ETSStringType::Identical(TypeRelation *relation, Type *other) bool ETSStringType::AssignmentSource(TypeRelation *relation, Type *target) { - auto node = relation->GetNode(); - if ((relation->InAssignmentContext() || relation->ApplyStringToChar()) && IsConvertibleTo(target)) { - node->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOX_TO_CHAR); - if (target->IsETSObjectType()) { - node->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR); - } - relation->Result(true); - } else { - relation->Result(target->IsETSStringType() && AreStringTypesAssignable(this, target)); - } - + relation->Result(target->IsETSStringType() && AreStringTypesAssignable(this, target)); return relation->IsTrue(); } @@ -84,15 +74,4 @@ void ETSStringType::IsSubtypeOf(TypeRelation *relation, Type *source) auto *const checker = relation->GetChecker()->AsETSChecker(); relation->IsSupertypeOf(source, checker->GlobalBuiltinETSStringType()); } - -bool ETSStringType::IsConvertibleTo(Type const *to) const -{ - const bool targetIsChar = - to->IsCharType() || - // ETSObjectType is used in arrow function expression call. - (to->IsETSObjectType() && to->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)); - - return targetIsChar && IsConstantType() && value_.IsConvertibleToChar(); -} - } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsStringType.h b/ets2panda/checker/types/ets/etsStringType.h index 2e47f48eea53295796b17ada5234f95891e6c5ae..2aa87a138aa8b26436e46b564876e9c8532a353b 100644 --- a/ets2panda/checker/types/ets/etsStringType.h +++ b/ets2panda/checker/types/ets/etsStringType.h @@ -76,13 +76,6 @@ public: return value_; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), IsConstantType() ? (GetValue().Length() != 0) : false}; - } - - bool IsConvertibleTo(Type const *to) const; - private: util::StringView value_ {}; }; diff --git a/ets2panda/checker/types/ets/etsTupleType.h b/ets2panda/checker/types/ets/etsTupleType.h index 31aca83175f646508708e02de738e3e69f1aec57..f76aec4af439b605b8a2f3edfda28825306039ee 100644 --- a/ets2panda/checker/types/ets/etsTupleType.h +++ b/ets2panda/checker/types/ets/etsTupleType.h @@ -43,11 +43,6 @@ public: return typeList_; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - [[nodiscard]] ETSObjectType *GetWrapperType() const { return wrapperType_; diff --git a/ets2panda/checker/types/ets/etsTypeAliasType.h b/ets2panda/checker/types/ets/etsTypeAliasType.h index a0811891f9a32250542360191c57ad77fe7961e2..f5b249c69257d449d8e86183704cfe796d98c0e0 100644 --- a/ets2panda/checker/types/ets/etsTypeAliasType.h +++ b/ets2panda/checker/types/ets/etsTypeAliasType.h @@ -53,11 +53,6 @@ public: targetType_ = targetType; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void SetRecursive(bool value = true) { isRecursive_ = value; diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index fc29b8b98bf89d84e7ae688abce1ec1f7798dad9..a901f975b5a25467b706395b61f3f2548949283c 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -161,6 +161,7 @@ void ETSUnionType::RelationTarget(TypeRelation *relation, Type *source, RelFN co if (relFn(relation, source, checker->MaybeUnboxType(ct))) { if (related) { AmbiguousUnionOperation(relation); + return; } relation->GetNode()->SetBoxingUnboxingFlags(checker->GetBoxingFlag(ct)); related = true; @@ -225,22 +226,7 @@ void ETSUnionType::CastTarget(TypeRelation *relation, Type *source) RelationTarget(relation, source, relFn); } -static auto constexpr ETS_NORMALIZABLE_NUMERIC = TypeFlag(TypeFlag::ETS_NUMERIC); - -static Type *LargestNumeric(Type *t1, Type *t2) -{ - static_assert(TypeFlag::DOUBLE > TypeFlag::FLOAT); - static_assert(TypeFlag::FLOAT > TypeFlag::LONG); - static_assert(TypeFlag::LONG > TypeFlag::INT); - static_assert(TypeFlag::INT > TypeFlag::SHORT); - static_assert(TypeFlag::SHORT > TypeFlag::BYTE); - - auto v1 = t1->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; - auto v2 = t2->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; - ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v1)); - ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v2)); - return v1 > v2 ? t1 : t2; -} +static auto constexpr ETS_NORMALIZABLE_NUMERIC = TypeFlag(TypeFlag::ETS_INTEGRAL_NUMERIC); static std::optional TryMergeTypes(TypeRelation *relation, Type *const t1, Type *const t2) { @@ -310,9 +296,29 @@ void ETSUnionType::NormalizeTypes(TypeRelation *relation, ArenaVector &t if (types.size() == 1) { return; } - auto const isNumeric = [](auto *ct) { return ct->HasTypeFlag(ETS_NORMALIZABLE_NUMERIC); }; + auto const isNumeric = [relation](auto *ct) { + auto *checker = relation->GetChecker()->AsETSChecker(); + return checker->MaybeUnboxType(ct)->HasTypeFlag(ETS_NORMALIZABLE_NUMERIC); + }; + // CC-OFFNXT(G.FMT.14-CPP) project code style + auto const largerNumeric = [relation](Type *t1, Type *t2) -> Type * { + static_assert(TypeFlag::LONG > TypeFlag::INT); + static_assert(TypeFlag::INT > TypeFlag::SHORT); + static_assert(TypeFlag::SHORT > TypeFlag::BYTE); + + auto *checker = relation->GetChecker()->AsETSChecker(); + auto *unboxedT1 = checker->MaybeUnboxType(t1); + auto *unboxedT2 = checker->MaybeUnboxType(t2); + + auto v1 = unboxedT1->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; + auto v2 = unboxedT2->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; + ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v1)); + ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v2)); + return v1 > v2 ? t1 : t2; + }; + if (std::all_of(types.begin(), types.end(), isNumeric)) { - types[0] = std::accumulate(std::next(types.begin()), types.end(), types[0], LargestNumeric); + types[0] = std::accumulate(std::next(types.begin()), types.end(), types[0], largerNumeric); types.resize(1); return; } @@ -379,7 +385,8 @@ bool ETSUnionType::IsAssignableType(checker::Type *sourceType) const noexcept // NOTE! When calling this method we assume that 'AssignmentTarget(...)' check was passes successfully, // thus the required assignable type always exists. -checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, checker::Type *sourceType) const noexcept +checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, checker::Type *sourceType, + bool narrowingAllowed) const noexcept { if (IsAssignableType(sourceType)) { return sourceType; @@ -410,7 +417,7 @@ checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, che return type; } } - if (sourceType->IsConstantType() && !numericTypes.empty()) { + if (narrowingAllowed && !numericTypes.empty()) { return numericTypes.begin()->second; } } @@ -628,50 +635,6 @@ Type *ETSUnionType::FindTypeIsCastableToThis(ir::Expression *node, TypeRelation return nullptr; } -Type *ETSUnionType::FindTypeIsCastableToSomeType(ir::Expression *node, TypeRelation *relation, Type *target) const -{ - ES2PANDA_ASSERT(node); - bool nodeWasSet = false; - if (relation->GetNode() == nullptr) { - nodeWasSet = true; - relation->SetNode(node); - relation->SetFlags(TypeRelationFlag::CASTING_CONTEXT); - } - auto isCastablePred = [](TypeRelation *r, Type *sourceType, Type *targetType) { - if (targetType->IsETSUnionType()) { - auto *foundTargetType = targetType->AsETSUnionType()->FindTypeIsCastableToThis(r->GetNode(), r, sourceType); - r->Result(foundTargetType != nullptr); - } else { - r->IsCastableTo(sourceType, targetType); - } - return r->IsTrue(); - }; - // Prioritize object to object conversion - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), - [relation, target, &isCastablePred](Type *source) { - return isCastablePred(relation, source, target) && source->IsETSReferenceType() && - target->IsETSReferenceType(); - }); // CC-OFF(G.FMT.02) project code style - if (it != constituentTypes_.end()) { - if (nodeWasSet) { - relation->SetNode(nullptr); - relation->RemoveFlags(TypeRelationFlag::CASTING_CONTEXT); - } - return *it; - } - it = std::find_if( - constituentTypes_.begin(), constituentTypes_.end(), - [relation, target, &isCastablePred](Type *source) { return isCastablePred(relation, source, target); }); - if (nodeWasSet) { - relation->SetNode(nullptr); - relation->RemoveFlags(TypeRelationFlag::CASTING_CONTEXT); - } - if (it != constituentTypes_.end()) { - return *it; - } - return nullptr; -} - Type *ETSUnionType::FindUnboxableType() const { auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), @@ -690,34 +653,6 @@ bool ETSUnionType::HasObjectType(ETSObjectFlags flag) const return it != constituentTypes_.end(); } -Type *ETSUnionType::FindExactOrBoxedType(ETSChecker *checker, Type *const type) const -{ - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), [checker, type](Type *ct) { - if (ct->IsETSUnboxableObject()) { - auto *const unboxedCt = checker->MaybeUnboxInRelation(ct); - return unboxedCt == type; - } - return ct == type; - }); - if (it != constituentTypes_.end()) { - return *it; - } - return nullptr; -} - -std::tuple ETSUnionType::ResolveConditionExpr() const -{ - if (PossiblyETSString()) { - return {false, false}; - } - if (std::all_of(ConstituentTypes().begin(), ConstituentTypes().end(), - [](checker::Type const *ct) { return ct->DefinitelyETSNullish(); })) { - return {true, false}; - } - // We have to test if union can contain builtin numerics or string types to infer "true" - return {false, false}; -} - bool ETSUnionType::HasType(Type *type) const { for (const auto &cType : constituentTypes_) { diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index d38376a8f827c8faddfbaa7e779b88bcd65226e3..962abbe0ce6587cb03607ffe44b650a848679f98 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -46,7 +46,6 @@ public: void IsSubtypeOf(TypeRelation *relation, Type *target) override; void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; Type *FindTypeIsCastableToThis(ir::Expression *node, TypeRelation *relation, Type *source) const; - Type *FindTypeIsCastableToSomeType(ir::Expression *node, TypeRelation *relation, Type *target) const; Type *FindUnboxableType() const; bool HasObjectType(ETSObjectFlags flag) const; @@ -54,14 +53,10 @@ public: bool IsOverlapWith(TypeRelation *relation, Type *type); - Type *FindExactOrBoxedType(ETSChecker *checker, Type *type) const; - static void NormalizeTypes(TypeRelation *relation, ArenaVector &types); static ArenaVector GetNonConstantTypes(ETSChecker *checker, const ArenaVector &types); - std::tuple ResolveConditionExpr() const override; - // Do not use it anywhere except codegen Type *GetAssemblerLUB() const { @@ -74,7 +69,8 @@ public: return std::all_of(constituentTypes_.cbegin(), constituentTypes_.cend(), p); } - [[nodiscard]] checker::Type *GetAssignableType(ETSChecker *checker, checker::Type *sourceType) const noexcept; + [[nodiscard]] checker::Type *GetAssignableType(ETSChecker *checker, checker::Type *sourceType, + bool narrowingAllowed) const noexcept; [[nodiscard]] std::pair GetComplimentaryType(ETSChecker *checker, checker::Type *sourceType); diff --git a/ets2panda/checker/types/ets/etsVoidType.cpp b/ets2panda/checker/types/ets/etsVoidType.cpp index bb3e90fb257d0bc0fb0a69f895d449c6e7b0192f..0fe7ede62002e0d284a5238d309d5957cef10b3d 100644 --- a/ets2panda/checker/types/ets/etsVoidType.cpp +++ b/ets2panda/checker/types/ets/etsVoidType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -23,6 +23,11 @@ void ETSVoidType::Identical(TypeRelation *relation, Type *other) } } +void ETSVoidType::IsSupertypeOf(TypeRelation *const relation, Type *source) +{ + relation->Result(source->IsETSUndefinedType()); +} + bool ETSVoidType::AssignmentSource(TypeRelation *relation, Type *target) { // NOTE(vpukhov): #19701 void refactoring diff --git a/ets2panda/checker/types/ets/etsVoidType.h b/ets2panda/checker/types/ets/etsVoidType.h index bf6f9fcf7ff8261ae4ffdec8213aa4f790a524e2..845d638d89b8a49fd592686f29dcbba5ea15f5ba 100644 --- a/ets2panda/checker/types/ets/etsVoidType.h +++ b/ets2panda/checker/types/ets/etsVoidType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -26,6 +26,7 @@ public: void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override diff --git a/ets2panda/checker/types/ets/floatType.h b/ets2panda/checker/types/ets/floatType.h index 61f04f8e0b5b37eb34d2b1da22ac6f064d282b11..936effb4b0f1f59e8d5ccc5824f7e1653aab4277 100644 --- a/ets2panda/checker/types/ets/floatType.h +++ b/ets2panda/checker/types/ets/floatType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,12 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_FLOAT; } - std::tuple ResolveConditionExpr() const override - { - // isNan = !(value_ == value_) - return {IsConstantType(), (value_ != 0) && (value_ == value_)}; - } - private: UType value_ {0.0}; }; diff --git a/ets2panda/checker/types/ets/intType.h b/ets2panda/checker/types/ets/intType.h index b1583a869578ff5243ca051353b4a963b54698aa..835cc47d612c7010193530b2196075b5350085c6 100644 --- a/ets2panda/checker/types/ets/intType.h +++ b/ets2panda/checker/types/ets/intType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_INT; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/longType.h b/ets2panda/checker/types/ets/longType.h index 898b692072905d627d0f84b0138d0faf46161e87..0823bc7608f4840b9e2db740f130590ba8ee6cec 100644 --- a/ets2panda/checker/types/ets/longType.h +++ b/ets2panda/checker/types/ets/longType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_LONG; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/shortType.h b/ets2panda/checker/types/ets/shortType.h index 0cbd73ab16e223a284fa41bd1692c33588f48c6b..4b226806a322536a8c10bb03e5169d534fa8f2b1 100644 --- a/ets2panda/checker/types/ets/shortType.h +++ b/ets2panda/checker/types/ets/shortType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_SHORT; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/types.h b/ets2panda/checker/types/ets/types.h index 89d59b801ed6bc0f632dd6dd7f7adf08473c41f8..7a731779e57b3fd9b077b35cd497a9f903da6df4 100644 --- a/ets2panda/checker/types/ets/types.h +++ b/ets2panda/checker/types/ets/types.h @@ -41,5 +41,6 @@ #include "checker/types/signature.h" #include "etsReadonlyType.h" #include "etsNeverType.h" +#include "etsEnumType.h" #endif /* TYPES_H */ diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index 2644c1b7192f9c83e57987746f75fd2c0dc1e8f6..dcada0dd73b28a26616aca1ef9da797fda5152a8 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -164,6 +164,7 @@ void GlobalTypesHolder::AddEtsSpecificBuiltinTypes() builtinNameMappings_.emplace("Int", GlobalTypeId::ETS_INT_BUILTIN); builtinNameMappings_.emplace("Integral", GlobalTypeId::ETS_INTEGRAL_BUILTIN); builtinNameMappings_.emplace("Long", GlobalTypeId::ETS_LONG_BUILTIN); + builtinNameMappings_.emplace("Numeric", GlobalTypeId::ETS_NUMERIC_BUILTIN); builtinNameMappings_.emplace("Object", GlobalTypeId::ETS_OBJECT_BUILTIN); builtinNameMappings_.emplace("Runtime", GlobalTypeId::ETS_RUNTIME_BUILTIN); builtinNameMappings_.emplace("RuntimeLinker", GlobalTypeId::ETS_RUNTIME_LINKER_BUILTIN); @@ -482,6 +483,11 @@ Type *GlobalTypesHolder::GlobalLongBuiltinType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_LONG_BUILTIN)); } +Type *GlobalTypesHolder::GlobalNumericBuiltinType() +{ + return globalTypes_.at(static_cast(GlobalTypeId::ETS_NUMERIC_BUILTIN)); +} + Type *GlobalTypesHolder::GlobalMapBuiltinType() { return globalTypes_.at(static_cast(GlobalTypeId::ETS_MAP_BUILTIN)); diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index cd5e0235394f9215516b7f0f327eb9c819490e90..96569e2b9f26d8bd767d89284d64d9673d24b880 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -74,6 +74,7 @@ enum class GlobalTypeId : std::size_t { ETS_INT_BUILTIN, ETS_INTEGRAL_BUILTIN, ETS_LONG_BUILTIN, + ETS_NUMERIC_BUILTIN, ETS_MAP_BUILTIN, ETS_ERROR_BUILTIN, ETS_RUNTIME_BUILTIN, @@ -97,7 +98,6 @@ enum class GlobalTypeId : std::size_t { ETS_FUNCTION_BUILTIN, ETS_REGEXP_BUILTIN, ETS_ARRAY_BUILTIN, - ETS_ARRAY, ETS_INTEROP_JSRUNTIME_BUILTIN, ETS_INTEROP_JSVALUE_BUILTIN, ETS_BOX_BUILTIN, @@ -111,6 +111,7 @@ enum class GlobalTypeId : std::size_t { ETS_DOUBLE_BOX_BUILTIN, ETS_BIG_INT_BUILTIN, ETS_BIG_INT, + ETS_ARRAY, ETS_FUNCTION0_CLASS, ETS_FUNCTION1_CLASS, @@ -282,6 +283,7 @@ public: Type *GlobalIntegerBuiltinType(); Type *GlobalIntegralBuiltinType(); Type *GlobalLongBuiltinType(); + Type *GlobalNumericBuiltinType(); Type *GlobalErrorBuiltinType(); Type *GlobalRuntimeBuiltinType(); Type *GlobalShortBuiltinType(); diff --git a/ets2panda/checker/types/signature.h b/ets2panda/checker/types/signature.h index 2a4f8ec06d417aed65fdc416c2ac9a38ee6fd543..d94e607e8b2a5ab473eb2081fefd38dd9c6fc806 100644 --- a/ets2panda/checker/types/signature.h +++ b/ets2panda/checker/types/signature.h @@ -90,6 +90,7 @@ enum class SignatureFlags : uint32_t { RETHROWS = 1U << 17U, EXTENSION_FUNCTION = 1U << 18U, DUPLICATE_ASM = 1U << 19U, + BRIDGE = 1U << 20U, INTERNAL_PROTECTED = INTERNAL | PROTECTED, GETTER_OR_SETTER = GETTER | SETTER, @@ -223,6 +224,11 @@ public: return signatureInfo_->restVar; } + [[nodiscard]] varbinder::LocalVariable *RestVar() noexcept + { + return signatureInfo_->restVar; + } + [[nodiscard]] uint8_t ProtectionFlag() const noexcept { if ((flags_ & SignatureFlags::PRIVATE) != 0) { diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index 1a0895b37a62d2824bab0b9fbf52314c9f7a80e5..2a0d79af857eee0e98294c8a0b422373df00b8f2 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -267,15 +267,24 @@ public: ToAssemblerType(ss); } - virtual uint32_t Rank() const + std::string ToAssemblerType() const { - return 0; + std::stringstream ss; + ToAssemblerType(ss); + return ss.str(); } - virtual std::tuple ResolveConditionExpr() const + std::string ToAssemblerTypeWithRank() const { - ES2PANDA_UNREACHABLE(); - }; + std::stringstream ss; + ToAssemblerTypeWithRank(ss); + return ss.str(); + } + + virtual uint32_t Rank() const + { + return 0; + } virtual void Identical(TypeRelation *relation, Type *other); virtual void AssignmentTarget(TypeRelation *relation, Type *source) = 0; diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index 5f592559743f774d68753ab09afb721d77d5e545..5b66e1c63d292fa6bff0960481727d329013eea2 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -204,20 +204,58 @@ bool TypeRelation::IsCastableTo(Type *const source, Type *const target) return result_ == RelationResult::TRUE; } +Type *TypeRelation::SelectBoxedUnionTargetType(Type *target, Type *source) +{ + ETSChecker *checker = this->GetChecker()->AsETSChecker(); + + if (!target->IsETSUnionType() || !source->IsETSObjectType()) { + return nullptr; + } + Type *boxedUnionTarget = target->AsETSUnionType()->FindUnboxableType(); + if (boxedUnionTarget == nullptr) { + return nullptr; + } + Type *targetUnboxedType = checker->MaybeUnboxType(boxedUnionTarget); + if (targetUnboxedType == nullptr || !targetUnboxedType->IsETSPrimitiveType()) { + return nullptr; + } + // if + return boxedUnionTarget; +} + bool TypeRelation::IsLegalBoxedPrimitiveConversion(Type *target, Type *source) { - if (!target->IsETSReferenceType() || !source->IsETSReferenceType()) { + auto type = this->GetNode()->TsType(); + ETSChecker *checker = this->GetChecker()->AsETSChecker(); + + if (target == nullptr || source == nullptr) { return false; } + + if (target->IsETSUnionType() && source->IsETSObjectType()) { + Type *sourceUnboxedType = checker->MaybeUnboxType(source); + if (sourceUnboxedType == nullptr || !sourceUnboxedType->IsETSPrimitiveType()) { + return false; + } + Type *boxedUnionTarget = target->AsETSUnionType()->FindUnboxableType(); + if (boxedUnionTarget == nullptr) { + return false; + } + Type *targetUnboxedType = checker->MaybeUnboxType(boxedUnionTarget); + if (targetUnboxedType == nullptr || !targetUnboxedType->IsETSPrimitiveType()) { + return false; + } + return this->Result(this->IsAssignableTo(sourceUnboxedType, target)); + } + if (!target->IsETSObjectType() || !source->IsETSObjectType()) { return false; } + if (!target->AsETSObjectType()->IsBoxedPrimitive() || !source->AsETSObjectType()->IsBoxedPrimitive()) { return false; } - ETSChecker *checker = this->GetChecker()->AsETSChecker(); - Type *targetUnboxedType = checker->MaybeUnboxType(target); Type *sourceUnboxedType = checker->MaybeUnboxType(source); @@ -228,7 +266,9 @@ bool TypeRelation::IsLegalBoxedPrimitiveConversion(Type *target, Type *source) return false; } - return this->Result(this->IsAssignableTo(sourceUnboxedType, targetUnboxedType)); + bool res = this->Result(this->IsAssignableTo(sourceUnboxedType, targetUnboxedType)); + this->GetNode()->SetTsType(type); + return res; } bool TypeRelation::IsSupertypeOf(Type *super, Type *sub) diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index 4fadbde95edcf70b50e043e8e2da9d2b11492897..1387cac1e11fba14c1be309827789ca1535cb509 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -63,9 +63,10 @@ enum class TypeRelationFlag : uint32_t { OVERRIDING_CONTEXT = 1U << 25U, IGNORE_REST_PARAM = 1U << 26U, STRING_TO_CHAR = 1U << 27U, + OVERLOADING_CONTEXT = 1U << 28U, ASSIGNMENT_CONTEXT = WIDENING | BOXING | UNBOXING, - BRIDGE_CHECK = OVERRIDING_CONTEXT | IGNORE_TYPE_PARAMETERS | NO_RETURN_TYPE_CHECK, + BRIDGE_CHECK = OVERRIDING_CONTEXT | IGNORE_TYPE_PARAMETERS, CASTING_CONTEXT = NARROWING | WIDENING | BOXING | UNBOXING | UNCHECKED_CAST, }; @@ -156,11 +157,6 @@ public: return (flags_ & TypeRelationFlag::UNBOXING) != 0; } - bool ApplyStringToChar() const - { - return (flags_ & TypeRelationFlag::STRING_TO_CHAR) != 0; - } - bool NoReturnTypeCheck() const { return (flags_ & TypeRelationFlag::NO_RETURN_TYPE_CHECK) != 0; @@ -297,6 +293,7 @@ public: { return IsSupertypeOf(const_cast(super), const_cast(sub)); } + Type *SelectBoxedUnionTargetType(Type *target, Type *source); bool IsLegalBoxedPrimitiveConversion(Type *target, Type *source); bool IsSupertypeOf(Type *super, Type *sub); bool IsIdenticalTo(IndexInfo *source, IndexInfo *target); diff --git a/ets2panda/compiler/base/condition.cpp b/ets2panda/compiler/base/condition.cpp index c8a7d0de4dbbc06d728f934d25c777bec1edc21a..db9afc179038633c12282080a53e6f98e0883755 100644 --- a/ets2panda/compiler/base/condition.cpp +++ b/ets2panda/compiler/base/condition.cpp @@ -15,6 +15,7 @@ #include "condition.h" +#include "checker/ETSAnalyzerHelpers.h" #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/expressions/assignmentExpression.h" diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 0affcc5bc9b1be08b14a938ff85e73a2b3952b06..b4fdea643f281a4d0bd4af6f8a17d80524741a9a 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -334,6 +334,11 @@ void ETSCompiler::Compile(const ir::ETSTypeReferencePart *node) const ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), node->TsType())); } +void ETSCompiler::Compile(const ir::OpaqueTypeNode *node) const +{ + GetETSGen()->SetAccumulatorType(node->TsType()); +} + void ETSCompiler::Compile([[maybe_unused]] const ir::ETSWildcardType *node) const { ES2PANDA_UNREACHABLE(); @@ -1524,6 +1529,7 @@ void ETSCompiler::Compile(const ir::VariableDeclarator *st) const etsg->LoadDefaultValue(st, st->Id()->AsIdentifier()->Variable()->TsType()); } + // ????????????????????????????????????? is this meaningfull???? etsg->ApplyConversion(st, st->TsType()); lref.SetValue(); } diff --git a/ets2panda/compiler/core/ETSCompilerUnrechable.cpp b/ets2panda/compiler/core/ETSCompilerUnrechable.cpp index 3f3908e8206d4f92de117ae319809c813e6dc108..26d98fa12f417eeb538273a2fcc6549f489a9146 100644 --- a/ets2panda/compiler/core/ETSCompilerUnrechable.cpp +++ b/ets2panda/compiler/core/ETSCompilerUnrechable.cpp @@ -188,11 +188,6 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::OmittedExpression *expr) co ES2PANDA_UNREACHABLE(); } -void ETSCompiler::Compile([[maybe_unused]] const ir::OpaqueTypeNode *node) const -{ - ES2PANDA_UNREACHABLE(); -} - void ETSCompiler::Compile([[maybe_unused]] const ir::BrokenTypeNode *node) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index ea7f55889c26061accaf588457df0c9de33de43f..57a00db32b9795d6e16ffabb325d7d1310dc2394 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -807,7 +807,7 @@ void ETSGen::TestIsInstanceConstituent(const ir::AstNode *const node, std::tuple ES2PANDA_ASSERT(!target->IsETSDynamicType()); auto [ifTrue, ifFalse] = label; - if (target->IsConstantType()) { + if (target->IsConstantType() && (target->IsETSBigIntType() || target->IsETSStringType())) { TestIsInstanceConstant(node, ifTrue, srcReg, target); return; } @@ -1006,6 +1006,13 @@ void ETSGen::GuardUncheckedType(const ir::AstNode *node, const checker::Type *un SetAccumulatorType(unchecked); // this check guards possible type violations, **do not relax it** CheckedReferenceNarrowing(node, Checker()->MaybeBoxType(target)); + // Because on previos step accumulator type may be set in CheckerReferenceNarrowing to boxed countepart of + // target We need to apply unbox conversion if needed to avoid RTE + if (target->IsETSPrimitiveType() && GetAccumulatorType()->IsETSUnboxableObject()) { + // NOTE: need to refactor + node->AddBoxingUnboxingFlags(Checker()->GetUnboxingFlag(target)); + ApplyConversion(node, target); + } } SetAccumulatorType(target); } @@ -1024,14 +1031,16 @@ void ETSGen::EmitFailedTypeCastException(const ir::AstNode *node, const VReg src void ETSGen::LoadConstantObject(const ir::Expression *node, const checker::Type *type) { - if (type->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL)) { + if (type->IsETSBigIntType()) { LoadAccumulatorBigInt(node, type->AsETSObjectType()->AsETSBigIntType()->GetValue()); const VReg value = AllocReg(); StoreAccumulator(node, value); CreateBigIntObject(node, value); - } else { + } else if (type->IsETSStringType()) { LoadAccumulatorString(node, type->AsETSObjectType()->AsETSStringType()->GetValue()); SetAccumulatorType(node->TsType()); + } else { + ES2PANDA_UNREACHABLE(); } } @@ -1140,12 +1149,6 @@ void ETSGen::ApplyConversion(const ir::AstNode *node, const checker::Type *targe const bool hasUnboxingflags = (node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U; if (hasBoxingflags && !hasUnboxingflags) { ApplyBoxingConversion(node); - - if (node->HasAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING)) { - CastToString(node); - node->RemoveAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); - } - return; } @@ -1315,6 +1318,8 @@ void ETSGen::EmitBoxingConversion(const ir::AstNode *node) auto boxedType = const_cast(GetAccumulatorType()); const_cast(node->AsExpression())->SetTsType(boxedType); } + + node->RemoveBoxingUnboxingFlags(boxingFlag); } void ETSGen::SwapBinaryOpArgs(const ir::AstNode *const node, const VReg lhs) @@ -1700,9 +1705,13 @@ void ETSGen::CastToInt(const ir::AstNode *node) void ETSGen::CastToReftype(const ir::AstNode *const node, const checker::Type *const targetType, const bool unchecked) { - ES2PANDA_ASSERT(GetAccumulatorType()->IsETSReferenceType()); - const auto *const sourceType = GetAccumulatorType(); + // sourceType can be either RefType or CharType + ES2PANDA_ASSERT(sourceType->IsETSReferenceType() || sourceType->IsCharType()); + if (sourceType->IsCharType()) { + // NOTE: temporary flag have to be set for CastToString + node->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR); + } if (sourceType->IsETSDynamicType()) { CastDynamicToObject(node, targetType); @@ -1792,20 +1801,13 @@ void ETSGen::CastToString(const ir::AstNode *const node) if (sourceType->IsETSStringType()) { return; } - if (sourceType->IsETSCharType()) { - Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, dummyReg_, 0); - return; - } - if (sourceType->IsETSPrimitiveType()) { - EmitBoxingConversion(node); - } else { - ES2PANDA_ASSERT(sourceType->IsETSReferenceType()); - } + ES2PANDA_ASSERT(sourceType->IsETSReferenceType()); // caller must ensure parameter is not null Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, dummyReg_, 0); SetAccumulatorType(Checker()->GetGlobalTypesHolder()->GlobalETSStringBuiltinType()); } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic, big switch case void ETSGen::CastToDynamic(const ir::AstNode *node, const checker::ETSDynamicType *type) { std::string_view methodName {}; @@ -1841,6 +1843,12 @@ void ETSGen::CastToDynamic(const ir::AstNode *node, const checker::ETSDynamicTyp case checker::TypeFlag::ETS_TUPLE: methodName = compiler::Signatures::Dynamic::NewObjectBuiltin(type->Language()); break; + case checker::TypeFlag::ETS_UNDEFINED: + methodName = compiler::Signatures::Dynamic::GetUndefinedBuiltin(type->Language()); + break; + case checker::TypeFlag::ETS_NULL: + methodName = compiler::Signatures::Dynamic::GetNullBuiltin(type->Language()); + break; case checker::TypeFlag::ETS_DYNAMIC_TYPE: SetAccumulatorType(type); return; @@ -2646,15 +2654,6 @@ void ETSGen::RefEqualityLoose(const ir::AstNode *node, VReg lhs, VReg rhs, Label if (ltype->DefinitelyETSNullish() || rtype->DefinitelyETSNullish()) { HandleDefinitelyNullishEquality(node, lhs, rhs, ifFalse); - } else if (!ltype->PossiblyETSValueTypedExceptNullish() || !rtype->PossiblyETSValueTypedExceptNullish()) { - auto ifTrue = AllocLabel(); - if ((ltype->PossiblyETSUndefined() && rtype->PossiblyETSNull()) || - (rtype->PossiblyETSUndefined() && ltype->PossiblyETSNull())) { - HandlePossiblyNullishEquality(node, lhs, rhs, ifFalse, ifTrue); - } - LoadAccumulator(node, lhs); - Ra().Emit(node, rhs, ifFalse); - SetLabel(node, ifTrue); } else if (auto spec = SelectLooseObjComparator( // try to select specific type // CC-OFFNXT(G.FMT.06-CPP) project code style const_cast(Checker()), const_cast(ltype), diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index f759d97a55f045c03d45bea620b633549775eb49..81da21404f28f8f506208a0d4bf7362bc84395bd 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -26,8 +26,6 @@ #include "ir/base/scriptFunction.h" #include "ir/base/classProperty.h" #include "ir/statements/annotationDeclaration.h" -#include "ir/ts/tsEnumDeclaration.h" -#include "ir/ts/tsEnumMember.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/ts/tsInterfaceBody.h" #include "ir/ts/tsTypeParameterDeclaration.h" @@ -341,37 +339,53 @@ void ETSEmitter::GenExternalRecord(varbinder::RecordTable *recordTable, const pa } // Helper function to reduce EmitDefaultFieldValue size and pass code check -static pandasm::ScalarValue CreateScalarValue(const checker::Type *type, checker::TypeFlag typeKind) +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic, big switch case +static pandasm::ScalarValue CreateScalarValue(ir::Literal const *literal, checker::TypeFlag typeKind) { switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: { + ES2PANDA_ASSERT(literal->IsBooleanLiteral()); return pandasm::ScalarValue::Create( - static_cast(type->AsETSBooleanType()->GetValue())); + static_cast(literal->AsBooleanLiteral()->Value())); } case checker::TypeFlag::BYTE: { - return pandasm::ScalarValue::Create(type->AsByteType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsByte()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetByte()); } case checker::TypeFlag::SHORT: { - return pandasm::ScalarValue::Create(type->AsShortType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsShort()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetShort()); } case checker::TypeFlag::INT: { - return pandasm::ScalarValue::Create(type->AsIntType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsInt()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetInt()); } case checker::TypeFlag::LONG: { - return pandasm::ScalarValue::Create(type->AsLongType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsLong()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetLong()); } case checker::TypeFlag::FLOAT: { - return pandasm::ScalarValue::Create(type->AsFloatType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsFloat()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetFloat()); } case checker::TypeFlag::DOUBLE: { - return pandasm::ScalarValue::Create(type->AsDoubleType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsDouble()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetDouble()); } case checker::TypeFlag::CHAR: { - return pandasm::ScalarValue::Create(type->AsCharType()->GetValue()); + ES2PANDA_ASSERT(literal->IsCharLiteral()); + return pandasm::ScalarValue::Create(literal->AsCharLiteral()->Char()); } case checker::TypeFlag::ETS_OBJECT: { + ES2PANDA_ASSERT(literal->IsStringLiteral()); return pandasm::ScalarValue::Create( - type->AsETSObjectType()->AsETSStringType()->GetValue().Mutf8()); + literal->AsStringLiteral()->Str().Mutf8()); } default: { ES2PANDA_UNREACHABLE(); @@ -381,19 +395,14 @@ static pandasm::ScalarValue CreateScalarValue(const checker::Type *type, checker void ETSEmitter::EmitDefaultFieldValue(pandasm::Field &classField, const ir::Expression *init) { - if (init == nullptr) { + if (init == nullptr || !init->IsLiteral()) { return; } const auto *type = init->TsType(); - - if (!type->HasTypeFlag(checker::TypeFlag::CONSTANT)) { - return; - } - auto typeKind = checker::ETSChecker::TypeKind(type); classField.metadata->SetFieldType(classField.type); - classField.metadata->SetValue(CreateScalarValue(type, typeKind)); + classField.metadata->SetValue(CreateScalarValue(init->AsLiteral(), typeKind)); } void ETSEmitter::GenInterfaceMethodDefinition(const ir::MethodDefinition *methodDef, bool external) @@ -610,32 +619,6 @@ void ETSEmitter::GenClassRecord(const ir::ClassDefinition *classDef, bool extern Program()->recordTable.emplace(classRecord.name, std::move(classRecord)); } -// Helper function to check if the unary expression is a numeric literal with negation. -// This expression should be handled during lowering with the associated issue number. -static bool IsNegativeLiteralNode(const ir::UnaryExpression *expr) -{ - return expr->OperatorType() == lexer::TokenType::PUNCTUATOR_MINUS && expr->Argument()->IsNumberLiteral(); -} - -void ETSEmitter::CreateEnumProp(const ir::ClassProperty *prop, pandasm::Field &field) -{ - if (prop->Value() == nullptr) { - return; - } - field.metadata->SetFieldType(field.type); - auto declNode = prop->Value()->AsMemberExpression()->PropVar()->Declaration()->Node(); - auto *init = declNode->AsClassProperty()->OriginEnumMember()->Init(); - if (init->IsNumberLiteral()) { - auto value = init->AsNumberLiteral()->Number().GetInt(); - field.metadata->SetValue(pandasm::ScalarValue::Create(value)); - } else if (init->IsStringLiteral()) { - auto value = init->AsStringLiteral()->Str().Mutf8(); - field.metadata->SetValue(pandasm::ScalarValue::Create(value)); - } else { - ES2PANDA_UNREACHABLE(); - } -} - void ETSEmitter::ProcessArrayExpression( std::string &baseName, std::vector>> &result, std::vector &literals, const ir::Expression *elem) @@ -652,68 +635,53 @@ void ETSEmitter::ProcessArrayExpression( } } -static void ProcessEnumExpression(std::vector &literals, const ir::Expression *elem) -{ - auto *memberExpr = elem->IsCallExpression() ? elem->AsCallExpression()->Arguments()[0]->AsMemberExpression() - : elem->AsMemberExpression(); - auto *init = memberExpr->PropVar()->Declaration()->Node()->AsClassProperty()->OriginEnumMember()->Init(); - if (init->IsNumberLiteral()) { - auto enumValue = static_cast(init->AsNumberLiteral()->Number().GetInt()); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::TAGVALUE, - static_cast(panda_file::LiteralTag::INTEGER)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::INTEGER, enumValue}); - } else { - auto enumValue = init->AsStringLiteral()->Str().Mutf8(); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::TAGVALUE, - static_cast(panda_file::LiteralTag::STRING)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, enumValue}); - } -} - void ETSEmitter::ProcessArrayElement(const ir::Expression *elem, std::vector &literals, std::string &baseName, LiteralArrayVector &result) { - switch (elem->Type()) { - case ir::AstNodeType::NUMBER_LITERAL: { - auto doubleValue = elem->AsNumberLiteral()->Number().GetDouble(); - literals.emplace_back(pandasm::LiteralArray::Literal { - panda_file::LiteralTag::TAGVALUE, static_cast(panda_file::LiteralTag::DOUBLE)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::DOUBLE, doubleValue}); + ES2PANDA_ASSERT(elem->IsLiteral() || elem->IsArrayExpression()); + auto emplaceLiteral = [&literals](panda_file::LiteralTag tag, auto value) { + literals.emplace_back( + pandasm::LiteralArray::Literal {panda_file::LiteralTag::TAGVALUE, static_cast(tag)}); + literals.emplace_back(pandasm::LiteralArray::Literal {tag, value}); + }; + // NOTE(dkofanov): Why 'LiteralTag::ARRAY_*'-types isn't used? + switch (checker::ETSChecker::TypeKind(elem->TsType())) { + case checker::TypeFlag::ETS_BOOLEAN: { + emplaceLiteral(panda_file::LiteralTag::BOOL, elem->AsBooleanLiteral()->Value()); break; } - case ir::AstNodeType::BOOLEAN_LITERAL: { - bool boolValue = elem->AsBooleanLiteral()->Value(); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::TAGVALUE, - static_cast(panda_file::LiteralTag::BOOL)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::BOOL, boolValue}); + case checker::TypeFlag::CHAR: + case checker::TypeFlag::BYTE: + case checker::TypeFlag::SHORT: + case checker::TypeFlag::INT: { + emplaceLiteral(panda_file::LiteralTag::INTEGER, + static_cast(elem->AsNumberLiteral()->Number().GetInt())); break; } - case ir::AstNodeType::STRING_LITERAL: { - std::string stringValue {elem->AsStringLiteral()->Str().Utf8()}; - literals.emplace_back(pandasm::LiteralArray::Literal { - panda_file::LiteralTag::TAGVALUE, static_cast(panda_file::LiteralTag::STRING)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, stringValue}); + case checker::TypeFlag::LONG: { + emplaceLiteral(panda_file::LiteralTag::BIGINT, + static_cast(elem->AsNumberLiteral()->Number().GetInt())); break; } - case ir::AstNodeType::ARRAY_EXPRESSION: { - ProcessArrayExpression(baseName, result, literals, elem); + case checker::TypeFlag::FLOAT: { + emplaceLiteral(panda_file::LiteralTag::FLOAT, elem->AsNumberLiteral()->Number().GetFloat()); break; } - case ir::AstNodeType::MEMBER_EXPRESSION: - case ir::AstNodeType::CALL_EXPRESSION: { - ProcessEnumExpression(literals, elem); + case checker::TypeFlag::DOUBLE: { + emplaceLiteral(panda_file::LiteralTag::DOUBLE, elem->AsNumberLiteral()->Number().GetDouble()); break; } - case ir::AstNodeType::UNARY_EXPRESSION: { - double doubleValue = (-1) * elem->AsUnaryExpression()->Argument()->AsNumberLiteral()->Number().GetDouble(); - literals.emplace_back(pandasm::LiteralArray::Literal { - panda_file::LiteralTag::TAGVALUE, static_cast(panda_file::LiteralTag::DOUBLE)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::DOUBLE, doubleValue}); + case checker::TypeFlag::ETS_OBJECT: { + emplaceLiteral(panda_file::LiteralTag::STRING, elem->AsStringLiteral()->ToString()); break; } - default: - ES2PANDA_UNREACHABLE(); + case checker::TypeFlag::ETS_ARRAY: { + ProcessArrayExpression(baseName, result, literals, elem); break; + } + default: { + ES2PANDA_UNREACHABLE(); + } } } @@ -742,13 +710,9 @@ void ETSEmitter::CreateLiteralArrayProp(const ir::ClassProperty *prop, std::stri ++rank; elemType = checker->GetElementTypeOfArray(elemType); } - if (elemType->IsETSEnumType()) { - field.type = PandasmTypeWithRank(elemType, rank); - } else { - std::stringstream ss; - elemType->ToAssemblerType(ss); - field.type = pandasm::Type(ss.str(), rank); - } + std::stringstream ss; + elemType->ToAssemblerType(ss); + field.type = pandasm::Type(ss.str(), rank); auto value = prop->Value(); if (value != nullptr) { @@ -773,8 +737,6 @@ void ETSEmitter::GenCustomAnnotationProp(const ir::ClassProperty *prop, std::str if (external) { field.metadata->SetAttribute(Signatures::EXTERNAL); - } else if (type->IsETSEnumType()) { - CreateEnumProp(prop, field); } else if (type->IsETSPrimitiveType() || type->IsETSStringType()) { EmitDefaultFieldValue(field, prop->Value()); } else if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { @@ -823,58 +785,20 @@ pandasm::AnnotationElement ETSEmitter::ProcessArrayType(const ir::ClassProperty std::string_view {litArrays.back().first}))}; } -pandasm::AnnotationElement ETSEmitter::ProcessETSEnumType(std::string &baseName, const ir::Expression *init, - const checker::Type *type) -{ - auto declNode = init->AsMemberExpression()->PropVar()->Declaration()->Node(); - auto *initValue = declNode->AsClassProperty()->OriginEnumMember()->Init(); - if (type->IsETSIntEnumType()) { - auto enumValue = static_cast(initValue->AsNumberLiteral()->Number().GetInt()); - auto intEnumValue = pandasm::ScalarValue::Create(enumValue); - return pandasm::AnnotationElement {baseName, std::make_unique(intEnumValue)}; - } - ES2PANDA_ASSERT(type->IsETSStringEnumType()); - auto enumValue = initValue->AsStringLiteral()->Str().Mutf8(); - auto stringValue = pandasm::ScalarValue::Create(enumValue); - return pandasm::AnnotationElement {baseName, std::make_unique(stringValue)}; -} - pandasm::AnnotationElement ETSEmitter::GenCustomAnnotationElement(const ir::ClassProperty *prop, std::string &baseName) { const auto *init = prop->Value(); const auto *type = init->TsType(); - auto typeKind = checker::ETSChecker::TypeKind(type); - auto propName = prop->Id()->Name().Mutf8(); if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { return ProcessArrayType(prop, baseName, init); } - - if (type->IsETSEnumType()) { - return ProcessETSEnumType(baseName, init, type); - } - switch (checker::ETSChecker::TypeKind( - Context()->checker->AsETSChecker()->MaybeUnboxType(const_cast(type)))) { - case checker::TypeFlag::BYTE: - case checker::TypeFlag::SHORT: - case checker::TypeFlag::INT: - case checker::TypeFlag::LONG: - case checker::TypeFlag::FLOAT: - case checker::TypeFlag::DOUBLE: - case checker::TypeFlag::ETS_BOOLEAN: - case checker::TypeFlag::ETS_OBJECT: { - if (init->IsUnaryExpression() && IsNegativeLiteralNode(init->AsUnaryExpression())) { - double negNumberValue = - (-1) * init->AsUnaryExpression()->Argument()->AsNumberLiteral()->Number().GetDouble(); - return pandasm::AnnotationElement { - propName, std::make_unique( - pandasm::ScalarValue::Create(negNumberValue))}; - } - return pandasm::AnnotationElement { - propName, std::make_unique(CreateScalarValue(init->TsType(), typeKind))}; - } - default: - ES2PANDA_UNREACHABLE(); + if (init->IsLiteral()) { + auto typeKind = checker::ETSChecker::TypeKind(type); + auto propName = prop->Id()->Name().Mutf8(); + return pandasm::AnnotationElement { + propName, std::make_unique(CreateScalarValue(init->AsLiteral(), typeKind))}; } + ES2PANDA_UNREACHABLE(); } pandasm::AnnotationData ETSEmitter::GenCustomAnnotation(ir::AnnotationUsage *anno, std::string &baseName) @@ -1018,32 +942,37 @@ ir::MethodDefinition *ETSEmitter::FindAsyncImpl(ir::ScriptFunction *asyncFunc) const ir::ClassDefinition *classDef = ownerNode->AsClassDefinition(); ES2PANDA_ASSERT(classDef != nullptr); - auto it = - std::find_if(classDef->Body().rbegin(), classDef->Body().rend(), [&implName, &asyncFunc](ir::AstNode *node) { - if (!node->IsMethodDefinition()) { - return false; - } - bool isSameName = node->AsMethodDefinition()->Id()->Name().Utf8() == implName; - bool isBothStaticOrInstance = - (node->Modifiers() & ir::ModifierFlags::STATIC) == (asyncFunc->Modifiers() & ir::ModifierFlags::STATIC); - return isSameName && isBothStaticOrInstance; - }); - if (it == classDef->Body().rend()) { + ir::MethodDefinition *method = nullptr; + for (auto node : classDef->Body()) { + if (!node->IsMethodDefinition()) { + continue; + } + bool isSameName = node->AsMethodDefinition()->Id()->Name().Utf8() == implName; + bool isBothStaticOrInstance = + (node->Modifiers() & ir::ModifierFlags::STATIC) == (asyncFunc->Modifiers() & ir::ModifierFlags::STATIC); + if (isSameName && isBothStaticOrInstance) { + method = node->AsMethodDefinition(); + break; + } + } + if (method == nullptr) { return nullptr; } - ir::MethodDefinition *method = (*it)->AsMethodDefinition(); auto *checker = static_cast(Context()->checker); checker::TypeRelation *typeRel = checker->Relation(); checker::SavedTypeRelationFlagsContext savedFlagsCtx(typeRel, checker::TypeRelationFlag::NO_RETURN_TYPE_CHECK); method->Function()->Signature()->IsSubtypeOf(typeRel, asyncFunc->Signature()); - auto overloadIt = method->Overloads().begin(); - while (overloadIt != method->Overloads().end() && !typeRel->IsTrue()) { - method = *overloadIt; - method->Function()->Signature()->IsSubtypeOf(typeRel, asyncFunc->Signature()); - ++overloadIt; + if (typeRel->IsTrue()) { + return method; + } + for (auto overload : method->Overloads()) { + overload->Function()->Signature()->IsSubtypeOf(typeRel, asyncFunc->Signature()); + if (typeRel->IsTrue()) { + return overload; + } } - return typeRel->IsTrue() ? method : nullptr; + return nullptr; } pandasm::AnnotationData ETSEmitter::GenAnnotationAsync(ir::ScriptFunction *scriptFunc) diff --git a/ets2panda/compiler/core/ETSemitter.h b/ets2panda/compiler/core/ETSemitter.h index 937d81276a5b1e244daf4eeb49640cfb11dd81ae..c41988cadd168f60c4570b8c6a560a98a5c792b7 100644 --- a/ets2panda/compiler/core/ETSemitter.h +++ b/ets2panda/compiler/core/ETSemitter.h @@ -90,11 +90,8 @@ private: void GenClassRecord(const ir::ClassDefinition *classDef, bool external); pandasm::AnnotationElement ProcessArrayType(const ir::ClassProperty *prop, std::string &baseName, const ir::Expression *init); - pandasm::AnnotationElement ProcessETSEnumType(std::string &baseName, const ir::Expression *init, - const checker::Type *type); pandasm::AnnotationElement GenCustomAnnotationElement(const ir::ClassProperty *prop, std::string &baseName); pandasm::AnnotationData GenCustomAnnotation(ir::AnnotationUsage *anno, std::string &baseName); - void CreateEnumProp(const ir::ClassProperty *prop, pandasm::Field &field); void ProcessArrayElement(const ir::Expression *elem, std::vector &literals, std::string &baseName, LiteralArrayVector &result); LiteralArrayVector CreateLiteralArray(std::string &baseName, const ir::Expression *array); diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index b4a76e4e4eb00eeaa6d37a71fec92a789732cee1..e936e5857a780023a3f1f93f852a3072e69d50f6 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -127,9 +127,14 @@ static bool RunVerifierAndPhases(public_lib::Context &context, parser::Program & const auto verifierEachPhase = options.IsAstVerifierEachPhase(); ast_verifier::ASTVerifier verifier(context, program); + bool afterCheckerPhase = false; while (auto phase = context.phaseManager->NextPhase()) { const auto name = std::string {phase->Name()}; + if (phase->Name() == compiler::CheckerPhase::NAME) { + afterCheckerPhase = true; + } + if (options.GetSkipPhases().count(name) > 0) { continue; } @@ -145,7 +150,7 @@ static bool RunVerifierAndPhases(public_lib::Context &context, parser::Program & } // Stop lowerings processing after Checker phase if any error happened. - if (phase->Name() == compiler::CheckerPhase::NAME && context.diagnosticEngine->IsAnyError()) { + if (afterCheckerPhase && context.diagnosticEngine->IsAnyError()) { return false; } } diff --git a/ets2panda/compiler/lowering/checkerPhase.h b/ets2panda/compiler/lowering/checkerPhase.h index 03b9e6979b12a3d326a1b34b60f90a870b110652..13d99612107f504fe0615f85c4498fda21dbe1dd 100644 --- a/ets2panda/compiler/lowering/checkerPhase.h +++ b/ets2panda/compiler/lowering/checkerPhase.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -21,7 +21,7 @@ namespace ark::es2panda::compiler { class CheckerPhase : public Phase { public: - static constexpr std::string_view NAME = "CheckerPhase"; + static constexpr std::string_view const NAME = "CheckerPhase"; std::string_view Name() const override { return NAME; diff --git a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp index a9aa187de82ac2c266206b969e1b8ef6a7812535..55b253c522e5b2d9a9207728d69a671e51a8d2fa 100644 --- a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp @@ -88,15 +88,26 @@ ir::AstNode *ArrayLiteralLowering::TryTransformLiteralArrayToRefArray(ir::ArrayE std::vector newStmts; std::stringstream ss; auto *genSymIdent = Gensym(Allocator()); + auto *genSymIdent2 = Gensym(Allocator()); auto *type = checker_->AllocNode(arrayType, Allocator()); + // ss << "let @@I1 : FixedArray<@@T2> = @@E3;"; + // ss << "Array.from<@@T4>(@@I5);"; ss << "let @@I1 : FixedArray<@@T2> = @@E3;"; - ss << "Array.from<@@T4>(@@I5);"; + ss << "let @@I4 : Array<@@T5> = new Array<@@T6>(@@I7.length);"; + ss << "for (let i = 0; i < @@I8.length; ++i) { @@I9[i] = @@I10[i]}"; + ss << "@@I11;"; newStmts.emplace_back(genSymIdent); newStmts.emplace_back(type); - literalArray->SetTsType(nullptr); newStmts.emplace_back(literalArray); + literalArray->SetTsType(nullptr); + newStmts.emplace_back(genSymIdent2); + newStmts.emplace_back(type->Clone(Allocator(), nullptr)); newStmts.emplace_back(type->Clone(Allocator(), nullptr)); newStmts.emplace_back(genSymIdent->Clone(Allocator(), nullptr)); + newStmts.emplace_back(genSymIdent->Clone(Allocator(), nullptr)); + newStmts.emplace_back(genSymIdent2->Clone(Allocator(), nullptr)); + newStmts.emplace_back(genSymIdent->Clone(Allocator(), nullptr)); + newStmts.emplace_back(genSymIdent2->Clone(Allocator(), nullptr)); auto *parent = literalArray->Parent(); auto *loweringResult = parser_->CreateFormattedExpression(ss.str(), newStmts); @@ -255,4 +266,4 @@ ArenaAllocator *ArrayLiteralLowering::Allocator() return checker_->Allocator(); } -} // namespace ark::es2panda::compiler \ No newline at end of file +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp index d801b5526c23dc6f88d31f35fcc4c16c3a85e444..52dd7ccbc8d41afd37a78441e0ea1e4e20a8c887 100644 --- a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp +++ b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp @@ -169,6 +169,7 @@ void ComposeAsyncImplMethod(checker::ETSChecker *checker, ir::MethodDefinition * auto *baseOverloadImplMethod = node->BaseOverloadMethod()->AsyncPairMethod(); implMethod->Function()->Id()->SetVariable(baseOverloadImplMethod->Function()->Id()->Variable()); baseOverloadImplMethod->AddOverload(implMethod); + implMethod->SetParent(baseOverloadImplMethod); } else { classDef->Body().push_back(implMethod); } diff --git a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp index 2f63e74222530e2f0edf6d3029c46af1fd5eb825..e5e5c6d78df6965b1708d6f63839fef109262d00 100644 --- a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp +++ b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp @@ -134,6 +134,7 @@ static void HandleFunctionParam(public_lib::Context *ctx, ir::ETSParameterExpres auto *initId = allocator->New(id->Name(), allocator); initId->SetVariable(id->Variable()); initId->SetTsType(oldType); + initId->SetRange(id->Range()); // The new variable will have the same name as the parameter. This is not representable in source code. auto *boxedType = checker->GlobalBuiltinBoxType(oldType); @@ -146,6 +147,7 @@ static void HandleFunctionParam(public_lib::Context *ctx, ir::ETSParameterExpres auto *newDeclarator = util::NodeAllocator::ForceSetParent( allocator, ir::VariableDeclaratorFlag::CONST, allocator->New(newVarName.View(), allocator), newInit); + newDeclarator->SetRange(param->Range()); ArenaVector declVec {allocator->Adapter()}; declVec.emplace_back(newDeclarator); @@ -162,6 +164,7 @@ static void HandleFunctionParam(public_lib::Context *ctx, ir::ETSParameterExpres auto *newDeclaration = util::NodeAllocator::ForceSetParent( allocator, ir::VariableDeclaration::VariableDeclarationKind::CONST, allocator, std::move(declVec)); newDeclaration->SetParent(body); + newDeclaration->SetRange(param->Range()); bodyStmts.insert(bodyStmts.begin(), newDeclaration); auto lexScope = varbinder::LexicalScope::Enter(varBinder, scope); @@ -192,6 +195,8 @@ static ir::AstNode *HandleVariableDeclarator(public_lib::Context *ctx, ir::Varia if (arg->TsType() != type) { arg = util::NodeAllocator::ForceSetParent( allocator, arg, allocator->New(type, allocator), false); + arg->AsTSAsExpression()->TypeAnnotation()->SetRange(declarator->Init()->Range()); + arg->SetRange(declarator->Init()->Range()); } initArgs.push_back(arg); } @@ -201,6 +206,11 @@ static ir::AstNode *HandleVariableDeclarator(public_lib::Context *ctx, ir::Varia allocator, declarator->Flag(), allocator->New(id->Name(), allocator), newInit); newDeclarator->SetParent(declarator->Parent()); + newInit->GetTypeRef()->SetRange(declarator->Range()); + newInit->SetRange(declarator->Range()); + newDeclarator->Id()->SetRange(declarator->Range()); + newDeclarator->SetRange(declarator->Range()); + auto *newDecl = allocator->New(oldVar->Name(), newDeclarator); auto *newVar = allocator->New(newDecl, oldVar->Flags()); newDeclarator->Id()->AsIdentifier()->SetVariable(newVar); @@ -352,6 +362,7 @@ bool BoxingForLocals::PerformForModule(public_lib::Context *ctx, parser::Program std::function searchForFunctions = [&](ir::AstNode *ast) { if (ast->IsScriptFunction()) { HandleScriptFunction(ctx, ast->AsScriptFunction()); // no recursion + RefineSourceRanges(ast); } else { ast->Iterate(searchForFunctions); } diff --git a/ets2panda/compiler/lowering/ets/constStringToCharLowering.cpp b/ets2panda/compiler/lowering/ets/constStringToCharLowering.cpp deleted file mode 100644 index 73a1658357880f22c5fd79e266c3322371fc8439..0000000000000000000000000000000000000000 --- a/ets2panda/compiler/lowering/ets/constStringToCharLowering.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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 "constStringToCharLowering.h" - -#include "checker/ETSchecker.h" - -namespace ark::es2panda::compiler { - -std::string_view ConstStringToCharLowering::Name() const -{ - return "ConstStringToCharLowering"; -} - -ir::AstNode *TryConvertToCharLiteral(checker::ETSChecker *checker, ir::AstNode *ast) -{ - if (!ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOX_TO_CHAR) || !ast->IsExpression() || - ast->AsExpression()->TsType() == nullptr || !ast->AsExpression()->TsType()->IsETSStringType()) { - return nullptr; - } - - auto type = ast->AsExpression()->TsType()->AsETSStringType(); - if (!type->IsConstantType() || !type->GetValue().IsConvertibleToChar()) { - return nullptr; - } - - auto parent = ast->Parent(); - util::StringView::Iterator it(type->GetValue()); - auto value = static_cast(it.PeekCp()); - - auto newValue = checker->Allocator()->New(value); - newValue->SetParent(parent); - newValue->SetRange(ast->Range()); - if (ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR)) { - newValue->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR); - } - - newValue->Check(checker); - return newValue; -} - -bool ConstStringToCharLowering::PerformForModule(public_lib::Context *const ctx, parser::Program *const program) -{ - auto *const checker = ctx->checker->AsETSChecker(); - - program->Ast()->TransformChildrenRecursively( - // CC-OFFNXT(G.FMT.14-CPP) project code style - [checker](ir::AstNode *ast) -> ir::AstNode * { - if (auto newValue = TryConvertToCharLiteral(checker, ast); newValue != nullptr) { - return newValue; - } - - return ast; - }, - Name()); - - return true; -} - -} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index 503cf4dd996e5e2bc35ccca4bf367067d2c91451..39e33dfc10ebb2d8464b773a8939446967ecddd8 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -14,25 +14,198 @@ */ #include "constantExpressionLowering.h" +#include #include "checker/ETSchecker.h" #include "compiler/lowering/util.h" -#include "lexer/token/token.h" +#include "ir/expressions/literals/undefinedLiteral.h" +#include "compiler/lowering/scopesInit/scopesInitPhase.h" +#include "util/helpers.h" namespace ark::es2panda::compiler { using AstNodePtr = ir::AstNode *; -void ConstantExpressionLowering::LogError(const diagnostic::DiagnosticKind &diagnostic, - const util::DiagnosticMessageParams &diagnosticParams, - const lexer::SourcePosition &pos) const +static ir::BooleanLiteral *CreateBooleanLiteral(bool val, ir::AstNode *parent, const lexer::SourceRange &loc, + ArenaAllocator *allocator) { - context_->diagnosticEngine->LogDiagnostic(diagnostic, diagnosticParams, pos); + auto resNode = util::NodeAllocator::Alloc(allocator, val); + resNode->SetParent(parent); + resNode->SetRange(loc); + resNode->SetFolded(); + return resNode; +} + +template +static ir::NumberLiteral *CreateNumberLiteral(T val, ir::AstNode *parent, const lexer::SourceRange &loc, + ArenaAllocator *allocator) +{ + auto resNum = lexer::Number(val); + + auto *resNode = util::NodeAllocator::Alloc(allocator, resNum); + + // Some hack to set string representation of lexer::Number + resNode->Number().SetStr(util::UString(resNode->ToString(), allocator).View()); + + resNode->SetParent(parent); + resNode->SetRange(loc); + resNode->SetFolded(); + return resNode; +} + +static ir::Identifier *CreateErrorIdentifier(const ir::AstNode *node, ArenaAllocator *allocator) +{ + // Creating Identifier without passing any arguments leads to creating Error Identifier with *ERROR_LITERAL* + auto res = util::NodeAllocator::Alloc(allocator, allocator); + + res->SetParent(const_cast(node)->Parent()); + res->SetRange(node->Range()); + return res; +} + +static ir::CharLiteral *CreateCharLiteral(char16_t val, ir::AstNode *parent, const lexer::SourceRange &loc, + ArenaAllocator *allocator) +{ + auto *result = util::NodeAllocator::Alloc(allocator, val); + result->SetParent(parent); + result->SetRange(loc); + result->SetFolded(); + return result; +} + +static ir::PrimitiveType TypeRankToPrimitiveType(TypeRank tr) +{ + switch (tr) { + case TypeRank::CHAR: + return ir::PrimitiveType::CHAR; + case TypeRank::INT8: + return ir::PrimitiveType::BYTE; + case TypeRank::INT16: + return ir::PrimitiveType::SHORT; + case TypeRank::INT32: + return ir::PrimitiveType::INT; + case TypeRank::INT64: + return ir::PrimitiveType::LONG; + case TypeRank::FLOAT: + return ir::PrimitiveType::FLOAT; + case TypeRank::DOUBLE: + return ir::PrimitiveType::DOUBLE; + } + ES2PANDA_UNREACHABLE(); +} + +static TypeRank GetTypeRank(const ir::Literal *literal) +{ + if (literal->IsCharLiteral()) { + return TypeRank::CHAR; + } + if (literal->IsNumberLiteral()) { + auto number = literal->AsNumberLiteral()->Number(); + if (number.IsByte()) { + return TypeRank::INT8; + } + if (number.IsShort()) { + return TypeRank::INT16; + } + if (number.IsInt()) { + return TypeRank::INT32; + } + if (number.IsLong()) { + return TypeRank::INT64; + } + if (number.IsFloat()) { + return TypeRank::FLOAT; + } + if (number.IsDouble()) { + return TypeRank::DOUBLE; + } + } + ES2PANDA_UNREACHABLE(); +} + +template +static TargetType GetVal(const ir::Literal *node) +{ + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(node->IsBooleanLiteral()); + return node->AsBooleanLiteral()->Value(); + } + + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(node->IsCharLiteral()); + return node->AsCharLiteral()->Char(); + } + + ES2PANDA_ASSERT(node->IsNumberLiteral()); + + auto numNode = node->AsNumberLiteral(); + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsByte()); + return numNode->Number().GetByte(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsShort()); + return numNode->Number().GetShort(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsInt()); + return numNode->Number().GetInt(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsLong()); + return numNode->Number().GetLong(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsFloat()); + return numNode->Number().GetFloat(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsDouble()); + return numNode->Number().GetDouble(); + } + ES2PANDA_UNREACHABLE(); +} + +template +static To CastValTo(const ir::Literal *lit) +{ + if (lit->IsBooleanLiteral()) { + return static_cast(GetVal(lit)); + } + + ES2PANDA_ASSERT(lit->IsNumberLiteral() || lit->IsCharLiteral()); + + auto rank = GetTypeRank(lit); + switch (rank) { + case TypeRank::DOUBLE: + return static_cast(GetVal(lit)); + case TypeRank::FLOAT: + return static_cast(GetVal(lit)); + case TypeRank::INT64: + return static_cast(GetVal(lit)); + case TypeRank::INT32: + return static_cast(GetVal(lit)); + case TypeRank::INT16: + return static_cast(GetVal(lit)); + case TypeRank::INT8: + return static_cast(GetVal(lit)); + case TypeRank::CHAR: + return static_cast(GetVal(lit)); + } + + ES2PANDA_UNREACHABLE(); +} + +static bool IsConvertibleToNumericType(const ir::Literal *lit) +{ + // true if CharLiteral and NumberLiteral + return !(lit->IsStringLiteral() || lit->IsBooleanLiteral() || lit->IsNullLiteral() || lit->IsUndefinedLiteral()); } -static bool IsSupportedLiteralForNumeric(ir::Literal *const node) +static void LogError(public_lib::Context *context, const diagnostic::DiagnosticKind &diagnostic, + const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos) { - return node->IsNumberLiteral() || node->IsCharLiteral() || node->IsBooleanLiteral(); + context->diagnosticEngine->LogDiagnostic(diagnostic, diagnosticParams, pos); } static bool IsSupportedLiteral(ir::Expression *const node) @@ -52,136 +225,226 @@ static bool IsStringTypeReference(ir::ETSTypeReference *type) return name == "string" || name == "String"; } -static bool CheckIsBooleanConstantForUnary(ir::Literal *const unaryLiteral, lexer::TokenType opType) +template +static ir::AstNode *CommonCastNumberLiteralTo(const ir::Literal *num, ArenaAllocator *allocator) { - if (unaryLiteral->IsBooleanLiteral()) { - return true; + auto parent = const_cast(num)->Parent(); + + if constexpr (std::is_same_v) { + return CreateCharLiteral(CastValTo(num), parent, num->Range(), allocator); } - return opType == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; + + return CreateNumberLiteral(CastValTo(num), parent, num->Range(), allocator); } -static bool CheckIsBooleanConstantForBinary(ir::Literal *lhs, ir::Literal *rhs, lexer::TokenType opType) +template +static ir::AstNode *FloatingPointNumberLiteralCast(const ir::Literal *num, public_lib::Context *context) { - if (lhs->IsBooleanLiteral() && rhs->IsBooleanLiteral()) { - return true; + if (sizeof(From) > sizeof(To)) { + // Constant narrowing floating point conversion is not permitted + LogError(context, diagnostic::CONSTANT_FLOATING_POINT_COVERSION, {}, num->Start()); + return const_cast(num); } - return opType == lexer::TokenType::PUNCTUATOR_GREATER_THAN || - opType == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - opType == lexer::TokenType::PUNCTUATOR_LESS_THAN || opType == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL || - opType == lexer::TokenType::PUNCTUATOR_EQUAL || opType == lexer::TokenType::PUNCTUATOR_NOT_EQUAL || - opType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || opType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR; + + // float -> double + return CommonCastNumberLiteralTo(num, context->allocator); } -static bool CheckIsNumericConstant(ir::Literal *const left, ir::Literal *const right) +template +static ir::AstNode *NarrowingNumberLiteralCast(const ir::Literal *num, public_lib::Context *context) { - return (left->IsNumberLiteral() || left->IsCharLiteral()) && (right->IsNumberLiteral() || right->IsCharLiteral()); + auto maxTo = std::numeric_limits::max(); + auto minTo = std::numeric_limits::min(); + auto val = GetVal(num); + if (val < minTo || val > maxTo) { + LogError(context, diagnostic::CONSTANT_VALUE_OUT_OF_RANGE, {}, num->Start()); + return const_cast(num); + } + + return CommonCastNumberLiteralTo(num, context->allocator); } -template -static TargetType GetOperand(ir::Literal *const node) +template +static ir::AstNode *IntegralNumberLiteralCast(const ir::Literal *num, public_lib::Context *context) { - if (node->IsBooleanLiteral()) { - return node->AsBooleanLiteral()->Value(); + if (sizeof(From) > sizeof(To)) { + return NarrowingNumberLiteralCast(num, context); } - if (node->IsNumberLiteral()) { - auto numNode = node->AsNumberLiteral(); - if (numNode->Number().IsInt()) { - return numNode->Number().GetInt(); - } - if (numNode->Number().IsLong()) { - return numNode->Number().GetLong(); - } - if (numNode->Number().IsFloat()) { - return numNode->Number().GetFloat(); - } - if (numNode->Number().IsDouble()) { - return numNode->Number().GetDouble(); - } - ES2PANDA_UNREACHABLE(); + // Widening + return CommonCastNumberLiteralTo(num, context->allocator); +} + +template +static ir::AstNode *CastNumberOrCharLiteralFromTo(const ir::Literal *num, public_lib::Context *context) +{ + if constexpr (std::is_same_v) { + return const_cast(num); } - if (node->IsCharLiteral()) { - return node->AsCharLiteral()->Char(); + if constexpr (std::is_floating_point_v && std::is_floating_point_v) { + return FloatingPointNumberLiteralCast(num, context); } - ES2PANDA_UNREACHABLE(); -} + if constexpr (std::is_integral_v && std::is_integral_v) { + return IntegralNumberLiteralCast(num, context); + } -static TypeRank GetTypeRank(ir::Literal *const literal) -{ - if (literal->IsCharLiteral()) { - return TypeRank::CHAR; + if constexpr (std::is_integral_v && std::is_floating_point_v) { + // integral -> floating point (widening) + return CommonCastNumberLiteralTo(num, context->allocator); } - if (literal->IsNumberLiteral()) { - auto number = literal->AsNumberLiteral()->Number(); - if (number.IsInt()) { - return TypeRank::INT32; - } - if (number.IsLong()) { - return TypeRank::INT64; - } - if (number.IsDouble()) { - return TypeRank::DOUBLE; - } - return TypeRank::FLOAT; + + if constexpr (std::is_floating_point_v && std::is_integral_v) { + // Constant narrowing floating point conversion is not permitted + LogError(context, diagnostic::CONSTANT_FLOATING_POINT_COVERSION, {}, num->Start()); + return const_cast(num); } + ES2PANDA_UNREACHABLE(); } -static bool TestLiteralIsNotZero(ir::Literal *literal) +template +static ir::AstNode *CastNumberOrCharLiteralFrom(const ir::Literal *lit, ir::PrimitiveType type, + public_lib::Context *context) { - ES2PANDA_ASSERT(literal->IsCharLiteral() || literal->IsNumberLiteral()); - if (literal->IsCharLiteral()) { - return literal->AsCharLiteral()->Char() != 0; + switch (type) { + case ir::PrimitiveType::CHAR: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::BYTE: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::SHORT: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::INT: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::LONG: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::FLOAT: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::DOUBLE: + return CastNumberOrCharLiteralFromTo(lit, context); + default: + ES2PANDA_UNREACHABLE(); } +} - auto number = literal->AsNumberLiteral()->Number(); - if (number.IsInt()) { - return number.GetInt() != 0; +static ir::AstNode *CorrectNumberOrCharLiteral(const ir::Literal *lit, ir::PrimitiveType type, + public_lib::Context *context) +{ + if (TypeRankToPrimitiveType(GetTypeRank(lit)) == type) { + return const_cast(lit); } - if (number.IsLong()) { - return number.GetLong() != 0; + + switch (GetTypeRank(lit)) { + case TypeRank::CHAR: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::INT8: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::INT16: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::INT32: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::INT64: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::FLOAT: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::DOUBLE: + return CastNumberOrCharLiteralFrom(lit, type, context); + default: + ES2PANDA_UNREACHABLE(); } - if (number.IsDouble()) { - return number.GetDouble() != 0; +} + +ir::TypeNode *GetTypeAnnotationFromVarDecl(const ir::Literal *lit) +{ + auto *parent = lit->Parent(); + if (!parent->IsVariableDeclarator()) { + return nullptr; } - if (number.IsFloat()) { - return number.GetFloat() != 0; + auto vd = parent->AsVariableDeclarator(); + if (!vd->Id()->IsIdentifier()) { + return nullptr; } - ES2PANDA_UNREACHABLE(); + return vd->Id()->AsIdentifier()->TypeAnnotation(); } -ir::AstNode *ConstantExpressionLowering::FoldTernaryConstant(ir::ConditionalExpression *cond) +static ir::PrimitiveType GetRightTypeOfNumberOrCharLiteral(const ir::Literal *lit) { - ir::AstNode *resNode {}; + auto *parent = lit->Parent(); + if (parent->IsVariableDeclarator()) { + auto vb = parent->AsVariableDeclarator(); + if (!vb->Id()->IsIdentifier()) { + return TypeRankToPrimitiveType(GetTypeRank(lit)); + } + + if (vb->Id()->AsIdentifier()->TypeAnnotation() == nullptr) { + return TypeRankToPrimitiveType(GetTypeRank(lit)); + } + + if (vb->Id()->AsIdentifier()->TypeAnnotation()->IsETSPrimitiveType()) { + return vb->Id()->AsIdentifier()->TypeAnnotation()->AsETSPrimitiveType()->GetPrimitiveType(); + } + } else if (parent->IsClassProperty()) { + auto cp = parent->AsClassProperty(); + if (cp->TypeAnnotation() == nullptr) { + return TypeRankToPrimitiveType(GetTypeRank(lit)); + } - auto const testCond = cond->Test()->AsLiteral(); - if (testCond->IsBooleanLiteral()) { - resNode = testCond->AsBooleanLiteral()->Value() ? cond->Consequent() : cond->Alternate(); + if (cp->TypeAnnotation()->IsETSPrimitiveType()) { + return cp->TypeAnnotation()->AsETSPrimitiveType()->GetPrimitiveType(); + } + } + + return TypeRankToPrimitiveType(GetTypeRank(lit)); +} + +static ir::AstNode *TryToCorrectNumberOrCharLiteral(ir::AstNode *node, public_lib::Context *context) +{ + if (node->IsNumberLiteral() || node->IsCharLiteral()) { + auto lit = node->AsExpression()->AsLiteral(); + return CorrectNumberOrCharLiteral(lit, GetRightTypeOfNumberOrCharLiteral(lit), context); } + + return node; +} + +// NOLINTBEGIN(readability-else-after-return) +static bool TestLiteral(const ir::Literal *lit) +{ // 15.10.1 Extended Conditional Expression - if (testCond->IsStringLiteral()) { - resNode = !testCond->AsStringLiteral()->Str().Empty() ? cond->Consequent() : cond->Alternate(); + if (lit->IsBooleanLiteral()) { + return lit->AsBooleanLiteral()->Value(); } - if (testCond->IsNullLiteral() || testCond->IsUndefinedLiteral()) { - resNode = cond->Alternate(); + if (lit->IsStringLiteral()) { + return !lit->AsStringLiteral()->Str().Empty(); } - if (testCond->IsCharLiteral() || testCond->IsNumberLiteral()) { - resNode = TestLiteralIsNotZero(testCond) ? cond->Consequent() : cond->Alternate(); + if (lit->IsNullLiteral() || lit->IsUndefinedLiteral()) { + return false; } - - if (resNode == nullptr) { - return cond; + if (lit->IsCharLiteral()) { + return lit->AsCharLiteral()->Char() != 0; + } + if (lit->IsNumberLiteral()) { + return !lit->AsNumberLiteral()->Number().IsZero(); } + ES2PANDA_UNREACHABLE(); +} +// NOLINTEND(readability-else-after-return) - resNode->SetParent(cond->Parent()); +ir::AstNode *ConstantExpressionLowering::FoldTernaryConstant(ir::ConditionalExpression *cond) +{ + auto const test = cond->Test()->AsLiteral(); + auto res = TestLiteral(test) ? cond->Consequent() : cond->Alternate(); + auto resNode = res->Clone(context_->allocator, cond->Parent()); + auto *scope = NearestScope(resNode->Parent()); + auto localCtx = varbinder::LexicalScope::Enter(varbinder_, scope); + InitScopesPhaseETS::RunExternalNode(resNode, varbinder_); resNode->SetRange(cond->Range()); return resNode; } template -bool ConstantExpressionLowering::PerformRelationOperator(InputType left, InputType right, lexer::TokenType opType) +static bool PerformRelationOperation(InputType left, InputType right, lexer::TokenType opType) { switch (opType) { case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { @@ -196,9 +459,22 @@ bool ConstantExpressionLowering::PerformRelationOperator(InputType left, InputTy case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { return left <= right; } + case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_EQUAL: { + if constexpr (std::is_floating_point_v) { + // Compare floating point numbers in two steps: + // 1. With fixed epsilon + // 2. with adaptive epsilon + // CC-OFFNXT(G.FMT.03-CPP) project code style + static constexpr auto EPSILON = 1.0e-5F; + if (std::fabs(left - right) <= EPSILON) { + return true; + } + return std::fabs(left - right) <= EPSILON * std::fmax(std::fabs(left), std::fabs(right)); + } return left == right; } + case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { return left != right; } @@ -208,367 +484,541 @@ bool ConstantExpressionLowering::PerformRelationOperator(InputType left, InputTy } } -bool ConstantExpressionLowering::HandleRelationOperator(ir::Literal *left, ir::Literal *right, lexer::TokenType opType) +static ir::AstNode *HandleNumericalRelationalExpression(const ir::BinaryExpression *expr, ArenaAllocator *allocator) { - if (left->IsBooleanLiteral()) { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); - } - if (left->IsStringLiteral()) { - return PerformRelationOperator(left->AsStringLiteral()->Str(), right->AsStringLiteral()->Str(), opType); - } + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + ES2PANDA_ASSERT(left->IsNumberLiteral() || left->IsCharLiteral()); + ES2PANDA_ASSERT(right->IsNumberLiteral() || right->IsCharLiteral()); - TypeRank leftRank = GetTypeRank(left); - TypeRank rightRank = GetTypeRank(right); - TypeRank targetRank = std::max(leftRank, rightRank); + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); + + bool res = false; switch (targetRank) { case TypeRank::DOUBLE: { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); + res = PerformRelationOperation(CastValTo(left), CastValTo(right), opType); + break; } case TypeRank::FLOAT: { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); + res = PerformRelationOperation(CastValTo(left), CastValTo(right), opType); + break; } case TypeRank::INT64: { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); + res = PerformRelationOperation(CastValTo(left), CastValTo(right), opType); + break; } case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: case TypeRank::CHAR: { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); + res = PerformRelationOperation(CastValTo(left), CastValTo(right), opType); + break; } default: { ES2PANDA_UNREACHABLE(); } } + + return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), allocator); } -bool ConstantExpressionLowering::HandleBitwiseLogicalOperator(ir::Literal *left, ir::Literal *right, - lexer::TokenType opType) +static ir::AstNode *HandleNullUndefinedRelation(const ir::BinaryExpression *expr, public_lib::Context *context) { - bool leftValue = left->AsBooleanLiteral()->Value(); - bool rightValue = right->AsBooleanLiteral()->Value(); + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + bool isLeftNullUndefined = left->IsNullLiteral() || left->IsUndefinedLiteral(); + bool isRightNullUndefined = right->IsNullLiteral() || right->IsUndefinedLiteral(); + + // Either left operand is null/undefined or right operand is null/undefined + ES2PANDA_ASSERT(isLeftNullUndefined || isRightNullUndefined); + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + switch (opType) { - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { - return (static_cast(leftValue) ^ static_cast(rightValue)) != 0U; + case lexer::TokenType::PUNCTUATOR_EQUAL: { + if ((isLeftNullUndefined && !isRightNullUndefined) || (!isLeftNullUndefined && isRightNullUndefined)) { + return CreateBooleanLiteral(false, parent, loc, allocator); + } + return CreateBooleanLiteral(true, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { - return (static_cast(leftValue) & static_cast(rightValue)) != 0U; + case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { + if ((isLeftNullUndefined && !isRightNullUndefined) || (!isLeftNullUndefined && isRightNullUndefined)) { + return CreateBooleanLiteral(true, parent, loc, allocator); + } + return CreateBooleanLiteral(false, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { - return (static_cast(leftValue) | static_cast(rightValue)) != 0U; + case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: { + // null === null and undefined === undefined are true + return CreateBooleanLiteral(left->IsNullLiteral() == right->IsNullLiteral(), parent, loc, allocator); } + case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: + // null !== undefined is true + return CreateBooleanLiteral(left->IsNullLiteral() != right->IsNullLiteral(), parent, loc, allocator); default: { - ES2PANDA_UNREACHABLE(); + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); } } } -ir::AstNode *ConstantExpressionLowering::HandleLogicalOperator(ir::BinaryExpression *expr, lexer::TokenType opType) +static ir::AstNode *HandleRelationalExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { - auto left = expr->Left(); - auto right = expr->Right(); + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + if (IsConvertibleToNumericType(left) && IsConvertibleToNumericType(right)) { + return HandleNumericalRelationalExpression(expr, context->allocator); + } - bool leftBoolValue = false; - ir::AstNode *resultValueNode = nullptr; + if (left->IsStringLiteral() && right->IsStringLiteral()) { + auto res = PerformRelationOperation(left->AsStringLiteral()->Str(), right->AsStringLiteral()->Str(), opType); + return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), + context->allocator); + } - if (left->IsBooleanLiteral()) { - leftBoolValue = left->AsBooleanLiteral()->Value(); - } else if (left->IsNumberLiteral() || left->IsCharLiteral()) { - leftBoolValue = GetOperand(left->AsLiteral()) != 0; - } else if (left->IsStringLiteral()) { - leftBoolValue = left->AsStringLiteral()->Str().Length() != 0; - } else if (left->IsNullLiteral() || left->IsUndefinedLiteral()) { - leftBoolValue = false; - } else { - ES2PANDA_UNREACHABLE(); + if (left->IsBooleanLiteral() && right->IsBooleanLiteral()) { + auto res = PerformRelationOperation(GetVal(left), GetVal(right), opType); + return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), + context->allocator); } + if ((left->IsNullLiteral() || left->IsUndefinedLiteral()) || + (right->IsNullLiteral() || right->IsUndefinedLiteral())) { + return HandleNullUndefinedRelation(expr, context); + } + + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); +} + +static bool IsMultiplicativeExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_MULTIPLY || opType == lexer::TokenType::PUNCTUATOR_DIVIDE || + opType == lexer::TokenType::PUNCTUATOR_MOD; +} + +static bool IsRelationalExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_GREATER_THAN || + opType == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || + opType == lexer::TokenType::PUNCTUATOR_LESS_THAN || opType == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL || + opType == lexer::TokenType::PUNCTUATOR_EQUAL || opType == lexer::TokenType::PUNCTUATOR_NOT_EQUAL || + opType == lexer::TokenType::PUNCTUATOR_STRICT_EQUAL || + opType == lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL; +} + +static bool IsAdditiveExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + + return opType == lexer::TokenType::PUNCTUATOR_PLUS || opType == lexer::TokenType::PUNCTUATOR_MINUS; +} + +template +static TargetType PerformMultiplicativeOperation(TargetType leftNum, TargetType rightNum, + const ir::BinaryExpression *expr, public_lib::Context *context) +{ + auto isForbiddenZeroDivision = [&rightNum]() { return std::is_integral_v && rightNum == 0; }; + auto opType = expr->OperatorType(); switch (opType) { - case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: { - if (!leftBoolValue) { - resultValueNode = left; - break; + case lexer::TokenType::PUNCTUATOR_MULTIPLY: { + return leftNum * rightNum; + } + case lexer::TokenType::PUNCTUATOR_DIVIDE: { + if (isForbiddenZeroDivision()) { + LogError(context, diagnostic::DIVISION_BY_ZERO, {}, expr->Start()); + // Max integral value + return std::numeric_limits::max(); } - resultValueNode = right; - break; + return leftNum / rightNum; } - case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { - if (leftBoolValue) { - resultValueNode = left; + case lexer::TokenType::PUNCTUATOR_MOD: { + if (isForbiddenZeroDivision()) { + LogError(context, diagnostic::DIVISION_BY_ZERO, {}, expr->Start()); + // Max integral value + return std::numeric_limits::max(); + } + if constexpr (std::is_integral_v) { + return leftNum % rightNum; } else { - resultValueNode = right; + return std::fmod(leftNum, rightNum); } - break; } - default: { + default: + ES2PANDA_UNREACHABLE(); + } +} + +static ir::AstNode *HandleMultiplicativeExpression(const ir::BinaryExpression *expr, public_lib::Context *context) +{ + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + if (!IsConvertibleToNumericType(left) && !IsConvertibleToNumericType(right)) { + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); + } + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); + switch (targetRank) { + case TypeRank::DOUBLE: { + double res = + PerformMultiplicativeOperation(CastValTo(left), CastValTo(right), expr, context); + return CreateNumberLiteral(res, parent, loc, allocator); + } + case TypeRank::FLOAT: { + float res = PerformMultiplicativeOperation(CastValTo(left), CastValTo(right), expr, context); + return CreateNumberLiteral(res, parent, loc, allocator); + } + case TypeRank::INT64: { + int64_t res = + PerformMultiplicativeOperation(CastValTo(left), CastValTo(right), expr, context); + return CreateNumberLiteral(res, parent, loc, allocator); + } + case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: + case TypeRank::CHAR: { + int32_t res = + PerformMultiplicativeOperation(CastValTo(left), CastValTo(right), expr, context); + return CreateNumberLiteral(res, parent, loc, allocator); + } + default: ES2PANDA_UNREACHABLE(); + } +} + +template +static TargetType PerformAdditiveOperation(TargetType left, TargetType right, lexer::TokenType opType) +{ + if constexpr (std::is_floating_point_v) { + switch (opType) { + case lexer::TokenType::PUNCTUATOR_PLUS: + return left + right; + case lexer::TokenType::PUNCTUATOR_MINUS: + return left - right; + default: + ES2PANDA_UNREACHABLE(); + } + } else { + // Integral types + // try bit cast to unsigned counterpart to avoid signed integer overflow + auto uLeft = bit_cast, TargetType>(left); + auto uRight = bit_cast, TargetType>(right); + + switch (opType) { + case lexer::TokenType::PUNCTUATOR_PLUS: { + return bit_cast>(uLeft + uRight); + } + case lexer::TokenType::PUNCTUATOR_MINUS: { + return bit_cast>(uLeft - uRight); + } + default: + ES2PANDA_UNREACHABLE(); } } +} - resultValueNode->SetParent(expr->Parent()); - resultValueNode->SetRange({left->Range().start, right->Range().end}); - return resultValueNode; +static ir::AstNode *PerformStringAdditiveOperation(const ir::BinaryExpression *expr, public_lib::Context *context) +{ + auto const lhs = expr->Left()->AsLiteral(); + auto const rhs = expr->Right()->AsLiteral(); + auto const resStr = util::UString(lhs->ToString() + rhs->ToString(), context->allocator).View(); + auto resNode = util::NodeAllocator::Alloc(context->allocator, resStr); + resNode->SetParent(const_cast(expr)->Parent()); + resNode->SetRange(expr->Range()); + return resNode; } -ir::AstNode *ConstantExpressionLowering::FoldBinaryBooleanConstant(ir::BinaryExpression *expr) +static ir::AstNode *HandleAdditiveExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { auto left = expr->Left()->AsLiteral(); auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + if ((opType == lexer::TokenType::PUNCTUATOR_PLUS) && (left->IsStringLiteral() || right->IsStringLiteral())) { + return PerformStringAdditiveOperation(expr, context); + } - bool result {}; - switch (expr->OperatorType()) { - case lexer::TokenType::PUNCTUATOR_GREATER_THAN: - case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: - case lexer::TokenType::PUNCTUATOR_LESS_THAN: - case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: - case lexer::TokenType::PUNCTUATOR_EQUAL: - case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - if ((left->IsBooleanLiteral() && right->IsBooleanLiteral()) || CheckIsNumericConstant(left, right) || - (left->IsStringLiteral() && right->IsStringLiteral())) { - result = HandleRelationOperator(left, right, expr->OperatorType()); - break; - } - return expr; + if (!IsConvertibleToNumericType(left) && !IsConvertibleToNumericType(right)) { + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); + } + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); + switch (targetRank) { + case TypeRank::DOUBLE: { + auto res = PerformAdditiveOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { - if (left->IsBooleanLiteral() && right->IsBooleanLiteral()) { - result = HandleBitwiseLogicalOperator(left, right, expr->OperatorType()); - break; - } - return expr; + case TypeRank::FLOAT: { + auto res = PerformAdditiveOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: - case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { - // Special because of extended conditional expression - return HandleLogicalOperator(expr, expr->OperatorType()); + case TypeRank::INT64: { + int64_t res = PerformAdditiveOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - default: { - return expr; + case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: + case TypeRank::CHAR: { + int32_t res = PerformAdditiveOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } + default: + ES2PANDA_UNREACHABLE(); } +} - auto resNode = util::NodeAllocator::Alloc(context_->allocator, result); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; +static bool IsShiftExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || opType == lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT || + opType == lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT; } -template -IntegerType ConstantExpressionLowering::PerformBitwiseArithmetic(IntegerType left, IntegerType right, - lexer::TokenType operationType) +template +static SignedType PerformShiftOperation(SignedType left, SignedType right, lexer::TokenType opType) { - using UnsignedType = std::make_unsigned_t; + using UnsignedType = std::make_unsigned_t; - UnsignedType result = 0; - UnsignedType unsignedLeftValue = left; - UnsignedType unsignedRightValue = right; + SignedType result = 0; + auto uLeft = bit_cast(left); + auto uRight = bit_cast(right); auto mask = std::numeric_limits::digits - 1U; - auto shift = unsignedRightValue & mask; + UnsignedType shift = uRight & mask; - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { - result = unsignedLeftValue & unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { - result = unsignedLeftValue | unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { - result = unsignedLeftValue ^ unsignedRightValue; - break; - } + switch (opType) { case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: { static_assert(sizeof(UnsignedType) == 4 || sizeof(UnsignedType) == 8); - result = unsignedLeftValue << shift; - break; + return bit_cast(uLeft << shift); } case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: { - static_assert(sizeof(IntegerType) == 4 || sizeof(IntegerType) == 8); - result = static_cast(unsignedLeftValue) >> shift; // NOLINT(hicpp-signed-bitwise) - break; + static_assert(sizeof(SignedType) == 4 || sizeof(SignedType) == 8); + return bit_cast(left >> shift); // NOLINT(hicpp-signed-bitwise) } case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: { static_assert(sizeof(UnsignedType) == 4 || sizeof(UnsignedType) == 8); - result = unsignedLeftValue >> shift; - break; + return bit_cast(uLeft >> shift); } - default: { + default: ES2PANDA_UNREACHABLE(); - } } - return result; } -template -lexer::Number ConstantExpressionLowering::HandleBitwiseOperator(TargetType leftNum, TargetType rightNum, - lexer::TokenType operationType, TypeRank targetRank) +static ir::AstNode *HandleShiftExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + if (!IsConvertibleToNumericType(left) && !IsConvertibleToNumericType(right)) { + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); + } + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); switch (targetRank) { - case TypeRank::DOUBLE: { - return lexer::Number(PerformBitwiseArithmetic(leftNum, rightNum, operationType)); - } - case TypeRank::FLOAT: { - return lexer::Number(PerformBitwiseArithmetic(leftNum, rightNum, operationType)); - } + case TypeRank::DOUBLE: case TypeRank::INT64: { - return lexer::Number(PerformBitwiseArithmetic(leftNum, rightNum, operationType)); + int64_t res = PerformShiftOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } + case TypeRank::FLOAT: case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: case TypeRank::CHAR: { - return lexer::Number(PerformBitwiseArithmetic(leftNum, rightNum, operationType)); + int32_t res = PerformShiftOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - default: { + default: ES2PANDA_UNREACHABLE(); - } } } -template -TargetType ConstantExpressionLowering::HandleArithmeticOperation(TargetType leftNum, TargetType rightNum, - ir::BinaryExpression *expr) +static bool IsBitwiseLogicalExpression(const ir::BinaryExpression *expr) { - auto isForbiddenZeroDivision = [&rightNum]() { return std::is_integral::value && rightNum == 0; }; - auto operationType = expr->OperatorType(); - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_PLUS: { - return leftNum + rightNum; + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_BITWISE_XOR || opType == lexer::TokenType::PUNCTUATOR_BITWISE_AND || + opType == lexer::TokenType::PUNCTUATOR_BITWISE_OR; +} + +template +static SignedType PerformBitwiseLogicalOperation(SignedType left, SignedType right, lexer::TokenType opType) +{ + using UnsignedType = std::make_unsigned_t; + + auto uLeft = bit_cast(left); + auto uRight = bit_cast(right); + + switch (opType) { + case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { + return uLeft & uRight; } - case lexer::TokenType::PUNCTUATOR_MINUS: { - return leftNum - rightNum; + case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { + return uLeft | uRight; } - case lexer::TokenType::PUNCTUATOR_DIVIDE: { - if (isForbiddenZeroDivision()) { - LogError(diagnostic::DIVISION_BY_ZERO, {}, expr->Start()); - return rightNum; - } - return leftNum / rightNum; + case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { + return uLeft ^ uRight; } - case lexer::TokenType::PUNCTUATOR_MULTIPLY: { - return leftNum * rightNum; + default: + ES2PANDA_UNREACHABLE(); + } +} + +static ir::AstNode *HandleNumericBitwiseLogicalExpression(const ir::BinaryExpression *expr, + public_lib::Context *context) +{ + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); + switch (targetRank) { + case TypeRank::DOUBLE: + case TypeRank::INT64: { + int64_t res = PerformBitwiseLogicalOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_MOD: { - if (isForbiddenZeroDivision()) { - LogError(diagnostic::DIVISION_BY_ZERO, {}, expr->Start()); - return rightNum; - } - if constexpr (std::is_integral_v) { - return leftNum % rightNum; - } else { - return std::fmod(leftNum, rightNum); - } + case TypeRank::FLOAT: + case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: + case TypeRank::CHAR: { + int32_t res = PerformBitwiseLogicalOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } default: ES2PANDA_UNREACHABLE(); } } -template -ir::AstNode *ConstantExpressionLowering::FoldBinaryNumericConstantHelper(ir::BinaryExpression *expr, - TypeRank targetRank) +static ir::AstNode *HandleBitwiseLogicalExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { - auto const lhs = expr->Left()->AsLiteral(); - auto const rhs = expr->Right()->AsLiteral(); - lexer::Number resNum {}; - auto lhsNumber = GetOperand(lhs); - auto rhsNumber = GetOperand(rhs); - switch (expr->OperatorType()) { - case lexer::TokenType::PUNCTUATOR_DIVIDE: - case lexer::TokenType::PUNCTUATOR_MOD: - case lexer::TokenType::PUNCTUATOR_PLUS: - case lexer::TokenType::PUNCTUATOR_MINUS: - case lexer::TokenType::PUNCTUATOR_MULTIPLY: { - auto num = HandleArithmeticOperation(lhsNumber, rhsNumber, expr); - resNum = lexer::Number(num); + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + if (IsConvertibleToNumericType(left) && IsConvertibleToNumericType(right)) { + return HandleNumericBitwiseLogicalExpression(expr, context); + } + + if (!left->IsBooleanLiteral() && !right->IsBooleanLiteral()) { + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); + } + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + bool res = false; + + auto leftVal = left->AsBooleanLiteral()->Value(); + auto rightVal = right->AsBooleanLiteral()->Value(); + switch (opType) { + case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { + res = ((static_cast(leftVal) & static_cast(rightVal)) != 0); break; } - case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { - resNum = HandleBitwiseOperator(lhsNumber, rhsNumber, expr->OperatorType(), targetRank); + case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { + res = ((static_cast(leftVal) | static_cast(rightVal)) != 0); break; } - default: { - // Operation might not support. - return expr; + case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { + res = leftVal ^ rightVal; + break; } + default: + ES2PANDA_UNREACHABLE(); } + return CreateBooleanLiteral(res, parent, loc, allocator); +} - ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(context_->allocator, resNum); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; +static bool IsConditionalExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || opType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR; } -ir::AstNode *ConstantExpressionLowering::FoldBinaryNumericConstant(ir::BinaryExpression *expr) +static ir::AstNode *HandleConditionalExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { - auto left = expr->Left()->AsLiteral(); - auto right = expr->Right()->AsLiteral(); - if (!IsSupportedLiteralForNumeric(left) && !IsSupportedLiteralForNumeric(right)) { - return expr; - } + auto left = const_cast(expr)->Left()->AsLiteral(); + auto right = const_cast(expr)->Right()->AsLiteral(); - TypeRank leftRank = GetTypeRank(left); - TypeRank rightRank = GetTypeRank(right); - TypeRank targetRank = std::max(leftRank, rightRank); - switch (targetRank) { - case TypeRank::DOUBLE: { - return FoldBinaryNumericConstantHelper(expr, targetRank); - } - case TypeRank::FLOAT: { - return FoldBinaryNumericConstantHelper(expr, targetRank); - } - case TypeRank::INT64: { - return FoldBinaryNumericConstantHelper(expr, targetRank); + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + bool lhs = TestLiteral(left); + bool rhs = TestLiteral(right); + + auto opType = expr->OperatorType(); + switch (opType) { + case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: { + return CreateBooleanLiteral(lhs && rhs, parent, loc, allocator); } - case TypeRank::INT32: - case TypeRank::CHAR: { - return FoldBinaryNumericConstantHelper(expr, targetRank); + case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { + return CreateBooleanLiteral(lhs || rhs, parent, loc, allocator); } default: { ES2PANDA_UNREACHABLE(); } } + ES2PANDA_UNREACHABLE(); } -ir::AstNode *ConstantExpressionLowering::FoldBinaryStringConstant(ir::BinaryExpression *const expr) +static ir::AstNode *FoldBinaryExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { - if (expr->OperatorType() != lexer::TokenType::PUNCTUATOR_PLUS) { - LogError(diagnostic::UNSUPPORTED_OPERATOR_FOR_STRING, {}, expr->Left()->Start()); - return expr; + if (IsMultiplicativeExpression(expr)) { + return HandleMultiplicativeExpression(expr, context); } - - auto const lhs = expr->Left()->AsLiteral(); - auto const rhs = expr->Right()->AsLiteral(); - auto const resStr = util::UString(lhs->ToString() + rhs->ToString(), context_->allocator).View(); - auto resNode = util::NodeAllocator::Alloc(context_->allocator, resStr); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; -} - -ir::AstNode *ConstantExpressionLowering::FoldBinaryConstant(ir::BinaryExpression *const expr) -{ - auto const lhs = expr->Left()->AsLiteral(); - auto const rhs = expr->Right()->AsLiteral(); - - auto isBooleanConstant = CheckIsBooleanConstantForBinary(lhs, rhs, expr->OperatorType()); - if (isBooleanConstant) { - return FoldBinaryBooleanConstant(expr); + if (IsAdditiveExpression(expr)) { + return HandleAdditiveExpression(expr, context); + } + if (IsShiftExpression(expr)) { + return HandleShiftExpression(expr, context); } - if (lhs->IsStringLiteral() || rhs->IsStringLiteral()) { - return FoldBinaryStringConstant(expr); + if (IsRelationalExpression(expr)) { + return HandleRelationalExpression(expr, context); } - return FoldBinaryNumericConstant(expr); + if (IsBitwiseLogicalExpression(expr)) { + return HandleBitwiseLogicalExpression(expr, context); + } + if (IsConditionalExpression(expr)) { + return HandleConditionalExpression(expr, context); + } + ES2PANDA_UNREACHABLE(); } template -lexer::Number ConstantExpressionLowering::HandleBitwiseNegate(InputType value, TypeRank rank) +static lexer::Number HandleBitwiseNegate(InputType value, TypeRank rank) { switch (rank) { case TypeRank::DOUBLE: @@ -577,6 +1027,8 @@ lexer::Number ConstantExpressionLowering::HandleBitwiseNegate(InputType value, T } case TypeRank::FLOAT: case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: case TypeRank::CHAR: { return lexer::Number(static_cast(~static_cast(value))); } @@ -587,10 +1039,10 @@ lexer::Number ConstantExpressionLowering::HandleBitwiseNegate(InputType value, T } template -ir::AstNode *ConstantExpressionLowering::FoldUnaryNumericConstantHelper(ir::UnaryExpression *unary, ir::Literal *node, - TypeRank rank) +static ir::AstNode *FoldUnaryNumericConstantHelper(const ir::UnaryExpression *unary, const ir::Literal *node, + TypeRank rank, ArenaAllocator *allocator) { - auto value = GetOperand(node); + auto value = CastValTo(node); lexer::Number resNum {}; switch (unary->OperatorType()) { @@ -611,30 +1063,32 @@ ir::AstNode *ConstantExpressionLowering::FoldUnaryNumericConstantHelper(ir::Unar } } - ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(context_->allocator, resNum); - resNode->SetParent(unary->Parent()); + ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(allocator, resNum); + resNode->SetParent(const_cast(unary)->Parent()); resNode->SetRange(unary->Range()); return resNode; } -ir::AstNode *ConstantExpressionLowering::FoldUnaryNumericConstant(ir::UnaryExpression *unary) +static ir::AstNode *FoldUnaryNumericConstant(const ir::UnaryExpression *unary, ArenaAllocator *allocator) { auto literal = unary->Argument()->AsLiteral(); TypeRank rank = GetTypeRank(literal); switch (rank) { case TypeRank::DOUBLE: { - return FoldUnaryNumericConstantHelper(unary, literal, rank); + return FoldUnaryNumericConstantHelper(unary, literal, rank, allocator); } case TypeRank::FLOAT: { - return FoldUnaryNumericConstantHelper(unary, literal, rank); + return FoldUnaryNumericConstantHelper(unary, literal, rank, allocator); } case TypeRank::INT64: { - return FoldUnaryNumericConstantHelper(unary, literal, rank); + return FoldUnaryNumericConstantHelper(unary, literal, rank, allocator); } case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: case TypeRank::CHAR: { - return FoldUnaryNumericConstantHelper(unary, literal, rank); + return FoldUnaryNumericConstantHelper(unary, literal, rank, allocator); } default: { ES2PANDA_UNREACHABLE(); @@ -642,42 +1096,31 @@ ir::AstNode *ConstantExpressionLowering::FoldUnaryNumericConstant(ir::UnaryExpre } } -ir::AstNode *ConstantExpressionLowering::FoldUnaryBooleanConstant(ir::UnaryExpression *unary) +static ir::AstNode *FoldLogicalUnaryExpression(const ir::UnaryExpression *unary, ArenaAllocator *allocator) { - bool result {}; - auto *unaryLiteral = unary->Argument()->AsLiteral(); - - if (unary->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) { - // 15.10.1 Extended Conditional Expression - if (unaryLiteral->IsUndefinedLiteral() || unaryLiteral->IsNullLiteral()) { - result = true; - } else { - bool value = GetOperand(unaryLiteral); - result = !value; - } - } else { - ES2PANDA_UNREACHABLE(); - } - - auto resNode = util::NodeAllocator::Alloc(context_->allocator, result); - resNode->SetParent(unary->Parent()); + auto resNode = + util::NodeAllocator::Alloc(allocator, !TestLiteral(unary->Argument()->AsLiteral())); + resNode->SetParent(const_cast(unary)->Parent()); resNode->SetRange(unary->Range()); return resNode; } -ir::AstNode *ConstantExpressionLowering::FoldUnaryConstant(ir::UnaryExpression *const unary) +static ir::AstNode *FoldUnaryExpression(const ir::UnaryExpression *unary, public_lib::Context *context) { - auto unaryLiteral = unary->Argument()->AsLiteral(); + if (unary->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) { + return FoldLogicalUnaryExpression(unary, context->allocator); + } - auto isBooleanConstant = CheckIsBooleanConstantForUnary(unaryLiteral, unary->OperatorType()); - if (isBooleanConstant) { - return FoldUnaryBooleanConstant(unary); + auto lit = unary->Argument()->AsLiteral(); + if (lit->IsNumberLiteral() || lit->IsCharLiteral() || lit->IsBooleanLiteral()) { + return FoldUnaryNumericConstant(unary, context->allocator); } - return FoldUnaryNumericConstant(unary); + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_UNARY_EXPRESSION, {}, unary->Start()); + return CreateErrorIdentifier(unary, context->allocator); } -ir::AstNode *ConstantExpressionLowering::TryFoldTSAsExpressionForString(ir::TSAsExpression *expr) +static ir::AstNode *TryFoldTSAsExpressionForString(ir::TSAsExpression *expr) { if (expr->Expr()->IsStringLiteral() && expr->TypeAnnotation()->IsETSTypeReference() && IsStringTypeReference(expr->TypeAnnotation()->AsETSTypeReference())) { @@ -689,193 +1132,243 @@ ir::AstNode *ConstantExpressionLowering::TryFoldTSAsExpressionForString(ir::TSAs return expr; } -ir::AstNode *ConstantExpressionLowering::FoldTSAsExpressionToChar(ir::TSAsExpression *expr) -{ - auto *sourceLiteral = expr->Expr()->AsLiteral(); - auto resChar = GetOperand(sourceLiteral); - ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(context_->allocator, resChar); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; -} - -ir::AstNode *ConstantExpressionLowering::FoldTSAsExpressionToBoolean(ir::TSAsExpression *expr) -{ - auto *sourceLiteral = expr->Expr()->AsLiteral(); - auto resBool = GetOperand(sourceLiteral); - ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(context_->allocator, resBool); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; -} - -ir::AstNode *ConstantExpressionLowering::FoldTSAsExpression(ir::TSAsExpression *const expr) +static ir::AstNode *FoldTSAsExpression(ir::TSAsExpression *const expr, ArenaAllocator *allocator) { - if (expr->TypeAnnotation()->IsETSPrimitiveType()) { - auto *sourceLiteral = expr->Expr()->AsLiteral(); - lexer::Number resNum; + // For correct type inference, don't remove explicit type cast for array elements: + // [1 as int] should be inferred as int[], otherwise ([1]) it will be inferred as number[] + if (expr->TypeAnnotation()->IsETSPrimitiveType() && !expr->Parent()->IsArrayExpression()) { + auto *srcLit = expr->Expr()->AsLiteral(); switch (expr->TypeAnnotation()->AsETSPrimitiveType()->GetPrimitiveType()) { - case ir::PrimitiveType::CHAR: { - return FoldTSAsExpressionToChar(expr); - } - case ir::PrimitiveType::BOOLEAN: { - return FoldTSAsExpressionToBoolean(expr); - } - case ir::PrimitiveType::BYTE: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::SHORT: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::INT: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::LONG: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::FLOAT: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::DOUBLE: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - default: { - return expr; - } + case ir::PrimitiveType::CHAR: + return CreateCharLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::BOOLEAN: + return CreateBooleanLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::BYTE: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::SHORT: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::INT: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::LONG: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::FLOAT: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::DOUBLE: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + default: + ES2PANDA_UNREACHABLE(); } - ir::TypedAstNode *result = util::NodeAllocator::Alloc(context_->allocator, resNum); - result->SetParent(expr->Parent()); - result->SetRange(expr->Range()); - return result; } return TryFoldTSAsExpressionForString(expr); } -ir::AstNode *ConstantExpressionLowering::FoldMultilineString(ir::TemplateLiteral *expr) +static ir::AstNode *FoldTemplateLiteral(ir::TemplateLiteral *expr, ArenaAllocator *allocator) { - auto *result = util::NodeAllocator::Alloc(context_->allocator, expr->GetMultilineString()); - result->SetParent(expr->Parent()); - result->SetRange(expr->Range()); - return result; -} + auto litToString = [allocator](const ir::Literal *lit) { + if (lit->IsNumberLiteral()) { + return util::UString(lit->AsNumberLiteral()->ToString(), allocator).View(); + } + if (lit->IsCharLiteral()) { + return util::UString(lit->AsCharLiteral()->ToString(), allocator).View(); + } + if (lit->IsBooleanLiteral()) { + return util::UString(lit->AsBooleanLiteral()->ToString(), allocator).View(); + } + if (lit->IsStringLiteral()) { + return lit->AsStringLiteral()->Str(); + } + if (lit->IsUndefinedLiteral()) { + return util::UString(lit->AsUndefinedLiteral()->ToString(), allocator).View(); + } + if (lit->IsNullLiteral()) { + return util::UString(lit->AsNullLiteral()->ToString(), allocator).View(); + } + ES2PANDA_UNREACHABLE(); + }; -ir::AstNode *ConstantExpressionLowering::UnFoldEnumMemberExpression(ir::AstNode *constantNode) -{ - ir::NodeTransformer handleUnfoldEnumMember = [this, constantNode](ir::AstNode *const node) { - if (node->IsMemberExpression() && !node->Parent()->IsMemberExpression()) { - auto memExp = node->AsMemberExpression(); - return FindAndReplaceEnumMember(memExp, constantNode); + util::UString result(allocator); + auto quasis = expr->Quasis(); + auto expressions = expr->Expressions(); + + if (!quasis[0]->Raw().Empty()) { + result.Append(quasis[0]->Cooked()); + } + + auto const num = expressions.size(); + std::size_t i = 0U; + while (i < num) { + result.Append(litToString(expressions[i]->AsLiteral())); + if (!quasis[++i]->Raw().Empty()) { + result.Append(quasis[i]->Cooked()); } + } - return node; - }; - constantNode->TransformChildrenRecursivelyPostorder(handleUnfoldEnumMember, Name()); - return constantNode; + auto *strLit = util::NodeAllocator::Alloc(allocator, result.View()); + strLit->SetParent(expr->Parent()); + strLit->SetRange(expr->Range()); + return strLit; } -ir::AstNode *ConstantExpressionLowering::FindNameInEnumMember(ArenaVector *members, - util::StringView targetName) +static varbinder::Variable *ResolveIdentifier(const ir::Identifier *ident) { - auto it = std::find_if(members->begin(), members->end(), [&targetName](ir::AstNode *member) { - return member->AsTSEnumMember()->Key()->AsIdentifier()->Name() == targetName; - }); - return (it != members->end()) ? *it : nullptr; + if (ident->Variable() != nullptr) { + return ident->Variable(); + } + + varbinder::ResolveBindingOptions option = + varbinder::ResolveBindingOptions::ALL_DECLARATION | varbinder::ResolveBindingOptions::ALL_VARIABLES; + + varbinder::Scope *scope = NearestScope(ident); + auto *resolved = scope->Find(ident->Name(), option).variable; + return resolved; } -ir::AstNode *ConstantExpressionLowering::FindAndReplaceEnumMember(ir::MemberExpression *expr, ir::AstNode *node) +static varbinder::Variable *ResolveMemberExpressionProperty(ir::MemberExpression *me) { - if (!expr->Object()->IsIdentifier()) { - return expr; + varbinder::Variable *var = nullptr; + auto meObject = me->Object(); + if (meObject->IsMemberExpression()) { + var = ResolveMemberExpressionProperty(meObject->AsMemberExpression()); + } else if (meObject->IsIdentifier()) { + var = ResolveIdentifier(meObject->AsIdentifier()); + } + + if (var == nullptr) { + return nullptr; + } + + auto decl = var->Declaration(); + if (decl->IsClassDecl()) { + // NOTE(gogabr) : for some reason, ETSGLOBAL points to class declaration instead of definition. + auto *declNode = decl->AsClassDecl()->Node(); + auto *classDef = declNode->IsClassDefinition() ? declNode->AsClassDefinition() + : declNode->IsClassDeclaration() ? declNode->AsClassDeclaration()->Definition() + : nullptr; + ES2PANDA_ASSERT(classDef != nullptr); + + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) + auto scope = classDef->Scope(); + auto option = var->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE_OR_ENUM) + ? varbinder::ResolveBindingOptions::STATIC_DECLARATION | + varbinder::ResolveBindingOptions::STATIC_VARIABLES + : varbinder::ResolveBindingOptions::DECLARATION | varbinder::ResolveBindingOptions::VARIABLES; + return scope->FindLocal(me->Property()->AsIdentifier()->Name(), option); } - auto objectName = expr->Object()->AsIdentifier()->Name(); - auto propertyName = expr->Property()->AsIdentifier()->Name(); - for (auto curScope = node->Scope(); curScope != nullptr; curScope = curScope->Parent()) { - auto *foundDecl = curScope->FindDecl(objectName); - if (foundDecl == nullptr || !foundDecl->Node()->IsTSEnumDeclaration()) { - continue; + return nullptr; +} + +static bool IsConstantExpression(ir::AstNode *expr) +{ + if (!expr->IsExpression()) { + if (expr->IsETSTypeReference()) { + return false; } + } - auto members = foundDecl->Node()->AsTSEnumDeclaration()->Members(); - auto member = FindNameInEnumMember(&members, propertyName); - if (member != nullptr) { - auto *transformedInit = member->AsTSEnumMember()->Init(); - if (transformedInit == nullptr) { - return expr; - } + if (expr->IsETSPrimitiveType()) { + return true; + } + + if (expr->IsIdentifier()) { + auto var = ResolveIdentifier(expr->AsIdentifier()); + return var != nullptr && var->Declaration()->IsConstDecl(); + } - auto clonedInit = transformedInit->Clone(context_->allocator, transformedInit->Parent()); - clonedInit->SetRange(expr->Range()); - return UnFoldEnumMemberExpression(clonedInit); + if (expr->IsMemberExpression()) { + auto me = expr->AsMemberExpression(); + if (me->Kind() != ir::MemberExpressionKind::PROPERTY_ACCESS) { + return false; } + + auto var = ResolveMemberExpressionProperty(me); + return var != nullptr && var->Declaration()->IsReadonlyDecl(); } - return expr; -} -varbinder::Variable *ConstantExpressionLowering::FindIdentifier(ir::Identifier *ident) -{ - auto localCtx = varbinder::LexicalScope::Enter(varbinder_, NearestScope(ident)); - auto option = varbinder::ResolveBindingOptions::ALL_VARIABLES; - auto *resolved = localCtx.GetScope()->FindInFunctionScope(ident->Name(), option).variable; - if (resolved == nullptr) { - resolved = localCtx.GetScope()->FindInGlobal(ident->Name(), option).variable; + if (IsSupportedLiteral(expr->AsExpression())) { + return true; } - return resolved; + + auto isNotConstantExpression = [](ir::AstNode *node) { return !IsConstantExpression(node); }; + + return (expr->IsBinaryExpression() || expr->IsUnaryExpression() || expr->IsTSAsExpression() || + expr->IsConditionalExpression() || expr->IsTemplateLiteral()) && + !expr->IsAnyChild(isNotConstantExpression); } -ir::AstNode *ConstantExpressionLowering::UnfoldConstIdentifier(ir::AstNode *node, ir::AstNode *originNode) +ir::AstNode *ConstantExpressionLowering::UnfoldResolvedReference(ir::AstNode *resolved, ir::AstNode *node) { ir::AstNode *resNode = nullptr; - if (node->IsClassProperty()) { - auto prop = node->AsClassElement(); - resNode = prop->Value()->Clone(context_->allocator, originNode->Parent()); - resNode->SetRange(originNode->Range()); + if (resolved->IsClassProperty()) { + auto propVal = resolved->AsClassElement()->Value(); + if (propVal != nullptr && IsConstantExpression(propVal)) { + resNode = propVal->Clone(context_->allocator, node->Parent()); + resNode->SetRange(node->Range()); + } + } else if (resolved->Parent()->IsVariableDeclarator()) { + auto init = resolved->Parent()->AsVariableDeclarator()->Init(); + if (init != nullptr && IsConstantExpression(init)) { + resNode = init->Clone(context_->allocator, node->Parent()); + resNode->SetRange(node->Range()); + } + } + + if (resNode != nullptr) { + return MaybeUnfold(resNode); } - if (node->Parent()->IsVariableDeclarator()) { - resNode = node->Parent()->AsVariableDeclarator()->Init()->Clone(context_->allocator, originNode->Parent()); - resNode->SetRange(originNode->Range()); + + // failed to unfold + return node; +} + +ir::AstNode *ConstantExpressionLowering::MaybeUnfoldIdentifier(ir::Identifier *node) +{ + if (!node->IsReference(varbinder_->Extension())) { + return node; } - if (resNode == nullptr) { + + auto *resolved = ResolveIdentifier(node); + if (resolved == nullptr || !resolved->Declaration()->IsConstDecl()) { return node; } - if (!resNode->IsIdentifier()) { - return UnfoldConstIdentifiers(resNode); + return UnfoldResolvedReference(resolved->Declaration()->Node(), node); +} + +ir::AstNode *ConstantExpressionLowering::MaybeUnfoldMemberExpression(ir::MemberExpression *node) +{ + if (node->Kind() != ir::MemberExpressionKind::PROPERTY_ACCESS) { + return node; } - auto *ident = resNode->AsIdentifier(); - auto *resolved = FindIdentifier(ident); - if (resolved == nullptr) { - return resNode; + + if (auto *const property = node->Property(); property->IsLiteral()) { + property->SetParent(node->Parent()); + property->SetRange(node->Range()); + return property; } - if (!resolved->Declaration()->IsConstDecl()) { - return resNode; + + auto resolved = ResolveMemberExpressionProperty(node); + if (resolved == nullptr || !resolved->Declaration()->IsReadonlyDecl()) { + return node; } - return UnfoldConstIdentifier(resolved->Declaration()->Node(), resNode); + return UnfoldResolvedReference(resolved->Declaration()->Node(), node); } -ir::AstNode *ConstantExpressionLowering::UnfoldConstIdentifiers(ir::AstNode *constantNode) +ir::AstNode *ConstantExpressionLowering::MaybeUnfold(ir::AstNode *node) { - ir::NodeTransformer handleUnfoldIdentifiers = [this](ir::AstNode *const node) { - if (node->IsIdentifier()) { - auto *ident = node->AsIdentifier(); - auto *resolved = FindIdentifier(ident); - if (resolved == nullptr) { - return node; - } - if (!resolved->Declaration()->IsConstDecl()) { - return node; - } - return UnfoldConstIdentifier(resolved->Declaration()->Node(), node); + ir::NodeTransformer handleMaybeUnfold = [this](ir::AstNode *const n) { + if (n->IsIdentifier()) { + return MaybeUnfoldIdentifier(n->AsIdentifier()); } - return node; + + if (n->IsMemberExpression()) { + return MaybeUnfoldMemberExpression(n->AsMemberExpression()); + } + + return n; }; - constantNode->TransformChildrenRecursivelyPostorder(handleUnfoldIdentifiers, Name()); - return constantNode; + + node->TransformChildrenRecursivelyPostorder(handleMaybeUnfold, Name()); + return handleMaybeUnfold(node); } static bool IsPotentialConstant(const ir::AstNodeType type) @@ -885,48 +1378,48 @@ static bool IsPotentialConstant(const ir::AstNodeType type) type == ir::AstNodeType::CONDITIONAL_EXPRESSION || type == ir::AstNodeType::IDENTIFIER; } -ir::AstNode *ConstantExpressionLowering::FoldConstant(ir::AstNode *constantNode) +ir::AstNode *ConstantExpressionLowering::Fold(ir::AstNode *constantNode) { ir::NodeTransformer handleFoldConstant = [this](ir::AstNode *const node) { if (node->IsTemplateLiteral()) { auto tmpLiteral = node->AsTemplateLiteral(); - if (tmpLiteral->Expressions().empty()) { - return FoldMultilineString(tmpLiteral); + auto exprs = tmpLiteral->Expressions(); + auto notSupportedLit = std::find_if(exprs.begin(), exprs.end(), + [](ir::Expression *maybeLit) { return !IsSupportedLiteral(maybeLit); }); + // Cannot fold TemplateLiteral containing unsupported literal + if (notSupportedLit != exprs.end()) { + return node; } - LogError(diagnostic::STRING_INTERPOLATION_NOT_CONSTANT, {}, node->Start()); + return FoldTemplateLiteral(tmpLiteral, context_->allocator); } if (node->IsTSAsExpression()) { auto tsAsExpr = node->AsTSAsExpression(); if (IsSupportedLiteral(tsAsExpr->Expr())) { - return FoldTSAsExpression(tsAsExpr); + return FoldTSAsExpression(tsAsExpr, context_->allocator); } - LogError(diagnostic::ONLY_CONSTANT_EXPRESSION, {}, node->Start()); } if (node->IsUnaryExpression()) { auto unaryOp = node->AsUnaryExpression(); if (IsSupportedLiteral(unaryOp->Argument())) { - return FoldUnaryConstant(unaryOp); + return FoldUnaryExpression(unaryOp, context_); } - LogError(diagnostic::ONLY_CONSTANT_EXPRESSION, {}, node->Start()); } if (node->IsBinaryExpression()) { auto binop = node->AsBinaryExpression(); if (IsSupportedLiteral(binop->Left()) && IsSupportedLiteral(binop->Right())) { - return FoldBinaryConstant(binop); + return FoldBinaryExpression(binop, context_); } - LogError(diagnostic::ONLY_CONSTANT_EXPRESSION, {}, node->Start()); } if (node->IsConditionalExpression()) { auto condExp = node->AsConditionalExpression(); if (IsSupportedLiteral(condExp->Test())) { return FoldTernaryConstant(condExp); } - LogError(diagnostic::ONLY_CONSTANT_EXPRESSION, {}, node->Start()); } return node; }; constantNode->TransformChildrenRecursivelyPostorder(handleFoldConstant, Name()); - return constantNode; + return TryToCorrectNumberOrCharLiteral(handleFoldConstant(constantNode), context_); } // Note: memberExpression can be constant when it is enum property access, this check will be enabled after Issue23082. @@ -942,10 +1435,10 @@ void ConstantExpressionLowering::IsInitByConstant(ir::AstNode *node) } if (!IsPotentialConstant(initTobeChecked->Type())) { - LogError(diagnostic::INVALID_INIT_IN_PACKAGE, {}, initTobeChecked->Start()); + LogError(context_, diagnostic::INVALID_INIT_IN_PACKAGE, {}, initTobeChecked->Start()); return; } - assignExpr->SetRight(FoldConstant(UnfoldConstIdentifiers(initTobeChecked))->AsExpression()); + assignExpr->SetRight(Fold(MaybeUnfold(initTobeChecked))->AsExpression()); } if (node->IsClassProperty()) { @@ -960,10 +1453,10 @@ void ConstantExpressionLowering::IsInitByConstant(ir::AstNode *node) } if (!IsPotentialConstant(initTobeChecked->Type())) { - LogError(diagnostic::INVALID_INIT_IN_PACKAGE, {}, initTobeChecked->Start()); + LogError(context_, diagnostic::INVALID_INIT_IN_PACKAGE, {}, initTobeChecked->Start()); return; } - classProp->SetValue(FoldConstant(UnfoldConstIdentifiers(initTobeChecked))->AsExpression()); + classProp->SetValue(Fold(MaybeUnfold(initTobeChecked))->AsExpression()); } } @@ -998,20 +1491,14 @@ bool ConstantExpressionLowering::PerformForModule(public_lib::Context *ctx, pars context_ = ctx; program_ = program; varbinder_ = ctx->parserProgram->VarBinder()->AsETSBinder(); + program->Ast()->TransformChildrenRecursively( [this](ir::AstNode *const node) -> AstNodePtr { - if (node->IsAnnotationDeclaration() || node->IsAnnotationUsage()) { - return FoldConstant(UnfoldConstIdentifiers(node)); - } - if (node->IsTSEnumDeclaration()) { - return FoldConstant(UnFoldEnumMemberExpression(UnfoldConstIdentifiers(node))); - } - // Note: Package need to check whether its immediate initializer is const expression. if (this->program_->IsPackage() && node->IsClassDefinition() && node->AsClassDefinition()->IsGlobal()) { TryFoldInitializerOfPackage(node->AsClassDefinition()); } - return node; + return Fold(MaybeUnfold(node)); }, Name()); diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.h b/ets2panda/compiler/lowering/ets/constantExpressionLowering.h index 8d9c3e77a16a7f12d12754a501ca1ed9e8966b9d..0bf1aead0f276b24723988984f48e463c48c1248 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.h +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.h @@ -22,7 +22,9 @@ namespace ark::es2panda::compiler { enum class TypeRank { // Keep this order + INT8, CHAR, + INT16, INT32, INT64, FLOAT, @@ -39,77 +41,14 @@ public: bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; private: - void LogError(const diagnostic::DiagnosticKind &diagnostic, const util::DiagnosticMessageParams &diagnosticParams, - const lexer::SourcePosition &pos) const; + ir::AstNode *MaybeUnfold(ir::AstNode *node); + ir::AstNode *MaybeUnfoldIdentifier(ir::Identifier *node); + ir::AstNode *MaybeUnfoldMemberExpression(ir::MemberExpression *node); + ir::AstNode *UnfoldResolvedReference(ir::AstNode *resolved, ir::AstNode *node); + ir::AstNode *Fold(ir::AstNode *constantNode); ir::AstNode *FoldTernaryConstant(ir::ConditionalExpression *cond); - template - bool PerformRelationOperator(InputType left, InputType right, lexer::TokenType opType); - - bool HandleRelationOperator(ir::Literal *left, ir::Literal *right, lexer::TokenType opType); - - bool HandleBitwiseLogicalOperator(ir::Literal *left, ir::Literal *right, lexer::TokenType opType); - - ir::AstNode *HandleLogicalOperator(ir::BinaryExpression *expr, lexer::TokenType opType); - - ir::AstNode *FoldBinaryBooleanConstant(ir::BinaryExpression *expr); - - template - IntegerType PerformBitwiseArithmetic(IntegerType left, IntegerType right, lexer::TokenType operationType); - - template - lexer::Number HandleBitwiseOperator(TargetType leftNum, TargetType rightNum, lexer::TokenType operationType, - TypeRank targetRank); - - template - TargetType HandleArithmeticOperation(TargetType leftNum, TargetType rightNum, ir::BinaryExpression *expr); - - template - ir::AstNode *FoldBinaryNumericConstantHelper(ir::BinaryExpression *expr, TypeRank targetRank); - - ir::AstNode *FoldBinaryNumericConstant(ir::BinaryExpression *expr); - - ir::AstNode *FoldBinaryStringConstant(ir::BinaryExpression *expr); - - ir::AstNode *FoldBinaryConstant(ir::BinaryExpression *expr); - - template - lexer::Number HandleBitwiseNegate(InputType value, TypeRank rank); - - template - ir::AstNode *FoldUnaryNumericConstantHelper(ir::UnaryExpression *unary, ir::Literal *node, TypeRank rank); - - ir::AstNode *FoldUnaryNumericConstant(ir::UnaryExpression *unary); - - ir::AstNode *FoldUnaryBooleanConstant(ir::UnaryExpression *unary); - - ir::AstNode *FoldUnaryConstant(ir::UnaryExpression *unary); - - ir::AstNode *TryFoldTSAsExpressionForString(ir::TSAsExpression *expr); - - ir::AstNode *FoldTSAsExpressionToChar(ir::TSAsExpression *expr); - - ir::AstNode *FoldTSAsExpressionToBoolean(ir::TSAsExpression *expr); - - ir::AstNode *FoldTSAsExpression(ir::TSAsExpression *expr); - - ir::AstNode *FoldMultilineString(ir::TemplateLiteral *expr); - - ir::AstNode *FoldConstant(ir::AstNode *constantNode); - - varbinder::Variable *FindIdentifier(ir::Identifier *ident); - - ir::AstNode *UnfoldConstIdentifier(ir::AstNode *node, ir::AstNode *originNode); - - ir::AstNode *UnFoldEnumMemberExpression(ir::AstNode *constantNode); - - ir::AstNode *FindNameInEnumMember(ArenaVector *members, util::StringView targetName); - - ir::AstNode *FindAndReplaceEnumMember(ir::MemberExpression *expr, ir::AstNode *node); - - ir::AstNode *UnfoldConstIdentifiers(ir::AstNode *constantNode); - void IsInitByConstant(ir::AstNode *node); void TryFoldInitializerOfPackage(ir::ClassDefinition *globalClass); diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index 7a524ec4aae95ec4dacf61983b8b6be82daee563..1bb5c1f806c695a9ae6c2603a6302eb74b83e74d 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -164,6 +164,7 @@ template void EnumLoweringPhase::CreateEnumItemFields(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *const enumClass, EnumType enumType) { + static_assert(ORDINAL_TYPE == ir::PrimitiveType::INT); int32_t ordinal = 0; auto createEnumItemField = [this, enumClass, enumType, &ordinal](ir::TSEnumMember *const member) { auto *const enumMemberIdent = @@ -327,7 +328,7 @@ void EnumLoweringPhase::CreateCCtorForEnumClass(ir::ClassDefinition *const enumC ir::ClassProperty *EnumLoweringPhase::CreateOrdinalField(ir::ClassDefinition *const enumClass) { auto *const fieldIdent = Allocator()->New(ORDINAL_NAME, Allocator()); - auto *const intTypeAnnotation = Allocator()->New(ir::PrimitiveType::INT, Allocator()); + auto *const intTypeAnnotation = Allocator()->New(ORDINAL_TYPE, Allocator()); auto *field = checker_->AllocNode(fieldIdent, nullptr, intTypeAnnotation, ir::ModifierFlags::PRIVATE | ir::ModifierFlags::READONLY, Allocator(), false); @@ -342,7 +343,7 @@ ir::ScriptFunction *EnumLoweringPhase::CreateFunctionForCtorOfEnumClass(ir::Clas { ArenaVector params(Allocator()->Adapter()); - auto *const intTypeAnnotation = checker_->AllocNode(ir::PrimitiveType::INT, Allocator()); + auto *const intTypeAnnotation = checker_->AllocNode(ORDINAL_TYPE, Allocator()); auto *const inputOrdinalParam = MakeFunctionParam(checker_, PARAM_ORDINAL, intTypeAnnotation); params.push_back(inputOrdinalParam); @@ -391,11 +392,13 @@ ir::ScriptFunction *EnumLoweringPhase::CreateFunctionForCtorOfEnumClass(ir::Clas thisExpr, fieldIdentifier, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); auto *rightHandSide = checker_->AllocNode(PARAM_ORDINAL, Allocator()); rightHandSide->SetVariable(inputOrdinalParam->Ident()->Variable()); - auto *initializer = checker_->AllocNode(leftHandSide, rightHandSide, - lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - auto initStatement = checker_->AllocNode(initializer); - initStatement->SetParent(body); - body->Statements().push_back(initStatement); + if (!enumClass->IsDeclare()) { + auto *initializer = checker_->AllocNode(leftHandSide, rightHandSide, + lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + auto initStatement = checker_->AllocNode(initializer); + initStatement->SetParent(body); + body->Statements().push_back(initStatement); + } return func; } @@ -407,7 +410,7 @@ void EnumLoweringPhase::CreateCtorForEnumClass(ir::ClassDefinition *const enumCl auto *const identClone = func->Id()->Clone(Allocator(), nullptr); auto *const methodDef = checker_->AllocNode( - ir::MethodDefinitionKind::CONSTRUCTOR, identClone, funcExpr, ir::ModifierFlags::PUBLIC, Allocator(), false); + ir::MethodDefinitionKind::CONSTRUCTOR, identClone, funcExpr, ir::ModifierFlags::PRIVATE, Allocator(), false); methodDef->SetParent(enumClass); enumClass->Body().push_back(methodDef); } @@ -595,8 +598,7 @@ ir::Identifier *EnumLoweringPhase::CreateEnumValuesArray(const ir::TSEnumDeclara lexer::Number(member->AsTSEnumMember() ->Init() ->AsNumberLiteral() - ->Number() - .GetValue())); + ->Number())); return enumValueLiteral; }); // clang-format on @@ -786,10 +788,11 @@ void EnumLoweringPhase::CreateEnumGetNameMethod(const ir::TSEnumDeclaration *con namespace { -ir::VariableDeclaration *CreateForLoopInitVariableDeclaration(checker::ETSChecker *checker, - ir::Identifier *const loopIdentifier) +static ir::VariableDeclaration *CreateForLoopInitVariableDeclaration(checker::ETSChecker *checker, + ir::Identifier *const loopIdentifier) { - auto *const init = checker->AllocNode("0"); + static_assert(EnumLoweringPhase::ORDINAL_TYPE == ir::PrimitiveType::INT); + auto *const init = checker->AllocNode(lexer::Number((int32_t)0)); auto *const decl = checker->AllocNode(ir::VariableDeclaratorFlag::LET, loopIdentifier, init); loopIdentifier->SetParent(decl); @@ -801,9 +804,9 @@ ir::VariableDeclaration *CreateForLoopInitVariableDeclaration(checker::ETSChecke return declaration; } -ir::BinaryExpression *CreateForLoopTest(checker::ETSChecker *checker, ir::Identifier *const enumClassIdentifier, - ir::Identifier *const namesArrayIdentifier, - ir::Identifier *const loopIdentifier) +static ir::BinaryExpression *CreateForLoopTest(checker::ETSChecker *checker, ir::Identifier *const enumClassIdentifier, + ir::Identifier *const namesArrayIdentifier, + ir::Identifier *const loopIdentifier) { auto *const lengthIdent = checker->AllocNode("length", checker->Allocator()); auto *const propertyAccessExpr = @@ -816,7 +819,7 @@ ir::BinaryExpression *CreateForLoopTest(checker::ETSChecker *checker, ir::Identi return binaryExpr; } -ir::UpdateExpression *CreateForLoopUpdate(checker::ETSChecker *checker, ir::Identifier *const loopIdentifier) +static ir::UpdateExpression *CreateForLoopUpdate(checker::ETSChecker *checker, ir::Identifier *const loopIdentifier) { auto *const forLoopIdentClone = loopIdentifier->Clone(checker->Allocator(), nullptr); auto *const incrementExpr = @@ -824,9 +827,9 @@ ir::UpdateExpression *CreateForLoopUpdate(checker::ETSChecker *checker, ir::Iden return incrementExpr; } -ir::IfStatement *CreateIf(checker::ETSChecker *checker, ir::MemberExpression *propertyAccessExpr, - ir::MemberExpression *itemAccessExpr, ir::Identifier *const loopIdentifier, - ir::ETSParameterExpression *const parameter) +static ir::IfStatement *CreateIf(checker::ETSChecker *checker, ir::MemberExpression *propertyAccessExpr, + ir::MemberExpression *itemAccessExpr, ir::Identifier *const loopIdentifier, + ir::ETSParameterExpression *const parameter) { auto *const forLoopIdentClone1 = loopIdentifier->Clone(checker->Allocator(), nullptr); auto *const namesArrayElementExpr = checker->AllocNode( @@ -967,7 +970,7 @@ void EnumLoweringPhase::CreateEnumGetOrdinalMethod(const ir::TSEnumDeclaration * body.push_back(returnStmt); ArenaVector params(Allocator()->Adapter()); - auto *const intTypeAnnotation = Allocator()->New(ir::PrimitiveType::INT, Allocator()); + auto *const intTypeAnnotation = Allocator()->New(ORDINAL_TYPE, Allocator()); auto *const function = MakeFunction({std::move(params), std::move(body), intTypeAnnotation, enumDecl, ir::ModifierFlags::PUBLIC}); diff --git a/ets2panda/compiler/lowering/ets/enumLowering.h b/ets2panda/compiler/lowering/ets/enumLowering.h index 75a38b23fd1073d9f0731dd8e2ab8f4590e6dd41..c1ab9c989cb60d68e10666db434d3c82f09de35f 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.h +++ b/ets2panda/compiler/lowering/ets/enumLowering.h @@ -24,17 +24,18 @@ namespace ark::es2panda::compiler { class EnumLoweringPhase : public PhaseForDeclarations { public: - static constexpr std::string_view const STRING_REFERENCE_TYPE {"String"}; - static constexpr std::string_view const IDENTIFIER_I {"i"}; - static constexpr std::string_view const PARAM_NAME {"name"}; - static constexpr std::string_view const PARAM_VALUE {"value"}; - static constexpr std::string_view const PARAM_ORDINAL {"ordinal"}; - static constexpr std::string_view const STRING_VALUES_ARRAY_NAME {"#StringValuesArray"}; - static constexpr std::string_view const ITEMS_ARRAY_NAME {"#ItemsArray"}; - static constexpr std::string_view const NAMES_ARRAY_NAME {"#NamesArray"}; - static constexpr std::string_view const VALUES_ARRAY_NAME {"#ValuesArray"}; - static constexpr std::string_view const ORDINAL_NAME {"#ordinal"}; - static constexpr std::string_view const BASE_CLASS_NAME {"BaseEnum"}; + static constexpr std::string_view STRING_REFERENCE_TYPE {"String"}; + static constexpr std::string_view IDENTIFIER_I {"i"}; + static constexpr std::string_view PARAM_NAME {"name"}; + static constexpr std::string_view PARAM_VALUE {"value"}; + static constexpr std::string_view PARAM_ORDINAL {"ordinal"}; + static constexpr std::string_view ITEMS_ARRAY_NAME {"#ItemsArray"}; + static constexpr std::string_view STRING_VALUES_ARRAY_NAME {checker::ETSEnumType::STRING_VALUES_ARRAY_NAME}; + static constexpr std::string_view NAMES_ARRAY_NAME {checker::ETSEnumType::NAMES_ARRAY_NAME}; + static constexpr std::string_view VALUES_ARRAY_NAME {checker::ETSEnumType::VALUES_ARRAY_NAME}; + static constexpr std::string_view BASE_CLASS_NAME {"BaseEnum"}; + static constexpr std::string_view ORDINAL_NAME {"#ordinal"}; + static constexpr auto ORDINAL_TYPE {ir::PrimitiveType::INT}; enum EnumType { INT = 0, LONG = 1, STRING = 2 }; diff --git a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp index 3fb0f59817c80ba2a19c7d2b8cf26203175ff824..e5ba691c7ad1fc5a5091dd49d149939a73483f8b 100644 --- a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp @@ -91,7 +91,9 @@ static EnumCastType NeedHandleEnumCasting(ir::TSAsExpression *node) { auto type = node->TsType(); EnumCastType castType = EnumCastType::NONE; - if (type->IsETSStringType()) { + if (type == nullptr) { + return castType; + } else if (type->IsETSStringType()) { castType = EnumCastType::CAST_TO_STRING; } else if (type->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC) || (type->IsETSObjectType() && @@ -325,15 +327,28 @@ ir::AstNode *EnumPostCheckLoweringPhase::GenerateEnumCasting(ir::TSAsExpression return node; } +static auto *InlineValueOf(ir::MemberExpression *enumMemberRef, ArenaAllocator *allocator) +{ + auto key = enumMemberRef->Property()->AsIdentifier()->Name().Utf8(); + auto enumType = enumMemberRef->TsType()->AsETSEnumType(); + auto ord = enumType->GetOrdinalFromMemberName(key); + auto origLiteral = enumType->GetValueLiteralFromOrdinal(ord); + auto literal = origLiteral->Clone(allocator, enumMemberRef->Parent())->AsExpression(); + literal->SetTsType(origLiteral->TsType()); + return literal; +} + ir::AstNode *EnumPostCheckLoweringPhase::GenerateValueOfCall(ir::AstNode *const node) { - node->Parent()->AddAstNodeFlags(ir::AstNodeFlags::RECHECK); + node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); if (!node->IsExpression()) { - node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); return node; } + node->Parent()->AddAstNodeFlags(ir::AstNodeFlags::RECHECK); + if (node->AsExpression()->TsType()->AsETSEnumType()->NodeIsEnumLiteral(node->AsExpression())) { + return InlineValueOf(node->AsMemberExpression(), checker_->Allocator()); + } auto *callExpr = CreateCallInstanceEnumExpression(checker_, node, checker::ETSEnumType::VALUE_OF_METHOD_NAME); - node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); return callExpr; } @@ -403,7 +418,7 @@ bool EnumPostCheckLoweringPhase::PerformForModule(public_lib::Context *ctx, pars } return GenerateEnumCasting(node->AsTSAsExpression(), castFlag); } - if (node->IsSwitchStatement() && node->AsSwitchStatement()->Discriminant()->TsType()->IsETSEnumType()) { + if (node->IsSwitchStatement() && node->AsSwitchStatement()->Discriminant()->TsType() && node->AsSwitchStatement()->Discriminant()->TsType()->IsETSEnumType()) { return GenerateGetOrdinalCallForSwitch(node->AsSwitchStatement()); } return node; diff --git a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h index 867cc73f8a35c0f0d05250cd3f4325c87989a33b..d765846356e456d2981e518f69689cffcbbd7705 100644 --- a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h +++ b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h @@ -29,7 +29,7 @@ enum class EnumCastType { CAST_TO_STRING_ENUM, }; -class EnumPostCheckLoweringPhase : public PhaseForBodies { +class EnumPostCheckLoweringPhase : public PhaseForDeclarations { public: EnumPostCheckLoweringPhase() noexcept = default; std::string_view Name() const override diff --git a/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp b/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3891497c8e5eda3652a8a0fb07514cb9ec57fb49 --- /dev/null +++ b/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp @@ -0,0 +1,85 @@ +/* + * 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 "enumPropertiesInAnnotationsLowering.h" +#include "ir/base/classProperty.h" +#include "checker/types/ets/etsArrayType.h" +#include "checker/types/ets/etsEnumType.h" +#include "ir/base/classProperty.h" + +namespace ark::es2panda::compiler { + +static void TransformEnumArrayRecursively(checker::ETSArrayType *propType) +{ + if (propType->ElementType()->IsETSEnumType()) { + auto newElemType = propType->ElementType()->AsETSEnumType()->Underlying(); + propType->SetElementType(newElemType); + return; + } + if (propType->ElementType()->IsETSArrayType()) { + TransformEnumArrayRecursively(propType->ElementType()->AsETSArrayType()); + } +} + +static void SetValueType(ir::Expression *value, checker::Type *newType) +{ + if (value->Variable() != nullptr) { + value->Variable()->SetTsType(newType); + } + value->SetTsType(newType); + if (newType->IsETSArrayType() && newType->AsETSArrayType()->ElementType()->IsETSArrayType()) { + for (auto elem : value->AsArrayExpression()->Elements()) { + SetValueType(elem, newType->AsETSArrayType()->ElementType()); + } + } +} + +static void TransformEnumToUnderlying(ir::ClassProperty *prop, checker::Checker *checker) +{ + checker::Type *propType = prop->TsType(); + checker::Type *newPropType {}; + if (propType->IsETSEnumType()) { + prop->SetTypeAnnotation(nullptr); + newPropType = propType->AsETSEnumType()->Underlying(); + } else if (propType->IsETSArrayType()) { + prop->SetTypeAnnotation(nullptr); + newPropType = propType->Clone(checker); + TransformEnumArrayRecursively(newPropType->AsETSArrayType()); + } else { + return; + } + prop->SetTsType(newPropType); + prop->Key()->SetTsType(newPropType); + prop->Key()->Variable()->SetTsType(newPropType); + if (prop->Value() != nullptr) { + SetValueType(prop->Value(), newPropType); + } +} + +bool EnumPropertiesInAnnotationsLoweringPhase::PerformForModule([[maybe_unused]] public_lib::Context *ctx, + parser::Program *program) +{ + auto *checker = ctx->checker; + program->Ast()->IterateRecursively([checker](auto *node) { + if (node->IsAnnotationDeclaration() || node->IsAnnotationUsage()) { + node->Iterate([checker](auto *child) { + child->IsClassProperty() ? TransformEnumToUnderlying(child->AsClassProperty(), checker) : void(); + }); + } + }); + return true; +} + +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h b/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h new file mode 100644 index 0000000000000000000000000000000000000000..c5869ede39b315f905a95f3c54ce9b744f8ff145 --- /dev/null +++ b/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h @@ -0,0 +1,35 @@ +/* + * 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_ENUM_PROPERTIES_IN_ANNOTATIONS_LOWERING_H +#define ES2PANDA_COMPILER_ENUM_PROPERTIES_IN_ANNOTATIONS_LOWERING_H + +#include "compiler/lowering/phase.h" + +namespace ark::es2panda::compiler { + +class EnumPropertiesInAnnotationsLoweringPhase : public PhaseForDeclarations { +public: + EnumPropertiesInAnnotationsLoweringPhase() noexcept = default; + std::string_view Name() const override + { + return "EnumPropertiesInAnnotationsLoweringPhase"; + } + bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; +}; + +} // namespace ark::es2panda::compiler + +#endif // ES2PANDA_COMPILER_ENUM_PROPERTIES_IN_ANNOTATIONS_LOWERING_H diff --git a/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp b/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp index 59f3c0a0ccd10925a47e7eb56dc91fff94eebaf7..3afbd0dc32002209b1c7a727cea8553a3124c5fb 100644 --- a/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp +++ b/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp @@ -64,7 +64,7 @@ std::string GenericBridgesPhase::CreateMethodDefinitionString(ir::ClassDefinitio } typeNodes.emplace_back(checker->AllocNode( - const_cast(derivedFunction->Signature()->ReturnType()), checker->Allocator())); + const_cast(baseSignature->ReturnType()), checker->Allocator())); str1 += "): @@T" + std::to_string(typeNodes.size()) + ' '; typeNodes.emplace_back(checker->AllocNode( @@ -78,7 +78,7 @@ std::string GenericBridgesPhase::CreateMethodDefinitionString(ir::ClassDefinitio void GenericBridgesPhase::AddGenericBridge(ir::ClassDefinition const *const classDefinition, ir::MethodDefinition *const methodDefinition, checker::Signature const *baseSignature, - ir::ScriptFunction const *const derivedFunction) const + ir::ScriptFunction *const derivedFunction) const { auto *parser = context_->parser->AsETSParser(); std::vector typeNodes {}; @@ -116,13 +116,17 @@ void GenericBridgesPhase::AddGenericBridge(ir::ClassDefinition const *const clas auto *methodType = methodDefinition->Id()->Variable()->TsType()->AsETSFunctionType(); checker->BuildFunctionSignature(bridgeMethod->Function()); + bridgeMethod->Function()->Signature()->AddSignatureFlag(checker::SignatureFlags::BRIDGE); + auto *const bridgeMethodType = checker->BuildMethodType(bridgeMethod->Function()); - checker->CheckIdenticalOverloads(methodType, bridgeMethodType, bridgeMethod); + checker->CheckIdenticalOverloads(methodType, bridgeMethodType, bridgeMethod, false, + checker::TypeRelationFlag::NONE); bridgeMethod->SetTsType(bridgeMethodType); methodType->AddCallSignature(bridgeMethod->Function()->Signature()); methodDefinition->Id()->Variable()->SetTsType(methodType); - bridgeMethod->Check(checker); + bridgeMethod->Function()->Body()->Check( + checker); // avoid checking overriding, this may fail if only return type is different. } void GenericBridgesPhase::ProcessScriptFunction(ir::ClassDefinition const *const classDefinition, @@ -156,11 +160,13 @@ void GenericBridgesPhase::ProcessScriptFunction(ir::ClassDefinition const *const } baseSignature2 = baseSignature2->Substitute(relation, substitutions.derivedConstraints); - ir::ScriptFunction const *derivedFunction = nullptr; + ir::ScriptFunction *derivedFunction = nullptr; checker::ETSFunctionType const *methodType = derivedMethod->Id()->Variable()->TsType()->AsETSFunctionType(); for (auto *signature : methodType->CallSignatures()) { signature = signature->Substitute(relation, substitutions.derivedConstraints); - if (overrides(baseSignature1, signature) || checker->HasSameAssemblySignature(baseSignature1, signature)) { + // A special case is when the overriding function's return type is going to be unboxed. + if ((overrides(baseSignature1, signature) || checker->HasSameAssemblySignature(baseSignature1, signature)) && + baseSignature1->ReturnType()->IsETSUnboxableObject() == signature->ReturnType()->IsETSUnboxableObject()) { // NOTE: we already have custom-implemented method with the required bridge signature. // Probably sometimes we will issue warning notification here... return; diff --git a/ets2panda/compiler/lowering/ets/genericBridgesLowering.h b/ets2panda/compiler/lowering/ets/genericBridgesLowering.h index 508c4160ffae6f4582ed4fddc99553cfbd0ea4dc..4fafc089c686a6d3fee0ec1d1aa40b5029084e34 100644 --- a/ets2panda/compiler/lowering/ets/genericBridgesLowering.h +++ b/ets2panda/compiler/lowering/ets/genericBridgesLowering.h @@ -54,7 +54,7 @@ private: ir::MethodDefinition *derivedMethod, Substitutions const &substitutions) const; void AddGenericBridge(ir::ClassDefinition const *classDefinition, ir::MethodDefinition *methodDefinition, - checker::Signature const *baseSignature, ir::ScriptFunction const *derivedFunction) const; + checker::Signature const *baseSignature, ir::ScriptFunction *derivedFunction) const; std::string CreateMethodDefinitionString(ir::ClassDefinition const *classDefinition, checker::Signature const *baseSignature, diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 28e9a1c0ab58d42d74a3ee6d846f5d62ec2d0e82..ed062d4a3e93106ba4f8dd72bac83ee6e1d91af5 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -1123,8 +1123,14 @@ static ir::AstNode *InsertInvokeCall(public_lib::Context *ctx, ir::CallExpressio newCallee->SetTsType(prop->TsType()); newCallee->SetObjectType(ifaceType); + /* Pull out substituted call signature */ + auto *funcIface = + ifaceType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE) ? ifaceType : ifaceType->Interfaces()[0]; + checker::Signature *callSig = funcIface->GetFunctionalInterfaceInvokeType()->CallSignatures()[0]; + ES2PANDA_ASSERT(callSig != nullptr); + call->SetCallee(newCallee); - call->SetSignature(prop->TsType()->AsETSFunctionType()->CallSignatures()[0]); + call->SetSignature(callSig); /* NOTE(gogabr): argument types may have been spoiled by widening/narrowing conversions. Repair them here. diff --git a/ets2panda/compiler/lowering/ets/opAssignment.cpp b/ets2panda/compiler/lowering/ets/opAssignment.cpp index af57069fddde3e78eeac1bbd40e47563068a511c..682e53d8e825f981da194b40ecb02d433900e04f 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.cpp +++ b/ets2panda/compiler/lowering/ets/opAssignment.cpp @@ -128,15 +128,15 @@ static std::string GenFormatForExpression(ir::Expression *expr, size_t ix1, size if ((kind & ir::MemberExpressionKind::PROPERTY_ACCESS) != 0) { res += ".@@I" + std::to_string(ix2); } else if (kind == ir::MemberExpressionKind::ELEMENT_ACCESS) { - res += "[@@I" + std::to_string(ix2) + "]"; + res += "[@@E" + std::to_string(ix2) + "]"; } } return res; } -static ir::Identifier *GetClone(ArenaAllocator *allocator, ir::Identifier *node) +static ir::Expression *GetClone(ArenaAllocator *allocator, ir::Expression *node) { - return node == nullptr ? nullptr : node->Clone(allocator, nullptr); + return node == nullptr ? nullptr : node->Clone(allocator, nullptr)->AsExpression(); } static std::string GetFormatPlaceholder(const ir::Expression *expr, const size_t counter) @@ -292,7 +292,7 @@ ir::AstNode *HandleOpAssignment(public_lib::Context *ctx, ir::AssignmentExpressi struct ArgumentInfo { std::string newAssignmentStatements {}; ir::Identifier *id1 = nullptr; - ir::Identifier *id2 = nullptr; + ir::Expression *id2 = nullptr; ir::Identifier *id3 = nullptr; ir::Expression *object = nullptr; ir::Expression *property = nullptr; @@ -309,12 +309,12 @@ static void ParseArgument(public_lib::Context *ctx, ir::Expression *argument, Ar } if (argument->IsIdentifier()) { - info.id1 = GetClone(allocator, argument->AsIdentifier()); + info.id1 = GetClone(allocator, argument->AsIdentifier())->AsIdentifier(); } else if (argument->IsMemberExpression()) { auto *memberExpression = argument->AsMemberExpression(); if (info.object = memberExpression->Object(); info.object != nullptr && info.object->IsIdentifier()) { - info.id1 = GetClone(allocator, info.object->AsIdentifier()); + info.id1 = GetClone(allocator, info.object->AsIdentifier())->AsIdentifier(); } else if (info.object != nullptr) { info.id1 = Gensym(allocator); info.newAssignmentStatements = "const @@I1 = (@@E2) as @@T3; "; @@ -323,9 +323,13 @@ static void ParseArgument(public_lib::Context *ctx, ir::Expression *argument, Ar if (info.property = memberExpression->Property(); info.property != nullptr && info.property->IsIdentifier()) { info.id2 = GetClone(allocator, info.property->AsIdentifier()); + } else if (info.property != nullptr && info.property->IsLiteral()) { + // Be careful not to disturb tuple element access + info.id2 = GetClone(allocator, info.property); } else if (info.property != nullptr) { info.id2 = Gensym(allocator); - info.newAssignmentStatements += "const @@I4 = (@@E5) as @@T6; "; + info.newAssignmentStatements += "const @@I4 = (@@E5) as @@T6;"; + info.newAssignmentStatements += ";"; info.propType = info.property->TsType(); } } diff --git a/ets2panda/compiler/lowering/ets/opAssignment.h b/ets2panda/compiler/lowering/ets/opAssignment.h index 6a45b47b29da6bbb484918e507602e42a5a6edc4..adbc88070ffc8fab0b2ac5ad8368ae0e198e9ca0 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.h +++ b/ets2panda/compiler/lowering/ets/opAssignment.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -22,9 +22,10 @@ namespace ark::es2panda::compiler { class OpAssignmentLowering : public PhaseForBodies { public: + static constexpr std::string_view const NAME = "OpAssignmentLowering"; std::string_view Name() const override { - return "OpAssignmentLowering"; + return NAME; } bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; diff --git a/ets2panda/compiler/lowering/ets/recordLowering.cpp b/ets2panda/compiler/lowering/ets/recordLowering.cpp index d8e2cfc9d7cf4d742a71f28c720d81526bb22309..504b42d93b5fe218a97024c89834984b6d98eb68 100644 --- a/ets2panda/compiler/lowering/ets/recordLowering.cpp +++ b/ets2panda/compiler/lowering/ets/recordLowering.cpp @@ -152,6 +152,21 @@ ir::Statement *RecordLowering::CreateStatement(const std::string &src, ir::Expre return nullptr; } +void RecordLowering::CheckKeyType(checker::ETSChecker *checker, checker::Type const *const keyType, + ir::ObjectExpression const *const expr, public_lib::Context *ctx) const noexcept +{ + if (keyType->IsETSObjectType()) { + if (keyType->IsETSStringType() || + checker->Relation()->IsIdenticalTo(keyType, checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType()) || + checker->Relation()->IsIdenticalTo(keyType, checker->GetGlobalTypesHolder()->GlobalIntegralBuiltinType()) || + keyType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_NUMERIC) || + keyType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::ENUM_OBJECT)) { + return; + } + } + ctx->checker->AsETSChecker()->LogError(diagnostic::OBJ_LIT_UNKNOWN_PROP, {}, expr->Start()); +} + ir::Expression *RecordLowering::UpdateObjectExpression(ir::ObjectExpression *expr, public_lib::Context *ctx) { auto checker = ctx->checker->AsETSChecker(); @@ -171,10 +186,23 @@ ir::Expression *RecordLowering::UpdateObjectExpression(ir::ObjectExpression *exp // Access type arguments [[maybe_unused]] size_t constexpr NUM_ARGUMENTS = 2; - auto typeArguments = expr->PreferredType()->AsETSObjectType()->TypeArguments(); + auto const &typeArguments = expr->PreferredType()->AsETSObjectType()->TypeArguments(); ES2PANDA_ASSERT(typeArguments.size() == NUM_ARGUMENTS); + auto const *keyType = typeArguments[0]; + if (keyType->IsETSTypeParameter()) { + keyType = keyType->AsETSTypeParameter()->GetConstraintType(); + } + // check keys correctness + if (keyType->IsETSUnionType()) { + for (auto const *const ct : keyType->AsETSUnionType()->ConstituentTypes()) { + CheckKeyType(checker, ct, expr, ctx); + } + } else { + CheckKeyType(checker, keyType, expr, ctx); + } + KeySetType keySet; CheckDuplicateKey(keySet, expr, ctx); CheckLiteralsCompleteness(keySet, expr, ctx); diff --git a/ets2panda/compiler/lowering/ets/recordLowering.h b/ets2panda/compiler/lowering/ets/recordLowering.h index a422dc60831fa2a6fcf71077974a9f2e5dbd29ba..ffdf7f795ef12cb2db9ee97235e1281e4c60afd9 100644 --- a/ets2panda/compiler/lowering/ets/recordLowering.h +++ b/ets2panda/compiler/lowering/ets/recordLowering.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023 - 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 @@ -39,6 +39,8 @@ private: void CheckLiteralsCompleteness(KeySetType &keySet, ir::ObjectExpression *expr, public_lib::Context *ctx); ir::Statement *CreateStatement(const std::string &src, ir::Expression *ident, ir::Expression *key, ir::Expression *value, public_lib::Context *ctx); + void CheckKeyType(checker::ETSChecker *checker, checker::Type const *keyType, ir::ObjectExpression const *expr, + public_lib::Context *ctx) const noexcept; }; } // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp b/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp index 12d58293e39aac300a120e5a9be316f38bb8746c..d2fc30b97c18512ffdf7ed4b43e5d196958bebb1 100644 --- a/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp +++ b/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp @@ -22,11 +22,11 @@ namespace ark::es2panda::compiler { using AstNodePtr = ir::AstNode *; -static ir::AstNode *ConvertToResizableArrayType(ir::TSArrayType *node, public_lib::Context *ctx) +static ir::AstNode *ConvertToResizableArrayType(ir::TSArrayType *node, public_lib::Context *ctx, bool insideAnnotdecl) { auto *parser = ctx->parser->AsETSParser(); - ir::TypeNode *typeAnnotation = - parser->CreateFormattedTypeAnnotation("Array<" + node->ElementType()->DumpEtsSrc() + ">"); + ir::TypeNode *typeAnnotation = parser->CreateFormattedTypeAnnotation((insideAnnotdecl ? "FixedArray<" : "Array<") + + node->ElementType()->DumpEtsSrc() + ">"); typeAnnotation->SetAnnotations(std::move(node->Annotations())); typeAnnotation->SetParent(node->Parent()); typeAnnotation->SetRange(node->Range()); @@ -37,13 +37,24 @@ static ir::AstNode *ConvertToResizableArrayType(ir::TSArrayType *node, public_li bool ResizableArrayConvert::PerformForModule(public_lib::Context *ctx, parser::Program *program) { - program->Ast()->TransformChildrenRecursivelyPreorder( - [ctx](ir::AstNode *node) -> AstNodePtr { + bool insideAnnotdecl = false; + program->Ast()->TransformChildrenRecursively( + [&insideAnnotdecl, ctx](ir::AstNode *node) -> AstNodePtr { + if (node->IsAnnotationDeclaration()) { + ES2PANDA_ASSERT(!insideAnnotdecl); + insideAnnotdecl = true; + } if (node->IsTSArrayType()) { - return ConvertToResizableArrayType(node->AsTSArrayType(), ctx); + return ConvertToResizableArrayType(node->AsTSArrayType(), ctx, insideAnnotdecl); } return node; }, + [&insideAnnotdecl](ir::AstNode *node) { + if (node->IsAnnotationDeclaration()) { + ES2PANDA_ASSERT(insideAnnotdecl); + insideAnnotdecl = false; + } + }, Name()); return true; diff --git a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp index 8726f60f085f22928e994a12db0d90467b090019..b8b421ea10c3d95799a3bb8885243786235cc01b 100644 --- a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp @@ -108,12 +108,22 @@ static ir::Expression *CreateRestArgsArray(public_lib::Context *context, ArenaVe std::stringstream ss; auto *genSymIdent = Gensym(allocator); + auto *genSymIdent2 = Gensym(allocator); + // Was: + // ss << "let @@I1 : FixedArray<@@T2> = @@E3;"; + // ss << "Array.from<@@T4>(@@I5);"; + // Now: + // NOTE: refactor me! ss << "let @@I1 : FixedArray<@@T2> = @@E3;"; - ss << "Array.from<@@T4>(@@I5);"; + ss << "let @@I4 : Array<@@T5> = new Array<@@T6>(@@I7.length);"; + ss << "for (let i = 0; i < @@I8.length; ++i) { @@I9[i] = @@I10[i]}"; + ss << "@@I11;"; auto *arrayExpr = checker->AllocNode(std::move(copiedArguments), allocator); - auto *loweringResult = - parser->CreateFormattedExpression(ss.str(), genSymIdent, type, arrayExpr, type->Clone(allocator, nullptr), - genSymIdent->Clone(allocator, nullptr)); + auto *loweringResult = parser->CreateFormattedExpression( + ss.str(), genSymIdent, type->Clone(allocator, nullptr), arrayExpr, genSymIdent2, type, + type->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), + genSymIdent2->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), + genSymIdent2->Clone(allocator, nullptr)); return loweringResult; } @@ -221,4 +231,4 @@ bool RestArgsLowering::PerformForModule(public_lib::Context *ctx, parser::Progra Name()); return true; } -} // namespace ark::es2panda::compiler \ No newline at end of file +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/spreadLowering.cpp b/ets2panda/compiler/lowering/ets/spreadLowering.cpp index 5ea7b5fb2a5fada9cfb3b6defba9f1481f284745..31bd8b08a94069d0b37b13b3e6dacc5250c58dc6 100644 --- a/ets2panda/compiler/lowering/ets/spreadLowering.cpp +++ b/ets2panda/compiler/lowering/ets/spreadLowering.cpp @@ -96,7 +96,8 @@ static ir::Identifier *CreateNewArrayDeclareStatement(public_lib::Context *ctx, // But now cast Expression doesn't support built-in array (cast fatherType[] to sonType[]), so "newArrayName // as arrayType" should be added after cast Expression is implemented completely. // Related issue: #issue20162 - if (checker::ETSChecker::IsReferenceType(arrayElementType)) { + if (checker->IsReferenceType(arrayElementType) && + !(arrayElementType->IsETSObjectType() && arrayElementType->AsETSObjectType()->IsBoxedPrimitive())) { arrayElementType = checker->CreateETSUnionType({arrayElementType, checker->GlobalETSUndefinedType()}); } diff --git a/ets2panda/compiler/lowering/ets/stringComparison.cpp b/ets2panda/compiler/lowering/ets/stringComparison.cpp index e7f0cb4f16fe5e16ef9f78fa01daad65ff108d95..17d48fbbef57ab2e54273a7586e611c6d86c2fee 100644 --- a/ets2panda/compiler/lowering/ets/stringComparison.cpp +++ b/ets2panda/compiler/lowering/ets/stringComparison.cpp @@ -81,7 +81,7 @@ void StringComparisonLowering::ProcessBinaryExpression(ir::BinaryExpression *exp checker::ETSChecker *checker = ctx->checker->AsETSChecker(); ArenaVector callArgs(checker->Allocator()->Adapter()); ir::Expression *accessor = nullptr; - auto *zeroExpr = checker->AllocNode(util::StringView("0")); + auto *zeroExpr = checker->AllocNode(lexer::Number(int32_t(0))); auto *const callee = checker->AllocNode("compareTo", checker->Allocator()); auto *var = checker->GlobalBuiltinETSStringType()->GetProperty(callee->AsIdentifier()->Name(), checker::PropertySearchFlags::SEARCH_METHOD); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index 9b675c5de20031a6c515c23593679e6c4dbaf356..9b79dc94c9a7d3e3709146eefd1219dae3e27527 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -107,11 +107,10 @@ static void InsertInGlobal(ir::ClassDefinition *globalClass, ir::AstNode *node) node->SetParent(globalClass); } -void GlobalClassHandler::SetupInitializerBlock(parser::Program *program, - ArenaVector> &&initializerBlock, +void GlobalClassHandler::SetupInitializerBlock(ArenaVector> &&initializerBlock, ir::ClassDefinition *globalClass) { - if (program->IsDeclarationModule() || initializerBlock.empty()) { + if (globalProgram_->IsDeclarationModule() || initializerBlock.empty()) { return; } @@ -125,25 +124,24 @@ void GlobalClassHandler::SetupInitializerBlock(parser::Program *program, } // Note: cannot use the all same name for every stdlib package. - std::string moduleName = std::string(program->ModuleName()); + std::string moduleName = std::string(globalProgram_->ModuleName()); std::replace(moduleName.begin(), moduleName.end(), '.', '_'); util::UString initializerBlockName = util::UString {std::string(compiler::Signatures::INITIALIZER_BLOCK_INIT) + moduleName, allocator_}; ir::MethodDefinition *initializerBlockInit = - CreateGlobalMethod(initializerBlockName.View().Utf8(), std::move(blockStmts), program); + CreateGlobalMethod(initializerBlockName.View().Utf8(), std::move(blockStmts)); InsertInGlobal(globalClass, initializerBlockInit); AddInitCallToStaticBlock(globalClass, initializerBlockInit); } -void GlobalClassHandler::SetupGlobalMethods(parser::Program *program, ArenaVector &&initStatements, +void GlobalClassHandler::SetupGlobalMethods(ArenaVector &&initStatements, ir::ClassDefinition *globalClass, bool isDeclare) { if (isDeclare) { return; } - ir::MethodDefinition *initMethod = - CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements), program); + ir::MethodDefinition *initMethod = CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements)); InsertInGlobal(globalClass, initMethod); if (!initMethod->Function()->Body()->AsBlockStatement()->Statements().empty()) { AddInitCallToStaticBlock(globalClass, initMethod); @@ -178,18 +176,32 @@ void GlobalClassHandler::MergeNamespace(ArenaVector &namespaces } } -ArenaVector GlobalClassHandler::TransformNamespaces(ArenaVector &namespaces, - parser::Program *program) +ArenaVector GlobalClassHandler::TransformNamespaces(ArenaVector &namespaces) { ArenaVector classDecls {allocator_->Adapter()}; - MergeNamespace(namespaces, program); + MergeNamespace(namespaces, globalProgram_); for (auto ns : namespaces) { - classDecls.emplace_back(TransformNamespace(ns, program)); + classDecls.emplace_back(TransformNamespace(ns)); } return classDecls; } -ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, parser::Program *program) +void GlobalClassHandler::TransformBrokenNamespace() +{ + globalProgram_->Ast()->TransformChildrenRecursively( + // CC-OFFNXT(G.FMT.14-CPP) project code style + [this](ir::AstNode *node) -> ir::AstNode * { + if (node->IsETSModule() && node->AsETSModule()->IsNamespace()) { + auto res = TransformNamespace(node->AsETSModule()); + res->SetParent(node->Parent()); + return res; + } + return node; + }, + "TransformBrokenNamespace"); +} + +ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns) { ir::ClassDeclaration *const globalDecl = CreateTransformedClass(ns); ir::ClassDefinition *const globalClass = globalDecl->Definition(); @@ -202,16 +214,16 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, statement->Iterate([this](ir::AstNode *node) { AddStaticBlockToClass(node); }); } auto stmts = CollectProgramGlobalStatements(body, globalClass, ns); - immediateInitializers.emplace_back(GlobalStmts {program, std::move(stmts.immediateInit)}); + immediateInitializers.emplace_back(GlobalStmts {globalProgram_, std::move(stmts.immediateInit)}); for (auto &initBlock : stmts.initializerBlocks) { - initializerBlock.emplace_back(GlobalStmts {program, std::move(initBlock)}); + initializerBlock.emplace_back(GlobalStmts {globalProgram_, std::move(initBlock)}); } AddStaticBlockToClass(globalClass); const ModuleDependencies md {allocator_->Adapter()}; - auto immediateInitStatements = FormInitMethodStatements(program, &md, std::move(immediateInitializers)); - auto initializerBlockStatements = FormInitStaticBlockMethodStatements(program, &md, std::move(initializerBlock)); - SetupGlobalMethods(program, std::move(immediateInitStatements), globalClass, ns->IsDeclare()); - SetupInitializerBlock(program, std::move(initializerBlockStatements), globalClass); + auto immediateInitStatements = FormInitMethodStatements(&md, std::move(immediateInitializers)); + auto initializerBlockStatements = FormInitStaticBlockMethodStatements(&md, std::move(initializerBlock)); + SetupGlobalMethods(std::move(immediateInitStatements), globalClass, ns->IsDeclare()); + SetupInitializerBlock(std::move(initializerBlockStatements), globalClass); // remove namespaceDecl from orginal node auto end = std::remove_if(body.begin(), body.end(), [&namespaces](ir::AstNode *node) { @@ -222,7 +234,7 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, return false; }); body.erase(end, body.end()); - auto globalClasses = TransformNamespaces(namespaces, program); + auto globalClasses = TransformNamespaces(namespaces); for (auto *cls : globalClasses) { globalClass->Body().emplace_back(cls); cls->SetParent(globalClass); @@ -238,12 +250,12 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, return globalDecl; } -void GlobalClassHandler::CollectProgramGlobalClasses(parser::Program *program, ArenaVector namespaces) +void GlobalClassHandler::CollectProgramGlobalClasses(ArenaVector namespaces) { - auto classDecls = TransformNamespaces(namespaces, program); + auto classDecls = TransformNamespaces(namespaces); for (auto cls : classDecls) { - program->Ast()->Statements().push_back(cls); - cls->SetParent(program->Ast()); + globalProgram_->Ast()->Statements().push_back(cls); + cls->SetParent(globalProgram_->Ast()); CollectNamespaceExportedClasses(cls->Definition()); } } @@ -268,14 +280,12 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & if (programs.empty()) { return; } - ArenaUnorderedSet packageInitializerBlockCount(allocator_->Adapter()); - parser::Program *const globalProgram = programs.front(); - ir::ClassDeclaration *const globalDecl = CreateGlobalClass(globalProgram); + ir::ClassDeclaration *const globalDecl = CreateGlobalClass(globalProgram_); ir::ClassDefinition *const globalClass = globalDecl->Definition(); // NOTE(vpukhov): a clash inside program list is possible - ES2PANDA_ASSERT(globalProgram->IsPackage() || programs.size() == 1); + ES2PANDA_ASSERT(globalProgram_->IsPackage() || programs.size() == 1); ArenaVector immediateInitializers(allocator_->Adapter()); ArenaVector initializerBlock(allocator_->Adapter()); @@ -301,30 +311,29 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & program->SetGlobalClass(globalClass); } - globalProgram->Ast()->Statements().emplace_back(globalDecl); - globalDecl->SetParent(globalProgram->Ast()); + globalProgram_->Ast()->Statements().emplace_back(globalDecl); + globalDecl->SetParent(globalProgram_->Ast()); globalClass->SetGlobalInitialized(); - CollectProgramGlobalClasses(globalProgram, namespaces); - auto initializerBlockStmts = - FormInitStaticBlockMethodStatements(globalProgram, moduleDependencies, std::move(initializerBlock)); - CollectExportedClasses(globalClass, globalProgram->Ast()->Statements()); + CollectProgramGlobalClasses(namespaces); + TransformBrokenNamespace(); + auto initializerBlockStmts = FormInitStaticBlockMethodStatements(moduleDependencies, std::move(initializerBlock)); + + CollectExportedClasses(globalClass, globalProgram_->Ast()->Statements()); // NOTE(vpukhov): stdlib checks are to be removed - do not extend the existing logic - if (globalProgram->Kind() != parser::ScriptKind::STDLIB) { + if (globalProgram_->Kind() != parser::ScriptKind::STDLIB) { AddStaticBlockToClass(globalClass); - if (!util::Helpers::IsStdLib(globalProgram)) { - auto immInitStmts = - FormInitMethodStatements(globalProgram, moduleDependencies, std::move(immediateInitializers)); - SetupGlobalMethods(globalProgram, std::move(immInitStmts)); + if (!util::Helpers::IsStdLib(globalProgram_)) { + auto initStatements = FormInitMethodStatements(moduleDependencies, std::move(immediateInitializers)); + SetupGlobalMethods(std::move(initStatements)); } } - SetupInitializerBlock(globalProgram, std::move(initializerBlockStmts), globalClass); + SetupInitializerBlock(std::move(initializerBlockStmts), globalClass); } -ir::MethodDefinition *GlobalClassHandler::CreateGlobalMethod(std::string_view name, - ArenaVector &&statements, - const parser::Program *program) +ir::MethodDefinition *GlobalClassHandler::CreateGlobalMethod(const std::string_view name, + ArenaVector &&statements) { const auto functionFlags = ir::ScriptFunctionFlags::NONE; auto functionModifiers = ir::ModifierFlags::STATIC | ir::ModifierFlags::PUBLIC; @@ -344,7 +353,7 @@ ir::MethodDefinition *GlobalClassHandler::CreateGlobalMethod(std::string_view na auto *methodDef = NodeAllocator::Alloc(allocator_, ir::MethodDefinitionKind::METHOD, ident->Clone(allocator_, nullptr)->AsExpression(), funcExpr, functionModifiers, allocator_, false); - methodDef->SetRange({lexer::SourcePosition(program), lexer::SourcePosition(program)}); + methodDef->SetRange({lexer::SourcePosition(globalProgram_), lexer::SourcePosition(globalProgram_)}); return methodDef; } @@ -393,13 +402,13 @@ ir::Identifier *GlobalClassHandler::RefIdent(const util::StringView &name) } ArenaVector> GlobalClassHandler::FormInitStaticBlockMethodStatements( - parser::Program *program, const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements) + const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements) { // Note: will create method body for initializer block one by one, don't merge them. ArenaVector> staticBlocks(allocator_->Adapter()); for (const auto &[p, ps] : initStatements) { ArenaVector statements(allocator_->Adapter()); - if (!util::Helpers::IsStdLib(program) && moduleDependencies != nullptr) { + if (!util::Helpers::IsStdLib(globalProgram_) && moduleDependencies != nullptr) { FormDependentInitTriggers(statements, moduleDependencies); } statements.insert(statements.end(), ps.begin(), ps.end()); @@ -409,12 +418,11 @@ ArenaVector> GlobalClassHandler::FormInitStaticBloc return staticBlocks; } -ArenaVector GlobalClassHandler::FormInitMethodStatements(parser::Program *program, - const ModuleDependencies *moduleDependencies, +ArenaVector GlobalClassHandler::FormInitMethodStatements(const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements) { ArenaVector statements(allocator_->Adapter()); - if (!util::Helpers::IsStdLib(program) && moduleDependencies != nullptr) { + if (!util::Helpers::IsStdLib(globalProgram_) && moduleDependencies != nullptr) { FormDependentInitTriggers(statements, moduleDependencies); } for (const auto &[p, ps] : initStatements) { @@ -549,14 +557,14 @@ static bool HasMethod(ir::ClassDefinition const *cls, const std::string_view nam }); } -void GlobalClassHandler::SetupGlobalMethods(parser::Program *program, ArenaVector &&initStatements) +void GlobalClassHandler::SetupGlobalMethods(ArenaVector &&initStatements) { - ir::ClassDefinition *const globalClass = program->GlobalClass(); - SetupGlobalMethods(program, std::move(initStatements), globalClass, program->IsDeclarationModule()); + ir::ClassDefinition *const globalClass = globalProgram_->GlobalClass(); + SetupGlobalMethods(std::move(initStatements), globalClass, globalProgram_->IsDeclarationModule()); - if (program->IsSeparateModule() && !HasMethod(globalClass, compiler::Signatures::MAIN)) { - ir::MethodDefinition *mainMethod = CreateGlobalMethod( - compiler::Signatures::MAIN, ArenaVector(allocator_->Adapter()), program); + if (globalProgram_->IsSeparateModule() && !HasMethod(globalClass, compiler::Signatures::MAIN)) { + ir::MethodDefinition *mainMethod = + CreateGlobalMethod(compiler::Signatures::MAIN, ArenaVector(allocator_->Adapter())); InsertInGlobal(globalClass, mainMethod); } } diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h index ae589327d1f9cafc16e003de9f9d4a35a80ae261..1d65297dec4532f76d1f1c739578ede7e41928b9 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h @@ -31,8 +31,13 @@ public: parser::Program *program; ArenaVector statements; }; - explicit GlobalClassHandler(parser::ETSParser *parser, ArenaAllocator *allocator) - : parser_(parser), allocator_(allocator), packageInitializerBlockCount_(allocator->Adapter()) {}; + explicit GlobalClassHandler(parser::ETSParser *parser, ArenaAllocator *allocator, parser::Program *program) + : parser_(parser), + allocator_(allocator), + globalProgram_(program), + packageInitializerBlockCount_(allocator->Adapter()) {}; + + static void MergeNamespace(ArenaVector &namespaces, parser::Program *program); /** * Each "Module" has it's own global class, which contains all top level statements across "module" @@ -40,9 +45,13 @@ public: * @param programs - vector of files in module */ void SetupGlobalClass(const ArenaVector &programs, const ModuleDependencies *moduleDependencies); - void static MergeNamespace(ArenaVector &namespaces, parser::Program *program); + void CheckPackageMultiInitializerBlock(util::StringView packageName, const ArenaVector> &initializerBlocks); + void SetGlobalProgram(parser::Program *program) + { + globalProgram_ = program; + } private: /** @@ -50,35 +59,32 @@ private: * @param program program of module * @param init_statements statements which should be executed */ - void SetupGlobalMethods(parser::Program *program, ArenaVector &&statements); + void SetupGlobalMethods(ArenaVector &&statements); void AddStaticBlockToClass(ir::AstNode *node); - void CollectProgramGlobalClasses(parser::Program *program, ArenaVector namespaces); - ir::ClassDeclaration *TransformNamespace(ir::ETSModule *ns, parser::Program *program); + void CollectProgramGlobalClasses(ArenaVector namespaces); + ir::ClassDeclaration *TransformNamespace(ir::ETSModule *ns); ir::ClassDeclaration *CreateTransformedClass(ir::ETSModule *ns); template void CollectExportedClasses(ir::ClassDefinition *classDef, const ArenaVector &statements); void CollectNamespaceExportedClasses(ir::ClassDefinition *classDef); - void SetupGlobalMethods(parser::Program *program, ArenaVector &&initStatements, - ir::ClassDefinition *globalClass, bool isDeclare); - void SetupInitializerBlock(parser::Program *program, ArenaVector> &&initializerBlock, + void SetupGlobalMethods(ArenaVector &&initStatements, ir::ClassDefinition *globalClass, + bool isDeclare); + void SetupInitializerBlock(ArenaVector> &&initializerBlock, ir::ClassDefinition *globalClass); - ArenaVector TransformNamespaces(ArenaVector &namespaces, - parser::Program *program); + ArenaVector TransformNamespaces(ArenaVector &namespaces); ir::ClassDeclaration *CreateGlobalClass(const parser::Program *globalProgram); ir::ClassStaticBlock *CreateStaticBlock(ir::ClassDefinition *classDef); - ir::MethodDefinition *CreateGlobalMethod(std::string_view name, ArenaVector &&statements, - const parser::Program *program); + ir::MethodDefinition *CreateGlobalMethod(std::string_view name, ArenaVector &&statements); void AddInitCallToStaticBlock(ir::ClassDefinition *globalClass, ir::MethodDefinition *initMethod); void AddInitializerBlockToStaticBlock(ir::ClassDefinition *globalClass, ArenaVector &&initializerBlocks); ArenaVector> FormInitStaticBlockMethodStatements( - parser::Program *program, const ModuleDependencies *moduleDependencies, - ArenaVector &&initStatements); + const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements); + void TransformBrokenNamespace(); - ArenaVector FormInitMethodStatements(parser::Program *program, - const ModuleDependencies *moduleDependencies, + ArenaVector FormInitMethodStatements(const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements); void FormDependentInitTriggers(ArenaVector &statements, @@ -92,6 +98,7 @@ private: parser::ETSParser *const parser_; ArenaAllocator *const allocator_; + parser::Program *globalProgram_; ArenaUnorderedSet packageInitializerBlockCount_; }; } // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp index 448e32937d5cbac42eef1ce0f58f4d8521c16ad8..bc31ae6c65a7eb4ec0cd6919779742ee7e347782 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp @@ -56,15 +56,17 @@ bool TopLevelStatements::Perform(public_lib::Context *ctx, parser::Program *prog // NOTE(vpukhov): enforce compilation failure } - GlobalClassHandler globalClass(ctx->parser->AsETSParser(), program->Allocator()); + GlobalClassHandler globalClass(ctx->parser->AsETSParser(), program->Allocator(), program); for (auto &[package, extPrograms] : program->ExternalSources()) { auto moduleDependencies = imports.HandleGlobalStmts(extPrograms); + globalClass.SetGlobalProgram(extPrograms.front()); globalClass.SetupGlobalClass(extPrograms, &moduleDependencies); } ArenaVector mainModule(program->Allocator()->Adapter()); mainModule.emplace_back(program); auto moduleDependencies = imports.HandleGlobalStmts(mainModule); + globalClass.SetGlobalProgram(program); globalClass.SetupGlobalClass(mainModule, &moduleDependencies); return true; } diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4610361ad3cc57ad1e8f00908fc70edd982bce1e --- /dev/null +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -0,0 +1,1389 @@ +/* + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "generated/tokenType.h" +#include "ir/visitor/IterateAstVisitor.h" +#include "checker/ETSchecker.h" +#include "checker/ets/dynamic/dynamicCall.h" +#include "checker/types/ets/etsTupleType.h" +#include "checker/types/globalTypesHolder.h" +#include "compiler/lowering/util.h" +#include "ir/ets/etsTuple.h" + +#include "compiler/lowering/ets/unboxLowering.h" +#include +#include + +namespace ark::es2panda::compiler { + +namespace { +struct UnboxContext { + // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes,readability-identifier-naming) + explicit UnboxContext(parser::ETSParser *_parser, varbinder::ETSBinder *_varbinder, checker::ETSChecker *_checker) + : parser(_parser), varbinder(_varbinder), checker(_checker), handled(_checker->Allocator()->Adapter()) + { + } + + // NOLINTBEGIN(misc-non-private-member-variables-in-classes) + parser::ETSParser *parser; + varbinder::ETSBinder *varbinder; + checker::ETSChecker *checker; + ArenaSet handled; + // NOLINTEND(misc-non-private-member-variables-in-classes) +}; +} // namespace + +static bool IsRecursivelyUnboxedReference(checker::Type *t); + +static bool IsRecursivelyUnboxed(checker::Type *t) +{ + return t->IsETSPrimitiveType() || IsRecursivelyUnboxedReference(t); +} + +static checker::Type *GetArrayElementType(checker::Type *arrType) +{ + if (arrType->IsETSResizableArrayType()) { + return arrType->AsETSResizableArrayType()->ElementType(); + } + + if (arrType->IsETSArrayType()) { + return arrType->AsETSArrayType()->ElementType(); + } + return nullptr; +} + +static bool IsRecursivelyUnboxedReference(checker::Type *t) +{ + return (t->IsETSTupleType() && + std::any_of(t->AsETSTupleType()->GetTupleTypesList().begin(), + t->AsETSTupleType()->GetTupleTypesList().end(), IsRecursivelyUnboxedReference)) || + (t->IsETSArrayType() && IsRecursivelyUnboxed(GetArrayElementType(t))) || + (t->IsETSUnionType() && + std::any_of(t->AsETSUnionType()->ConstituentTypes().begin(), t->AsETSUnionType()->ConstituentTypes().end(), + IsRecursivelyUnboxedReference)) || + (t->IsETSObjectType() && + std::any_of(t->AsETSObjectType()->TypeArguments().begin(), t->AsETSObjectType()->TypeArguments().end(), + IsRecursivelyUnboxedReference)); +} + +static bool TypeIsBoxedPrimitive(checker::Type *tp) +{ + return tp->IsETSObjectType() && tp->AsETSObjectType()->IsBoxedPrimitive(); +} + +static bool IsUnboxingApplicableReference(checker::Type *t); + +static bool IsUnboxingApplicable(checker::Type *t) +{ + return TypeIsBoxedPrimitive(t) || IsUnboxingApplicableReference(t); +} + +static bool IsUnboxingApplicableReference(checker::Type *t) +{ + return (t->IsETSTupleType() && + std::any_of(t->AsETSTupleType()->GetTupleTypesList().begin(), + t->AsETSTupleType()->GetTupleTypesList().end(), IsUnboxingApplicableReference)) || + (t->IsETSArrayType() && IsUnboxingApplicable(GetArrayElementType(t))) || + (t->IsETSUnionType() && + std::any_of(t->AsETSUnionType()->ConstituentTypes().begin(), t->AsETSUnionType()->ConstituentTypes().end(), + IsUnboxingApplicableReference)) || + (t->IsETSObjectType() && + std::any_of(t->AsETSObjectType()->TypeArguments().begin(), t->AsETSObjectType()->TypeArguments().end(), + IsUnboxingApplicableReference)); +} + +static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, checker::Type *t); + +static checker::Type *MaybeRecursivelyUnboxType(UnboxContext *uctx, checker::Type *t) +{ + if (TypeIsBoxedPrimitive(t)) { + return uctx->checker->MaybeUnboxType(t); + } + return MaybeRecursivelyUnboxReferenceType(uctx, t); +} + +// CC-OFFNXT(huge_method,G.FUN.01-CPP) solid logic +static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, checker::Type *t) +{ + auto *allocator = uctx->checker->Allocator(); + bool anyChange = false; + static std::uint64_t typeId = 0U; + + if (t == nullptr) { + return t; + } + + if (t->IsETSTypeParameter()) { + auto typeParameter = t->AsETSTypeParameter(); + auto constraintType = typeParameter->GetConstraintType(); + // We need to avoid endless recursion in case of recursive generic types, say 'class A>' + if (typeId == 0U) { + typeId = t->Id(); + typeParameter->SetConstraintType(MaybeRecursivelyUnboxReferenceType(uctx, constraintType)); + typeId = 0U; + } else if (t->Id() != typeId) { + typeParameter->SetConstraintType(MaybeRecursivelyUnboxReferenceType(uctx, constraintType)); + } + return t; + } + + if (t->IsETSTupleType()) { + auto *srcTup = t->AsETSTupleType(); + + ArenaVector newTps {allocator->Adapter()}; + for (auto *e : srcTup->GetTupleTypesList()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + + return anyChange ? allocator->New(uctx->checker, newTps) : t; + } + + if (t->IsETSArrayType()) { + auto *srcArr = t->AsETSArrayType(); + auto *newE = MaybeRecursivelyUnboxType(uctx, srcArr->ElementType()); + return (newE == srcArr->ElementType()) ? t : uctx->checker->CreateETSArrayType(newE); + } + + if (t->IsETSResizableArrayType()) { + auto *srcArr = t->AsETSResizableArrayType(); + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, srcArr->ElementType()); + return (newE == srcArr->ElementType()) ? t : uctx->checker->CreateETSResizableArrayType(newE); + } + + if (t->IsETSUnionType()) { + auto *srcUnion = t->AsETSUnionType(); + ArenaVector newTps {allocator->Adapter()}; + for (auto *e : srcUnion->ConstituentTypes()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + return anyChange ? uctx->checker->CreateETSUnionType(std::move(newTps)) : t; + } + + if (t->IsETSObjectType()) { + auto *objTp = t->AsETSObjectType(); + ArenaVector newTps {allocator->Adapter()}; + for (auto *e : objTp->TypeArguments()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + return anyChange ? objTp->GetOriginalBaseType()->SubstituteArguments(uctx->checker->Relation(), newTps) : t; + } + + return t; +} + +// We should never see an array of boxed primitives, even as a component of some bigger type construction +static checker::Type *NormalizeType(UnboxContext *uctx, checker::Type *tp) +{ + return MaybeRecursivelyUnboxReferenceType(uctx, tp); +} + +static void NormalizeAllTypes(UnboxContext *uctx, ir::AstNode *ast) +{ + // Use preorder to avoid dealing with inner structure of type nodes: they are quickly replaced + // by opaque nodes that have no children. + ast->TransformChildrenRecursivelyPreorder( + // CC-OFFNXT(G.FMT.14-CPP) project code style + [uctx](ir::AstNode *child) -> ir::AstNode * { + if (child->IsExpression() && child->AsExpression()->IsTypeNode()) { + // Avoid dealing with annotation usages. + // ETSTypeReferenceParts only appear within ETSTypeReference, so the only way to get one is + // again through AnnotationUsage. + if (child->Parent()->IsAnnotationUsage() || child->IsETSTypeReferencePart()) { + return child; + } + auto typeNodeType = child->AsExpression()->AsTypeNode()->GetType(uctx->checker); + if (typeNodeType == nullptr || typeNodeType->IsETSDynamicType()) { + return child; + } + auto r = uctx->checker->Allocator()->New(NormalizeType(uctx, typeNodeType), + uctx->checker->Allocator()); + r->SetRange(child->Range()); + r->SetParent(child->Parent()); + return r; + } + if (child->IsTyped()) { + child->AsTyped()->SetTsType(NormalizeType(uctx, child->AsTyped()->TsType())); + if (child->Variable() != nullptr && child->Variable()->TsType() != nullptr) { + child->Variable()->SetTsType(NormalizeType(uctx, child->Variable()->TsType())); + } + } + return child; + }, + "unbox-normalize-types"); +} + +static void HandleScriptFunctionHeader(UnboxContext *uctx, ir::ScriptFunction *func) +{ + auto *sig = func->Signature(); + if (sig == nullptr) { + return; + } + + // Special case for primitive `valueOf` functions -- should still return boxed values (used in codegen) + if (func->Parent()->Parent()->IsMethodDefinition() && + func->Parent()->Parent()->AsMethodDefinition()->Id()->Name() == "valueOf" && + ContainingClass(func)->AsETSObjectType()->IsBoxedPrimitive() && sig->Params().size() == 1 && + !sig->Params()[0]->TsType()->IsETSEnumType()) { + auto *boxed = func->Parent()->Parent()->Parent()->AsTyped()->TsType(); + auto *unboxed = MaybeRecursivelyUnboxType(uctx, boxed); + + ES2PANDA_ASSERT(sig->ReturnType() == boxed); + + sig->Params()[0]->SetTsType(unboxed); + uctx->varbinder->BuildFunctionName(func); + return; + } + + // Special case for enum boxing function -- this should still return a boxed value + if (func->Parent()->Parent()->IsMethodDefinition() && + func->Parent()->Parent()->AsMethodDefinition()->Id()->Name() == "boxedfromInt") { + return; + } + + for (size_t i = 0; i < func->Signature()->Params().size(); i++) { + auto *sigParam = func->Signature()->Params()[i]; + auto *funcParam = func->Params()[i]->AsETSParameterExpression(); + if (IsUnboxingApplicable(sigParam->TsType())) { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, sigParam->TsType()); + sigParam->SetTsType(unboxedType); + funcParam->SetTsType(unboxedType); + funcParam->Ident()->SetTsType(unboxedType); + funcParam->Variable()->SetTsType(unboxedType); + } + } + if (sig->RestVar() != nullptr) { + auto *funcRestParam = func->Params()[func->Params().size() - 1]->AsETSParameterExpression(); + ES2PANDA_ASSERT(funcRestParam != nullptr && funcRestParam->IsRestParameter()); + + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, sig->RestVar()->TsType()); + sig->RestVar()->SetTsType(unboxedType); + funcRestParam->Ident()->SetTsType(unboxedType); + funcRestParam->Ident()->Variable()->SetTsType(unboxedType); + } + if (IsUnboxingApplicable(sig->ReturnType())) { + sig->SetReturnType(MaybeRecursivelyUnboxType(uctx, sig->ReturnType())); + } + + // Signature may have changed, so need to change internal name. + uctx->varbinder->BuildFunctionName(func); +} + +static void HandleClassProperty(UnboxContext *uctx, ir::ClassProperty *prop) +{ + auto *propType = prop->TsType(); + if (propType == nullptr) { + propType = prop->Key()->Variable()->TsType(); + } + ES2PANDA_ASSERT(propType != nullptr); + if (IsUnboxingApplicable(propType) && prop->Key()->IsIdentifier()) { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, propType); + prop->SetTsType(unboxedType); + prop->Key()->Variable()->SetTsType(unboxedType); + } +} + +static void HandleVariableDeclarator(UnboxContext *uctx, ir::VariableDeclarator *vdecl) +{ + if (IsUnboxingApplicable(vdecl->Id()->Variable()->TsType())) { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, vdecl->Id()->Variable()->TsType()); + vdecl->SetTsType(unboxedType); + vdecl->Id()->SetTsType(unboxedType); + vdecl->Id()->Variable()->SetTsType(unboxedType); + } +} + +static void HandleDeclarationNode(UnboxContext *uctx, ir::AstNode *ast) /// +{ + if (uctx->handled.count(ast) > 0) { + return; + } + if (ast->IsScriptFunction()) { + HandleScriptFunctionHeader(uctx, ast->AsScriptFunction()); + } else if (ast->IsMethodDefinition()) { + HandleScriptFunctionHeader(uctx, ast->AsMethodDefinition()->Function()); + } else if (ast->IsClassProperty()) { + HandleClassProperty(uctx, ast->AsClassProperty()); + } else if (ast->IsVariableDeclarator()) { + HandleVariableDeclarator(uctx, ast->AsVariableDeclarator()); + } + uctx->handled.insert(ast); +} + +static ir::Expression *InsertUnboxing(UnboxContext *uctx, ir::Expression *expr) +{ + auto *boxedType = expr->TsType(); + if (boxedType->IsETSTypeParameter()) { + boxedType = boxedType->AsETSTypeParameter()->GetConstraintType(); + } + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, boxedType); + auto *parent = expr->Parent(); + + auto *allocator = uctx->checker->Allocator(); + + auto *arenaString = allocator->New(allocator->Adapter()); + if (unboxedType->IsETSIntEnumType() || unboxedType->IsETSStringEnumType()) { + arenaString->append("unbox"); + } else { + arenaString->append("unboxed"); + } + auto *methodId = allocator->New(util::StringView(arenaString), allocator); + auto *mexpr = util::NodeAllocator::ForceSetParent( + allocator, expr, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *call = util::NodeAllocator::ForceSetParent( + allocator, mexpr, ArenaVector(allocator->Adapter()), nullptr, false); + call->SetParent(parent); + auto range = expr->Range(); + methodId->SetRange(range); + mexpr->SetRange(range); + call->SetRange(range); + + CheckLoweredNode(uctx->varbinder, uctx->checker, call); + + /* Ensure that calleeMethod's signature is updated to return an unboxed value */ + auto *calleeMethod = methodId->Variable()->Declaration()->Node(); + HandleDeclarationNode(uctx, calleeMethod); + call->SetTsType(unboxedType); + + return call; +} + +static ir::Expression *InsertBoxing(UnboxContext *uctx, ir::Expression *expr) +{ + auto *unboxedType = expr->TsType(); + auto *boxedType = uctx->checker->MaybeBoxType(unboxedType); + auto *parent = expr->Parent(); + + auto *allocator = uctx->checker->Allocator(); + + auto args = ArenaVector(allocator->Adapter()); + + if (unboxedType->IsETSIntEnumType() || unboxedType->IsETSStringEnumType()) { + auto *memberExpr = util::NodeAllocator::ForceSetParent( + allocator, allocator->New(boxedType, allocator), + allocator->New("boxedfromInt", allocator), ir::MemberExpressionKind::PROPERTY_ACCESS, false, + false); + auto *asExpr = util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(uctx->checker->GlobalIntType(), allocator), false); + args.push_back(asExpr); + auto *call = util::NodeAllocator::ForceSetParent(allocator, memberExpr, std::move(args), + nullptr, false); + + call->SetParent(parent); + auto range = expr->Range(); + memberExpr->Object()->SetRange(range); + memberExpr->Property()->SetRange(range); + memberExpr->SetRange(range); + asExpr->TypeAnnotation()->SetRange(range); + asExpr->SetRange(range); + call->SetRange(range); + + CheckLoweredNode(uctx->varbinder, uctx->checker, call); + HandleDeclarationNode(uctx, call); + + return call; + } + + args.push_back(expr); + auto *constrCall = util::NodeAllocator::ForceSetParent( + allocator, allocator->New(boxedType, allocator), std::move(args)); + constrCall->SetParent(parent); + + auto range = expr->Range(); + constrCall->GetTypeRef()->SetRange(range); + constrCall->SetRange(range); + + CheckLoweredNode(uctx->varbinder, uctx->checker, constrCall); + + /* Ensure that the constructor signature is updated to accept an unboxed value */ + auto *constructor = constrCall->GetSignature()->Function(); + HandleDeclarationNode(uctx, constructor); + + return constrCall; +} + +/* NOTE(gogabr): conversions should be inserted at the checker stage. This function is temporary. */ +static ir::Expression *InsertPrimitiveConversionIfNeeded(UnboxContext *uctx, ir::Expression *expr, + checker::Type *expectedType) +{ + auto *checker = uctx->checker; + auto *relation = checker->Relation(); + auto *allocator = checker->Allocator(); + auto *actualType = expr->TsType(); + auto *parent = expr->Parent(); + + ES2PANDA_ASSERT(IsRecursivelyUnboxed(actualType)); + + if (relation->IsSupertypeOf(expectedType, uctx->checker->MaybeBoxType(actualType))) { + return expr; + } + + checker::Type *toConvert = nullptr; + auto checkSubtyping = [expectedType, checker, &toConvert](checker::Type *tp) { + if (toConvert != nullptr) { + return; + } + if (checker->Relation()->IsSupertypeOf(expectedType, checker->MaybeBoxType(tp))) { + toConvert = tp; + } + }; + checkSubtyping(checker->GlobalByteBuiltinType()); + checkSubtyping(checker->GlobalShortBuiltinType()); + checkSubtyping(checker->GlobalIntBuiltinType()); + checkSubtyping(checker->GlobalLongBuiltinType()); + checkSubtyping(checker->GlobalFloatBuiltinType()); + checkSubtyping(checker->GlobalDoubleBuiltinType()); + if (toConvert == nullptr && actualType->IsCharType() && + relation->IsSupertypeOf(expectedType, checker->GlobalBuiltinETSStringType())) { + toConvert = uctx->checker->GlobalBuiltinETSStringType(); + } + if (toConvert == nullptr && actualType->IsByteType() && + relation->IsSupertypeOf(expectedType, checker->GlobalCharBuiltinType())) { + toConvert = uctx->checker->GlobalCharBuiltinType(); + } + ES2PANDA_ASSERT(toConvert != nullptr); + auto *toConvertUnboxed = checker->MaybeUnboxType(toConvert); + + auto *res = util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(toConvertUnboxed, allocator), false); + res->SetParent(parent); + res->SetTsType(toConvertUnboxed); + + auto range = expr->Range(); + res->TypeAnnotation()->SetRange(range); + res->SetRange(range); + + return res; +} + +// CC-OFFNXT(huge_cyclomatic_complexity,G.FUN.01-CPP) solid logic +static ir::Expression *PerformLiteralConversion(UnboxContext *uctx, lexer::Number const &n, checker::Type *expectedType) +{ + auto *allocator = uctx->checker->Allocator(); + bool isInt = false; + int64_t longValue = 0; + double doubleValue = 0.0; + if (n.IsByte()) { + longValue = n.GetByte(); + isInt = true; + } else if (n.IsShort()) { + longValue = n.GetShort(); + isInt = true; + } else if (n.IsInt()) { + longValue = n.GetInt(); + isInt = true; + } else if (n.IsLong()) { + longValue = n.GetLong(); + isInt = true; + } else if (n.IsFloat()) { + doubleValue = n.GetFloat(); + isInt = false; + } else if (n.IsDouble()) { + doubleValue = n.GetDouble(); + isInt = false; + } else { + ES2PANDA_UNREACHABLE(); + } + + lexer::Number num {}; + if (expectedType->IsByteType()) { + num = lexer::Number {isInt ? (int8_t)longValue : (int8_t)doubleValue}; + } else if (expectedType->IsShortType()) { + num = lexer::Number {isInt ? (int16_t)longValue : (int16_t)doubleValue}; + } else if (expectedType->IsIntType()) { + num = lexer::Number {isInt ? (int32_t)longValue : (int32_t)doubleValue}; + } else if (expectedType->IsLongType()) { + num = lexer::Number {isInt ? longValue : (int64_t)doubleValue}; + } else if (expectedType->IsFloatType()) { + num = lexer::Number {isInt ? (float)longValue : (float)doubleValue}; + } else if (expectedType->IsDoubleType()) { + num = lexer::Number {isInt ? (double)longValue : doubleValue}; + } else { + ES2PANDA_UNREACHABLE(); + } + + auto *res = allocator->New(num); + res->SetTsType(expectedType); + return res; +} + +static ir::Expression *InsertConversionBetweenPrimitivesIfNeeded(UnboxContext *uctx, ir::Expression *expr, + checker::Type *expectedType) +{ + auto *oldType = expr->TsType(); + if (uctx->checker->Relation()->IsIdenticalTo(oldType, expectedType)) { + return expr; + } + + auto *checker = uctx->checker; + auto *parent = expr->Parent(); + ir::Expression *res; + + auto range = expr->Range(); + + if (expr->IsNumberLiteral() && expectedType->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { + /* Some contexts (namely, annotations) expect literals, so provide them if possible */ + res = PerformLiteralConversion(uctx, expr->AsNumberLiteral()->Number(), expectedType); + res->SetRange(range); + } else if (expr->IsCharLiteral() && expectedType->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { + res = PerformLiteralConversion(uctx, lexer::Number {expr->AsCharLiteral()->Char()}, expectedType); + res->SetRange(range); + } else { + auto *allocator = checker->Allocator(); + res = util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(expectedType, allocator), false); + res->AsTSAsExpression()->TypeAnnotation()->SetRange(range); + res->SetRange(range); + } + + res->SetParent(parent); + res->SetTsType(expectedType); + return res; +} + +static ir::Expression *AdjustType(UnboxContext *uctx, ir::Expression *expr, checker::Type *expectedType) +{ + if (expr == nullptr) { + return nullptr; + } + expectedType = uctx->checker->GetApparentType(expectedType); + auto *actualType = expr->TsType(); + + if (expectedType->IsETSDynamicType()) { + return expr; + } + if (actualType->IsETSDynamicType()) { + auto *parent = expr->Parent(); + auto *allocator = uctx->checker->Allocator(); + auto *res = util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(expectedType, allocator), false); + res->SetParent(parent); + res->SetTsType(expectedType); + res->SetRange(expr->Range()); + return res; + } + + expr->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); + if (actualType->IsETSPrimitiveType() && uctx->checker->IsReferenceType(expectedType)) { + expr = InsertPrimitiveConversionIfNeeded(uctx, expr, expectedType); + ES2PANDA_ASSERT( + uctx->checker->Relation()->IsSupertypeOf(expectedType, uctx->checker->MaybeBoxType(expr->TsType())) || + (expr->TsType()->IsCharType() && expectedType->IsETSStringType())); + return InsertBoxing(uctx, expr); + } + if ((TypeIsBoxedPrimitive(actualType) || + (actualType->IsETSTypeParameter() && + TypeIsBoxedPrimitive(actualType->AsETSTypeParameter()->GetConstraintType()))) && + expectedType->IsETSPrimitiveType()) { + return InsertConversionBetweenPrimitivesIfNeeded(uctx, InsertUnboxing(uctx, expr), expectedType); + } + if (TypeIsBoxedPrimitive(actualType) && uctx->checker->IsReferenceType(expectedType) && + !uctx->checker->Relation()->IsSupertypeOf(expectedType, actualType)) { + return AdjustType(uctx, InsertUnboxing(uctx, expr), expectedType); + } + if (actualType->IsETSPrimitiveType() && expectedType->IsETSPrimitiveType()) { + return InsertConversionBetweenPrimitivesIfNeeded(uctx, expr, expectedType); + } + return expr; +} + +static void HandleForOfStatement(UnboxContext *uctx, ir::ForOfStatement *forOf) +{ + auto *left = forOf->Left(); + + ir::Identifier *id = nullptr; + if (left->IsIdentifier()) { + id = left->AsIdentifier(); + } else if (left->IsVariableDeclaration()) { + ES2PANDA_ASSERT(left->AsVariableDeclaration()->Declarators().size() == 1); + id = left->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier(); + } + ES2PANDA_ASSERT(id != nullptr); + + // NOTE(gogabr): we need to recompute the right side type instead of just unboxing; + // this may be, for example, a generic call that returns a boxed array. + auto *tp = MaybeRecursivelyUnboxType(uctx, forOf->Right()->TsType()); + + checker::Type *elemTp = nullptr; + if (tp->IsETSArrayType()) { + elemTp = GetArrayElementType(tp); + } else if (tp->IsETSStringType()) { + elemTp = uctx->checker->GlobalCharType(); + } else { + ES2PANDA_ASSERT(tp->IsETSUnionType()); + ES2PANDA_ASSERT(id->Variable()->TsType()->IsETSUnionType()); + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) + elemTp = id->Variable()->TsType(); // always a union type, no need to change + } + + /* This type assignment beats other assignment that could be produced during normal handling of id's declaration + */ + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) + id->SetTsType(elemTp); + id->Variable()->SetTsType(elemTp); + id->Variable()->Declaration()->Node()->AsTyped()->SetTsType(elemTp); +} + +// Borrowed from arithmetic.cpp, didn't want to make it public -- gogabr +static checker::Type *EffectiveTypeOfNumericOrEqualsOp(checker::ETSChecker *checker, checker::Type *left, + checker::Type *right) +{ + if (left->IsDoubleType() || right->IsDoubleType()) { + return checker->GlobalDoubleType(); + } + if (left->IsFloatType() || right->IsFloatType()) { + return checker->GlobalFloatType(); + } + if (left->IsLongType() || right->IsLongType()) { + return checker->GlobalLongType(); + } + if (left->IsCharType() && right->IsCharType()) { + return checker->GlobalCharType(); + } + if (left->IsETSBooleanType() && right->IsETSBooleanType()) { + return checker->GlobalETSBooleanType(); + } + return checker->GlobalIntType(); +} + +static void ReplaceInParent(ir::AstNode *from, ir::AstNode *to) +{ + // CC-OFFNXT(G.FMT.14-CPP) project code style + auto const replaceNode = [=](ir::AstNode *child) -> ir::AstNode * { + if (child == from) { + to->SetParent(from->Parent()); + return to; + } + return child; + }; + from->Parent()->TransformChildren(replaceNode, "UnboxLoweringReplaceInParent"); +} + +namespace { +struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { + explicit UnboxVisitor(UnboxContext *uctx) : uctx_(uctx) {} + + void VisitReturnStatement(ir::ReturnStatement *retStmt) override + { + ir::ScriptFunction *nearestScriptFunction = nullptr; + for (ir::AstNode *curr = retStmt; curr != nullptr; curr = curr->Parent()) { + if (curr->IsScriptFunction()) { + nearestScriptFunction = curr->AsScriptFunction(); + break; + } + } + ES2PANDA_ASSERT(nearestScriptFunction != nullptr); + + retStmt->SetArgument(AdjustType(uctx_, retStmt->Argument(), nearestScriptFunction->Signature()->ReturnType())); + } + + void VisitIfStatement(ir::IfStatement *ifStmt) override + { + if (TypeIsBoxedPrimitive(ifStmt->Test()->TsType())) { + ifStmt->SetTest(InsertUnboxing(uctx_, ifStmt->Test())); + } + } + + void VisitWhileStatement(ir::WhileStatement *whStmt) override + { + if (TypeIsBoxedPrimitive(whStmt->Test()->TsType())) { + whStmt->SetTest(InsertUnboxing(uctx_, whStmt->Test())); + } + } + + void VisitSwitchStatement(ir::SwitchStatement *swtch) override + { + auto *discType = uctx_->checker->MaybeUnboxType(swtch->Discriminant()->TsType()); + if (!discType->IsETSPrimitiveType()) { // should be string + return; + } + swtch->SetDiscriminant(AdjustType(uctx_, swtch->Discriminant(), discType)); + for (auto *scase : swtch->Cases()) { + scase->SetTest(AdjustType(uctx_, scase->Test(), discType)); + } + } + + void HandleDynamicCall(ir::CallExpression *call) + { + auto *sig = call->Signature(); + auto numSysParams = checker::DynamicCall::IsByValue(uctx_->varbinder, call->Callee()) ? 2 : 3; + for (size_t ix = 0; ix < call->Arguments().size(); ix++) { + auto *expectedType = sig->Params()[numSysParams + ix]->TsType(); + call->Arguments()[ix] = AdjustType(uctx_, call->Arguments()[ix], expectedType); + } + } + + // CC-OFFNXT(huge_method,G.FUN.01-CPP) solid logic + void VisitCallExpression(ir::CallExpression *call) override + { + if (call->Callee()->TsType()->IsETSDynamicType()) { + HandleDynamicCall(call); + return; + } + + auto *func = call->Signature()->Function(); + if (func == nullptr) { + // some lambda call, all arguments and return type need to be boxed + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t i = 0; i < call->Arguments().size(); i++) { + auto *arg = call->Arguments()[i]; + call->Arguments()[i] = AdjustType(uctx_, arg, uctx_->checker->MaybeBoxType(arg->TsType())); + } + return; + } + + HandleDeclarationNode(uctx_, func); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t i = 0; i < call->Arguments().size(); i++) { + auto *arg = call->Arguments()[i]; + + if (i >= func->Signature()->Params().size()) { + auto *restVar = call->Signature()->RestVar(); + if (restVar != nullptr && + !arg->IsSpreadElement()) { // NOTE(gogabr) should we try to unbox spread elements? + auto *restElemType = GetArrayElementType(restVar->TsType()); + call->Arguments()[i] = AdjustType(uctx_, arg, restElemType); + } + } else { + auto *origSigType = func->Signature()->Params()[i]->TsType(); + if (origSigType->IsETSPrimitiveType()) { + call->Signature()->Params()[i]->SetTsType(origSigType); + call->Arguments()[i] = AdjustType(uctx_, arg, origSigType); + } else { + call->Arguments()[i] = AdjustType(uctx_, arg, call->Signature()->Params()[i]->TsType()); + } + } + } + + if (func->Signature()->ReturnType()->IsETSPrimitiveType()) { + call->Signature()->SetReturnType(func->Signature()->ReturnType()); + } else { + call->Signature()->SetReturnType(NormalizeType(uctx_, call->Signature()->ReturnType())); + } + + if (call->Signature()->HasSignatureFlag(checker::SignatureFlags::THIS_RETURN_TYPE)) { + auto *callee = call->Callee(); + auto isFuncRefCall = [&callee]() { + if (!callee->IsMemberExpression()) { + return false; + }; + auto *calleeObject = callee->AsMemberExpression()->Object(); + return (calleeObject) + ->TsType() + ->IsETSFunctionType() || // NOTE(gogabr): How can this happen after lambdaLowering? + (calleeObject->TsType()->IsETSObjectType() && + calleeObject->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::FUNCTIONAL)); + }(); + if (callee->IsMemberExpression() && !isFuncRefCall) { + call->SetTsType(callee->AsMemberExpression()->Object()->TsType()); + } else { + // Either a functional reference call, or + // function with receiver called in a "normal", "function-like" way: + // function f(x: this) : this { return this } + // f(new A) + ES2PANDA_ASSERT(!call->Arguments().empty()); + call->SetTsType(call->Arguments()[0]->TsType()); + } + } else { + call->SetTsType(call->Signature()->ReturnType()); + } + } + + void HandleDynamicConstructorCall(ir::ETSNewClassInstanceExpression *call) + { + auto *sig = call->GetSignature(); + auto numSysParams = checker::DynamicCall::IsByValue(uctx_->varbinder, call->GetTypeRef()) ? 2 : 3; + for (size_t ix = 0; ix < call->GetArguments().size(); ix++) { + auto *expectedType = sig->Params()[numSysParams + ix]->TsType(); + call->GetArguments()[ix] = AdjustType(uctx_, call->GetArguments()[ix], expectedType); + } + } + + void VisitETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression *call) override + { + if (call->GetTypeRef()->TsType()->IsETSDynamicType()) { + HandleDynamicConstructorCall(call); + return; + } + + auto *func = call->GetSignature()->Function(); + HandleDeclarationNode(uctx_, func); + + for (size_t i = 0; i < call->GetArguments().size(); i++) { + auto *arg = call->GetArguments()[i]; + + if (i >= func->Signature()->Params().size()) { + auto *restVar = call->GetSignature()->RestVar(); + if (restVar != nullptr && + !arg->IsSpreadElement()) { // NOTE(gogabr) should we try to unbox spread elements? + auto *restElemType = GetArrayElementType(restVar->TsType()); + call->GetArguments()[i] = AdjustType(uctx_, arg, restElemType); + } + } else { + auto *origSigType = func->Signature()->Params()[i]->TsType(); + if (origSigType->IsETSPrimitiveType()) { + call->GetSignature()->Params()[i]->SetTsType(origSigType); + call->GetArguments()[i] = AdjustType(uctx_, arg, origSigType); + } else { + call->GetArguments()[i] = AdjustType(uctx_, arg, call->GetSignature()->Params()[i]->TsType()); + } + } + } + + call->SetTsType(call->GetTypeRef()->TsType()); + } + + void VisitSpreadElement(ir::SpreadElement *spread) override + { + spread->SetTsType(spread->Argument()->TsType()); + } + + void VisitArrayExpression(ir::ArrayExpression *aexpr) override + { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx_, aexpr->TsType()); + aexpr->SetTsType(unboxedType); + + for (size_t i = 0; i < aexpr->Elements().size(); i++) { + checker::Type *expectedType; + if (aexpr->TsType()->IsETSTupleType()) { + expectedType = aexpr->TsType()->AsETSTupleType()->GetTypeAtIndex(i); + } else if (aexpr->TsType()->IsETSArrayType()) { + expectedType = GetArrayElementType(aexpr->TsType()); + } else { + ES2PANDA_UNREACHABLE(); + } + aexpr->Elements()[i] = AdjustType(uctx_, aexpr->Elements()[i], expectedType); + } + } + + void HandleArithmeticLike(ir::BinaryExpression *bexpr) + { + bexpr->SetTsType(uctx_->checker->MaybeUnboxType(bexpr->TsType())); + bexpr->SetOperationType(uctx_->checker->MaybeUnboxType(bexpr->OperationType())); + if (TypeIsBoxedPrimitive(bexpr->Left()->TsType())) { + bexpr->SetLeft(InsertUnboxing(uctx_, bexpr->Left())); + } + if (TypeIsBoxedPrimitive(bexpr->Right()->TsType())) { + bexpr->SetRight(InsertUnboxing(uctx_, bexpr->Right())); + } + } + + void HandleEqualityOrInequality(ir::BinaryExpression *bexpr) + { + auto *leftTp = bexpr->Left()->TsType(); + auto *rightTp = bexpr->Right()->TsType(); + + checker::Type *opType = nullptr; + if ((leftTp->IsETSPrimitiveType() || TypeIsBoxedPrimitive(leftTp)) && + (rightTp->IsETSPrimitiveType() || TypeIsBoxedPrimitive(rightTp))) { + auto *newLeftTp = uctx_->checker->MaybeUnboxType(leftTp); + auto *newRightTp = uctx_->checker->MaybeUnboxType(rightTp); + bexpr->SetLeft(AdjustType(uctx_, bexpr->Left(), newLeftTp)); + bexpr->SetRight(AdjustType(uctx_, bexpr->Right(), newRightTp)); + + opType = EffectiveTypeOfNumericOrEqualsOp(uctx_->checker, newLeftTp, newRightTp); + bexpr->SetLeft(InsertConversionBetweenPrimitivesIfNeeded(uctx_, bexpr->Left(), opType)); + bexpr->SetRight(InsertConversionBetweenPrimitivesIfNeeded(uctx_, bexpr->Right(), opType)); + } else { + bexpr->SetLeft(AdjustType(uctx_, bexpr->Left(), uctx_->checker->MaybeBoxType(leftTp))); + bexpr->SetRight(AdjustType(uctx_, bexpr->Right(), uctx_->checker->MaybeBoxType(rightTp))); + opType = bexpr->OperationType(); + } + + bexpr->SetOperationType(opType); + bexpr->SetTsType(uctx_->checker->GlobalETSBooleanType()); + } + + void HandleLogical(ir::BinaryExpression *bexpr) + { + auto *leftType = bexpr->Left()->TsType(); + auto *rightType = bexpr->Right()->TsType(); + if (uctx_->checker->Relation()->IsIdenticalTo(leftType, rightType)) { + bexpr->SetTsType(leftType); + bexpr->SetOperationType(leftType); + } else { + // NOTE(gogabr): simplify codegen here. Lower logical operators. + auto *oldLeft = bexpr->Left(); + auto *oldRight = bexpr->Right(); + auto *leftBoxed = uctx_->checker->MaybeBoxType(leftType); + auto *rightBoxed = uctx_->checker->MaybeBoxType(rightType); + auto *resType = uctx_->checker->MaybeUnboxType(uctx_->checker->CreateETSUnionType( + {leftBoxed, rightBoxed})); // currently CreateETSUnionType returns nonunion numeric type if you try to + // create a *Numeric*|*OtherNumeric* + bexpr->SetLeft(AdjustType(uctx_, oldLeft, resType)); + bexpr->SetRight(AdjustType(uctx_, oldRight, resType)); + if (bexpr->Result() == oldLeft) { + bexpr->SetResult(bexpr->Left()); + } else if (bexpr->Result() == oldRight) { + bexpr->SetResult(bexpr->Right()); + } + bexpr->SetTsType(resType); + bexpr->SetOperationType(bexpr->TsType()); + } + } + + void VisitBinaryExpression(ir::BinaryExpression *bexpr) override + { + if (bexpr->IsArithmetic() || bexpr->IsBitwise() || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LESS_THAN || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_GREATER_THAN || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT) { + HandleArithmeticLike(bexpr); + return; + } + if (bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_STRICT_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NOT_EQUAL) { + HandleEqualityOrInequality(bexpr); + return; + } + if (bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING) { + bexpr->SetLeft( + AdjustType(uctx_, bexpr->Left(), + uctx_->checker->CreateETSUnionType({bexpr->TsType(), uctx_->checker->GlobalETSNullType(), + uctx_->checker->GlobalETSUndefinedType()}))); + bexpr->SetRight(AdjustType(uctx_, bexpr->Right(), bexpr->TsType())); + return; + } + if (bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_OR) { + HandleLogical(bexpr); + return; + } + + if (bexpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF) { + bexpr->SetLeft(AdjustType(uctx_, bexpr->Left(), uctx_->checker->MaybeBoxType(bexpr->Left()->TsType()))); + bexpr->SetTsType(uctx_->checker->GlobalETSBooleanType()); + return; + } + } + + void VisitUnaryExpression(ir::UnaryExpression *uexpr) override + { + if (uexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_TILDE) { + uexpr->SetArgument(AdjustType(uctx_, uexpr->Argument(), uexpr->TsType())); + } + + uexpr->SetTsType(uctx_->checker->MaybeUnboxType(uexpr->TsType())); + if (TypeIsBoxedPrimitive(uexpr->Argument()->TsType())) { + uexpr->SetArgument(InsertUnboxing(uctx_, uexpr->Argument())); + } + } + + static bool IsStaticMemberExpression(ir::MemberExpression *mexpr) + { + ES2PANDA_ASSERT(mexpr->Kind() == ir::MemberExpressionKind::PROPERTY_ACCESS); + + auto *propDeclNode = mexpr->Property()->Variable()->Declaration()->Node(); + if (propDeclNode->IsMethodDefinition()) { + return propDeclNode->AsMethodDefinition()->IsStatic(); + } + if (propDeclNode->IsClassProperty()) { + return propDeclNode->AsClassProperty()->IsStatic(); + } + return propDeclNode->IsTSEnumMember(); + } + + static int GetNumberLiteral(ir::Expression *expr) // NOTE(gogabr): should use code from ConstantExpressionLowering + { + if (expr->IsNumberLiteral()) { + return static_cast(expr->AsNumberLiteral()->Number().GetDouble()); + } + // References to temp variables can appear in lowerings + if (expr->IsIdentifier()) { + auto *declNode = expr->Variable()->Declaration()->Node()->Parent()->AsVariableDeclarator(); + auto *initVal = declNode->Init(); + while (initVal->IsTSAsExpression()) { + initVal = initVal->AsTSAsExpression()->Expr(); + } + ES2PANDA_ASSERT(initVal->IsNumberLiteral()); + return initVal->AsNumberLiteral()->Number().GetInt(); + } + ES2PANDA_UNREACHABLE(); + } + + // CC-OFFNXT(huge_depth,huge_method,huge_cyclomatic_complexity,G.FUN.01-CPP) solid logic + void VisitMemberExpression(ir::MemberExpression *mexpr) override + { + if (mexpr->Object()->TsType()->IsETSDynamicType()) { + return; + } + if (mexpr->Kind() == ir::MemberExpressionKind::PROPERTY_ACCESS) { + if (mexpr->Property()->Variable() != nullptr) { + checker::Type *propType = nullptr; + if (mexpr->Property()->Variable()->Declaration() != nullptr && + mexpr->Property()->Variable()->Declaration()->Node() != nullptr && + mexpr->Property()->Variable()->Declaration()->Node()->IsTyped() && + mexpr->Property()->Variable()->Declaration()->Node()->AsTyped()->TsType() != nullptr) { + HandleDeclarationNode(uctx_, mexpr->Property()->Variable()->Declaration()->Node()); + propType = mexpr->Property()->Variable()->Declaration()->Node()->AsTyped()->TsType(); + } else if (mexpr->Property()->Variable()->TsType() != nullptr) { + propType = mexpr->Property()->Variable()->TsType(); + } else { + propType = mexpr->Property()->TsType(); + } + ES2PANDA_ASSERT(propType != nullptr); + + /* Special handling for getters/setters. */ + if (propType->IsETSMethodType()) { + bool needSetter = mexpr->Parent()->IsAssignmentExpression() && + mexpr == mexpr->Parent()->AsAssignmentExpression()->Left(); + if (needSetter) { + if (auto *setterSig = propType->AsETSFunctionType()->FindSetter(); setterSig != nullptr) { + HandleDeclarationNode(uctx_, setterSig->Function()); + propType = setterSig->Params()[0]->TsType(); + } + } else if (auto *getterSig = propType->AsETSFunctionType()->FindGetter(); getterSig != nullptr) { + HandleDeclarationNode(uctx_, getterSig->Function()); + propType = getterSig->ReturnType(); + } + } else if (mexpr->Property()->Variable() != nullptr) { + /* Adjustment needed for Readonly types and possibly some other cases */ + mexpr->Property()->Variable()->SetTsType(propType); + } + + if (IsRecursivelyUnboxed(propType)) { + mexpr->Property()->SetTsType(propType); + mexpr->SetTsType(propType); + } + } else if (mexpr->Property()->Variable() == nullptr && mexpr->Object()->TsType()->IsETSArrayType() && + mexpr->Property()->AsIdentifier()->Name() == "length") { + mexpr->SetTsType(uctx_->checker->GlobalIntType()); + } + if (mexpr->Object()->TsType()->IsETSPrimitiveType() && !IsStaticMemberExpression(mexpr)) { + // NOTE(gogabr): need to handle some elementary method calls as intrinsics + mexpr->SetObject(InsertBoxing(uctx_, mexpr->Object())); + } + } else if (mexpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS) { + /* Getters are already handled in a lowering, we need a primtive as an index */ + if (TypeIsBoxedPrimitive(mexpr->Property()->TsType())) { + mexpr->SetProperty(InsertUnboxing(uctx_, mexpr->Property())); + } + + if (mexpr->Object()->TsType()->IsETSTupleType()) { + auto tupType = mexpr->Object()->TsType()->AsETSTupleType(); + auto index = GetNumberLiteral(mexpr->Property()); + ES2PANDA_ASSERT(index >= 0 && (size_t)index < tupType->GetTupleSize()); + mexpr->SetTsType(tupType->GetTupleTypesList()[index]); + } else if (mexpr->Object()->TsType()->IsETSArrayType()) { + mexpr->SetTsType(GetArrayElementType(mexpr->Object()->TsType())); + } + /* mexpr->Object() may also have never type; nothing needs to be done in that case */ + } else { + ES2PANDA_UNREACHABLE(); + } + } + + void VisitTSAsExpression(ir::TSAsExpression *asExpr) override + { + auto *exprType = asExpr->Expr()->TsType(); + auto *targetType = asExpr->TypeAnnotation()->TsType(); + if (targetType->IsETSPrimitiveType() || TypeIsBoxedPrimitive(targetType)) { + if (exprType->IsETSPrimitiveType() || TypeIsBoxedPrimitive(exprType)) { + auto *primTargetType = MaybeRecursivelyUnboxType(uctx_, targetType); + asExpr->TypeAnnotation()->SetTsType(primTargetType); + asExpr->SetExpr(AdjustType(uctx_, asExpr->Expr(), MaybeRecursivelyUnboxType(uctx_, exprType))); + asExpr->SetTsType(primTargetType); + } else { + auto *boxedTargetType = uctx_->checker->MaybeBoxType(targetType); + asExpr->TypeAnnotation()->SetTsType(boxedTargetType); + asExpr->SetTsType(boxedTargetType); + } + } else if (exprType->IsETSPrimitiveType()) { + asExpr->SetExpr(AdjustType(uctx_, asExpr->Expr(), targetType)); + } + asExpr->SetTsType(asExpr->TypeAnnotation()->TsType()); + } + + void VisitConditionalExpression(ir::ConditionalExpression *cexpr) override + { + if (TypeIsBoxedPrimitive(cexpr->Test()->TsType())) { + cexpr->SetTest(InsertUnboxing(uctx_, cexpr->Test())); + } + + auto *tp = cexpr->TsType(); + if (!tp->IsETSPrimitiveType() && !TypeIsBoxedPrimitive(tp)) { + // Box if needed + cexpr->SetConsequent(AdjustType(uctx_, cexpr->Consequent(), tp)); + cexpr->SetAlternate(AdjustType(uctx_, cexpr->Alternate(), tp)); + } else { + // Unbox if needed + auto *primTp = uctx_->checker->MaybeUnboxType(tp); + cexpr->SetConsequent(AdjustType(uctx_, cexpr->Consequent(), primTp)); + cexpr->SetAlternate(AdjustType(uctx_, cexpr->Alternate(), primTp)); + cexpr->SetTsType(primTp); + } + } + + void VisitETSNewArrayInstanceExpression(ir::ETSNewArrayInstanceExpression *nexpr) override + { + auto unboxedType = MaybeRecursivelyUnboxType(uctx_, nexpr->TsType()); + nexpr->SetTsType(unboxedType); + nexpr->TypeReference()->SetTsType(GetArrayElementType(unboxedType)); + + nexpr->SetDimension( + AdjustType(uctx_, nexpr->Dimension(), uctx_->checker->MaybeUnboxType(nexpr->Dimension()->TsType()))); + } + + void VisitETSNewMultiDimArrayInstanceExpression(ir::ETSNewMultiDimArrayInstanceExpression *nexpr) override + { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx_, nexpr->TsType()); + nexpr->SetTsType(unboxedType); + + auto toUnbox = unboxedType; + for (auto &dim : nexpr->Dimensions()) { + dim = AdjustType(uctx_, dim, uctx_->checker->MaybeUnboxType(dim->TsType())); + toUnbox = GetArrayElementType(toUnbox); + } + + nexpr->TypeReference()->SetTsType(toUnbox); + nexpr->SetSignature( + uctx_->checker->CreateBuiltinArraySignature(unboxedType->AsETSArrayType(), nexpr->Dimensions().size())); + } + + void VisitBlockExpression(ir::BlockExpression *bexpr) override + { + auto &stmts = bexpr->Statements(); + auto *lastStmt = stmts[stmts.size() - 1]; + ES2PANDA_ASSERT(lastStmt->IsExpressionStatement()); + + bexpr->SetTsType(lastStmt->AsExpressionStatement()->GetExpression()->TsType()); + } + + void VisitSequenceExpression(ir::SequenceExpression *sexpr) override + { + sexpr->SetTsType(sexpr->Sequence().back()->TsType()); + } + + void HandleLiteral(ir::Literal *lit) + { + if (lit->TsType() == nullptr) { + return; + } + lit->SetTsType(uctx_->checker->MaybeUnboxType(lit->TsType())); + } + + void VisitBooleanLiteral(ir::BooleanLiteral *blit) override + { + HandleLiteral(blit); + } + void VisitCharLiteral(ir::CharLiteral *clit) override + { + HandleLiteral(clit); + } + void VisitNumberLiteral(ir::NumberLiteral *nlit) override + { + HandleLiteral(nlit); + } + + void HandleVariableRef(ir::Expression *expr) + { + auto *var = expr->Variable(); + if (var == nullptr || var->TsType() == nullptr || expr->TsType() == nullptr || + var->Declaration() == nullptr) { // lambda invoke function + return; + } + auto *declNode = var->Declaration()->Node(); + if (declNode->IsClassProperty()) { + HandleDeclarationNode(uctx_, declNode); + } + if (declNode->IsClassDeclaration() || declNode->IsTSEnumDeclaration() || declNode->IsTSInterfaceDeclaration()) { + return; + } + if (expr->Variable()->TsType()->IsETSPrimitiveType()) { + expr->SetTsType(expr->Variable()->TsType()); + } else if (expr->TsType()->IsETSPrimitiveType()) { + expr->SetTsType(uctx_->checker->MaybeBoxType(expr->TsType())); + } else { + expr->SetTsType(NormalizeType(uctx_, expr->TsType())); + } + } + + void VisitIdentifier(ir::Identifier *id) override + { + HandleVariableRef(id); + } + + void VisitTSQualifiedName(ir::TSQualifiedName *qname) override + { + HandleVariableRef(qname); + } + + void VisitAssignmentExpression(ir::AssignmentExpression *aexpr) override + { + aexpr->SetRight(AdjustType(uctx_, aexpr->Right(), aexpr->Left()->TsType())); + aexpr->SetTsType(aexpr->Left()->TsType()); + } + + void VisitClassProperty(ir::ClassProperty *prop) override + { + prop->SetValue(AdjustType(uctx_, prop->Value(), prop->Key()->Variable()->TsType())); + } + + void VisitETSParameterExpression(ir::ETSParameterExpression *pexpr) override + { + pexpr->AsETSParameterExpression()->SetInitializer( + AdjustType(uctx_, pexpr->Initializer(), pexpr->Ident()->TsType())); + } + + void VisitVariableDeclarator(ir::VariableDeclarator *vdecl) override + { + if (vdecl->Init() != nullptr) { + vdecl->SetInit(AdjustType(uctx_, vdecl->Init(), vdecl->Id()->Variable()->TsType())); + } + } + + void VisitTSNonNullExpression(ir::TSNonNullExpression *nnexpr) override + { + if (nnexpr->Expr()->TsType()->IsETSPrimitiveType()) { + ReplaceInParent(nnexpr, nnexpr->Expr()); + return; + } + nnexpr->SetTsType(uctx_->checker->GetNonNullishType(nnexpr->Expr()->TsType())); + nnexpr->SetOriginalType(nnexpr->TsType()); + } + + // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes, readability-identifier-naming) + UnboxContext *uctx_; +}; +} // namespace + +// Extracted just to avoid large depth of method 'SetUpBuiltinConstructorsAndMethods(UnboxContext *uctx)'. +static void HandleInstanceMethodsDeclaration(checker::Type *tp, UnboxContext *uctx) +{ + for (auto [_, var] : tp->AsETSObjectType()->InstanceMethods()) { + auto *nd = var->Declaration()->Node(); + HandleDeclarationNode(uctx, nd); + if (nd->IsMethodDefinition()) { + for (auto overload : nd->AsMethodDefinition()->Overloads()) { + HandleDeclarationNode(uctx, overload); + } + } + } +} + +// Extracted just to avoid large depth of method 'SetUpBuiltinConstructorsAndMethods(UnboxContext *uctx)'. +static void HandleStaticMethodDeclaration(checker::Type *tp, UnboxContext *uctx) +{ + for (auto [_, var] : tp->AsETSObjectType()->StaticMethods()) { + auto *nd = var->Declaration()->Node(); + HandleDeclarationNode(uctx, nd); + if (nd->IsMethodDefinition()) { + for (auto overload : nd->AsMethodDefinition()->Overloads()) { + HandleDeclarationNode(uctx, overload); + } + } + } +} + +// We need to convert function declarations that can be referenced even without explicit mention +// in the source code. +void SetUpBuiltinConstructorsAndMethods(UnboxContext *uctx) +{ + auto *checker = uctx->checker; + auto setUpType = [&uctx](checker::Type *tp) { + if (tp == nullptr || !tp->IsETSObjectType()) { + return; + } + for (auto *sig : tp->AsETSObjectType()->ConstructSignatures()) { + HandleDeclarationNode(uctx, sig->Function()); + } + HandleInstanceMethodsDeclaration(tp, uctx); + HandleStaticMethodDeclaration(tp, uctx); + }; + + for (auto tpix = (size_t)checker::GlobalTypeId::ETS_BOOLEAN; tpix < (size_t)checker::GlobalTypeId::ETS_BIG_INT; + tpix++) { + setUpType(checker->GetGlobalTypesHolder()->GlobalTypes()[tpix]); + } +} + +template +static void VisitExternalPrograms(UnboxVisitor *visitor, parser::Program *program) +{ + for (auto &[_, extPrograms] : program->ExternalSources()) { + (void)_; + for (auto *extProg : extPrograms) { + VisitExternalPrograms(visitor, extProg); + } + } + + if constexpr (!PROG_IS_EXTERNAL) { + return; + } + + auto annotationIterator = [visitor](auto *child) { + if (child->IsClassProperty()) { + auto prop = child->AsClassProperty(); + HandleClassProperty(visitor->uctx_, prop); + if (prop->Value() != nullptr) { + ES2PANDA_ASSERT(prop->Value()->IsLiteral() || prop->Value()->IsArrayExpression()); + prop->Value()->Accept(visitor); + } + visitor->VisitClassProperty(child->AsClassProperty()); + }; + }; + + program->Ast()->IterateRecursivelyPostorder([&annotationIterator](ir::AstNode *ast) { + if (ast->IsAnnotationDeclaration() || ast->IsAnnotationUsage()) { + // visitAnnotation(ast); + ast->Iterate(annotationIterator); + } + }); +} + +bool UnboxPhase::PerformForModule(public_lib::Context *ctx, parser::Program *program) +{ + auto uctx = UnboxContext(ctx->parser->AsETSParser(), ctx->checker->VarBinder()->AsETSBinder(), + ctx->checker->AsETSChecker()); + + SetUpBuiltinConstructorsAndMethods(&uctx); + + NormalizeAllTypes(&uctx, program->Ast()); + + program->Ast()->IterateRecursivelyPostorder([&uctx](ir::AstNode *ast) { + if (ast->IsClassProperty() || ast->IsScriptFunction() || ast->IsVariableDeclarator()) { + HandleDeclarationNode(&uctx, ast); + } else if (ast->IsForOfStatement()) { + HandleForOfStatement(&uctx, ast->AsForOfStatement()); + } + }); + + UnboxVisitor visitor(&uctx); + program->Ast()->IterateRecursivelyPostorder([&visitor](ir::AstNode *ast) { + ast->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); + ast->Accept(&visitor); + }); + VisitExternalPrograms(&visitor, program); + + for (auto *stmt : program->Ast()->Statements()) { + RefineSourceRanges(stmt); + } + uctx.checker->ClearApparentTypes(); + + return true; +} + +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/constStringToCharLowering.h b/ets2panda/compiler/lowering/ets/unboxLowering.h similarity index 66% rename from ets2panda/compiler/lowering/ets/constStringToCharLowering.h rename to ets2panda/compiler/lowering/ets/unboxLowering.h index e1ac39e53ced136a1009fc3af85c0a936a1ff957..d266f77905e1b05d7f8e7b3ba6a090a1335735da 100644 --- a/ets2panda/compiler/lowering/ets/constStringToCharLowering.h +++ b/ets2panda/compiler/lowering/ets/unboxLowering.h @@ -1,5 +1,5 @@ -/** - * Copyright (c) 2024 Huawei Device Co., Ltd. +/* + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,19 +13,24 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_LOWERING_CONST_STRING_TO_CHAR_LOWERING_H -#define ES2PANDA_COMPILER_LOWERING_CONST_STRING_TO_CHAR_LOWERING_H +#ifndef ES2PANDA_COMPILER_LOWERING_UNBOX_LOWERING_H +#define ES2PANDA_COMPILER_LOWERING_UNBOX_LOWERING_H #include "compiler/lowering/phase.h" namespace ark::es2panda::compiler { -class ConstStringToCharLowering : public PhaseForBodies { +class UnboxPhase : public PhaseForBodies { public: - std::string_view Name() const override; + std::string_view Name() const override + { + return "Unbox"; + } + bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; + // bool PostconditionForModule(public_lib::Context *ctx, const parser::Program *program) override; }; } // namespace ark::es2panda::compiler -#endif // ES2PANDA_COMPILER_LOWERING_CONST_STRING_TO_CHAR_LOWERING_H +#endif diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index 8b94066abc4b3066510708c306752c44274da83b..c409aeca04fef550602672aa224cf8c4d07e4720 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -203,64 +203,6 @@ static void HandleUnionPropertyAccess(checker::ETSChecker *checker, varbinder::V ES2PANDA_ASSERT(expr->PropVar() != nullptr); } -static ir::TSAsExpression *GenAsExpression(checker::ETSChecker *checker, checker::Type *const opaqueType, - ir::Expression *const node, ir::AstNode *const parent) -{ - auto *const typeNode = checker->AllocNode(opaqueType, checker->Allocator()); - auto *const asExpression = checker->AllocNode(node, typeNode, false); - asExpression->SetParent(parent); - asExpression->Check(checker); - return asExpression; -} - -/* - * Function that generates conversion from (union) to (primitive) type as to `as` expressions: - * (union) as (prim) => ((union) as (ref)) as (prim), - * where (ref) is some unboxable type from union constituent types. - * Finally, `(union) as (prim)` expression replaces union_node that came above. - */ -static ir::TSAsExpression *UnionCastToPrimitive(checker::ETSChecker *checker, checker::ETSObjectType *unboxableRef, - checker::Type *unboxedPrim, ir::Expression *unionNode) -{ - auto *const unionAsRefExpression = GenAsExpression(checker, unboxableRef, unionNode, nullptr); - return GenAsExpression(checker, unboxedPrim, unionAsRefExpression, unionNode->Parent()); -} - -static ir::TSAsExpression *HandleUnionCastToPrimitive(checker::ETSChecker *checker, ir::TSAsExpression *expr) -{ - auto *const unionType = expr->Expr()->TsType()->AsETSUnionType(); - auto *sourceType = unionType->FindExactOrBoxedType(checker, expr->TsType()); - if (sourceType == nullptr) { - sourceType = unionType->AsETSUnionType()->FindTypeIsCastableToSomeType(expr->Expr(), checker->Relation(), - expr->TsType()); - } - - if (sourceType != nullptr && expr->Expr()->GetBoxingUnboxingFlags() != ir::BoxingUnboxingFlags::NONE) { - auto *maybeUnboxingType = checker->MaybeUnboxInRelation(sourceType); - // when sourceType get `object`, it could cast to any primitive type but can't be unboxed; - if (maybeUnboxingType != nullptr && expr->TsType()->IsETSPrimitiveType()) { - auto *const asExpr = GenAsExpression(checker, sourceType, expr->Expr(), expr); - asExpr->SetBoxingUnboxingFlags(checker->GetUnboxingFlag(maybeUnboxingType)); - expr->Expr()->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); - expr->SetExpr(asExpr); - } - - return expr; - } - - auto *const unboxableUnionType = sourceType != nullptr ? sourceType : unionType->FindUnboxableType(); - auto *const unboxedUnionType = checker->MaybeUnboxInRelation(unboxableUnionType); - if (unboxableUnionType == nullptr || !unboxableUnionType->IsETSObjectType() || unboxedUnionType == nullptr) { - return expr; - } - - auto *const node = - UnionCastToPrimitive(checker, unboxableUnionType->AsETSObjectType(), unboxedUnionType, expr->Expr()); - node->SetParent(expr->Parent()); - - return node; -} - bool UnionLowering::PerformForModule(public_lib::Context *ctx, parser::Program *program) { checker::ETSChecker *checker = ctx->checker->AsETSChecker(); @@ -276,12 +218,6 @@ bool UnionLowering::PerformForModule(public_lib::Context *ctx, parser::Program * return ast; } } - if (ast->IsTSAsExpression() && ast->AsTSAsExpression()->Expr()->TsType() != nullptr && - ast->AsTSAsExpression()->Expr()->TsType()->IsETSUnionType() && - ast->AsTSAsExpression()->TsType() != nullptr && - ast->AsTSAsExpression()->TsType()->IsETSPrimitiveType()) { - return HandleUnionCastToPrimitive(checker, ast->AsTSAsExpression()); - } return ast; }, diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 0343d8663536d2ca70258e1adf0c2618e3e414a4..b9f9b265294bda31d9afac77424f83f2aadde1ca 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -23,7 +23,6 @@ #include "compiler/lowering/ets/boxedTypeLowering.h" #include "compiler/lowering/ets/boxingForLocals.h" #include "compiler/lowering/ets/capturedVariables.h" -#include "compiler/lowering/ets/constStringToCharLowering.h" #include "compiler/lowering/ets/constantExpressionLowering.h" #include "compiler/lowering/ets/declareOverloadLowering.h" #include "compiler/lowering/ets/cfgBuilderPhase.h" @@ -32,6 +31,7 @@ #include "compiler/lowering/ets/dynamicImportLowering.h" #include "compiler/lowering/ets/enumLowering.h" #include "compiler/lowering/ets/enumPostCheckLowering.h" +#include "compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h" #include "compiler/lowering/ets/restTupleLowering.h" #include "compiler/lowering/ets/expandBrackets.h" #include "compiler/lowering/ets/expressionLambdaLowering.h" @@ -59,6 +59,7 @@ #include "compiler/lowering/ets/stringConstantsLowering.h" #include "compiler/lowering/ets/stringConstructorLowering.h" #include "compiler/lowering/ets/topLevelStmts/topLevelStmts.h" +#include "compiler/lowering/ets/unboxLowering.h" #include "compiler/lowering/ets/unionLowering.h" #include "compiler/lowering/ets/typeFromLowering.h" #include "compiler/lowering/plugin_phase.h" @@ -80,10 +81,10 @@ static ArrayLiteralLowering g_arrayLiteralLowering {}; static BigIntLowering g_bigintLowering; static StringConstructorLowering g_stringConstructorLowering; static ConstantExpressionLowering g_constantExpressionLowering; -static ConstStringToCharLowering g_constStringToCharLowering; static InterfacePropertyDeclarationsPhase g_interfacePropDeclPhase; // NOLINT(fuchsia-statically-constructed-objects) static EnumLoweringPhase g_enumLoweringPhase; static EnumPostCheckLoweringPhase g_enumPostCheckLoweringPhase; +static EnumPropertiesInAnnotationsLoweringPhase g_enumPropertiesInAnnotationsLowering; static RestTupleConstructionPhase g_restTupleConstructionPhase; static SpreadConstructionPhase g_spreadConstructionPhase; static ExtensionAccessorPhase g_extensionAccessorPhase; @@ -117,6 +118,7 @@ static AsyncMethodLowering g_asyncMethodLowering; static TypeFromLowering g_typeFromLowering; static ResizableArrayConvert g_resizableArrayConvert; static RestArgsLowering g_restArgsLowering; +static UnboxPhase g_unboxPhase; static PluginPhase g_pluginsAfterParse {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse}; static PluginPhase g_pluginsAfterBind {"plugins-after-bind", ES2PANDA_STATE_BOUND, &util::Plugin::AfterBind}; static PluginPhase g_pluginsAfterCheck {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck}; @@ -163,13 +165,13 @@ std::vector GetETSPhaseList() &g_asyncMethodLowering, &g_declareOverloadLowering, &g_enumPostCheckLoweringPhase, + &g_enumPropertiesInAnnotationsLowering, &g_spreadConstructionPhase, &g_restArgsLowering, &g_arrayLiteralLowering, &g_bigintLowering, &g_opAssignmentLowering, &g_extensionAccessorPhase, - &g_constStringToCharLowering, &g_boxingForLocals, &g_recordLowering, &g_boxedTypeLowering, @@ -187,6 +189,7 @@ std::vector GetETSPhaseList() &g_optionalArgumentsLowering, // #22952 could be moved to earlier phase &g_genericBridgesLowering, &g_typeFromLowering, + &g_unboxPhase, &g_pluginsAfterLowerings, // pluginsAfterLowerings has to come at the very end, nothing should go after it }; // NOLINTEND diff --git a/ets2panda/compiler/lowering/util.h b/ets2panda/compiler/lowering/util.h index 423035454f9bc5d8feabb1efaa4f5bb14e030bc2..7ec26ad44fe3943d8fd023e7f98d4d5a812ee0a1 100644 --- a/ets2panda/compiler/lowering/util.h +++ b/ets2panda/compiler/lowering/util.h @@ -33,6 +33,7 @@ util::UString GenName(ArenaAllocator *allocator); void ClearTypesVariablesAndScopes(ir::AstNode *node) noexcept; ArenaSet FindCaptured(ArenaAllocator *allocator, ir::AstNode *scopeBearer) noexcept; void SetSourceRangesRecursively(ir::AstNode *node, const lexer::SourceRange &range); +ir::AstNode *RefineSourceRanges(ir::AstNode *node); // Rerun varbinder on the node. varbinder::Scope *Rebind(PhaseManager *phaseManager, varbinder::ETSBinder *varBinder, ir::AstNode *node); diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 2ce7f512ada1ebbc9c2c7acb4eba7c77db72bc9e..e8c75c93eee016e5bbfea596fa3ed990ced1f55b 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -1439,6 +1439,12 @@ signatures: return_type: BUILTIN_JSVALUE ref: BUILTIN_JSRUNTIME_GET_UNDEFINED + - callee: BUILTIN_JSRUNTIME + method_name: getNull + params: [] + return_type: BUILTIN_JSVALUE + ref: BUILTIN_JSRUNTIME_GET_NULL + - callee: BUILTIN_JSRUNTIME method_name: strictEqual params: [BUILTIN_JSVALUE, BUILTIN_JSVALUE] @@ -1766,3 +1772,4 @@ dynamiclangs: - type: dynamic builtin: BUILTIN_JSRUNTIME_SET_ELEMENT_JSVALUE get_undefined: BUILTIN_JSRUNTIME_GET_UNDEFINED + get_null: BUILTIN_JSRUNTIME_GET_NULL diff --git a/ets2panda/compiler/templates/signatures.h.erb b/ets2panda/compiler/templates/signatures.h.erb index 8f09ce229261f772a9c83296926e913006f1888e..afd5719623b6b2a622085ed708e48752da461589 100644 --- a/ets2panda/compiler/templates/signatures.h.erb +++ b/ets2panda/compiler/templates/signatures.h.erb @@ -162,6 +162,17 @@ public: ES2PANDA_UNREACHABLE(); } + static std::string_view GetNullBuiltin(Language lang) + { + ES2PANDA_ASSERT(IsSupported(lang)); +% Signatures::DYNAMIC.each do |lang, data| + if (lang.GetId() == Language::Id::<%= lang.upcase %>) { + return <%= data.builtins.get_null %>; + } +% end + ES2PANDA_UNREACHABLE(); + } + % def generate(attr, pref) % builtins = Hash.new() % Signatures::DYNAMIC.each do |lang, data| diff --git a/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp b/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp index 2f79f32dbfd39c7586187c4747786fde1df13fb7..581b830fde09bda9712c3a97819226edd4556d6f 100644 --- a/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp +++ b/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp @@ -64,7 +64,8 @@ ir::ReturnStatement *CreateTypedReturnStatement(checker::ETSChecker *checker, ir auto *callee = checker->AllocNode(apiClass, prop, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - ArenaVector args(1, checker->AllocNode("0"), allocator->Adapter()); + ArenaVector args(1, checker->AllocNode(lexer::Number((int64_t)0)), + allocator->Adapter()); auto *callExpression = checker->AllocNode(callee, std::move(args), nullptr, false); auto *asExpression = checker->AllocNode(callExpression, type->Clone(allocator, nullptr), false); diff --git a/ets2panda/evaluate/irCheckHelper.cpp b/ets2panda/evaluate/irCheckHelper.cpp index b963be112bd42940e0549f0d2636c740789dc3c6..2ae79653f3ace1ebab6eff413526417948c0e5bf 100644 --- a/ets2panda/evaluate/irCheckHelper.cpp +++ b/ets2panda/evaluate/irCheckHelper.cpp @@ -65,15 +65,16 @@ void IrCheckHelper::PreCheck() isPrecheckPassed_ = true; } +// NOLINTBEGIN(readability-identifier-naming) void IrCheckHelper::CheckDecls() { // All dependent user-classes must be created at this point, so we can run checker. while (!recursiveDecls_.empty()) { auto [program, scope, parent, node] = recursiveDecls_.front(); recursiveDecls_.pop_front(); - helpers::DoScopedAction(checker_, varBinder_, program, scope, parent, [this, node = node, scope = scope]() { - varBinder_->ResolveReferencesForScope(node, scope); - node->Check(checker_); + helpers::DoScopedAction(checker_, varBinder_, program, scope, parent, [this, node_ = node, scope_ = scope]() { + varBinder_->ResolveReferencesForScope(node_, scope_); + node_->Check(checker_); }); } } @@ -87,10 +88,11 @@ void IrCheckHelper::HandleCustomNodes() // Hence we delay `ETSChecker::Check` until all required classes are built and initialized in varbinder. auto [program, scope, parent, node] = *iter; helpers::DoScopedAction(checker_, varBinder_, program, scope, parent, - [varBinder = varBinder_, node = node]() { varBinder->HandleCustomNodes(node); }); + [varBinder = varBinder_, node_ = node]() { varBinder->HandleCustomNodes(node_); }); ++iter; } } +// NOLINTEND(readability-identifier-naming) void IrCheckHelper::CheckGlobalEntity(parser::Program *program, ir::AstNode *node, bool mustCheck) { diff --git a/ets2panda/ir/astNode.cpp b/ets2panda/ir/astNode.cpp index 14806412bdec39d1d4df3ddeaf7c7661f2dc2efb..e06c80311a2a7e2e8b84a4ee8997d6115b4f8add 100644 --- a/ets2panda/ir/astNode.cpp +++ b/ets2panda/ir/astNode.cpp @@ -127,10 +127,35 @@ void AstNode::TransformChildrenRecursively(const NodeTransformer &cb, std::strin TransformChildrenRecursivelyPostorder(cb, transformationName); } +void AstNode::TransformChildrenRecursively(const NodeTransformer &pre, const NodeTraverser &post, + std::string_view transformationName) +{ + TransformChildren( + [&pre, &post, transformationName](AstNode *child) { + auto *childReplacement = pre(child); + childReplacement->TransformChildrenRecursively(pre, post, transformationName); + post(childReplacement); + return childReplacement; + }, + transformationName); +} + +void AstNode::TransformChildrenRecursively(const NodeTraverser &pre, const NodeTransformer &post, + std::string_view transformationName) +{ + TransformChildren( + [&pre, &post, transformationName](AstNode *child) { + pre(child); + child->TransformChildrenRecursively(pre, post, transformationName); + return post(child); + }, + transformationName); +} + void AstNode::TransformChildrenRecursivelyPreorder(const NodeTransformer &cb, std::string_view transformationName) { TransformChildren( - [=](AstNode *child) { + [&cb, transformationName](AstNode *child) { auto *res = cb(child); res->TransformChildrenRecursivelyPreorder(cb, transformationName); return res; @@ -141,7 +166,7 @@ void AstNode::TransformChildrenRecursivelyPreorder(const NodeTransformer &cb, st void AstNode::TransformChildrenRecursivelyPostorder(const NodeTransformer &cb, std::string_view transformationName) { TransformChildren( - [=](AstNode *child) { + [&cb, transformationName](AstNode *child) { child->TransformChildrenRecursivelyPostorder(cb, transformationName); return cb(child); }, @@ -155,7 +180,7 @@ void AstNode::IterateRecursively(const NodeTraverser &cb) const void AstNode::IterateRecursivelyPreorder(const NodeTraverser &cb) const { - Iterate([=](AstNode *child) { + Iterate([&cb](AstNode *child) { cb(child); child->IterateRecursivelyPreorder(cb); }); @@ -163,7 +188,7 @@ void AstNode::IterateRecursivelyPreorder(const NodeTraverser &cb) const void AstNode::IterateRecursivelyPostorder(const NodeTraverser &cb) const { - Iterate([=](AstNode *child) { + Iterate([&cb](AstNode *child) { child->IterateRecursivelyPostorder(cb); cb(child); }); @@ -180,7 +205,7 @@ void AnyChildHelper(bool *found, const NodePredicate &cb, AstNode *ast) return; } - ast->Iterate([=](AstNode *child) { AnyChildHelper(found, cb, child); }); + ast->Iterate([&cb, found](AstNode *child) { AnyChildHelper(found, cb, child); }); } bool AstNode::IsAnyChild(const NodePredicate &cb) const diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index 1ea28d21171a2c2112df26fdde78703b62406332..2d1903dc4ca5c99f6e7f9476a751e851e628f0b8 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -529,8 +529,15 @@ public: virtual void Iterate(const NodeTraverser &cb) const = 0; void TransformChildrenRecursively(const NodeTransformer &cb, std::string_view transformationName); - void TransformChildrenRecursivelyPreorder(const NodeTransformer &cb, std::string_view transformationName); - void TransformChildrenRecursivelyPostorder(const NodeTransformer &cb, std::string_view transformationName); + void TransformChildrenRecursively(const NodeTransformer &pre, const NodeTraverser &post, + std::string_view transformationName); + void TransformChildrenRecursively(const NodeTraverser &pre, const NodeTransformer &post, + std::string_view transformationName); + // Keep these for perf reasons: + void TransformChildrenRecursivelyPreorder(const NodeTransformer &preorderTransformer, + std::string_view transformationName); + void TransformChildrenRecursivelyPostorder(const NodeTransformer &postorderTransformer, + std::string_view transformationName); void IterateRecursively(const NodeTraverser &cb) const; void IterateRecursivelyPreorder(const NodeTraverser &cb) const; diff --git a/ets2panda/ir/ets/etsFunctionType.cpp b/ets2panda/ir/ets/etsFunctionType.cpp index da4e93b20cfb8845d2cff05be1bf53c282ece6d1..89de5eee97858ffd8b0a3ddd583374bbfadef471 100644 --- a/ets2panda/ir/ets/etsFunctionType.cpp +++ b/ets2panda/ir/ets/etsFunctionType.cpp @@ -160,10 +160,6 @@ ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode clone->SetAnnotations(std::move(annotationUsages)); } - // If the scope is set to empty, it will result in the inability to retrieve the scope after clone, - // and an error cannot find type will be reported - clone->SetScope(this->scope_); - return clone; } } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ets/etsPrimitiveType.cpp b/ets2panda/ir/ets/etsPrimitiveType.cpp index c18f74350262d4994bce708bdd606cfcf57c1501..3809054d94095244153d53024ecc794035516eb2 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.cpp +++ b/ets2panda/ir/ets/etsPrimitiveType.cpp @@ -111,35 +111,35 @@ checker::Type *ETSPrimitiveType::GetType([[maybe_unused]] checker::ETSChecker *c { switch (type_) { case PrimitiveType::BYTE: { - SetTsType(checker->GlobalByteType()); + SetTsType(checker->GlobalByteBuiltinType()); return TsType(); } case PrimitiveType::SHORT: { - SetTsType(checker->GlobalShortType()); + SetTsType(checker->GlobalShortBuiltinType()); return TsType(); } case PrimitiveType::INT: { - SetTsType(checker->GlobalIntType()); + SetTsType(checker->GlobalIntBuiltinType()); return TsType(); } case PrimitiveType::LONG: { - SetTsType(checker->GlobalLongType()); + SetTsType(checker->GlobalLongBuiltinType()); return TsType(); } case PrimitiveType::FLOAT: { - SetTsType(checker->GlobalFloatType()); + SetTsType(checker->GlobalFloatBuiltinType()); return TsType(); } case PrimitiveType::DOUBLE: { - SetTsType(checker->GlobalDoubleType()); + SetTsType(checker->GlobalDoubleBuiltinType()); return TsType(); } case PrimitiveType::BOOLEAN: { - SetTsType(checker->GlobalETSBooleanType()); + SetTsType(checker->GlobalETSBooleanBuiltinType()); return TsType(); } case PrimitiveType::CHAR: { - SetTsType(checker->GlobalCharType()); + SetTsType(checker->GlobalCharBuiltinType()); return TsType(); } case PrimitiveType::VOID: { diff --git a/ets2panda/ir/ets/etsTuple.cpp b/ets2panda/ir/ets/etsTuple.cpp index a9ee2ee9d562cd7153fdb584dd31f2df4b333aa9..9fb5061662d51974d18cbaa9f43d3d2c06ebd708 100644 --- a/ets2panda/ir/ets/etsTuple.cpp +++ b/ets2panda/ir/ets/etsTuple.cpp @@ -97,10 +97,8 @@ checker::Type *ETSTuple::GetHolderTypeForTuple(checker::ETSChecker *const checke return typeList[0]; } - std::for_each(typeList.begin(), typeList.end(), [checker](auto &t) { t = checker->MaybeBoxType(t); }); - - auto ctypes = typeList; - return checker->CreateETSUnionType(std::move(ctypes)); + /* NOTE(gogabr): if we compute a union type, we'll lose smaller numeric types, so just return Object */ + return checker->GlobalETSNullishObjectType(); } checker::Type *ETSTuple::GetType(checker::ETSChecker *const checker) diff --git a/ets2panda/ir/expressions/binaryExpression.h b/ets2panda/ir/expressions/binaryExpression.h index e7accbe3b4a56cf65f2b510df1257a36ec202324..97de660fce53c06823ac88ff072d5dc3e7b058a9 100644 --- a/ets2panda/ir/expressions/binaryExpression.h +++ b/ets2panda/ir/expressions/binaryExpression.h @@ -114,21 +114,18 @@ public: { left_ = expr; left_->SetParent(this); - SetStart(left_->Start()); } void SetRight(Expression *expr) noexcept { right_ = expr; right_->SetParent(this); - SetEnd(right_->End()); } void SetResult(Expression *expr) noexcept { result_ = expr; result_->SetParent(this); - SetStart(result_->Start()); } void SetOperator(lexer::TokenType operatorType) noexcept diff --git a/ets2panda/ir/expressions/identifier.cpp b/ets2panda/ir/expressions/identifier.cpp index 3234d31f5d25bb584b07707aea481ce0c391bee0..dc9f18f9e25700ce2fe5dc94da5f1aead28cfb5e 100644 --- a/ets2panda/ir/expressions/identifier.cpp +++ b/ets2panda/ir/expressions/identifier.cpp @@ -443,7 +443,8 @@ bool Identifier::CheckDeclarationsPart2(const ir::AstNode *parent, ScriptExtensi } if (parent->Parent() != nullptr) { - if (parent->Parent()->IsTSEnumDeclaration()) { + if (parent->Parent()->IsTSEnumDeclaration() && + !(parent->IsTSEnumMember() && parent->AsTSEnumMember()->Init() == this)) { return true; } } diff --git a/ets2panda/ir/expressions/literal.h b/ets2panda/ir/expressions/literal.h index e4ad8c033ad01644efc6208146e9329c2c925c78..b8e7ea3b86d9c59ad736b127bee3986dca6fecb5 100644 --- a/ets2panda/ir/expressions/literal.h +++ b/ets2panda/ir/expressions/literal.h @@ -32,8 +32,21 @@ public: return true; } + [[nodiscard]] bool IsFolded() const noexcept + { + return folded_; + } + + void SetFolded(bool folded = true) noexcept + { + folded_ = folded; + } + protected: explicit Literal(AstNodeType const type) : Expression(type) {} + +private: + bool folded_ = false; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/expressions/literals/charLiteral.cpp b/ets2panda/ir/expressions/literals/charLiteral.cpp index c97c0216f0ebae182d452602c2a9b0a323eb3c59..16f519fc71b472ad0f0edf26d4fb8867aec71a29 100644 --- a/ets2panda/ir/expressions/literals/charLiteral.cpp +++ b/ets2panda/ir/expressions/literals/charLiteral.cpp @@ -35,13 +35,7 @@ void CharLiteral::Dump(ir::AstDumper *dumper) const void CharLiteral::Dump(ir::SrcDumper *dumper) const { - std::string utf8Str = util::Helpers::UTF16toUTF8(char_); - if (UNLIKELY(utf8Str.empty())) { - dumper->Add(std::to_string(char_)); - return; - } - - dumper->Add("c\'" + util::Helpers::CreateEscapedString(utf8Str) + "\'"); + dumper->Add("c\'" + ToString() + "\'"); } void CharLiteral::Compile([[maybe_unused]] compiler::PandaGen *pg) const @@ -77,8 +71,11 @@ CharLiteral *CharLiteral::Clone(ArenaAllocator *const allocator, AstNode *const std::string CharLiteral::ToString() const { - std::string charStr; - util::StringView::Mutf8Encode(&charStr, char_); - return charStr; + std::string utf8Str = util::Helpers::UTF16toUTF8(char_); + if (UNLIKELY(utf8Str.empty())) { + return std::to_string(char_); + } + return util::Helpers::CreateEscapedString(utf8Str); } + } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/expressions/literals/numberLiteral.cpp b/ets2panda/ir/expressions/literals/numberLiteral.cpp index 7a2c2267dc72abe8fa480caac1cbbf7340f4a3f2..7fe2c2214357f2a86c4e1078e7696c0b5fdc0b7c 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.cpp +++ b/ets2panda/ir/expressions/literals/numberLiteral.cpp @@ -62,6 +62,16 @@ void NumberLiteral::Dump(ir::SrcDumper *dumper) const dumper->Add(number_.GetDouble()); return; } + + if (number_.IsShort()) { + dumper->Add(number_.GetShort()); + return; + } + + if (number_.IsByte()) { + dumper->Add(number_.GetByte()); + return; + } } dumper->Add(std::string(number_.Str())); } @@ -387,6 +397,14 @@ std::string NumberLiteral::ToString() const FpToString(number_.GetFloat(), result); } + if (number_.IsShort()) { + IntegerToString(number_.GetShort(), result); + } + + if (number_.IsByte()) { + IntegerToString(static_cast(number_.GetByte()), result); + } + ES2PANDA_ASSERT(!result.empty()); return result; } diff --git a/ets2panda/ir/expressions/literals/numberLiteral.h b/ets2panda/ir/expressions/literals/numberLiteral.h index c9c4b5e2bc5f71255d5ad503dd77aab659ef1b07..00dfc4b098c230fdd903b60505a0c8fed12b59f0 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.h +++ b/ets2panda/ir/expressions/literals/numberLiteral.h @@ -29,7 +29,6 @@ public: NO_COPY_SEMANTIC(NumberLiteral); NO_MOVE_SEMANTIC(NumberLiteral); - explicit NumberLiteral(util::StringView const str) : Literal(AstNodeType::NUMBER_LITERAL), number_(str) {} explicit NumberLiteral(lexer::Number const number) : Literal(AstNodeType::NUMBER_LITERAL), number_(number) {} [[nodiscard]] const util::StringView &Str() const noexcept diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index fa676f54d20b8d18ae46cbbba89009f933cd372f..8fb25780f2adff70bbb8c2fc07751f03701325dc 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -285,33 +285,10 @@ checker::Type *MemberExpression::SetAndAdjustType(checker::ETSChecker *checker, std::optional MemberExpression::GetTupleIndexValue() const { - auto *propType = property_->TsType(); - if (object_->TsType() == nullptr || !object_->TsType()->IsETSTupleType() || - !propType->HasTypeFlag(checker::TypeFlag::CONSTANT | checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (object_->TsType() == nullptr || !object_->TsType()->IsETSTupleType() || !property_->IsNumberLiteral()) { return std::nullopt; } - - if (propType->IsByteType()) { - return propType->AsByteType()->GetValue(); - } - - if (propType->IsShortType()) { - return propType->AsShortType()->GetValue(); - } - - if (propType->IsIntType()) { - return propType->AsIntType()->GetValue(); - } - - if (propType->IsLongType()) { - if (auto val = propType->AsLongType()->GetValue(); - val <= std::numeric_limits::max() && val >= std::numeric_limits::min()) { - return static_cast(val); - } - return std::nullopt; - } - - ES2PANDA_UNREACHABLE(); + return property_->AsNumberLiteral()->Number().GetValueAndCastTo(); } bool MemberExpression::CheckArrayIndexValue(checker::ETSChecker *checker) const @@ -321,7 +298,7 @@ bool MemberExpression::CheckArrayIndexValue(checker::ETSChecker *checker) const auto const &number = property_->AsNumberLiteral()->Number(); if (number.IsInteger()) { - auto const value = number.GetLong(); + auto const value = number.GetValueAndCastTo(); if (value < 0) { checker->LogError(diagnostic::NEGATIVE_INDEX, {}, property_->Start()); return false; @@ -329,8 +306,7 @@ bool MemberExpression::CheckArrayIndexValue(checker::ETSChecker *checker) const index = static_cast(value); } else { ES2PANDA_ASSERT(number.IsReal()); - - double value = number.GetDouble(); + double value = number.GetValueAndCastTo(); double fraction = std::modf(value, &value); if (value < 0.0 || fraction >= std::numeric_limits::epsilon()) { checker->LogError(diagnostic::INDEX_NEGATIVE_OR_FRACTIONAL, {}, property_->Start()); @@ -419,15 +395,15 @@ checker::Type *MemberExpression::CheckIndexAccessMethod(checker::ETSChecker *che checker::Type *MemberExpression::GetTypeOfTupleElement(checker::ETSChecker *checker, checker::Type *baseType) { ES2PANDA_ASSERT(baseType->IsETSTupleType()); - checker::Type *type = nullptr; + ir::Expression *expr = nullptr; if (Property()->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { ES2PANDA_ASSERT(Property()->Variable()->Declaration()->Node()->AsClassElement()->Value()); - type = Property()->Variable()->Declaration()->Node()->AsClassElement()->Value()->TsType(); + expr = Property()->Variable()->Declaration()->Node()->AsClassElement()->Value(); } else { - type = Property()->TsType(); + expr = Property(); } - auto idxIfAny = checker->GetTupleElementAccessValue(type); + auto idxIfAny = checker->GetTupleElementAccessValue(expr); if (!idxIfAny.has_value()) { return nullptr; } diff --git a/ets2panda/ir/expressions/unaryExpression.h b/ets2panda/ir/expressions/unaryExpression.h index ac4d753d4eefcd0d1e8c705e3ea152f13e081480..18ae8109396d0cf6faecee2b28247cf092f7881b 100644 --- a/ets2panda/ir/expressions/unaryExpression.h +++ b/ets2panda/ir/expressions/unaryExpression.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -63,6 +63,11 @@ public: return argument_; } + void SetArgument(Expression *arg) + { + argument_ = arg; + } + [[nodiscard]] UnaryExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; diff --git a/ets2panda/ir/srcDump.cpp b/ets2panda/ir/srcDump.cpp index cd690492fc2b595e59c9fbec50b91a9aa147431c..b1b410f190263a81721e17ac313718c8764357b9 100644 --- a/ets2panda/ir/srcDump.cpp +++ b/ets2panda/ir/srcDump.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Huawei Device Co., Ltd. 2021-2024. All rights reserved. + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -55,6 +55,16 @@ void SrcDumper::Add(const std::string &str) ss_ << str; } +void SrcDumper::Add(int8_t i) +{ + ss_ << static_cast(i); +} + +void SrcDumper::Add(int16_t i) +{ + ss_ << i; +} + void SrcDumper::Add(int32_t i) { ss_ << i; diff --git a/ets2panda/ir/srcDump.h b/ets2panda/ir/srcDump.h index a60b6fe88586fd4680130d9a1940a42ed039e3c7..427a5cb4b9c65061e9bde0b3900f9d2ec3bfebd9 100644 --- a/ets2panda/ir/srcDump.h +++ b/ets2panda/ir/srcDump.h @@ -31,6 +31,8 @@ public: explicit SrcDumper(const ir::AstNode *node); void Add(const std::string &str); + void Add(int8_t i); + void Add(int16_t i); void Add(int32_t i); void Add(int64_t l); void Add(float f); diff --git a/ets2panda/ir/statements/annotationUsage.cpp b/ets2panda/ir/statements/annotationUsage.cpp index f45e55276922359211964b74b6326ddbd330c4dd..3ef4f21fafbe7b09e688fbd299363bc1161b52da 100644 --- a/ets2panda/ir/statements/annotationUsage.cpp +++ b/ets2panda/ir/statements/annotationUsage.cpp @@ -23,7 +23,7 @@ void AnnotationUsage::TransformChildren(const NodeTransformer &cb, std::string_v { if (auto *transformedNode = cb(expr_); expr_ != transformedNode) { expr_->SetTransformedNode(transformationName, transformedNode); - expr_ = transformedNode->AsIdentifier(); + expr_ = transformedNode->AsExpression(); } for (auto *&it : VectorIterationGuard(properties_)) { diff --git a/ets2panda/ir/statements/ifStatement.h b/ets2panda/ir/statements/ifStatement.h index 31860fefa64b51ba9e028b1b107ce6e9bf745089..8d6eaffbaa9174602526b3b2aa5bc6f24cd55586 100644 --- a/ets2panda/ir/statements/ifStatement.h +++ b/ets2panda/ir/statements/ifStatement.h @@ -49,6 +49,11 @@ public: return test_; } + void SetTest(Expression *test) noexcept + { + test_ = test; + } + [[nodiscard]] const Statement *Consequent() const noexcept { return consequent_; diff --git a/ets2panda/ir/statements/switchCaseStatement.cpp b/ets2panda/ir/statements/switchCaseStatement.cpp index f81b7c5409b518722cff123c4257454f8b87fab2..712190e1be32ded74d90d287ea66e94b2bd51392 100644 --- a/ets2panda/ir/statements/switchCaseStatement.cpp +++ b/ets2panda/ir/statements/switchCaseStatement.cpp @@ -103,7 +103,7 @@ void SwitchCaseStatement::CheckAndTestCase(checker::ETSChecker *checker, checker checker::Type *unboxedDiscType, ir::Expression *node, bool &isDefaultCase) { if (test_ != nullptr) { - auto caseType = test_->Check(checker); + auto *caseType = checker->MaybeUnboxType(test_->Check(checker)); bool validCaseType = true; if (caseType->HasTypeFlag(checker::TypeFlag::CHAR)) { diff --git a/ets2panda/ir/statements/whileStatement.h b/ets2panda/ir/statements/whileStatement.h index 7fe2484669126b41a8a20b0ccbf61d136b4c3269..7280ef306b36ca8129231cfdbcbe6dddf91907d2 100644 --- a/ets2panda/ir/statements/whileStatement.h +++ b/ets2panda/ir/statements/whileStatement.h @@ -42,6 +42,11 @@ public: return test_; } + void SetTest(Expression *test) + { + test_ = test; + } + const Statement *Body() const { return body_; diff --git a/ets2panda/lexer/lexer.h b/ets2panda/lexer/lexer.h index 94b10631ce09e3cb132123f156f45dd2e1441d68..f547761901ae2ff1fdd00d352092b533d44257cb 100644 --- a/ets2panda/lexer/lexer.h +++ b/ets2panda/lexer/lexer.h @@ -613,6 +613,7 @@ bool Lexer::ScanNumberRadix(bool leadingMinus, bool allowNumericSeparator) } GetToken().number_ = lexer::Number(number); + GetToken().number_.SetStr(SourceView(GetToken().Start().index, Iterator().Index())); return true; } diff --git a/ets2panda/lexer/token/number.h b/ets2panda/lexer/token/number.h index 47d8b2d0d1d6214f43e824eb70ecbd21bd549067..7a79eea77b42f5b5381e15f304a420c5e71d23de 100644 --- a/ets2panda/lexer/token/number.h +++ b/ets2panda/lexer/token/number.h @@ -55,15 +55,16 @@ template inline constexpr bool dependent_false_v = false; // NOLINTEND(readability-identifier-naming) -// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) class Number { public: - // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) explicit Number() noexcept : num_(static_cast(0)) {}; - explicit Number(util::StringView str) noexcept : str_(str) {} // NOLINTNEXTLINE(bugprone-exception-escape) explicit Number(util::StringView str, NumberFlags flags) noexcept; explicit Number(util::StringView str, double num) noexcept : str_(str), num_(num) {} + explicit Number(uint8_t num) noexcept : Number(static_cast(num)) {} + explicit Number(int8_t num) noexcept : num_(num) {} + explicit Number(uint16_t num) noexcept : Number(static_cast(num)) {} + explicit Number(int16_t num) noexcept : num_(num) {} explicit Number(uint32_t num) noexcept : Number(static_cast(num)) {} explicit Number(int32_t num) noexcept : num_(num) {} explicit Number(uint64_t num) noexcept : Number(static_cast(num)) {} @@ -73,7 +74,16 @@ public: DEFAULT_COPY_SEMANTIC(Number); DEFAULT_MOVE_SEMANTIC(Number); ~Number() = default; - // NOLINTEND(cppcoreguidelines-pro-type-member-init) + + bool IsByte() const noexcept + { + return std::holds_alternative(num_); + } + + bool IsShort() const noexcept + { + return std::holds_alternative(num_); + } bool IsInt() const noexcept { @@ -87,7 +97,7 @@ public: bool IsInteger() const noexcept { - return IsInt() || IsLong(); + return IsByte() || IsShort() || IsInt() || IsLong(); } bool IsFloat() const noexcept @@ -110,20 +120,36 @@ public: return (flags_ & NumberFlags::ERROR) != 0; } + int8_t GetByte() const + { + ES2PANDA_ASSERT(IsByte()); + return std::get(num_); + } + + int16_t GetShort() const + { + return std::visit(overloaded {[](int16_t value) { return value; }, + [](int8_t value) { return static_cast(value); }, + []([[maybe_unused]] auto value) -> int16_t { ES2PANDA_UNREACHABLE(); }}, + num_); + } + int32_t GetInt() const { - ES2PANDA_ASSERT(IsInt()); - return std::get(num_); + return std::visit(overloaded {[](int32_t value) { return value; }, + [](int16_t value) { return static_cast(value); }, + [](int8_t value) { return static_cast(value); }, + []([[maybe_unused]] auto value) -> int32_t { ES2PANDA_UNREACHABLE(); }}, + num_); } int64_t GetLong() const { return std::visit(overloaded {[](int64_t value) { return value; }, [](int32_t value) { return static_cast(value); }, - []([[maybe_unused]] auto value) { - ES2PANDA_ASSERT(false); - return static_cast(0); - }}, + [](int16_t value) { return static_cast(value); }, + [](int8_t value) { return static_cast(value); }, + []([[maybe_unused]] auto value) -> int64_t { ES2PANDA_UNREACHABLE(); }}, num_); } @@ -135,9 +161,10 @@ public: double GetDouble() const { - return std::visit( - overloaded {[](double value) { return value; }, [](auto value) { return static_cast(value); }}, - num_); + return std::visit(overloaded {[]([[maybe_unused]] std::monostate value) -> double { ES2PANDA_UNREACHABLE(); }, + [](double value) { return value; }, + [](auto value) { return static_cast(value); }}, + num_); } const util::StringView &Str() const @@ -145,9 +172,16 @@ public: return str_; } + void SetStr(util::StringView str) + { + str_ = str; + } + void Negate() { - std::visit(overloaded {[](auto &value) { value = -value; }}, num_); + std::visit(overloaded {[]([[maybe_unused]] std::monostate value) { ES2PANDA_UNREACHABLE(); }, + [](auto &value) { value = -value; }}, + num_); if (std::holds_alternative(num_)) { int64_t num = std::get(num_); if (num == INT32_MIN) { @@ -156,6 +190,14 @@ public: } } + bool IsZero() const + { + return std::visit(overloaded {[]([[maybe_unused]] std::monostate value) -> bool { ES2PANDA_UNREACHABLE(); }, + [](auto &value) { return value == 0; }}, + num_); + } + + // NOLINTBEGIN(readability-else-after-return) template bool CanGetValue() const noexcept { @@ -164,11 +206,15 @@ public: if constexpr (std::is_same_v) { return IsInteger(); } else if constexpr (std::is_same_v) { - return IsInt(); + return IsInt() || IsShort() || IsByte(); } else if constexpr (std::is_same_v) { return true; } else if constexpr (std::is_same_v) { return IsFloat(); + } else if constexpr (std::is_same_v) { + return IsShort() || IsByte(); + } else if constexpr (std::is_same_v) { + return IsByte(); } else { return false; } @@ -187,18 +233,42 @@ public: return GetDouble(); } else if constexpr (std::is_same_v) { return GetFloat(); + } else if constexpr (std::is_same_v) { + return GetShort(); + } else if constexpr (std::is_same_v) { + return GetByte(); } else { static_assert(dependent_false_v, "Invalid value type was requested for Number."); } } + template + TargetType GetValueAndCastTo() const + { + if (IsByte()) { + return static_cast(GetByte()); + } else if (IsShort()) { + return static_cast(GetShort()); + } else if (IsInt()) { + return static_cast(GetInt()); + } else if (IsLong()) { + return static_cast(GetLong()); + } else if (IsFloat()) { + return static_cast(GetFloat()); + } else if (IsDouble()) { + return static_cast(GetDouble()); + } + ES2PANDA_UNREACHABLE(); + } + // NOLINTEND(readability-else-after-return) + template void SetValue(RT &&value) { using T = typename std::remove_cv_t>; - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v) { + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v) { num_ = std::forward(value); } else { static_assert(dependent_false_v, "Invalid value type was requested for Number."); @@ -207,7 +277,7 @@ public: private: util::StringView str_ {}; - std::variant num_; + std::variant num_; NumberFlags flags_ {NumberFlags::NONE}; }; } // namespace ark::es2panda::lexer diff --git a/ets2panda/public/public.h b/ets2panda/public/public.h index ba457ce9928862ffe2c60721443ed1b2878c0020..acc4a8f4211d29448c1a581f307829e9777d6b28 100644 --- a/ets2panda/public/public.h +++ b/ets2panda/public/public.h @@ -23,7 +23,7 @@ #include "compiler/core/compileQueue.h" #include "parser/ETSparser.h" -#include "checker/checker.h" +#include "checker/ETSchecker.h" #include "compiler/core/emitter.h" namespace ark::es2panda::util { diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index cbe2883b04ba43cd8c2e80358e254d70b1ced544..567afb5a9968d19397068bdfa610bbc86abf4aac 100644 --- a/ets2panda/scripts/arkui.properties +++ b/ets2panda/scripts/arkui.properties @@ -1,3 +1,3 @@ ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git -ARKUI_DEV_BRANCH=panda_rev_7-1-type-error +ARKUI_DEV_BRANCH=panda_rev_7-remove-primitives ARKUI_DEST=koala-sig diff --git a/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets b/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets index 00f05b825e33f297adf1eaa28bc47b04beefb2fa..9e0ebf92e4e1820783350f9a63ae47494cff941a 100644 --- a/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets +++ b/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets @@ -26,7 +26,7 @@ export declare const int_17 = 12345 export declare const int_18: number = 12345 declare const x1: int = 5 declare const x2: int = -5 -declare const y1: float = 5.55 +declare const y1: float = 5.55f declare const y2: double = -5.55 declare const x3: int = 0x5 declare const x4: int = 0b101 @@ -50,7 +50,6 @@ declare const x51 = "abc" /* @@? 18:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_13 */ /* @@? 18:70 Error TypeError: Initializers are not allowed in ambient contexts: byte_23 */ /* @@? 19:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_14 */ -/* @@? 20:30 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: int_1 */ /* @@? 22:31 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: int_12 */ /* @@? 24:36 Error TypeError: Initializers are not allowed in ambient contexts: int_16 */ /* @@? 26:39 Error TypeError: Initializers are not allowed in ambient contexts: int_18 */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets index 3de018767341ea54bfa6a78c5aff26f2e82fc7bd..abbbc6bccaff53f3ff6c63ad434b903258ec6965 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets @@ -24,10 +24,10 @@ enum Size{S, M, L, XL, XXL} testProperty5: FixedArray = [Color.GREEN, Color.BLUE] } -/* @@? 20:29 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 22:39 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'int' */ -/* @@? 22:44 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'int' */ +/* @@? 20:29 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'Boolean' */ +/* @@? 22:39 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Int' */ +/* @@? 22:44 Error TypeError: Array element at index 1 with type 'Double' is not compatible with the target array element type 'Int' */ /* @@? 23:28 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ /* @@? 24:40 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ /* @@? 24:53 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets index dc97fe475cf0e40b547aaae9d3aadfb2f4f030b9..5199df48ef335f06341128c52126aaa31ce326fe 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets @@ -35,10 +35,10 @@ class B{ foo(){} } -/* @@? 29:24 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 31:25 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'int' */ -/* @@? 31:30 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'int' */ +/* @@? 29:24 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'Boolean' */ +/* @@? 31:25 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Int' */ +/* @@? 31:30 Error TypeError: Array element at index 1 with type 'Double' is not compatible with the target array element type 'Int' */ /* @@? 32:24 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ /* @@? 33:25 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ /* @@? 33:38 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets b/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets index e53edf414f6b30acaca6e1866c99198e6b8b1df5..05c91630b4f9070b50bc20129ec3aa6acbf5fc47 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets @@ -17,7 +17,7 @@ class C { public met(...p: FixedArray): string { return "nR" } - public met(...p: FixedArray): string { + public met(...p: FixedArray): string { return "NR" } } diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets b/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets index 2af023757fc898a051425c220ea4a619a89fef5e..9c64efd7b21a138359a11964330e7278b2852fde 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets @@ -15,11 +15,8 @@ //With rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void export declare function foo(...args:FixedArray):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets b/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets new file mode 100644 index 0000000000000000000000000000000000000000..7fa539e519cfdc81408461e08361ae31b45df3c2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets @@ -0,0 +1,29 @@ +/* + * 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. + */ + +function main() { + let x1 = [1, "a"] + let y1: [int, string, int, string] = /* @@ label */[/* @@ label1 */...x1, /* @@ label2 */...x1] + let x2 = [2] + let x3 = ["abc", "abc"] + let y2: [boolean, int, string, string] = /* @@ label3 */[true, /* @@ label4 */...x2, /* @@ label5 */...x3] +} + +/* @@? 18:56 Error TypeError: Initializer has 2 elements, but tuple requires 4 */ +/* @@? 18:72 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ +/* @@? 18:94 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ +/* @@? 21:61 Error TypeError: Initializer has 3 elements, but tuple requires 4 */ +/* @@? 21:83 Error TypeError: 'Double[]' cannot be spread in tuple. */ +/* @@? 21:105 Error TypeError: 'String[]' cannot be spread in tuple. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets index 83dfc9bcf5152c40fddbd17e88ef0e894701079a..a6a67b7da7bcad640dc38852fbce05777d689321 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets @@ -24,8 +24,6 @@ function main(): void { /* @@? 18:32 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:32 Error SyntaxError: Unexpected token '>'. */ /* @@? 18:32 Error SyntaxError: Unexpected token '>'. */ -/* @@? 18:32 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 18:32 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:35 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 18:42 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:42 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets index de7338a66b303278d853c1e38403b62b69b99fb7..063b903dd00df3b31a2031d24f0c13d011b67eb6 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets @@ -24,8 +24,6 @@ function main(): void { /* @@? 18:40 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:40 Error SyntaxError: Unexpected token '>'. */ /* @@? 18:40 Error SyntaxError: Unexpected token '>'. */ -/* @@? 18:40 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 18:40 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:43 Error TypeError: Class name 'Int' used in the wrong context */ /* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets index 616aaac57f0cc84b2026365cd45c3ef6d585592c..bffcc4a77664a013799f586d686613920a6b69f6 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets @@ -42,7 +42,7 @@ function getUnion(): A | B { function main() { const u = getUnion() assertEQ(/* @@ label1 */u.fld1, 42) - assertEQ(/* @@ label2 */u.fld2, 42.0) + assertEQ(u.fld2, 42.0) assertEQ(/* @@ label3 */u.fld3[0], "abc") assertEQ(/* @@ label4 */u.fld4[0], "def") assertEQ(/* @@ label5 */u.fld5, 42.0) @@ -52,7 +52,6 @@ function main() { } /* @@@ label1 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label2 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label3 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label4 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label5 Error TypeError: Member type must be the same for all union objects. */ diff --git a/ets2panda/test/ast/compiler/ets/FunctionType10.ets b/ets2panda/test/ast/compiler/ets/FunctionType10.ets index 2c1abfa1d121e6b26ba5b553c24bcb4b614b90cc..fc1a41058c3a1591eeb1191af23770bbf55deb22 100644 --- a/ets2panda/test/ast/compiler/ets/FunctionType10.ets +++ b/ets2panda/test/ast/compiler/ets/FunctionType10.ets @@ -21,4 +21,4 @@ function main() { let goo : int = /* @@ label */foo } -/* @@@ label Error TypeError: Type '() => Int' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '() => Int' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/FunctionType3.ets b/ets2panda/test/ast/compiler/ets/FunctionType3.ets index b4524e83ece4d36ed4c4de4d8527dcca58131ff3..0e68f79c692c8675402c8406b4d827ad2a7c600e 100644 --- a/ets2panda/test/ast/compiler/ets/FunctionType3.ets +++ b/ets2panda/test/ast/compiler/ets/FunctionType3.ets @@ -24,4 +24,4 @@ function main(): void { } /* @@@ label1 Error TypeError: Type '"foo"' is not compatible with type 'Int' at index 2 */ -/* @@@ label Error TypeError: No matching call signature for (int, "foo") */ +/* @@@ label Error TypeError: No matching call signature for (Int, "foo") */ diff --git a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets index f3352a60e9bd190b64671a2bc36c34e2c8a40f4e..367544573fd5d6029d211b7044a177e3ef6c5fab 100644 --- a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets +++ b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets @@ -16,4 +16,4 @@ class A>{} class B{} class C extends A/* @@ label */{} -/* @@@ label Error TypeError: Type B is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'B' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets index 9b39a2bf97fa56b04a110ef37a068abcf8d5f42e..da65d44cd5fef34d89df69ae4dfae461eb0e77c9 100644 --- a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets +++ b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets @@ -17,4 +17,4 @@ class A>{} class P2{} class P1 extends A/* @@ label */{} -/* @@@ label Error TypeError: Type P2 is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'P2' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets index 6e6a14c6ef3fcb5d6801b66753fc64e7a80025eb..23c49fd00f3806c29fe9c1e1d32bbf1ac93848ac 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets @@ -24,10 +24,10 @@ enum Size{S, M, L, XL, XXL} testProperty5: Size[] = [Color.GREEN, Color.BLUE] } -/* @@? 20:29 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 22:29 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'Int' */ -/* @@? 22:34 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'Int' */ +/* @@? 20:29 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'Boolean' */ +/* @@? 22:39 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Int' */ +/* @@? 22:44 Error TypeError: Array element at index 1 with type 'Double' is not compatible with the target array element type 'Int' */ /* @@? 23:28 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ /* @@? 24:30 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ /* @@? 24:43 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets index 09e201db4e66456a897ea0610492e2ee2808dd88..679bc167bba7eab61aa615a498bfb4e53ad0b137 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets @@ -19,6 +19,4 @@ let a = 1 instanceof MyAnno /* @@? 19:22 Error TypeError: Annotations cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ -/* @@? 19:22 Error TypeError: Annotations cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ \ No newline at end of file +/* @@? 19:22 Error TypeError: Annotations cannot be used as a type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets index b18eb027e59f66305ce32e828c742187dcb39834..4904fabba8dc0563e96c421d11cf98646aecb271 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets @@ -21,5 +21,5 @@ @MyAnno({testProperty1: /* @@ label */1, testProperty2: /* @@ label1 */""}) function foo(){} -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@@ label1 Error TypeError: Type '""' cannot be assigned to type 'double' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@@ label1 Error TypeError: Type '""' cannot be assigned to type 'Double' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets index ba05db9e1354c3cbd4356e5eca2529fe64a20e5d..09bee29a1d203e45cb26694b97b25261d2408a33 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets @@ -35,10 +35,10 @@ class B{ foo(){} } -/* @@? 29:24 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 31:25 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'Int' */ -/* @@? 31:30 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'Int' */ +/* @@? 29:24 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'Boolean' */ +/* @@? 31:25 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Int' */ +/* @@? 31:30 Error TypeError: Array element at index 1 with type 'Double' is not compatible with the target array element type 'Int' */ /* @@? 32:24 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ /* @@? 33:25 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ /* @@? 33:38 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets index 065c6baad198e7dc00525cb95c58e981f090216d..a61fa5db89ba7c8fdc995bfa8a46a71a38382d95 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets @@ -21,5 +21,5 @@ @MyAnno({testProperty2: /* @@ label */"Bob", testProperty1: /* @@ label1 */1}) class A{} -/* @@@ label Error TypeError: Type '"Bob"' cannot be assigned to type 'double' */ -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type '"Bob"' cannot be assigned to type 'Double' */ +/* @@@ label1 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets index e358f9440ee1426b4e3206cb8d8c2dae1e415b36..3de515f15a42261ebafdcfc39ea78be12b5a0e54 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets @@ -20,6 +20,6 @@ class A {} } -/* @@? 18:18 Error TypeError: Cannot cast type 'int' to 'String' */ -/* @@? 19:15 Error TypeError: Cannot cast type 'int' to 'A' */ -/* @@? 19:15 Error TypeError: Type 'A' cannot be assigned to type 'int' */ \ No newline at end of file +/* @@? 18:18 Error TypeError: Cannot cast type 'Int' to 'String' */ +/* @@? 19:15 Error TypeError: Cannot cast type 'Int' to 'A' */ +/* @@? 19:15 Error TypeError: Type 'A' cannot be assigned to type 'Int' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/assert_bad.ets b/ets2panda/test/ast/compiler/ets/assert_bad.ets index 0e9743b4bd2e4055a8278fc59ea1ce13604b10d5..2e425b5250dde7d61e6fe60200ab5f8d6c3bb980 100644 --- a/ets2panda/test/ast/compiler/ets/assert_bad.ets +++ b/ets2panda/test/ast/compiler/ets/assert_bad.ets @@ -19,5 +19,5 @@ function main(): int { return 0; } -/* @@@ label1 Error TypeError: No matching call signature for assertEQ(int, int, int) */ -/* @@@ label2 Error TypeError: Type 'int' is not compatible with type 'String|undefined' at index 3 */ \ No newline at end of file +/* @@@ label1 Error TypeError: No matching call signature for assertEQ(Int, Int, Int) */ +/* @@@ label2 Error TypeError: Type 'Int' is not compatible with type 'String|undefined' at index 3 */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/async_import_3.ets b/ets2panda/test/ast/compiler/ets/async_import_3.ets index 3622080a97b6f74692ea817eba28510819d18ae2..165c0f7649eae9371dcacc8dcc7727cab09fdee8 100644 --- a/ets2panda/test/ast/compiler/ets/async_import_3.ets +++ b/ets2panda/test/ast/compiler/ets/async_import_3.ets @@ -16,4 +16,4 @@ import {foo} from './async_import_4' let prop: int = foo() /* @@? 16:17 Error TypeError: Cannot use type 'void' as value. */ -/* @@? 16:17 Error TypeError: Type 'void' cannot be assigned to type 'int' */ \ No newline at end of file +/* @@? 16:17 Error TypeError: Type 'void' cannot be assigned to type 'Int' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts b/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts new file mode 100644 index 0000000000000000000000000000000000000000..8e8a1ea0ffc5814e408e89f0d656a682d3a06159 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +class A { + func(a: Double): String { return a.toExponential() } + func(a: Float): String { return a.toString() } + func(a: Int): String { return a.toString() } +} + +function main(): int{ + let c1: A = new A(); + let helpbyte: Byte = new Byte(1 as byte); + let helpdouble: Double = new Double(1 as double); + if (c1.func(helpbyte) != helpdouble.toExponential()) { + return 1; + } + return 0; +} diff --git a/ets2panda/test/ast/compiler/ets/boxingConversion1.ets b/ets2panda/test/ast/compiler/ets/boxingConversion1.ets index c4d703e4a25f9c17408d978147e9471016b71002..668502185abecff66deaa89bf2203e9d1d7153f7 100644 --- a/ets2panda/test/ast/compiler/ets/boxingConversion1.ets +++ b/ets2panda/test/ast/compiler/ets/boxingConversion1.ets @@ -18,4 +18,4 @@ function main() : void { let b: Byte = /* @@ label */new Byte(2); } -/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(int) */ +/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/boxingConversion4.ets b/ets2panda/test/ast/compiler/ets/boxingConversion4.ets index 219921314be7d2169d4de6cd525622a94fefc1ed..b26c8b8c527ab08929ea315ad36867a56075c86e 100644 --- a/ets2panda/test/ast/compiler/ets/boxingConversion4.ets +++ b/ets2panda/test/ast/compiler/ets/boxingConversion4.ets @@ -23,6 +23,6 @@ function main() : void { refInt(b); // primitive widening before boxing is not allowed } -/* @@@ label Error TypeError: No matching construct signature for std.core.Short(int) */ -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'short' */ -/* @@@ label2 Error TypeError: Type 'int' cannot be assigned to type 'short' */ +/* @@@ label Error TypeError: No matching construct signature for std.core.Short(Int) */ +/* @@@ label1 Error TypeError: Type 'Int' cannot be assigned to type 'Short' */ +/* @@@ label2 Error TypeError: Type 'Int' cannot be assigned to type 'Short' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets index a19a44352a9b97470e54b0e29138dd7b7a820c82..020e690781cad37f9ee3954729d88aa5b5e983f7 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets @@ -16,5 +16,3 @@ function foo(data : T): void { let aNumber = data! as boolean } - -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'boolean' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets index 1494ec034e28b737cb68cf2e9e2772e311199b33..e2f0327a04c916b5f01c617504dd08287e2bc03f 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets @@ -16,5 +16,3 @@ function foo(data : T): void { let aNumber = data! as int } - -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets index 5a6a68e66b7c31b4e376dbbab0378a25f9d79314..235ac7461a87ed860eafc57c6d261daa1fb660f1 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data! as number } -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'double' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets index a2c9561af576d18dc9f67b5e5f92b31b833c3c11..41fa96e0b972a191ce8db252290a426c280b41c9 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as boolean } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'boolean' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets index 6ee459478d6d679d26a1834fc0e28f66f459cd78..7b3d28faf85ba08dffa8d0e7a8fb5954f05c6f54 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as int } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets index c07d310c30a64138cfb17f83c8636b1ef76d12fb..89bcb6c6108a830fdd17aa960d456abd5f72fd1f 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as number } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'double' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets index 55d610c6b96cddc9cb45e7ff00c4a90840e28f8a..252c90bce1427f95a690d4bb686dca65fce17d19 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets @@ -16,5 +16,3 @@ function foo(data: T | boolean | null): void { let aNumber = data as int } - -/* @@? 17:19 Error TypeError: Cannot cast type 'T|Boolean|null' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets index 8a088bee5ffdea20255fe087f585bc844f24d7b1..54003819499bc62708314cd182cc3a466368a103 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets @@ -19,4 +19,3 @@ function foo(data: T | A): void { let aNumber = data as int } -/* @@? 19:19 Error TypeError: Cannot cast type 'T|A' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets index 5c261ef099dd9793dfd3be7acc127129f1660f26..9c91b473e799738e44f425bcd1ca2e50d93b66f2 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets @@ -18,4 +18,3 @@ function foo(data: T, x: boolean): void { let aNumber = data2 as int } -/* @@? 18:19 Error TypeError: Cannot cast type 'Boolean|NonNullable' to 'int' */ diff --git a/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets b/ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts similarity index 58% rename from ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets rename to ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts index 4d96d8de990f08633df87a01c1b9fcc6dfd9fa67..5e498766bb73978cda16393b6fcfb83649ac44ee 100644 --- a/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets +++ b/ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * 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 @@ -13,9 +13,23 @@ * limitations under the License. */ -function main(): void { - let c:char = c'X'; - let s:string = c; +class A {} - assertEQ(s, "X") -} \ No newline at end of file +function foo(a: Float): Float { + return a; +} + +function main(): int { + let c: A | Double = new Double(10.0 as double); + let b: Int = new Int(9 as int); + c = b + if (c != 9) { + return 1; + } + let k: Int = new Int(10 as int); + let v: Float = foo(k) + if (v.isNaN()) { + return 1; + } + return 0; +} diff --git a/ets2panda/test/ast/compiler/ets/circular_variable_init.ets b/ets2panda/test/ast/compiler/ets/circular_variable_init.ets index af59760eb594df83e7d67056e00a8ef05a348a7c..fc6881da7f2ee8bf16964c5c552197dffa291df7 100644 --- a/ets2panda/test/ast/compiler/ets/circular_variable_init.ets +++ b/ets2panda/test/ast/compiler/ets/circular_variable_init.ets @@ -47,7 +47,7 @@ function main() { /* @@? 23:19 Error TypeError: Circular dependency detected for identifier: b */ /* @@? 31:15 Error TypeError: Unresolved reference globalb */ /* @@? 33:5 Error TypeError: Circular dependency detected for identifier: globalc */ -/* @@? 37:7 Error TypeError: Circular dependency detected for identifier: constb */ +/* @@? 36:7 Error TypeError: Circular dependency detected for identifier: consta */ /* @@? 40:17 Error TypeError: Unresolved reference mainb */ /* @@? 42:17 Error TypeError: Variable 'maind' is accessed before it's initialization. */ /* @@? 43:9 Error TypeError: Circular dependency detected for identifier: maind */ diff --git a/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets b/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets index 8be10405f5a6463214649ab42f76f5b50545568b..49d13737727d30b8999a7433f098dc98006b333c 100644 --- a/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets +++ b/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets @@ -17,9 +17,7 @@ function foo(x: Double) {} function main(): void { let a : Int = new Int(2); - /* @@ label */foo(/* @@ label1 */a); + foo(a); return; } -/* @@@ label1 Error TypeError: Type 'Int' is not compatible with type 'Double' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/division-by-zero.ets b/ets2panda/test/ast/compiler/ets/division-by-zero.ets new file mode 100644 index 0000000000000000000000000000000000000000..85b5646d7379a7b59dfce0302410fec31e18c792 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/division-by-zero.ets @@ -0,0 +1,26 @@ +/* + * 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. + */ + +function main() : void { + let div_int : int = /* @@ label1 */1 / 0; + let div_long: long = /* @@ label2 */1 / 0; + let mod_int : int = /* @@ label3 */1 % 0; + let mod_long: long = /* @@ label4 */1 % 0; +} + +/* @@@ label1 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label2 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label3 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label4 Error SyntaxError: Division by zero is not allowed. */ diff --git a/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets b/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets index ace31b83f7dc7eeafb143d67e0ae082d75b6e275..1100d5c9d1088a68e7882e9905d32e1ec9bb46bf 100644 --- a/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets +++ b/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets @@ -20,4 +20,4 @@ let a: int = /* @@ label */E.FIRST - /* @@@ label Error TypeError: Type 'long' cannot be assigned to type 'int' */ \ No newline at end of file + /* @@@ label Error TypeError: Type 'Long' cannot be assigned to type 'Int' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets b/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets index b7deb047d7dd4c8f59c3a772c07c0fb3e3e0cc33..dda6ea9f3c09ebf10634c94fc704a58e86c59375 100644 --- a/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets +++ b/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets @@ -20,5 +20,4 @@ enum Color { Red = /* @@ label */b, } -/* @@@ label Error SyntaxError: Only constant expression is expected in the field */ /* @@@ label Error SyntaxError: Invalid enum initialization value */ diff --git a/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets b/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets index a04bb52e2b0fa9094531ab65ceafca4b9340460f..724f1b214d7440fb7cb51be7ce9d6102d2e0641b 100644 --- a/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets +++ b/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets @@ -20,4 +20,4 @@ function test(): int{ return /* @@ label */a; } -/* @@@ label Error TypeError: Type 'A|null' is not compatible with the enclosing method's return type 'int' */ +/* @@@ label Error TypeError: Type 'A|null' is not compatible with the enclosing method's return type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets b/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets index e5873018c872a9f1a2c8afdffb4fac0bd273c62d..d46422e571e83bd1d6a6a6335152a6ef889af3e1 100644 --- a/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets +++ b/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets @@ -17,4 +17,4 @@ class A{} let f: (() => int) | null = /* @@ label */5; -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => Int|null' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => Int|null' */ diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets index df828b5b4043b7892e177c270a41cb4d075cbf85..c97f4b9e8bd55821c387088c424708f347e28755 100644 --- a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets +++ b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets @@ -20,14 +20,13 @@ class B { function name(b: B) {} function name(b: B, n: string) {} -get name/* @@ label1 */(this: B): string { - return this.name_; +get name(this: B): string { + return this.name_; } -set name/* @@ label2 */(this: B, n: string) { +set name/* @@ label */(this: B, n: string) { this.name_ = n; } -/* @@@ label1 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets index df828b5b4043b7892e177c270a41cb4d075cbf85..c97f4b9e8bd55821c387088c424708f347e28755 100644 --- a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets +++ b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets @@ -20,14 +20,13 @@ class B { function name(b: B) {} function name(b: B, n: string) {} -get name/* @@ label1 */(this: B): string { - return this.name_; +get name(this: B): string { + return this.name_; } -set name/* @@ label2 */(this: B, n: string) { +set name/* @@ label */(this: B, n: string) { this.name_ = n; } -/* @@@ label1 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets index c3060b1928af65d338bcbc7cf40031eb5bdff8ca..6e0fe6102ba6c100c9cc404be687b10ab0229f5a 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets @@ -28,5 +28,5 @@ function main() { console.println(banana.name()); } -/* @@@ label Error TypeError: Signature price(): int is not visible here. */ +/* @@@ label Error TypeError: Signature price(): Int is not visible here. */ /* @@@ label Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets index 4ce3aa69d463542459e921bbb5c5f6aecacd63a6..a122118882e188f6d8596e77c56d2f396a230611 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets @@ -28,4 +28,4 @@ function main() { console.println(/* @@label */banana.name(2)); } -/* @@? 28:34 Error TypeError: No matching call signature for name(int) */ +/* @@@ label Error TypeError: No matching call signature for name(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets index e35530840d96f946bc7d373a46feb7c8434035d7..2e8df50de75c6d2e9be2a1cf3f35aeb6928983a3 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets @@ -39,6 +39,6 @@ function main() { asMethodCall(); } -/* @@? 30:5 Error TypeError: Expected 2 arguments, got 3. */ -/* @@? 30:5 Error TypeError: No matching call signature for foo(Fruit, double, double) */ -/* @@? 34:5 Error TypeError: No matching call signature for foo(double, double) */ +/* @@? 30:5 Error TypeError: Expected 2 arguments, got 3. */ +/* @@? 30:5 Error TypeError: No matching call signature for foo(Fruit, Double, Double) */ +/* @@? 34:5 Error TypeError: No matching call signature for foo(Double, Double) */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets index b41dbe9f8833c9924f26be2313e38262baa0cc7a..1c4439bcc7136a7c2c98de302d7c8cc9dc7e5163 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets @@ -21,4 +21,4 @@ function foo(this: B): this { return /* @@ label */2; } -/* @@@ label Error TypeError: Type 'int' is not compatible with the enclosing method's return type 'B' */ +/* @@@ label Error TypeError: Type 'Int' is not compatible with the enclosing method's return type 'B' */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets index fe797887873ce85ba7de91ee18cbc6ee819e44c7..11b245f328fa6e74d25d02acdd8746d4cf4c3955 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets @@ -22,4 +22,4 @@ function main(): void { let b : Person ={name: /* @@ label */42, age:25} } -/* @@@ label Error TypeError: Type 'int' is not compatible with type 'String' at property 'name' */ +/* @@@ label Error TypeError: Type 'Int' is not compatible with type 'String' at property 'name' */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets index 0980e0579ba368eb9be5e1ac7995fe9961c1e318..d12d67284b5a12d1a2967e8f79e05e205b429e4e 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets @@ -22,4 +22,4 @@ function main(): void { let b : Person/* @@ label */ ={name: "John", age:25} } -/* @@@ label Error TypeError: Type String is not assignable to constraint type Double */ +/* @@@ label Error TypeError: Type argument 'String' should be a subtype of 'Double'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets index 87ee60730287f0902ae428f4b178c1aac889bccb..fd7eed0b9edf505a81a665ea8fc1c3afe705f05a 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets @@ -22,5 +22,5 @@ function main(): void { let b : Person/* @@ label */ ={name: "John", age:/* @@ label1 */"25"} } -/* @@@ label Error TypeError: Type Double is not assignable to constraint type String */ +/* @@@ label Error TypeError: Type argument 'Double' should be a subtype of 'String'-constraint */ /* @@@ label1 Error TypeError: Type '"25"' is not compatible with type 'Double' at property 'age' */ diff --git a/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets b/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets index 0bfcb0ae7dd31fcedea54ed66fa937048425b6f7..1905464507069943fd44d75f80a28c7a7da25588 100644 --- a/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets +++ b/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets @@ -22,4 +22,4 @@ function main(): void { let a: A/* @@ label */; } -/* @@@ label Error TypeError: Type B is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'B' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets b/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets index a698d21b0fa19b52b8012fdb1aeb4edb5b711937..c8f046fedf8411f27f2f55d2a9fb84bad6e45592 100644 --- a/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets @@ -22,10 +22,9 @@ function main(): void { let prim_int = 5; switch(prim_int) { - /* @@ label */case /* @@ label1 */a_int.value: // not allowed, because type of a_int.value is Int + /* @@ label */case a_int.value: // not allowed, because type of a_int.value is Int default: } } -/* @@@ label1 Error TypeError: Switch case type 'Int' is not comparable to discriminant type 'int' */ /* @@@ label Error TypeError: Constant expression required */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference10.ets b/ets2panda/test/ast/compiler/ets/identifierReference10.ets index 161213981bb7ab32be097777858635d1a9b5c791..bb75765d532f7330f56161213ea840dcb21813f6 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference10.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference10.ets @@ -25,4 +25,4 @@ class A { } } -/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference12.ets b/ets2panda/test/ast/compiler/ets/identifierReference12.ets index 6b2358f878ef0c8020a48837ffe553f27b708016..1c34cf4214e39791ff58b24b218d0d53505ab981 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference12.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference12.ets @@ -25,4 +25,4 @@ class A { } } -/* @@@ label Error TypeError: Type 'int' has no call signatures. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference16.ets b/ets2panda/test/ast/compiler/ets/identifierReference16.ets index e21f0887722ff83679eca47a24b8b8caf2f7e723..aefc534f96224ee5e6560910e73b0cef63d5c7c9 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference16.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference16.ets @@ -45,4 +45,4 @@ class A extends B { /* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 41:7 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? 41:7 Error TypeError: No matching call signature for foo(int) */ +/* @@? 41:7 Error TypeError: No matching call signature for foo(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference3.ets b/ets2panda/test/ast/compiler/ets/identifierReference3.ets index 69a7d28c11d4a40dbed37eab95dda9c02a43149b..ddc353921b26c4b613eb7e4677dcf07b414af3f2 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference3.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference3.ets @@ -21,4 +21,4 @@ class A { } } -/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference9.ets b/ets2panda/test/ast/compiler/ets/identifierReference9.ets index 6303c2f318f1df4bd9ea6a3020e59c8681495476..006fc0197dbf87ac079541132e0dd7e22a2993ed 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference9.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference9.ets @@ -25,4 +25,4 @@ class A { } } -/* @@? 24:16 Error TypeError: Type 'int' cannot be assigned to type '() => void' */ +/* @@? 24:16 Error TypeError: Type 'Int' cannot be assigned to type '() => void' */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets index 35ac4831a4aedc21cb17de54bba5340f14cff376..810b288169035ab9584040656568878648fc8849 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets @@ -17,4 +17,4 @@ package mypackage; let myvar: number = exist_but_checker_fails_in_file; -/* @@? package_module_2.ets:19:39 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? package_module_2.ets:19:39 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets index ba854d07c801ed57c2fca81c2b95aa8d9874e75b..cf77170f19624360a6ea8102c4ef4e8bf55f7595 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets @@ -18,4 +18,4 @@ package mypackage; let exist_but_checker_fails_in_file: number = 8; let wong_type: string = /* @@ label */9; -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets index 3fb40e5499f04745e1abc7cdb7275d45ede07b2c..e5cd10f675b64d8c7bbd22776be880981a68db42 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets @@ -17,7 +17,7 @@ package mypack; // That is the main file, from which we will compile full package -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets index efd03230be271fcb0431b3f7f847392cbb76754d..f4149768badc83d9a50a26cee7d2d602a0b8e71e 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets @@ -17,7 +17,7 @@ package mypack; let a: int = "I am a number, I promise..."; -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets index 16e73a014394b9e71b3923d0790b6742f5b9ee17..fd775ce3a110fe1299b77d548e8d9ea43ed39e6e 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets @@ -17,7 +17,7 @@ package mypack; =) -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets index e7896830c2c3bc05921d438c4d58098021b8111e..77699feb8752ad6a20eb11040b0810fb7047eaae 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets @@ -21,7 +21,7 @@ function foo(): Day { return new good Day(); } -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets index c53d4298efae98c7136ec7b2427bad3fe3170442..6c96c0deea4ca2fff8a542b1d86c4edee87c1b92 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets @@ -24,9 +24,9 @@ export class A { let 1: number // First level import with both types of error -/* @@? import_1.ets:21:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_1.ets:21:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_1.ets:24:5 Error SyntaxError: Identifier expected, got 'number literal'. */ // Second level import import with both types of error -/* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_2.ets:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets index 5cfa82f173e8067a554b60b304d03177c9094e0f..ee8446260e75c7c6d73cc7f816f3d11732d0e132 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets @@ -20,7 +20,7 @@ export class B { var not_ok = false // Second level import import with both types of error -/* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_2.ets:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_2.ets:20:1 Error TypeError: Unresolved reference var */ /* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ /* @@? import_2.ets:20:5 Error TypeError: Unresolved reference not_ok */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets index a516db733330db00fc8e4f815b46dc13be2cbbfa..b3b38186ec69a4ad9efa7ff69b6cadfd4f18d4f4 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets @@ -18,15 +18,15 @@ import {A, B} from "./import_1.ets" let b = new B(10); // First level import with both types of error -/* @@? import_1.ets:21:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_1.ets:21:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_1.ets:24:5 Error SyntaxError: Identifier expected, got 'number literal'. */ // Second level import import with both types of error -/* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_2.ets:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ // Error in main file based on class from the most distant file /* @@? master_file.ets:18:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(int) */ +/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(Int) */ /* @@? master_file.ets:18:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(int) */ \ No newline at end of file +/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(Int) */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets b/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets index 821efecc9a7377a833f7cce6341c335aa3e8ccf2..2d98d9ee7385433f95468e8a97a7baa2c363327d 100644 --- a/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets +++ b/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets @@ -13,9 +13,12 @@ * limitations under the License. */ -export const floatInf: float = 1.0 / 0.0 +export const floatInf: float = /* @@ label2 */1.0 / 0.0 export const byteInf: byte = /* @@ label */1.0 / 0.0 export const shortInf: short = /* @@ label1 */1.0 / 0.0 -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'byte' */ -/* @@@ label1 Error TypeError: Type 'double' cannot be assigned to type 'short' */ +/* @@@ label Error TypeError: Type 'Double' cannot be assigned to type 'Byte' */ +/* @@@ label1 Error TypeError: Type 'Double' cannot be assigned to type 'Short' */ +/* @@@ label2 Error TypeError: Floating-point value cannot be converted */ +/* @@@ label1 Error TypeError: Floating-point value cannot be converted */ +/* @@@ label Error TypeError: Floating-point value cannot be converted */ diff --git a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets index 8615346ac52905f297cd38609556912d987fbc88..ee01f2ea072263be5959fe0d71797ecf70690cd1 100644 --- a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets +++ b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets @@ -34,5 +34,5 @@ function main(): void { assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class C, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets index f9dca621954df878d50e2c74d44fed6eb06ddf5f..7fdc5051d5e1890e9e9428d9d14e7f97d0c99353 100644 --- a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets +++ b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets @@ -34,5 +34,5 @@ function main(): void { assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class C, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets index 0569baa08c6615248693cf6056dcee7abac36f4e..1e78d0e9b20495d7a7a8db58255cd2789dfbcde3 100644 --- a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets +++ b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets @@ -30,5 +30,5 @@ function main(): void { let instance: B = new B(); assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class A, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets index f06ab002a2367dcffcc54d02d60bab06a2738654..781569a6a1f8fcb2ebcdbbe63daa66201b2bf121 100644 --- a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets +++ b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets @@ -30,5 +30,5 @@ function main(): void { let instance: B = new B(); assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from interface A because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets b/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets index b9c050c4e869727ed02a74c64eb4d352a44a491c..30a62660c775183180d4244cbeb030778b1cd7f3 100644 --- a/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets +++ b/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets @@ -22,4 +22,4 @@ function main(): void { test1() } -/* @@@ label Error TypeError: Type 'String' is not compatible with the enclosing method's return type 'int' */ +/* @@@ label Error TypeError: Type 'String' is not compatible with the enclosing method's return type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets b/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets index bfd45ae78cc38b365c4b92910655798dd3185a9c..259a8abf16d35b4d2d56f106a8c277beee8cf59c 100644 --- a/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets +++ b/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets @@ -36,4 +36,4 @@ function main(): void { } /* @@@ label1 Error TypeError: Type '"foo"' is not compatible with type 'Int' at index 2 */ -/* @@@ label Error TypeError: No matching call signature for (int, "foo") */ +/* @@@ label Error TypeError: No matching call signature for (Int, "foo") */ diff --git a/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets b/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets index 0f6a071170465cd24d97af4a831c43a19eee7a7f..b1c80e1dbeaec4098d478db5ac9fcdb4f5251463 100644 --- a/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets +++ b/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets @@ -42,4 +42,4 @@ function main(): int { let asd5: double = /* @@ label */foo(new A(), 2.1); return 0; } -/* @@@ label Error TypeError: Call to `foo` is ambiguous as `2` versions of `foo` are available: `foo(a: J, d: double): double` and `foo(a: I, d: double): double` */ +/* @@@ label Error TypeError: Call to `foo` is ambiguous as `2` versions of `foo` are available: `foo(a: J, d: Double): Double` and `foo(a: I, d: Double): Double` */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets index c81755739a2c0f0ced224c74ede4f029d0bbc986..0b828cc1314b15196cbd5d573b50bf5d370f12f3 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets @@ -24,6 +24,6 @@ Space1.foo(); // CTE Space1.foo(1234); //ok /* @@? 19:31 Error TypeError: Property 'constant' does not exist on type 'Space2' */ -/* @@? 20:23 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 20:23 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? 23:1 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 23:1 Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets index 713dbc66bc9ac5473222676835646d607b26c10c..89f6b4e6767cf39c411f58affdcda7919e680fb0 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets @@ -19,6 +19,4 @@ namespace MySpace { let a = 1 instanceof MySpace /* @@? 19:22 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ -/* @@? 19:22 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ \ No newline at end of file +/* @@? 19:22 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets b/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets index 44c12cb3bffe1d9b4d029a7ffeebb3451f0c41df..f703cbe4a9c5718c98a5d38183461f39dc2ac0a0 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets @@ -14,4 +14,4 @@ */ let x: int = /* @@ label */{}; -/* @@@ label Error TypeError: Target type for class composite needs to be an object type, found 'int' */ + diff --git a/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets b/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets index 38d5711cf96154af6a75ee1327a63ab41c2b5260..ce025f5c2a5a4a6e93340741f3af53e9fef5650d 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets @@ -21,4 +21,4 @@ let c: C = { f: /* @@ label */"ouch" }; -/* @@@ label Error TypeError: Type '"ouch"' is not compatible with type 'int' at property 'f' */ +/* @@@ label Error TypeError: Type '"ouch"' is not compatible with type 'Int' at property 'f' */ diff --git a/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets b/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets index 80d6e714825665db3d72c9b4b4851f9f82c88e76..ef3b7fd38fb0ff5a69ebe99fb3f814b5b6b0f199 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets @@ -40,6 +40,6 @@ function main(){ /* @@@ label Error TypeError: type C has no property named field3 */ /* @@@ label2 Error TypeError: Property field2 is not visible here. */ -/* @@@ label3 Error TypeError: Type '"some str"' is not compatible with type 'double' at property 'field1' */ +/* @@@ label3 Error TypeError: Type '"some str"' is not compatible with type 'Double' at property 'field1' */ /* @@@ label4 Error TypeError: type C2 has no parameterless constructor */ /* @@@ label5 Error TypeError: Signature constructor(): void is not visible here. */ diff --git a/ets2panda/test/ast/compiler/ets/override11.ets b/ets2panda/test/ast/compiler/ets/override11.ets index 1bf873cd54dd7cadd8c96116ead55c9d39df338f..2c43199671770c0c92a925404dcaadf1c5a81391 100644 --- a/ets2panda/test/ast/compiler/ets/override11.ets +++ b/ets2panda/test/ast/compiler/ets/override11.ets @@ -21,5 +21,5 @@ class B extends A { override fn(t: int): void { } } -/* @@? 21:14 Error TypeError: fn(t: int): void in B cannot override fn(t: int): int in A because overriding return type is not compatible with the other return type. */ -/* @@? 21:14 Error TypeError: Method fn(t: int): void in B not overriding any method */ +/* @@? 21:14 Error TypeError: fn(t: Int): void in B cannot override fn(t: Int): Int in A because overriding return type is not compatible with the other return type. */ +/* @@? 21:14 Error TypeError: Method fn(t: Int): void in B not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override14.ets b/ets2panda/test/ast/compiler/ets/override14.ets index 70cdd59cb77830507fafcba59c7d836531202371..59bca85ba3f6ab192075b05d734a1999a33027dd 100644 --- a/ets2panda/test/ast/compiler/ets/override14.ets +++ b/ets2panda/test/ast/compiler/ets/override14.ets @@ -21,5 +21,3 @@ class B extends A { override fn(t: Object): int { return 1} } -/* @@? 21:14 Error TypeError: fn(t: Object): int in B cannot override fn(t: T): T in A because overriding return type is not compatible with the other return type. */ -/* @@? 21:14 Error TypeError: Method fn(t: Object): int in B not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override15.ets b/ets2panda/test/ast/compiler/ets/override15.ets index 3a910c970c95ae22a019e3a26af8bfdf97aff625..22632b2eefe39396421bc6e471e28c352943348a 100644 --- a/ets2panda/test/ast/compiler/ets/override15.ets +++ b/ets2panda/test/ast/compiler/ets/override15.ets @@ -21,5 +21,5 @@ interface I2 extends I { fn(): float; } -/* @@? 21:5 Error TypeError: fn(): float in I2 cannot override fn(): int in I because overriding return type is not compatible with the other return type. */ -/* @@? 21:5 Error TypeError: Method fn(): float in I2 not overriding any method */ +/* @@? 21:5 Error TypeError: fn(): Float in I2 cannot override fn(): Int in I because overriding return type is not compatible with the other return type. */ +/* @@? 21:5 Error TypeError: Method fn(): Float in I2 not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override3.ets b/ets2panda/test/ast/compiler/ets/override3.ets index 0ed1c28b81f399efb8de88e06aeb83f5d1a92341..4031d36c0c90fcfbd6bf048a257250c9ab2888bd 100644 --- a/ets2panda/test/ast/compiler/ets/override3.ets +++ b/ets2panda/test/ast/compiler/ets/override3.ets @@ -17,5 +17,5 @@ interface I { toString(): int; } -/* @@? 17:11 Error TypeError: toString(): int in I cannot override toString(): String in Object because overriding return type is not compatible with the other return type. */ -/* @@? 17:11 Error TypeError: Method toString(): int in I not overriding any method */ +/* @@? 17:11 Error TypeError: toString(): Int in I cannot override toString(): String in Object because overriding return type is not compatible with the other return type. */ +/* @@? 17:11 Error TypeError: Method toString(): Int in I not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override7.ets b/ets2panda/test/ast/compiler/ets/override7.ets index 18900c1e849fef6fd0a098432c8ca20f446ea9cd..aca0ae3a32e7e578d50010e0b04addd4007e5a06 100644 --- a/ets2panda/test/ast/compiler/ets/override7.ets +++ b/ets2panda/test/ast/compiler/ets/override7.ets @@ -23,5 +23,5 @@ abstract class A implements I { public override fn(): int { return 1; } } -/* @@? 23:21 Error TypeError: fn(): int in A cannot override fn(): void in J because overriding return type is not compatible with the other return type. */ -/* @@? 23:21 Error TypeError: Method fn(): int in A not overriding any method */ +/* @@? 23:21 Error TypeError: fn(): Int in A cannot override fn(): void in J because overriding return type is not compatible with the other return type. */ +/* @@? 23:21 Error TypeError: Method fn(): Int in A not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets b/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets index 268606ee2e4db44ac8ff580a7f6fc8734341c184..abc1ea45628fd526592f8b87fcab27054610bdc4 100644 --- a/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets +++ b/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets @@ -25,4 +25,4 @@ class B { } } -/* @@@ label Error TypeError: Method foo(a: int): int in B not overriding any method */ +/* @@@ label Error TypeError: Method foo(a: Int): Int in B not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets b/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets index a7d08982f99179aec3d858b0365e2ebbf182124d..f2f1b08aa92063a310383baee9819bff4879b4e3 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets @@ -17,6 +17,6 @@ class A>>{} class C extends A/* @@ label1 */>{} /* A does not satisfy the constraint due to invariance of T */ -/* @@@ label Error TypeError: Type A is not assignable to constraint type A>> */ -/* @@@ label2 Error TypeError: Type C is not assignable to constraint type A> */ -/* @@@ label1 Error TypeError: Type A is not assignable to constraint type A>> */ +/* @@@ label Error TypeError: Type argument 'A' should be a subtype of 'A>>'-constraint */ +/* @@@ label2 Error TypeError: Type argument 'C' should be a subtype of 'A>'-constraint */ +/* @@@ label1 Error TypeError: Type argument 'A' should be a subtype of 'A>>'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets index 7bfe478c3052a4383c4a6b0fdc2b275eafdc02a8..9ee831177ac4d9cc1e1fbde7792d3e0a99f5ebd2 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets @@ -16,4 +16,4 @@ interface A>{} interface D{} interface B extends A/* @@ label */{} -/* @@@ label Error TypeError: Type D is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'D' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets index fb2f2817251f84371fef51ccd6edd50fa7c9474d..3596a49b970eaec3a724466ce519c6cc4d5c71fe 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets @@ -16,4 +16,4 @@ interface A,T2 extends A>{} interface D{} interface B extends A/* @@ label */{} -/* @@@ label Error TypeError: Type D is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'D' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets b/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets index 7a588b42f8c787d6e69d060965d2240e8848ea4e..0238b2626c749d6cb6993a98133fbe35cb83284b 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets @@ -19,4 +19,4 @@ class T

{} class C extends A/* @@ label */{} /* Constraint: B|D|C <: A, but B is not a subtype of A due to T invariance */ -/* @@@ label Error TypeError: Type B|D|C is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'B|D|C' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets index df5bce8676bbda21e4beda0551d0cf1d2ed441cf..78955a8122d25381b13e00dff486923743aa5f66 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets @@ -15,8 +15,7 @@ //declare function has body export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number {} -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ /* @@? 19:49 Error TypeError: Native, Abstract and Declare methods cannot have body. */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets index 227dab0f7806e557ef85546174370040f5639a37..27671485ba3f5d7637c94c0fb5767e439e97f762 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets @@ -15,7 +15,7 @@ //Not support non-declare function has same assembly code export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export function foo(a:A):number {} -/* @@? 19:8 Error TypeError: Function foo with this assembly signature already declared. */ \ No newline at end of file +/* @@? 19:17 Error TypeError: Function with a non void return type must return a value. */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets index 5440079d8e17649250390fdf6c3c8db80df59082..31d4512f58cc0790abb82bced518c32002048c24 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets @@ -15,10 +15,7 @@ //Without rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets index 9900d58e0c497eec7288b26465a4912f6b63cd88..a35dbbffd63dcc6dd1ef28d70e06f18682ae5a91 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets @@ -15,11 +15,8 @@ //With rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void export declare function foo(...args:string[]):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets b/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets index 116c419830283712211b242d46bfa09c3bf3e2e1..9f1621021f948ea7c4cf235f9d49736a5ad8d74e 100644 --- a/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets +++ b/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets @@ -22,13 +22,13 @@ class IndexStr { indexField: string = "title" foo() { switch (this.indexField) { - /* @@ label */case IndexField.TITLE: + case IndexField.TITLE: assertEQ(this.indexField, IndexField.TITLE) break; - case IndexField.TITLE: + /* @@ label */case IndexField.TITLE: assertEQ(this.indexField, IndexField.TITLE) } } } -/* @@@ label Error TypeError: Variable has same value with another switch case */ \ No newline at end of file +/* @@@ label Error TypeError: Case duplicate */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets index d874643b8fda8e8ee67c8107849ba96862e381f3..b03095bb29c8f63584f53ab314ea686c0139ae6b 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets @@ -19,4 +19,4 @@ function main(): void { let b: [number, number, number] = /* @@ label */a; } -/* @@@ label Error TypeError: Type '[double, double]' cannot be assigned to type '[double, double, double]' */ +/* @@@ label Error TypeError: Type '[Double, Double]' cannot be assigned to type '[Double, Double, Double]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets index 5c6ff60feaf69b0d7667706807265a3547ebcb1d..b6a37f7126cb07e239ba9a58b735f2b9fe0e6b4b 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets @@ -19,4 +19,4 @@ function main(): void { let b: [number, number] = /* @@ label */a; } -/* @@@ label Error TypeError: Type '[double, double, double]' cannot be assigned to type '[double, double]' */ +/* @@@ label Error TypeError: Type '[Double, Double, Double]' cannot be assigned to type '[Double, Double]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets index 55c0a6e370ab4f429b1abf49c52bd226c2291929..ea8e9d99a571a33951a62d101b72f40b3ca9978b 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets @@ -18,4 +18,4 @@ function main(): void { const array: (number|boolean) [] = tuple } -/* @@? 18:40 Error TypeError: Type '[double, double, boolean]' cannot be assigned to type 'Array' */ +/* @@? 18:40 Error TypeError: Type '[Double, Double, Boolean]' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets index 7f792a64d5403a11eb9a37a030c7c38777304655..0d723e75d437c8cbc73f88bde06c830465eca726 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets @@ -16,7 +16,6 @@ function main(): void { let a: [number] = [1]; - let b: [Number] = /* @@ label */a; + let b: [Number] = a; } -/* @@@ label Error TypeError: Type '[double]' cannot be assigned to type '[Double]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets index 44d8b2071e01f6987b256e9f0491e2f25d55ba8d..3bf4b2c6e5d981f14819bb287039ca779cc66d66 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets @@ -28,4 +28,4 @@ function main(): void { /* @@? 18:37 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:37 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:39 Error SyntaxError: Unexpected token '='. */ -/* @@? 19:50 Error TypeError: Type '[double, String, *ERROR_TYPE*]' cannot be assigned to type '[double, String, Int]' */ +/* @@@ label Error TypeError: Type '[Double, String, *ERROR_TYPE*]' cannot be assigned to type '[Double, String, Int]' */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets b/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets index 7e42c8c105bf2b5241abc90fbd791e8fbf2f671c..f3cc9e64c33dc67868eca46d1e389b42f69e6568 100644 --- a/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets @@ -40,14 +40,11 @@ type T15 = Required /* @@? 22:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ /* @@? 24:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ /* @@? 25:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ -/* @@? 26:18 Error TypeError: Only reference types can be converted to utility types. */ /* @@? 28:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ /* @@? 30:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ /* @@? 31:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ -/* @@? 32:20 Error TypeError: Only reference types can be converted to utility types. */ /* @@? 34:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ /* @@? 36:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ /* @@? 37:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ -/* @@? 38:20 Error TypeError: Only reference types can be converted to utility types. */ diff --git a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets index 61acb173f6c4f7637e2e3033e6e6cbf5fa815909..1563fd56e4aea8912774f88840de5d357931aa4a 100644 --- a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets +++ b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets @@ -17,4 +17,4 @@ function main() : void { let a: Byte = /* @@ label */new Byte(2); } -/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(int) */ +/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets index 2727c5fe2cd30fa543645706d3ee1ce8aae15318..38e048b38296eb026468c164de78440f92ff009f 100644 --- a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets +++ b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets @@ -17,4 +17,4 @@ function main() : void { let e: Float = /* @@ label */new Float(6,"3"); } -/* @@@ label Error TypeError: No matching construct signature for std.core.Float(int, "3") */ +/* @@@ label Error TypeError: No matching construct signature for std.core.Float(Int, "3") */ diff --git a/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets b/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets index 14947fde7e913d4efb9ed5c7b9ebf9620d63b70b..37e9904ba69f70fb502942607b007edc6bc8d4cc 100644 --- a/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets +++ b/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets @@ -22,4 +22,4 @@ function main(): void { /* @@? 20:3 Error TypeError: No matching call signature for assertTrue(void) */ /* @@? 20:23 Error TypeError: Cannot use type 'void' as value. */ -/* @@? 20:23 Error TypeError: Type 'void' is not compatible with type 'boolean' at index 1 */ \ No newline at end of file +/* @@? 20:23 Error TypeError: Type 'void' is not compatible with type 'Boolean' at index 1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets index 76ed96a9dbab145115f8603718f98c3f9cfa11bf..bbd4601ec722a3c1ba39ffaf9faac4413851c5c0 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets @@ -122,15 +122,10 @@ function main(): void { a.run(); } -/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 18:18 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 19:22 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 21:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 22:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 23:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ @@ -150,6 +145,7 @@ function main(): void { /* @@? 37:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 38:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 39:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ +/* @@? 41:26 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 47:13 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:21 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:28 Error TypeError: Static property 'A' must be accessed through it's class 'Random' */ @@ -157,30 +153,30 @@ function main(): void { /* @@? 47:37 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ /* @@? 48:26 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 48:33 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ +/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 53:27 Error TypeError: Type 'null' cannot be assigned to type 'Char' */ +/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 54:57 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 71:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 71:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 72:24 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 77:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 78:24 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 71:33 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 72:24 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 77:33 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 78:24 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 86:9 Error TypeError: Static property 'makeCumulative' must be accessed through it's class 'StringFasta' */ /* @@? 94:34 Error TypeError: Static property 'Random' must be accessed through it's class 'StringFasta' */ +/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 95:65 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 103:20 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 103:20 Error TypeError: Type 'Double' has no call signatures. */ /* @@? 112:16 Error TypeError: Static property 'fastaRepeat' must be accessed through it's class 'StringFasta' */ -/* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 112:48 Error TypeError: Static property 'ALU' must be accessed through it's class 'StringFasta' */ /* @@? 113:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ -/* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 113:46 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 114:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ -/* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 114:46 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 116:28 Error TypeError: 'expected' is a static property of 'StringFasta' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets b/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets index da4c91a29a93ee93e6ed17dcc36f090fefb9ecfd..6b8efd8afe3242f1c6959e00dfef6650a85bbd23 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets @@ -25,5 +25,5 @@ function foo(): number { } return n! } -/* @@? 23:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ + /* @@? 26:12 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets index fd74b049d9cf1f7fa1811afceca01c352bfc419e..25779dcb628b55d54e6189d4bd28539d82c193cd 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets @@ -32,4 +32,4 @@ function main(): void { } } -/* @@? 30:17 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'float'. */ +/* @@@ label Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Float'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets b/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets index 8e4083148a5f190ec911fb41311e7eb5b43d70f3..a49879c670f44037f457897496ce555d512c3d98 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets @@ -21,3 +21,5 @@ function main(): void { let b = s ?? a; b.toString(); } + +/* @@? 22:19 Error TypeError: Type String|Int[] is illegal in union member expression. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets b/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets index 6d3751d902f8eab281f4399c873927bc48d1709d..7f0a390e842243a0ddf2dee23729b7c65a284c2d 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets @@ -19,4 +19,4 @@ export class Test { } } -/* @@@ label Error TypeError: Type 'double' cannot be used as an index type. Only primitive or unboxable integral types can be used as index. */ +/* @@@ label Error TypeError: Type 'Double' cannot be used as an index type. Only primitive or unboxable integral types can be used as index. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets b/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets index b4ef18b4e99a3a2269bd9473f6728fa42eedfeac..010a140b3b22e95ce366797f6b259f8d0caa539b 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets @@ -37,4 +37,4 @@ let a: FixedArray = new int[5]; /* @@@ label Error TypeError: Variable 'non_prim_b' has already been declared. */ /* @@? 27:31 Error TypeError: Cannot find type 'Bool'. */ -/* @@? 27:38 Error TypeError: Type 'boolean' cannot be assigned to type 'Byte' */ +/* @@? 27:38 Error TypeError: Type 'Boolean' cannot be assigned to type 'Byte' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets b/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets index 90442a1300b850ec2513c1751658e4279d8c68a4..a7f6f9a173972513e20c6d9b1bcadaa4000ab3ce 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets @@ -57,7 +57,7 @@ function main(){ "Mary":["20", "30"] }; } -/* @@@ label Error TypeError: Type '"10"' is not compatible with type 'double' at property 'age' */ -/* @@@ label1 Error TypeError: Type '"100"' is not compatible with type 'double' at property 'salary' */ +/* @@@ label Error TypeError: Type '"10"' is not compatible with type 'Double' at property 'age' */ +/* @@@ label1 Error TypeError: Type '"100"' is not compatible with type 'Double' at property 'salary' */ /* @@@ label2 Error TypeError: type PersonInfoInterface has no property named agee */ /* @@@ label3 Error TypeError: type PersonInfoInterface has no property named other */ diff --git a/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets b/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets index 0790ded53ca3e65ebcba9a26f52e7afc87bde879..c50834ca9b67f8a08020e3bbd5bb132dc00aa9d1 100644 --- a/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets +++ b/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets @@ -32,7 +32,7 @@ class /* @@ label4 */{/* @@ label5 */} /* @@? 17:19 Error SyntaxError: Unexpected token 'function'. */ /* @@? 21:20 Error SyntaxError: Unexpected token 'let'. */ /* @@? 22:20 Error SyntaxError: Unexpected token 'let'. */ -/* @@? 24:17 Error TypeError: Type '"abc"' cannot be assigned to type 'double' */ +/* @@? 24:17 Error TypeError: Type '"abc"' cannot be assigned to type 'Double' */ /* @@? 28:22 Error SyntaxError: Identifier expected, got 'number literal'. */ /* @@? 30:22 Error SyntaxError: Identifier expected, got '{'. */ /* @@? 30:38 Error SyntaxError: Expected '{', got '}'. */ diff --git a/ets2panda/test/ast/parser/ets/StringFasta.ets b/ets2panda/test/ast/parser/ets/StringFasta.ets index a536da1d477f00880f75919bd76b830240e07b27..b19171c455f109798ba23f5a4e3ed4caca0a88ab 100644 --- a/ets2panda/test/ast/parser/ets/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/StringFasta.ets @@ -122,15 +122,10 @@ function main(): void { a.run(); } -/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 18:18 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 19:22 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 21:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 22:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 23:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ @@ -150,6 +145,7 @@ function main(): void { /* @@? 37:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 38:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 39:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ +/* @@? 41:26 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 47:13 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:21 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:28 Error TypeError: Static property 'A' must be accessed through it's class 'Random' */ @@ -157,30 +153,30 @@ function main(): void { /* @@? 47:37 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ /* @@? 48:26 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 48:33 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ +/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 53:27 Error TypeError: Type 'null' cannot be assigned to type 'Char' */ +/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 54:57 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 71:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 71:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 72:24 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 77:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 78:24 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 71:33 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 72:24 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 77:33 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 78:24 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 86:9 Error TypeError: Static property 'makeCumulative' must be accessed through it's class 'StringFasta' */ /* @@? 94:34 Error TypeError: Static property 'Random' must be accessed through it's class 'StringFasta' */ +/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 95:65 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 103:20 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 103:20 Error TypeError: Type 'Double' has no call signatures. */ /* @@? 112:16 Error TypeError: Static property 'fastaRepeat' must be accessed through it's class 'StringFasta' */ -/* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 112:48 Error TypeError: Static property 'ALU' must be accessed through it's class 'StringFasta' */ /* @@? 113:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ -/* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 113:46 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 114:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ -/* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 114:46 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 116:28 Error TypeError: 'expected' is a static property of 'StringFasta' */ diff --git a/ets2panda/test/ast/parser/ets/UnexpectedToken.ets b/ets2panda/test/ast/parser/ets/UnexpectedToken.ets index 6f85639581dfb8f5d6d1e473e733b9d3df68d30a..a7ee95c6e449b6ec88c820e48df83e54eb4df106 100644 --- a/ets2panda/test/ast/parser/ets/UnexpectedToken.ets +++ b/ets2panda/test/ast/parser/ets/UnexpectedToken.ets @@ -20,7 +20,6 @@ function main(): void { } } -/* @@? 18:19 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:25 Error SyntaxError: Unexpected token 'let'. */ /* @@? 18:25 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? 18:29 Error SyntaxError: Expected ';', got 'identification literal'. */ diff --git a/ets2panda/test/ast/parser/ets/accessor_call.ets b/ets2panda/test/ast/parser/ets/accessor_call.ets index 030d431499f21d0d9fab274a0961f16d1309bc18..918aaffe3935735b4bb87a0232011df893697547 100644 --- a/ets2panda/test/ast/parser/ets/accessor_call.ets +++ b/ets2panda/test/ast/parser/ets/accessor_call.ets @@ -21,4 +21,4 @@ function main(): void { /* @@ label */new A().x(); } -/* @@@ label Error TypeError: Type 'int' has no call signatures. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ diff --git a/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets b/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets index 27a91515bca38ba9aa439145bd36c8027d9e66a5..4d3d2c85391c59df3df421d2ec171879cb82d670 100644 --- a/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets +++ b/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets @@ -27,5 +27,5 @@ function main (): void { goo (0, new X(), "ambiguous") } -/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: int, p1: I1, s: String): void` and `goo(i: int, p2: I5, s: String): void` */ -/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: int, p1: I1, s: String): void` and `goo(i: int, p2: I2, s: String): void` */ +/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: Int, p1: I1, s: String): void` and `goo(i: Int, p2: I5, s: String): void` */ +/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: Int, p1: I1, s: String): void` and `goo(i: Int, p2: I2, s: String): void` */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets index cd104710cf1c2bf5fb4186fb4da86ff654bd321a..477f3727524461ce8a9fd59feadb12500c1e010b 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets @@ -21,4 +21,4 @@ @MyAnno({testProperty1: "1", testProperty2: [1, 2, a]}) class B{} -/* @@? 21:45 Error TypeError: Expected type for array literal should be an array type, got double */ +/* @@? 21:45 Error TypeError: Expected type for array literal should be an array type, got Double */ diff --git a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets index 4f43f45947bc04c843818e374273890a9a511f25..2ee2aaef9188772a1e2f983799408c830ef2447e 100644 --- a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets +++ b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets @@ -18,4 +18,4 @@ function main(): void { } /* @@@ label1 Error TypeError: No matching call signature for assertTrue("true") */ -/* @@@ label2 Error TypeError: Type '"true"' is not compatible with type 'boolean' at index 1 */ \ No newline at end of file +/* @@@ label2 Error TypeError: Type '"true"' is not compatible with type 'Boolean' at index 1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets index e63562d1a0993583cb2956ba5dd81b9be173bb26..425510b4402f62f2161c4c5cb740536c445dde1d 100644 --- a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets +++ b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets @@ -17,5 +17,5 @@ function main(): void { /* @@ label1 */assertTrue(/* @@ label2 */1) } -/* @@@ label1 Error TypeError: No matching call signature for assertTrue(int) */ -/* @@@ label2 Error TypeError: Type 'int' is not compatible with type 'boolean' at index 1 */ +/* @@@ label1 Error TypeError: No matching call signature for assertTrue(Int) */ +/* @@@ label2 Error TypeError: Type 'Int' is not compatible with type 'Boolean' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets b/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets index d19b824b7b5ec003e43b95c6964220598cf7aef4..2d9c1d6732e590dfd41211ae8ce4749bedaf29ff 100644 --- a/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets +++ b/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets @@ -20,4 +20,4 @@ function main() a = /* @@ label */b } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => Int' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => Int' */ diff --git a/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets b/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets index 1ff5c330df473013907b03a2909c42ccb81538c9..fca951695d795059af2144eaf118d1360da68648 100644 --- a/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets +++ b/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets @@ -27,4 +27,5 @@ function main() /* @@ label */b(1, 2) } -/* @@@ label Error TypeError: This expression is not callable. */ +/* @@@ label Error TypeError: No static $_invoke method and static $_instantiate method in b. b() is not allowed. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ diff --git a/ets2panda/test/ast/parser/ets/class_optional_property.ets b/ets2panda/test/ast/parser/ets/class_optional_property.ets index ce1be206b3083fb2b2dac5992fe4378eab8bbad5..a0c0ea28577b0444f7d3f5e04c35130c480b6d4e 100644 --- a/ets2panda/test/ast/parser/ets/class_optional_property.ets +++ b/ets2panda/test/ast/parser/ets/class_optional_property.ets @@ -17,4 +17,4 @@ class A { applyNormalAttribute ?: () => void = /* @@ label */1 } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => void|undefined' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => void|undefined' */ diff --git a/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets b/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets index f77025113d6a03ddbd00939ff3498011ad6af27d..627345cdb3e23d9f1f22a5403522a3ff5c40d539 100644 --- a/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets +++ b/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets @@ -25,5 +25,5 @@ enum Color { } -/* @@? 20:14 Error SyntaxError: Division by zero are not allowed in Enum or Annotation. */ -/* @@? 24:11 Error SyntaxError: Division by zero are not allowed in Enum or Annotation. */ +/* @@? 20:14 Error SyntaxError: Division by zero are not allowed. */ +/* @@? 24:11 Error SyntaxError: Division by zero are not allowed. */ diff --git a/ets2panda/test/ast/parser/ets/cycle_constructor.ets b/ets2panda/test/ast/parser/ets/cycle_constructor.ets index cfcd15c37117e8191d1a1c808a0252497119475f..4574098af62dbfdca5dbc4580d0e8ba72c85f81f 100644 --- a/ets2panda/test/ast/parser/ets/cycle_constructor.ets +++ b/ets2panda/test/ast/parser/ets/cycle_constructor.ets @@ -27,6 +27,6 @@ class B extends A { } /* @@? 25:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? 25:9 Error TypeError: No matching call signature for cycle_constructor.B(int) */ +/* @@? 25:9 Error TypeError: No matching call signature for cycle_constructor.B(Int) */ /* @@? 25:9 Error TypeError: No matching call signature for constructor */ /* @@? 25:14 Error TypeError: Using super is not allowed in constructor */ diff --git a/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets b/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets index 0c45ca27f6849ad0ff1809083335947178026352..29c95eb7e73edeec0489647523271cf63834cc9b 100644 --- a/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets @@ -20,4 +20,4 @@ declare class A { /* @@@ label Error SyntaxError: Initializers are not allowed in ambient contexts. */ /* @@? 17:18 Error TypeError: Initializers are not allowed in ambient contexts: f1 */ -/* @@? 17:18 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 17:18 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets b/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets index 175aac24e64efafd405c224f57575e8aac3fdf5f..d826e1d2056cd8c841cffd2ee8f069977b7ca548 100644 --- a/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets +++ b/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets @@ -20,4 +20,4 @@ declare class A { /* @@@ label Error SyntaxError: Initializers are not allowed in ambient contexts. */ /* @@? 17:25 Error TypeError: Initializers are not allowed in ambient contexts: f1 */ -/* @@? 17:25 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 17:25 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/declare_namespace_5.ets b/ets2panda/test/ast/parser/ets/declare_namespace_5.ets index 61605b9c0d41be5e590fd2276c0ed928727e5719..d51789195011e4f5a76ea22c01128aa41778f768 100644 --- a/ets2panda/test/ast/parser/ets/declare_namespace_5.ets +++ b/ets2panda/test/ast/parser/ets/declare_namespace_5.ets @@ -49,6 +49,7 @@ class B { } /* @@? 17:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ +/* @@? 18:9 Error TypeError: Unresolved reference dfdfsfdf */ /* @@? 20:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ /* @@? 23:20 Error TypeError: Unresolved reference foo */ /* @@? 27:11 Error TypeError: Property 'getInstance' does not exist on type 'B' */ diff --git a/ets2panda/test/ast/parser/ets/differentTypeCompare.ets b/ets2panda/test/ast/parser/ets/differentTypeCompare.ets index e41197292f16348b5911fcc0a048a82718a2ba67..bc6decc66b7e172aae0973d508da4e90b5cf8900 100644 --- a/ets2panda/test/ast/parser/ets/differentTypeCompare.ets +++ b/ets2panda/test/ast/parser/ets/differentTypeCompare.ets @@ -23,4 +23,4 @@ function main(): void { foo(/* @@ label */a == b); } -/* @@@ label Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@@ label Error TypeError: Operator '==' cannot be applied to types 'String' and 'Int'. */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets index e01a4ddc3b21c6c7dcb358e752a2f4d1b68ce4e5..349d9360948a474a6e8583929025eca4295301e2 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets @@ -22,5 +22,5 @@ import { A } from "dynamic_import_tests/modules/module" function main(): void { let x = /* @@ label */new A(/* @@ label1 */"abc", 10) } -/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'double' at index 1 */ -/* @@@ label Error TypeError: No matching construct signature for module.A("abc", int) */ +/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'Double' at index 1 */ +/* @@@ label Error TypeError: No matching construct signature for module.A("abc", Int) */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets index 6d872c4eabbbab5558b3f626cd45c30bb0c0a2f5..c2356b47e29135ca013137b2a7e4a1803f6b1d18 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(p: A): void { p.f1 = /* @@ label */10 } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets index 39bac5dcae933a6b81bac4e0f5352b11714ee72b..20edcbd465566ba1555e892fa1d18f18b061b658 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(): void { let x: string = /* @@ label */A.f2 } -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Double' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets index 23eb4a01ec774aa0e3edce4914baf27266be38ac..db83b85465026483c39f0d5a06e2b3960ca3f955 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets @@ -22,5 +22,5 @@ import { A } from "dynamic_import_tests/modules/module" function foo(p: A): void { /* @@ label */p.foo(/* @@ label1 */"abc") } -/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'double' at index 1 */ +/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'Double' at index 1 */ /* @@@ label Error TypeError: No matching call signature for foo("abc") */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets index 3acfee0beaa0a0da642ca8eaf5a429d99691863e..bb4b9e0c59ed936887cb351fbd4cd8b1c6402097 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(): void { let x: string = /* @@ label */A.bar() } -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Double' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/enum15.ets b/ets2panda/test/ast/parser/ets/enum15.ets index 94ef7cd8c0f89f505c029a468c3069637df8e66f..a673de147fdbbefc42e20613ecef6fa600856888 100644 --- a/ets2panda/test/ast/parser/ets/enum15.ets +++ b/ets2panda/test/ast/parser/ets/enum15.ets @@ -21,5 +21,4 @@ enum InvalidInitTypeEnum { /* @@? 18:11 Error SyntaxError: Invalid enum initialization value */ -/* @@? 19:7 Error SyntaxError: Only constant expression is expected in the field */ -/* @@? 19:7 Error SyntaxError: Invalid enum initialization value */ +/* @@? 19:7 Error SyntaxError: Invalid enum initialization value */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/enum_default_negative1.ets b/ets2panda/test/ast/parser/ets/enum_default_negative1.ets index 4b7f2a8fec4bd05a01349b5c73486c47bcdfa41d..a96b68ddd45b41991ba203da609226f14c77668d 100644 --- a/ets2panda/test/ast/parser/ets/enum_default_negative1.ets +++ b/ets2panda/test/ast/parser/ets/enum_default_negative1.ets @@ -23,7 +23,6 @@ enum B { } -/* @@? 17:9 Error SyntaxError: Unsupported operator for String. */ /* @@? 17:9 Error SyntaxError: Invalid enum initialization value */ -/* @@? 22:9 Error SyntaxError: Only constant expression is expected in the field */ +/* @@? 17:9 Error TypeError: Wrong type of operands for binary expression */ /* @@? 22:9 Error SyntaxError: Invalid enum initialization value */ diff --git a/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets b/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets index 6593711c1c5008fb95740028363e7ddac21adfeb..9981dd14b11b41c7126f6780ef80847541087fa3 100644 --- a/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets +++ b/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets @@ -25,5 +25,5 @@ function foo(): number { } return n! } -/* @@? 23:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ + /* @@? 26:12 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/for_await_of_loop.ets b/ets2panda/test/ast/parser/ets/for_await_of_loop.ets index aad9c9401809caa3da8e5b68332cc89819854b07..3b41c8b661529fd31f678ee9eb1cfd5dc49e8d88 100644 --- a/ets2panda/test/ast/parser/ets/for_await_of_loop.ets +++ b/ets2panda/test/ast/parser/ets/for_await_of_loop.ets @@ -19,7 +19,6 @@ for await (let k: int /* @@ label1 */= 0; /* @@ label2 */k < d.length; k++) { /* @@@ label1 Error SyntaxError: for-await-of loop variable declaration may not have an initializer. */ /* @@@ label2 Error SyntaxError: Unexpected token 'k'. */ -/* @@? 16:58 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 16:62 Error TypeError: Unresolved reference d */ /* @@? 17:5 Error TypeError: Cannot reference 'this' in this context. */ /* @@? 17:10 Error TypeError: Property '$_set_unsafe' does not exist on type 'Error' */ diff --git a/ets2panda/test/ast/parser/ets/for_of_02.ets b/ets2panda/test/ast/parser/ets/for_of_02.ets index 535270a5967403b2897ae0740dfcfa0c2a198a0c..b30a1e168da0563f008e4aae0ddf9f67330f4da5 100644 --- a/ets2panda/test/ast/parser/ets/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/for_of_02.ets @@ -32,4 +32,4 @@ function main(): void { } } -/* @@? 30:17 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'float'. */ +/* @@@ label Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Float'. */ diff --git a/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets b/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets index 167d3297a19d4909e7ac1081109bba1a9d70224a..58952390f714c6ef9b7d68e498d986c4613e9226 100644 --- a/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets +++ b/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets @@ -30,7 +30,7 @@ for (let value = 40 /* @@ label2 */of iterable2) { console.log(value); } -/* @@? 18:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'int'. */ -/* @@? 18:38 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ -/* @@? 28:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'int'. */ -/* @@? 28:36 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ +/* @@@ label1 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ +/* @@@ label2 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ +/* @@? 18:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Int'. */ +/* @@? 28:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Int'. */ diff --git a/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets b/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets index 2d256845c7d7ec41f92b2200882cf46d53c7e806..89efc28509de05402bb6315a6445fb2669123d2e 100644 --- a/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets +++ b/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets @@ -22,5 +22,5 @@ final class B extends A { public override fn(): int { return 42; } } -/* @@? 22:21 Error TypeError: fn(): int in B cannot override fn(): void in A because overriding return type is not compatible with the other return type. */ -/* @@? 22:21 Error TypeError: Method fn(): int in B not overriding any method */ +/* @@? 22:21 Error TypeError: fn(): Int in B cannot override fn(): void in A because overriding return type is not compatible with the other return type. */ +/* @@? 22:21 Error TypeError: Method fn(): Int in B not overriding any method */ diff --git a/ets2panda/test/ast/parser/ets/generic_error.ets b/ets2panda/test/ast/parser/ets/generic_error.ets index 1f5ee0a2518182ced77802dff40c85bf45c597b3..195bb99fa68ac1963cc56e5125ac5d2ba0d50148 100644 --- a/ets2panda/test/ast/parser/ets/generic_error.ets +++ b/ets2panda/test/ast/parser/ets/generic_error.ets @@ -23,4 +23,4 @@ function main(): void { let m = new OldMap/* @@ label */(); } -/* @@@ label Error TypeError: Type C is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'C' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets b/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets index 9268e2c5eb7c79153d49585131d7704dc296f540..3b5e329f9125c419349f8fe197fa7d770b29c5d8 100644 --- a/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets +++ b/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets @@ -19,4 +19,4 @@ function main(){ const myCharClass = new X/* @@ label */(); } -/* @@@ label Error TypeError: Type Char is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'Char' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets b/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets index d1fa3f8e04ff9d8e41534acce1e96c1b201221f7..ba846261acb7657783e6b5a2f7dd6235c0baff0e 100644 --- a/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets +++ b/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets @@ -39,7 +39,7 @@ class Hex extends Core { } } -/* @@? 33:22 Error TypeError: size(s: int): void in Hex cannot override size(s: int): void in Core because overridden method is final. */ -/* @@? 33:22 Error TypeError: Method size(s: int): void in Hex not overriding any method */ -/* @@? 37:22 Error TypeError: size(): int in Hex cannot override size(): int in Core because overridden method is final. */ -/* @@? 37:22 Error TypeError: Method size(): int in Hex not overriding any method */ +/* @@? 33:22 Error TypeError: size(s: Int): void in Hex cannot override size(s: Int): void in Core because overridden method is final. */ +/* @@? 33:22 Error TypeError: Method size(s: Int): void in Hex not overriding any method */ +/* @@? 37:22 Error TypeError: size(): Int in Hex cannot override size(): Int in Core because overridden method is final. */ +/* @@? 37:22 Error TypeError: Method size(): Int in Hex not overriding any method */ diff --git a/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets b/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets index fbf2024f41b6adb55f16c4d5531bc5a82e562986..d49ec5f228f819638682307d1cdb941dc4cde96f 100644 --- a/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets +++ b/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets @@ -21,3 +21,6 @@ function main(): void { let b = s ?? a; b.toString(); } + + +/* @@@ label Error TypeError: Type String|Int[] is illegal in union member expression. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets index b5508f11e48cfdb60591944353328bb4e1811050..cfbfbd87eddd1d49dff5130aca97e3ae7bf35e2d 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -export const flt: float = 2.345; +export const flt: float = 2.345f; export let c: int = 3; diff --git a/ets2panda/test/ast/parser/ets/keyof_constraint.ets b/ets2panda/test/ast/parser/ets/keyof_constraint.ets index b3265d6059e936d087bce74e9ee3de3c85320853..ed208c3516b71adf4ed70bfc607134a90356aff4 100644 --- a/ets2panda/test/ast/parser/ets/keyof_constraint.ets +++ b/ets2panda/test/ast/parser/ets/keyof_constraint.ets @@ -30,6 +30,6 @@ function main():void{ /* @@ label2 */getProperty(/* @@ label3 */"field12345"); } -/* @@@ label1 Error TypeError: Type "field12345" is not assignable to constraint type "method1"|"field1"|"field2" */ +/* @@@ label1 Error TypeError: Type argument '"field12345"' should be a subtype of '"method1"|"field1"|"field2"'-constraint */ /* @@@ label2 Error TypeError: No matching call signature for getProperty("field12345") */ /* @@@ label3 Error TypeError: Type '"field12345"' is not compatible with type '"method1"|"field1"|"field2"' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets b/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets index 4d006cbe6395efa1cdb6c0cf1a95f01efc762672..ca91aaa14d05e138436e4e3e8bb44978d79b2b3e 100644 --- a/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets +++ b/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets @@ -18,5 +18,5 @@ function main():void{ let c2:keyof Int = /* @@ label2 */"field1" } -/* @@@ label1 Error TypeError: Type '"field1"' cannot be assigned to type '"$_hashCode"|"add"|"unboxed"|"isGreaterThan"|"compareTo"|"createFromJSONValue"|"isLessEqualThan"|"mul"|"doubleValue"|"toString"|"byteValue"|"isLessThan"|"shortValue"|"sub"|"intValue"|"div"|"floatValue"|"equals"|"longValue"|"isGreaterEqualThan"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ -/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"$_hashCode"|"add"|"unboxed"|"isGreaterThan"|"compareTo"|"createFromJSONValue"|"isLessEqualThan"|"mul"|"doubleValue"|"toString"|"byteValue"|"isLessThan"|"shortValue"|"sub"|"intValue"|"div"|"floatValue"|"equals"|"longValue"|"isGreaterEqualThan"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label1 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"$_hashCode"|"add"|"toByte"|"unboxed"|"isGreaterThan"|"compareTo"|"toLong"|"createFromJSONValue"|"isLessEqualThan"|"isLessThan"|"toFloat"|"toString"|"mul"|"sub"|"isGreaterEqualThan"|"equals"|"div"|"toInt"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"$_hashCode"|"add"|"toByte"|"unboxed"|"isGreaterThan"|"compareTo"|"toLong"|"createFromJSONValue"|"isLessEqualThan"|"isLessThan"|"toFloat"|"toString"|"mul"|"sub"|"isGreaterEqualThan"|"equals"|"div"|"toInt"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ diff --git a/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets b/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets index c4248319400c6dca88a18040e725e3e3e3dc5329..75cc29a9124eff1f602cb0e682834e350602fbaf 100644 --- a/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets +++ b/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets @@ -20,10 +20,9 @@ function foo(callback: (x: boolean) => void): void { } function main(): void { - /* @@ label1 */foo((x) => { + foo((x) => { }); } /* @@@ label Error TypeError: Function foo with this assembly signature already declared. */ -/* @@@ label1 Error TypeError: Reference to foo is ambiguous */ diff --git a/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets b/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets index fbeb2cd8c74436edabc0350a32bdf2d7a302a3cc..8ab267434de4b279a18a4ac45f610e718e935e25 100644 --- a/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets +++ b/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets @@ -29,10 +29,10 @@ function main(): void { return y.length == x; }); // Should report an error - /* @@ label1 */foo((x, y) => { + foo((x, y) => /* @@ label1 */{ console.println("hello"); }); } /* @@@ label Error TypeError: Function foo with this assembly signature already declared. */ -/* @@@ label1 Error TypeError: Reference to foo is ambiguous */ +/* @@@ label1 Error TypeError: Type 'void' is not compatible with the enclosing method's return type 'Boolean' */ diff --git a/ets2panda/test/ast/parser/ets/loops.ets b/ets2panda/test/ast/parser/ets/loops.ets index 027c90e68219b347b2d236cfc8a803342e5fadeb..b615b0ecd600ac2732f80cbc1f4a68c4f34c2dc3 100644 --- a/ets2panda/test/ast/parser/ets/loops.ets +++ b/ets2panda/test/ast/parser/ets/loops.ets @@ -65,4 +65,3 @@ function labeledcontinue(): void { } /* @@? 19:15 Error TypeError: Unresolved reference i */ -/* @@? 19:15 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets index 7fbea40572514d454dd7dd155ae43746e2c46a2e..7656872082259533c237005afc004ffbbcc3a816 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets @@ -19,5 +19,5 @@ function foo (p: [int, string]) { let x: Readonly<[int, string]> = [] /* @@ label */foo(/* @@ label1 */x) -/* @@@ label1 Error TypeError: Type 'readonly [int, String]' is not compatible with type '[int, String]' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(readonly [int, String]) */ +/* @@@ label1 Error TypeError: Type 'readonly [Int, String]' is not compatible with type '[Int, String]' at index 1 */ +/* @@@ label Error TypeError: No matching call signature for foo(readonly [Int, String]) */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets index 0953054d474f4d57fee200f49df0951afa76a56d..1d321b90e4c8c89fcfe3c7f036f06e63f0993d80 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets @@ -17,4 +17,4 @@ function foo (x: Readonly<[int, string]>) { let y: [int, string] = /* @@ label */x } -/* @@@ label Error TypeError: Type 'readonly [int, String]' cannot be assigned to type '[int, String]' */ +/* @@@ label Error TypeError: Type 'readonly [Int, String]' cannot be assigned to type '[Int, String]' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets index fd6e6d841963f901bc18f99637d0a7901557daaf..12e4c37feda06db8e2dc233337fc66b095ca17bf 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets @@ -18,4 +18,4 @@ function foo (x: readonly [int, string]) { let y: [int, string] = /* @@ label */x } -/* @@@ label Error TypeError: Type 'readonly [int, String]' cannot be assigned to type '[int, String]' */ +/* @@@ label Error TypeError: Type 'readonly [Int, String]' cannot be assigned to type '[Int, String]' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets index 448f5ebcdb2c075250bdc23c61e164df822a64f9..c070f2aba93e0138a6a8cce31b73688f519f8c67 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets @@ -19,5 +19,5 @@ function foo (p: [int, string]) { let x: readonly [int, string] = [] /* @@ label */foo(/* @@ label1 */x) -/* @@@ label1 Error TypeError: Type 'readonly [int, String]' is not compatible with type '[int, String]' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(readonly [int, String]) */ +/* @@@ label Error TypeError: No matching call signature for foo(readonly [Int, String]) */ +/* @@@ label1 Error TypeError: Type 'readonly [Int, String]' is not compatible with type '[Int, String]' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets index 982bba0c4eaa18916905dae1346f730da524f81e..2dd0f6a4a1a9ec75cebe7c2e036ef64bce871777 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets @@ -19,4 +19,3 @@ function main(){ "key2": 2 } } -/* @@@ label Error TypeError: Type Char|String is not assignable to constraint type Numeric|String */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets index 71687363c509000dd2c5b2be74b2690af8fb1d13..d1e722c345b64754e7b731c22b194ae783720456 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets @@ -21,4 +21,4 @@ function main(){ 2: 2 } } -/* @@@ label Error TypeError: Type A|Double is not assignable to constraint type Numeric|String */ +/* @@@ label Error TypeError: Type argument 'A|Double' should be a subtype of 'Numeric|String'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets index 316c66534305e56a0e33031f5bb9c956389e0abb..70e71e1254487900c189573b3e14983ad604963a 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets @@ -18,4 +18,4 @@ class A{} function main(){ let a: Record/* @@ label */ } -/* @@@ label Error TypeError: Type BigInt is not assignable to constraint type Numeric|String */ +/* @@@ label Error TypeError: Type argument 'BigInt' should be a subtype of 'Numeric|String'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_06.ets b/ets2panda/test/ast/parser/ets/rest_parameter_06.ets index 969c4fc10f95b3c5e3bc5e20d0f24d1a8fc1e208..7a59b5b5edfc53f8ea6aa82e4abee3c04f5e2822 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_06.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_06.ets @@ -19,4 +19,4 @@ function sum(...numbers: [number, number, number]): number { /* @@ label */sum(10, 20, 30, 40) -/* @@@ label Error TypeError: No matching call signature for sum(int, int, int, int) */ +/* @@@ label Error TypeError: No matching call signature for sum(Int, Int, Int, Int) */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_07.ets b/ets2panda/test/ast/parser/ets/rest_parameter_07.ets index 922f5eeac935f299b0d4ffedf6ade63efe010a42..450b5b113b129b6bb1c72e7cb91fda410b953a4d 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_07.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_07.ets @@ -17,6 +17,6 @@ function sum(...numbers: [number, number, number]): number { return numbers[0] + numbers[1] + numbers[2] } -/* @@ label1 */sum(10, 20, /* @@ label2 */"one") +/* @@ label1 */sum(10, 20, "one") -/* @@@ label1 Error TypeError: No matching call signature for sum(int, int, "one") */ +/* @@@ label1 Error TypeError: No matching call signature for sum(Int, Int, "one") */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_08.ets b/ets2panda/test/ast/parser/ets/rest_parameter_08.ets index 9d882858460e1591c26af2644159a13cb207de4c..b3b1cab78b30908504a1409e0ef898ef830bd229 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_08.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_08.ets @@ -23,6 +23,6 @@ function sum(a: int, ...numbers: [number, number, number]): number { /* @@ label4 */sum(11,12,13,15,16) /* @@@ label1 Error TypeError: No matching call signature */ -/* @@@ label2 Error TypeError: No matching call signature for sum(int) */ -/* @@@ label3 Error TypeError: No matching call signature for sum(int, int, int) */ -/* @@@ label4 Error TypeError: No matching call signature for sum(int, int, int, int, int) */ +/* @@@ label2 Error TypeError: No matching call signature for sum(Int) */ +/* @@@ label3 Error TypeError: No matching call signature for sum(Int, Int, Int) */ +/* @@@ label4 Error TypeError: No matching call signature for sum(Int, Int, Int, Int, Int) */ diff --git a/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets b/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets index 6504bba42380f004042a2ae22abfef9c389c33c6..f527a7805615f8a32af543cafcc4d6090566a623 100644 --- a/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets +++ b/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets @@ -19,5 +19,4 @@ x = true ? x:():long=>32 let y:()=>int = ()=>16 as int y = true ? y:():int=>32 y = true ? ():int=>32:y -x = /* @@ label */true ? x:"apple" -/* @@@ label Error TypeError: Type '() => Long|"apple"' cannot be assigned to type '() => Long' */ \ No newline at end of file +x = true ? x:"apple" \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_43.ets b/ets2panda/test/ast/parser/ets/unexpected_token_43.ets index 5b223d199e73a6621af8ecb9f031431718422e8d..0453dad9ada179122f9082dbcbb1d2cdc0fe5af7 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_43.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_43.ets @@ -16,12 +16,9 @@ let v2 = `--- ${y + abc /* @@ label */${y} = ${ n*2 }!`/* @@ label1 */} ---`;` /* @@? 16:17 Error TypeError: Unresolved reference y */ -/* @@? 16:17 Error TypeError: Unresolved reference y */ -/* @@? 16:21 Error TypeError: Unresolved reference abc */ /* @@? 16:21 Error TypeError: Unresolved reference abc */ -/* @@? 16:39 Error SyntaxError: Expected '}', got 'identification literal'. */ -/* @@? 16:49 Error TypeError: Unresolved reference n */ +/* @@@ label Error SyntaxError: Expected '}', got 'identification literal'. */ /* @@? 16:49 Error TypeError: Unresolved reference n */ -/* @@? 16:71 Error SyntaxError: Unexpected token '}'. */ -/* @@? 16:76 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ -/* @@? 28:1 Error SyntaxError: Invalid left-hand side in prefix operation. */ +/* @@@ label1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 16:75 Error TypeError: Wrong operand type for unary expression */ +/* @@? 25:1 Error SyntaxError: Invalid left-hand side in prefix operation. */ diff --git a/ets2panda/test/compiler/ets/boxingConversion2-expected.txt b/ets2panda/test/compiler/ets/boxingConversion2-expected.txt index fd853951c7513246bf51d62a1fae3c1ce4d21471..0d27fe5b4d70065aba15396a4eed3df2bf54787d 100644 --- a/ets2panda/test/compiler/ets/boxingConversion2-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion2-expected.txt @@ -731,7 +731,7 @@ }, "end": { "line": 23, - "column": 23, + "column": 24, "program": "boxingConversion2.ets" } } @@ -744,7 +744,7 @@ }, "end": { "line": 23, - "column": 23, + "column": 24, "program": "boxingConversion2.ets" } } @@ -759,7 +759,7 @@ }, "end": { "line": 23, - "column": 24, + "column": 25, "program": "boxingConversion2.ets" } } diff --git a/ets2panda/test/compiler/ets/boxingConversion2.ets b/ets2panda/test/compiler/ets/boxingConversion2.ets index 094438ca8159cf0c3207f4f9f79f7ac59e4a37ab..1da22d4fbd678783bd70795b7c07c05ae0c224b7 100644 --- a/ets2panda/test/compiler/ets/boxingConversion2.ets +++ b/ets2panda/test/compiler/ets/boxingConversion2.ets @@ -20,7 +20,7 @@ function main() : void { let d: char = c'3'; let e: int = 4; let f: long = 5; - let g: float = 6.0; + let g: float = 6.0f; let h: double = 7.0; let i: Object = a; let j: Object = b; diff --git a/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt b/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt index 253a7e61b976020693d46b8da84276ac4f7a039e..ee1717f7c1473bd7fffbaae744a5d9bdfca45b0a 100644 --- a/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt +++ b/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt @@ -2190,7 +2190,7 @@ }, "end": { "line": 35, - "column": 28, + "column": 29, "program": "boxingUnboxingExpressions.ets" } } @@ -2203,7 +2203,7 @@ }, "end": { "line": 35, - "column": 28, + "column": 29, "program": "boxingUnboxingExpressions.ets" } } @@ -2218,7 +2218,7 @@ }, "end": { "line": 35, - "column": 29, + "column": 30, "program": "boxingUnboxingExpressions.ets" } } @@ -7597,7 +7597,7 @@ }, "end": { "line": 74, - "column": 28, + "column": 29, "program": "boxingUnboxingExpressions.ets" } } @@ -7610,7 +7610,7 @@ }, "end": { "line": 74, - "column": 28, + "column": 29, "program": "boxingUnboxingExpressions.ets" } } @@ -7625,7 +7625,7 @@ }, "end": { "line": 74, - "column": 29, + "column": 30, "program": "boxingUnboxingExpressions.ets" } } diff --git a/ets2panda/test/compiler/ets/boxingUnboxingExpressions.ets b/ets2panda/test/compiler/ets/boxingUnboxingExpressions.ets index d6aba0e0e016911f58d5407278eae3fa091690ca..5868f5f280fa286e566df686427368d02953fd83 100644 --- a/ets2panda/test/compiler/ets/boxingUnboxingExpressions.ets +++ b/ets2panda/test/compiler/ets/boxingUnboxingExpressions.ets @@ -32,7 +32,7 @@ class A { let j: Int = 200000; let k: long = new Long(200000000000); let l: Long = 200000000000; - let m: float = 2.22; + let m: float = 2.22f; let n: float = new Float(m); let o: Float = m; let p: double = new Double(2.2222222222); @@ -71,7 +71,7 @@ class A { this.integerReference(200000); this.longPrimitive(new Long(200000000000000)); this.longReference(200000000000000); - let f: float = 2.22; + let f: float = 2.22f; this.floatPrimitive(new Float(f)); this.floatReference(f); this.doublePrimitive(new Double(2.2222222222)); diff --git a/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt b/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt index e77bd7128750c71b08404a0018d74de762fc921e..7dfa6b132b475456ac45a54f106c8ff75fada933 100644 --- a/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt +++ b/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt @@ -267,38 +267,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 17, - "column": 24, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 17, - "column": 25, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 29, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 17, - "column": 33, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0, "loc": { "start": { "line": 17, @@ -410,38 +380,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 18, - "column": 27, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 31, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 18, - "column": 36, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 18, @@ -553,38 +493,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 19, - "column": 24, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 19, - "column": 25, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 29, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 19, - "column": 32, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 19, @@ -696,38 +606,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 20, - "column": 23, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 20, - "column": 24, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 28, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 20, - "column": 32, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 20, @@ -839,38 +719,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 21, - "column": 30, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 21, - "column": 31, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 35, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 21, - "column": 40, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 21, @@ -982,38 +832,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 22, - "column": 23, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 22, - "column": 26, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 22, - "column": 30, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 22, - "column": 35, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 22, @@ -1125,38 +945,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 23, - "column": 26, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 23, - "column": 27, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 31, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 23, - "column": 37, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 23, @@ -1268,38 +1058,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 24, - "column": 34, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 24, - "column": 37, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 24, - "column": 41, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 24, - "column": 47, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 24, @@ -1411,38 +1171,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 65, - "loc": { - "start": { - "line": 25, - "column": 29, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 25, - "column": 31, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 25, - "column": 35, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 25, - "column": 39, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "CharLiteral", + "value": "A", "loc": { "start": { "line": 25, @@ -1554,38 +1284,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 28, - "column": 29, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 28, - "column": 32, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 28, - "column": 36, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 28, - "column": 41, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 28, @@ -1697,38 +1397,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 29, - "column": 28, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 29, - "column": 31, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 29, - "column": 35, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 29, - "column": 38, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 29, @@ -1840,38 +1510,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 30, - "column": 25, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 30, - "column": 28, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 30, - "column": 32, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 30, - "column": 36, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 30, @@ -1983,38 +1623,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 65, - "loc": { - "start": { - "line": 31, - "column": 28, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 31, - "column": 32, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 31, - "column": 36, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 31, - "column": 40, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "CharLiteral", + "value": "A", "loc": { "start": { "line": 31, diff --git a/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt b/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt index 31f9c613849da97a49afd18c4f25d81d42980d6a..7ae397c5d5164afd976b6552da344444ce326b92 100644 --- a/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt +++ b/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt @@ -797,7 +797,7 @@ "loc": { "start": { "line": 24, - "column": 56, + "column": 60, "program": "dynamicLambdaJSValue.ets" }, "end": { diff --git a/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt b/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt index 5c094ae9aa2f0b24bad7930904f0cc5fde20aacf..0b4e83d3b2b88963f17f1ee7b21e76f38619064a 100644 --- a/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt +++ b/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt @@ -677,5 +677,4 @@ } } } -TypeError: Using the 'instance of' operator with non-object type 'a' [dynamic_instanceof_error.ets:24:11] TypeError: Right-hand side of instanceof expression must represent a type. [dynamic_instanceof_error.ets:24:11] diff --git a/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt b/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt index 2fd33256389be81ecbd2e47ed733173af8fbc566..0ae2590b830c812fd338d047af53ae78863e70e7 100644 --- a/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt +++ b/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt @@ -283,7 +283,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, @@ -5453,7 +5453,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, diff --git a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt index 8e5a6dcacbd8dfc13960654f74a634da669383bd..cade2472970f5eaff18a86a2af7106fcd3cda443 100644 --- a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt +++ b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt @@ -6914,9 +6914,8 @@ } }, "right": { - "type": "Identifier", - "name": "fastGrowThreshold", - "decorators": [], + "type": "NumberLiteral", + "value": 8192, "loc": { "start": { "line": 71, @@ -7004,9 +7003,8 @@ } }, "right": { - "type": "Identifier", - "name": "multiplier", - "decorators": [], + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 73, @@ -7052,7 +7050,7 @@ "loc": { "start": { "line": 73, - "column": 20, + "column": 44, "program": "generic_arrayaslist.ets" }, "end": { @@ -7115,9 +7113,8 @@ } }, "right": { - "type": "Identifier", - "name": "multiplier", - "decorators": [], + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 75, @@ -25303,4 +25300,4 @@ } } TypeError: Expected 1 arguments, got 3. [generic_arrayaslist.ets:115:9] -TypeError: No matching call signature for assertTrue(int, int, "No data to popBack in ArrayAsList!") [generic_arrayaslist.ets:115:9] +TypeError: No matching call signature for assertTrue(Int, Int, "No data to popBack in ArrayAsList!") [generic_arrayaslist.ets:115:9] diff --git a/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt b/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt index 4cc17d40520afeb3afb1b065851814a133276897..b3990eb3d0ecdddf72e1906149f51b5d3fef29a1 100644 --- a/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt @@ -177,7 +177,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, @@ -2661,7 +2661,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, @@ -7831,7 +7831,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, diff --git a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt index d04e570c0f22c272d885d9e64de8c7ae17874a55..a6b4aa5d8aa414b30fea2c69338415e240fb007c 100644 --- a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt @@ -409,7 +409,7 @@ "loc": { "start": { "line": 17, - "column": 9, + "column": 17, "program": "infer_imported_function_return_type_lib.ets" }, "end": { diff --git a/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt b/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt index bab47a98ee73d43c735f1a0fca4390952b2af36c..44c942b99dc807525de3e278f0af1c2453f5503b 100644 --- a/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt @@ -542,4 +542,3 @@ } } } -TypeError: Bad operand type, the types of the operands must be same type. [instanceof_object_long.ets:21:12] diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt index 39e640a0ff170b1aea3641b6fbd238b339f39126..01cee98d0ddb336cf30d46441adeebd7e9193abf 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt @@ -331,38 +331,8 @@ { "type": "ReturnStatement", "argument": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 17, - "column": 49, - "program": "lambda_infer_type_param2.ets" - }, - "end": { - "line": 17, - "column": 50, - "program": "lambda_infer_type_param2.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 54, - "program": "lambda_infer_type_param2.ets" - }, - "end": { - "line": 17, - "column": 59, - "program": "lambda_infer_type_param2.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt b/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt index 2b5107c89e012103608e617fd8b517b028ac4655..e621a9bb8eca42d939d725fed45126090a216aaa 100644 --- a/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt +++ b/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt @@ -308,9 +308,8 @@ { "type": "SwitchCase", "test": { - "type": "Identifier", - "name": "b", - "decorators": [], + "type": "NumberLiteral", + "value": 20, "loc": { "start": { "line": 21, diff --git a/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt b/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt index 9fff8c798dc60d63dc03f5fcf03682cd84b80652..05138eb7973aa586b0c885edca3d1f198ef40b62 100644 --- a/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt +++ b/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt @@ -717,9 +717,8 @@ { "type": "SwitchCase", "test": { - "type": "Identifier", - "name": "c", - "decorators": [], + "type": "NumberLiteral", + "value": 210000, "loc": { "start": { "line": 37, diff --git a/ets2panda/test/compiler/ets/tuple_types_1-expected.txt b/ets2panda/test/compiler/ets/tuple_types_1-expected.txt index d7a76bc74072e2eaf68df34bac654366785d8db8..43b1a9cac14405a685187993aec1b0a8294abc86 100644 --- a/ets2panda/test/compiler/ets/tuple_types_1-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_1-expected.txt @@ -2453,7 +2453,7 @@ "loc": { "start": { "line": 35, - "column": 19, + "column": 40, "program": "tuple_types_1.ets" }, "end": { diff --git a/ets2panda/test/compiler/ets/tuple_types_15-expected.txt b/ets2panda/test/compiler/ets/tuple_types_15-expected.txt index 410a69863909bd412f6d502ac3c2d834ce5a49bf..dfde229154e8a4675a4466b5338ca08bf6266bad 100644 --- a/ets2panda/test/compiler/ets/tuple_types_15-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_15-expected.txt @@ -1291,7 +1291,7 @@ "loc": { "start": { "line": 31, - "column": 26, + "column": 44, "program": "tuple_types_15.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt b/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt index 59013f92d3b4ffa22e7584eefa2e88c830e1a642..1284c1cdd2a637aa85146715c916c10912dc7a33 100644 --- a/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt +++ b/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt @@ -1502,7 +1502,7 @@ "loc": { "start": { "line": 31, - "column": 14, + "column": 26, "program": "AccessBinaryTrees.ets" }, "end": { @@ -2236,7 +2236,7 @@ "loc": { "start": { "line": 43, - "column": 39, + "column": 41, "program": "AccessBinaryTrees.ets" }, "end": { @@ -2920,43 +2920,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessBinaryTrees", - "decorators": [], - "loc": { - "start": { - "line": 54, - "column": 23, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 54, - "column": 40, - "program": "AccessBinaryTrees.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "startDepth", - "decorators": [], - "loc": { - "start": { - "line": 54, - "column": 41, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 54, - "column": 51, - "program": "AccessBinaryTrees.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 54, @@ -3019,43 +2984,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessBinaryTrees", - "decorators": [], - "loc": { - "start": { - "line": 54, - "column": 58, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 54, - "column": 75, - "program": "AccessBinaryTrees.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "endDepth", - "decorators": [], - "loc": { - "start": { - "line": 54, - "column": 76, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 54, - "column": 84, - "program": "AccessBinaryTrees.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 7, "loc": { "start": { "line": 54, @@ -3157,43 +3087,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessBinaryTrees", - "decorators": [], - "loc": { - "start": { - "line": 55, - "column": 27, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 55, - "column": 44, - "program": "AccessBinaryTrees.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "startDepth", - "decorators": [], - "loc": { - "start": { - "line": 55, - "column": 45, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 55, - "column": 55, - "program": "AccessBinaryTrees.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 55, @@ -5128,43 +5023,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessBinaryTrees", - "decorators": [], - "loc": { - "start": { - "line": 75, - "column": 19, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 75, - "column": 36, - "program": "AccessBinaryTrees.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 75, - "column": 37, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 75, - "column": 45, - "program": "AccessBinaryTrees.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": -4, "loc": { "start": { "line": 75, diff --git a/ets2panda/test/parser/ets/AccessNBody-expected.txt b/ets2panda/test/parser/ets/AccessNBody-expected.txt index 83097faa8d788de48670e7a59d4dedb58288ff84..c3bb92a60e7edbebc90b84ca8652fb5186f62780 100644 --- a/ets2panda/test/parser/ets/AccessNBody-expected.txt +++ b/ets2panda/test/parser/ets/AccessNBody-expected.txt @@ -197,7 +197,7 @@ "loc": { "start": { "line": 20, - "column": 36, + "column": 40, "program": "AccessNBody.ets" }, "end": { @@ -6671,7 +6671,7 @@ "loc": { "start": { "line": 78, - "column": 34, + "column": 39, "program": "AccessNBody.ets" }, "end": { @@ -7112,7 +7112,7 @@ "loc": { "start": { "line": 80, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -7311,7 +7311,7 @@ "loc": { "start": { "line": 81, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -7510,7 +7510,7 @@ "loc": { "start": { "line": 82, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -7709,7 +7709,7 @@ "loc": { "start": { "line": 83, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -7908,7 +7908,7 @@ "loc": { "start": { "line": 84, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -8107,7 +8107,7 @@ "loc": { "start": { "line": 85, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -10420,7 +10420,7 @@ "loc": { "start": { "line": 104, - "column": 39, + "column": 50, "program": "AccessNBody.ets" }, "end": { @@ -10564,7 +10564,7 @@ "loc": { "start": { "line": 104, - "column": 19, + "column": 25, "program": "AccessNBody.ets" }, "end": { @@ -11632,7 +11632,7 @@ "loc": { "start": { "line": 110, - "column": 34, + "column": 39, "program": "AccessNBody.ets" }, "end": { @@ -12227,7 +12227,7 @@ "loc": { "start": { "line": 119, - "column": 43, + "column": 47, "program": "AccessNBody.ets" }, "end": { @@ -12686,75 +12686,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00166008, - "loc": { - "start": { - "line": 125, - "column": 102, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 125, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 128, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 139, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 140, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 125, - "column": 128, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0.606326, "loc": { "start": { "line": 125, @@ -12769,75 +12702,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00769901, - "loc": { - "start": { - "line": 125, - "column": 155, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 178, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 192, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 193, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 125, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2.81199, "loc": { "start": { "line": 125, @@ -12852,75 +12718,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": -6.9046e-05, - "loc": { - "start": { - "line": 125, - "column": 208, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 232, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 235, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 246, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 247, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 260, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 125, - "column": 235, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 260, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": -0.0252184, "loc": { "start": { "line": 125, @@ -13298,21 +13097,69 @@ } } }, + { + "type": "NumberLiteral", + "value": -1.01077, + "loc": { + "start": { + "line": 128, + "column": 101, + "program": "AccessNBody.ets" + }, + "end": { + "line": 128, + "column": 153, + "program": "AccessNBody.ets" + } + } + }, + { + "type": "NumberLiteral", + "value": 1.82566, + "loc": { + "start": { + "line": 128, + "column": 155, + "program": "AccessNBody.ets" + }, + "end": { + "line": 128, + "column": 206, + "program": "AccessNBody.ets" + } + } + }, + { + "type": "NumberLiteral", + "value": 0.00841576, + "loc": { + "start": { + "line": 128, + "column": 208, + "program": "AccessNBody.ets" + }, + "end": { + "line": 128, + "column": 259, + "program": "AccessNBody.ets" + } + } + }, { "type": "BinaryExpression", "operator": "*", "left": { "type": "NumberLiteral", - "value": -0.00276743, + "value": 0.000285886, "loc": { "start": { "line": 128, - "column": 101, + "column": 261, "program": "AccessNBody.ets" }, "end": { "line": 128, - "column": 125, + "column": 284, "program": "AccessNBody.ets" } } @@ -13326,29 +13173,29 @@ "loc": { "start": { "line": 128, - "column": 128, + "column": 287, "program": "AccessNBody.ets" }, "end": { "line": 128, - "column": 139, + "column": 298, "program": "AccessNBody.ets" } } }, "property": { "type": "Identifier", - "name": "DAYS_PER_YEAR", + "name": "SOLAR_MASS", "decorators": [], "loc": { "start": { "line": 128, - "column": 140, + "column": 299, "program": "AccessNBody.ets" }, "end": { "line": 128, - "column": 153, + "column": 309, "program": "AccessNBody.ets" } } @@ -13358,12 +13205,12 @@ "loc": { "start": { "line": 128, - "column": 128, + "column": 287, "program": "AccessNBody.ets" }, "end": { "line": 128, - "column": 153, + "column": 309, "program": "AccessNBody.ets" } } @@ -13371,256 +13218,7 @@ "loc": { "start": { "line": 128, - "column": 101, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00499853, - "loc": { - "start": { - "line": 128, - "column": 155, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 178, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 192, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 193, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 128, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - "loc": { - "start": { - "line": 128, - "column": 155, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 2.30417e-05, - "loc": { - "start": { - "line": 128, - "column": 208, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 231, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 234, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 245, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 246, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 128, - "column": 234, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, - "loc": { - "start": { - "line": 128, - "column": 208, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, - { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.000285886, - "loc": { - "start": { - "line": 128, - "column": 261, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 284, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 287, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 298, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "SOLAR_MASS", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 299, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 309, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 128, - "column": 287, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 309, - "program": "AccessNBody.ets" - } - } - }, - "loc": { - "start": { - "line": 128, - "column": 261, + "column": 261, "program": "AccessNBody.ets" }, "end": { @@ -13912,158 +13510,24 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.0029646, - "loc": { - "start": { - "line": 131, - "column": 102, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 125, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 128, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 139, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 140, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 131, - "column": 128, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - "loc": { - "start": { - "line": 131, - "column": 102, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00237847, - "loc": { - "start": { - "line": 131, - "column": 155, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 178, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 192, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 193, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 131, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 206, - "program": "AccessNBody.ets" - } + "type": "NumberLiteral", + "value": 1.08279, + "loc": { + "start": { + "line": 131, + "column": 102, + "program": "AccessNBody.ets" + }, + "end": { + "line": 131, + "column": 153, + "program": "AccessNBody.ets" } - }, + } + }, + { + "type": "NumberLiteral", + "value": 0.868713, "loc": { "start": { "line": 131, @@ -14078,75 +13542,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": -2.9659e-05, - "loc": { - "start": { - "line": 131, - "column": 208, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 232, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 235, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 246, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 247, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 260, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 131, - "column": 235, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 260, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": -0.0108326, "loc": { "start": { "line": 131, @@ -14525,75 +13922,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00268068, - "loc": { - "start": { - "line": 134, - "column": 101, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 124, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 127, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 138, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 139, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 152, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 134, - "column": 127, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 152, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0.979091, "loc": { "start": { "line": 134, @@ -14608,75 +13938,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00162824, - "loc": { - "start": { - "line": 134, - "column": 154, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 177, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 180, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 191, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 192, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 205, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 134, - "column": 180, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 205, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0.594699, "loc": { "start": { "line": 134, @@ -14691,75 +13954,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": -9.51592e-05, - "loc": { - "start": { - "line": 134, - "column": 207, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 231, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 234, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 245, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 246, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 134, - "column": 234, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": -0.034756, "loc": { "start": { "line": 134, diff --git a/ets2panda/test/parser/ets/AccessNSieve-expected.txt b/ets2panda/test/parser/ets/AccessNSieve-expected.txt index bf181a0b4ab79328b210bed58e564af13a828bec..bca0f63108789e18ae2d670710c8b2f70f84e638 100644 --- a/ets2panda/test/parser/ets/AccessNSieve-expected.txt +++ b/ets2panda/test/parser/ets/AccessNSieve-expected.txt @@ -513,178 +513,12 @@ } }, "dimension": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "BinaryExpression", - "operator": "<<", - "left": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 23, - "column": 41, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 42, - "program": "AccessNSieve.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 46, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 58, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n1", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 59, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 61, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 23, - "column": 46, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 61, - "program": "AccessNSieve.ets" - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 40, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 62, - "program": "AccessNSieve.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 65, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 77, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n2", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 78, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 80, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 23, - "column": 65, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 80, - "program": "AccessNSieve.ets" - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 40, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 80, - "program": "AccessNSieve.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 23, - "column": 83, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 84, - "program": "AccessNSieve.ets" - } - } - }, + "type": "NumberLiteral", + "value": 80001, "loc": { "start": { "line": 23, - "column": 40, + "column": 65, "program": "AccessNSieve.ets" }, "end": { @@ -2395,43 +2229,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 46, - "column": 31, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 46, - "column": 43, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n1", - "decorators": [], - "loc": { - "start": { - "line": 46, - "column": 44, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 46, - "column": 46, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 46, @@ -2585,43 +2384,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 31, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 47, - "column": 43, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n2", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 44, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 47, - "column": 46, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 10000, "loc": { "start": { "line": 47, @@ -3164,43 +2928,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 55, - "column": 19, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 55, - "column": 31, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 55, - "column": 32, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 55, - "column": 40, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 14302, "loc": { "start": { "line": 55, diff --git a/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt b/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt index 978b8c3d6e60529b779b6b056c0c2972d7b85c59..e7dfdc922eb834af0a217f6dba15f9ae27717fa0 100644 --- a/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt +++ b/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt @@ -1948,43 +1948,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Bitops3BitBitsInByte", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 19, - "program": "Bitops3BitBitsInByte.ets" - }, - "end": { - "line": 37, - "column": 39, - "program": "Bitops3BitBitsInByte.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 40, - "program": "Bitops3BitBitsInByte.ets" - }, - "end": { - "line": 37, - "column": 48, - "program": "Bitops3BitBitsInByte.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 512000, "loc": { "start": { "line": 37, diff --git a/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt b/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt index 19b23b72af01cfa027065d232afa22d9fd5611d3..b3997a56592ad43f1191048c731cb96b41158a90 100644 --- a/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt +++ b/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt @@ -1690,43 +1690,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "BitopsBitsInByte", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 19, - "program": "BitopsBitsInByte.ets" - }, - "end": { - "line": 40, - "column": 35, - "program": "BitopsBitsInByte.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 36, - "program": "BitopsBitsInByte.ets" - }, - "end": { - "line": 40, - "column": 44, - "program": "BitopsBitsInByte.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 358400, "loc": { "start": { "line": 40, diff --git a/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt b/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt index 26c14b0b75d69ee30f728896d6a0c8515112acb0..8211a2bca83ad8f6e00151b1667dca30beb1d094 100644 --- a/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt +++ b/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt @@ -681,43 +681,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "BitopsBitwiseAnd", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 31, - "program": "BitopsBitwiseAnd.ets" - }, - "end": { - "line": 26, - "column": 47, - "program": "BitopsBitwiseAnd.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 48, - "program": "BitopsBitwiseAnd.ets" - }, - "end": { - "line": 26, - "column": 56, - "program": "BitopsBitwiseAnd.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 0, "loc": { "start": { "line": 26, diff --git a/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt b/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt index 8b1ab7c272608c29110ef9bcfd47964003041dac..9cac89a1568725602c18432deb0bb692a8f98279 100644 --- a/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt +++ b/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt @@ -586,7 +586,7 @@ "loc": { "start": { "line": 20, - "column": 21, + "column": 25, "program": "BitopsNSieveBits.ets" }, "end": { @@ -2259,7 +2259,7 @@ "loc": { "start": { "line": 37, - "column": 34, + "column": 47, "program": "BitopsNSieveBits.ets" }, "end": { @@ -3559,43 +3559,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "BitopsNSieveBits", - "decorators": [], - "loc": { - "start": { - "line": 53, - "column": 19, - "program": "BitopsNSieveBits.ets" - }, - "end": { - "line": 53, - "column": 35, - "program": "BitopsNSieveBits.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 53, - "column": 36, - "program": "BitopsNSieveBits.ets" - }, - "end": { - "line": 53, - "column": 44, - "program": "BitopsNSieveBits.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": -1286749544853, "loc": { "start": { "line": 53, diff --git a/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt b/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt index a2e875bc56468b890b241be8e46959d66804ff97..e9b661d180be46d1c5c9ad777e80e3eff6fe7094 100644 --- a/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt +++ b/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt @@ -2756,43 +2756,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "ControlFlowRecursive", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 23, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 47, - "column": 43, - "program": "ControlFlowRecursive.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n1", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 44, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 47, - "column": 46, - "program": "ControlFlowRecursive.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 47, @@ -2855,43 +2820,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "ControlFlowRecursive", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 53, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 47, - "column": 73, - "program": "ControlFlowRecursive.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n2", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 74, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 47, - "column": 76, - "program": "ControlFlowRecursive.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 47, @@ -3418,7 +3348,7 @@ "loc": { "start": { "line": 50, - "column": 42, + "column": 46, "program": "ControlFlowRecursive.ets" }, "end": { @@ -3499,7 +3429,7 @@ "loc": { "start": { "line": 50, - "column": 53, + "column": 57, "program": "ControlFlowRecursive.ets" }, "end": { @@ -3666,43 +3596,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "ControlFlowRecursive", - "decorators": [], - "loc": { - "start": { - "line": 53, - "column": 22, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 53, - "column": 42, - "program": "ControlFlowRecursive.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 53, - "column": 43, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 53, - "column": 51, - "program": "ControlFlowRecursive.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 57775, "loc": { "start": { "line": 53, diff --git a/ets2panda/test/parser/ets/MathCordic-expected.txt b/ets2panda/test/parser/ets/MathCordic-expected.txt index c0750d7e2ca8b6464a175125100f1607277ce8a5..24aa1ecc1730b94e251c4f20df0bfc1d46d5a8a6 100644 --- a/ets2panda/test/parser/ets/MathCordic-expected.txt +++ b/ets2panda/test/parser/ets/MathCordic-expected.txt @@ -2720,43 +2720,8 @@ "type": "BinaryExpression", "operator": "*", "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathCordic", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 32, - "program": "MathCordic.ets" - }, - "end": { - "line": 40, - "column": 42, - "program": "MathCordic.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "AG_CONST", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 43, - "program": "MathCordic.ets" - }, - "end": { - "line": 40, - "column": 51, - "program": "MathCordic.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 0.607253, "loc": { "start": { "line": 40, @@ -5061,43 +5026,8 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathCordic", - "decorators": [], - "loc": { - "start": { - "line": 63, - "column": 46, - "program": "MathCordic.ets" - }, - "end": { - "line": 63, - "column": 56, - "program": "MathCordic.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TARGET_ANGLE", - "decorators": [], - "loc": { - "start": { - "line": 63, - "column": 57, - "program": "MathCordic.ets" - }, - "end": { - "line": 63, - "column": 69, - "program": "MathCordic.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 28.027, "loc": { "start": { "line": 63, @@ -5707,43 +5637,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathCordic", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 25, - "program": "MathCordic.ets" - }, - "end": { - "line": 74, - "column": 35, - "program": "MathCordic.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 36, - "program": "MathCordic.ets" - }, - "end": { - "line": 74, - "column": 44, - "program": "MathCordic.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 10362.6, "loc": { "start": { "line": 74, diff --git a/ets2panda/test/parser/ets/MathPartialSums-expected.txt b/ets2panda/test/parser/ets/MathPartialSums-expected.txt index 5f16c7c1104805d2065e8fa8e123c9b6c09d66f3..7c3bcccd35ce17a10040b5befd73749196bde58a 100644 --- a/ets2panda/test/parser/ets/MathPartialSums-expected.txt +++ b/ets2panda/test/parser/ets/MathPartialSums-expected.txt @@ -1190,40 +1190,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 33, - "column": 29, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 33, - "column": 32, - "program": "MathPartialSums.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 33, - "column": 35, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 33, - "column": 38, - "program": "MathPartialSums.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0.666667, "loc": { "start": { "line": 33, @@ -3734,7 +3702,7 @@ "loc": { "start": { "line": 59, - "column": 11, + "column": 16, "program": "MathPartialSums.ets" }, "end": { @@ -4202,7 +4170,7 @@ "loc": { "start": { "line": 69, - "column": 12, + "column": 17, "program": "MathPartialSums.ets" }, "end": { @@ -4498,43 +4466,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathPartialSums", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 23, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 74, - "column": 38, - "program": "MathPartialSums.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n1", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 39, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 74, - "column": 41, - "program": "MathPartialSums.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 1024, "loc": { "start": { "line": 74, @@ -4597,43 +4530,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathPartialSums", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 48, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 74, - "column": 63, - "program": "MathPartialSums.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n2", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 64, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 74, - "column": 66, - "program": "MathPartialSums.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 16384, "loc": { "start": { "line": 74, @@ -4913,43 +4811,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathPartialSums", - "decorators": [], - "loc": { - "start": { - "line": 78, - "column": 19, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 78, - "column": 34, - "program": "MathPartialSums.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 78, - "column": 35, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 78, - "column": 43, - "program": "MathPartialSums.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 60.0899, "loc": { "start": { "line": 78, @@ -5169,7 +5032,7 @@ "loc": { "start": { "line": 79, - "column": 14, + "column": 40, "program": "MathPartialSums.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt b/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt index 23db51eb627de66e8143c1e32a482dbc41905089..bb875c96e8e4cadbabd39a2f04e4b9dea3628444 100644 --- a/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt +++ b/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt @@ -6832,43 +6832,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathSpectralNorm", - "decorators": [], - "loc": { - "start": { - "line": 87, - "column": 21, - "program": "MathSpectralNorm.ets" - }, - "end": { - "line": 87, - "column": 37, - "program": "MathSpectralNorm.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 87, - "column": 38, - "program": "MathSpectralNorm.ets" - }, - "end": { - "line": 87, - "column": 46, - "program": "MathSpectralNorm.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 5.08669, "loc": { "start": { "line": 87, diff --git a/ets2panda/test/parser/ets/Morph3d-expected.txt b/ets2panda/test/parser/ets/Morph3d-expected.txt index 1ad08a5f9f34a1d63932dd09ffaaaa0dec19a25d..e915efc57123acff822b9732546d9441fe067889 100644 --- a/ets2panda/test/parser/ets/Morph3d-expected.txt +++ b/ets2panda/test/parser/ets/Morph3d-expected.txt @@ -524,146 +524,12 @@ } }, "dimension": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 28, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 35, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 36, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 41, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 26, - "column": 28, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 41, - "program": "Morph3d.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 44, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 51, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 52, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 57, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 26, - "column": 44, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 57, - "program": "Morph3d.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 28, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 57, - "program": "Morph3d.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 26, - "column": 60, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 61, - "program": "Morph3d.ets" - } - } - }, + "type": "NumberLiteral", + "value": 43200, "loc": { "start": { "line": 26, - "column": 28, + "column": 44, "program": "Morph3d.ets" }, "end": { @@ -816,146 +682,12 @@ } }, "right": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 37, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 38, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 43, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 43, - "program": "Morph3d.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 46, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 53, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 54, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 59, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 46, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 59, - "program": "Morph3d.ets" - } - } - }, - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 59, - "program": "Morph3d.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 27, - "column": 62, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 63, - "program": "Morph3d.ets" - } - } - }, + "type": "NumberLiteral", + "value": 43200, "loc": { "start": { "line": 27, - "column": 30, + "column": 46, "program": "Morph3d.ets" }, "end": { @@ -1434,43 +1166,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 33, - "column": 39, - "program": "Morph3d.ets" - }, - "end": { - "line": 33, - "column": 46, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 33, - "column": 47, - "program": "Morph3d.ets" - }, - "end": { - "line": 33, - "column": 52, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 33, @@ -1487,7 +1184,7 @@ "loc": { "start": { "line": 33, - "column": 30, + "column": 35, "program": "Morph3d.ets" }, "end": { @@ -1677,7 +1374,7 @@ "loc": { "start": { "line": 34, - "column": 36, + "column": 40, "program": "Morph3d.ets" }, "end": { @@ -1860,43 +1557,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 31, - "program": "Morph3d.ets" - }, - "end": { - "line": 36, - "column": 38, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 39, - "program": "Morph3d.ets" - }, - "end": { - "line": 36, - "column": 44, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 36, @@ -2064,43 +1726,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 32, - "program": "Morph3d.ets" - }, - "end": { - "line": 37, - "column": 39, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 40, - "program": "Morph3d.ets" - }, - "end": { - "line": 37, - "column": 45, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 37, @@ -2268,43 +1895,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 38, - "column": 28, - "program": "Morph3d.ets" - }, - "end": { - "line": 38, - "column": 35, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 38, - "column": 36, - "program": "Morph3d.ets" - }, - "end": { - "line": 38, - "column": 41, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 38, @@ -2825,43 +2417,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 44, - "column": 22, - "program": "Morph3d.ets" - }, - "end": { - "line": 44, - "column": 29, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n", - "decorators": [], - "loc": { - "start": { - "line": 44, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 44, - "column": 31, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 15, "loc": { "start": { "line": 44, @@ -3417,43 +2974,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 50, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 50, - "column": 37, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 50, - "column": 38, - "program": "Morph3d.ets" - }, - "end": { - "line": 50, - "column": 43, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 50, @@ -3638,43 +3160,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 51, - "column": 40, - "program": "Morph3d.ets" - }, - "end": { - "line": 51, - "column": 47, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 51, - "column": 48, - "program": "Morph3d.ets" - }, - "end": { - "line": 51, - "column": 53, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 51, diff --git a/ets2panda/test/parser/ets/StringBase64-expected.txt b/ets2panda/test/parser/ets/StringBase64-expected.txt index a307f1139eafd6725284e7736e39d1ee960b7e34..62d180759b1b224050cac0ace120ec3f5dec44eb 100644 --- a/ets2panda/test/parser/ets/StringBase64-expected.txt +++ b/ets2panda/test/parser/ets/StringBase64-expected.txt @@ -3179,43 +3179,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 25, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 25, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 25, @@ -3484,43 +3449,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 26, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 26, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 26, @@ -3987,43 +3917,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 27, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 27, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 27, @@ -4522,43 +4417,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 28, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 28, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 28, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 28, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 28, @@ -4898,7 +4758,7 @@ "loc": { "start": { "line": 30, - "column": 13, + "column": 22, "program": "StringBase64.ets" }, "end": { @@ -5102,43 +4962,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 32, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 32, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 32, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 32, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 32, @@ -5493,43 +5318,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 34, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 34, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 34, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 34, - "column": 59, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 34, @@ -5996,43 +5786,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 35, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 35, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 35, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 35, - "column": 59, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 35, @@ -6361,43 +6116,8 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 36, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BASE64PAD", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 36, - "column": 53, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "=", "loc": { "start": { "line": 36, @@ -6517,43 +6237,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 39, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 39, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 39, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 39, - "column": 59, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 39, @@ -6850,43 +6535,8 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 40, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BASE64PAD", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 40, - "column": 53, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "=", "loc": { "start": { "line": 40, @@ -6985,43 +6635,8 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 41, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 41, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BASE64PAD", - "decorators": [], - "loc": { - "start": { - "line": 41, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 41, - "column": 53, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "=", "loc": { "start": { "line": 41, @@ -8339,43 +7954,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 52, - "column": 55, - "program": "StringBase64.ets" - }, - "end": { - "line": 52, - "column": 67, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BASE64PAD", - "decorators": [], - "loc": { - "start": { - "line": 52, - "column": 68, - "program": "StringBase64.ets" - }, - "end": { - "line": 52, - "column": 77, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "=", "loc": { "start": { "line": 52, diff --git a/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt b/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt index b375b4963ca04d9d9298d2be916e2a9a2c4e09d4..e3248a34b3d043267ba548ff6190095925bf280a 100644 --- a/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt +++ b/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt @@ -235,38 +235,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": -1, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "as_expression_unary_expression.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "as_expression_unary_expression.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 24, - "program": "as_expression_unary_expression.ets" - }, - "end": { - "line": 17, - "column": 28, - "program": "as_expression_unary_expression.ets" - } - } - }, + "type": "NumberLiteral", + "value": -1, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/assert-expected.txt b/ets2panda/test/parser/ets/assert-expected.txt index 223e74ab3fdb41ba7a9de7045f9ad123206184bb..b1044004b9fe65e33824504aac401031449d2792 100644 --- a/ets2panda/test/parser/ets/assert-expected.txt +++ b/ets2panda/test/parser/ets/assert-expected.txt @@ -431,7 +431,7 @@ "loc": { "start": { "line": 20, - "column": 20, + "column": 24, "program": "assert.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/assign-expected.txt b/ets2panda/test/parser/ets/assign-expected.txt index b6142a48972ef35b4edb2574709e83ec7de73e98..98ef7bde5d64fbeee571c19fc2dece796260bf70 100644 --- a/ets2panda/test/parser/ets/assign-expected.txt +++ b/ets2panda/test/parser/ets/assign-expected.txt @@ -397,9 +397,8 @@ } }, "right": { - "type": "Identifier", - "name": "b", - "decorators": [], + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/binary_op-expected.txt b/ets2panda/test/parser/ets/binary_op-expected.txt index 6ee5608b7e743501f7af6891bbff292e82b65dbc..66494fa2c32071a2115ee3a1ac15d2ff718366f2 100644 --- a/ets2panda/test/parser/ets/binary_op-expected.txt +++ b/ets2panda/test/parser/ets/binary_op-expected.txt @@ -806,7 +806,7 @@ "loc": { "start": { "line": 26, - "column": 10, + "column": 16, "program": "binary_op.ets" }, "end": { @@ -1136,7 +1136,7 @@ "loc": { "start": { "line": 31, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -1300,7 +1300,7 @@ "loc": { "start": { "line": 32, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -1464,7 +1464,7 @@ "loc": { "start": { "line": 33, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -1645,7 +1645,7 @@ "loc": { "start": { "line": 34, - "column": 17, + "column": 23, "program": "binary_op.ets" }, "end": { @@ -2119,7 +2119,7 @@ "loc": { "start": { "line": 40, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -3522,7 +3522,7 @@ "loc": { "start": { "line": 59, - "column": 11, + "column": 16, "program": "binary_op.ets" }, "end": { @@ -3882,7 +3882,7 @@ "loc": { "start": { "line": 64, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -4346,7 +4346,7 @@ "loc": { "start": { "line": 70, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -4600,7 +4600,7 @@ "loc": { "start": { "line": 73, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -4734,7 +4734,7 @@ "loc": { "start": { "line": 74, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -4919,7 +4919,7 @@ "loc": { "start": { "line": 75, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -5738,7 +5738,7 @@ "loc": { "start": { "line": 77, - "column": 17, + "column": 23, "program": "binary_op.ets" }, "end": { @@ -6470,7 +6470,7 @@ "loc": { "start": { "line": 26, - "column": 10, + "column": 16, "program": "binary_op.ets" }, "end": { @@ -6776,7 +6776,7 @@ "loc": { "start": { "line": 31, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -6932,7 +6932,7 @@ "loc": { "start": { "line": 32, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -7088,7 +7088,7 @@ "loc": { "start": { "line": 33, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -7261,7 +7261,7 @@ "loc": { "start": { "line": 34, - "column": 17, + "column": 23, "program": "binary_op.ets" }, "end": { @@ -7703,7 +7703,7 @@ "loc": { "start": { "line": 40, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -9002,7 +9002,7 @@ "loc": { "start": { "line": 59, - "column": 11, + "column": 16, "program": "binary_op.ets" }, "end": { @@ -9338,7 +9338,7 @@ "loc": { "start": { "line": 64, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -9770,7 +9770,7 @@ "loc": { "start": { "line": 70, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -10016,7 +10016,7 @@ "loc": { "start": { "line": 73, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -10142,7 +10142,7 @@ "loc": { "start": { "line": 74, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -10319,7 +10319,7 @@ "loc": { "start": { "line": 75, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -11122,7 +11122,7 @@ "loc": { "start": { "line": 77, - "column": 17, + "column": 23, "program": "binary_op.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/binary_operations-expected.txt b/ets2panda/test/parser/ets/binary_operations-expected.txt index b720e56330d26f26a73e2358fea1dbd1255ea8bf..e456b8b907fec344883b8c8f09b58113c6079b8e 100644 --- a/ets2panda/test/parser/ets/binary_operations-expected.txt +++ b/ets2panda/test/parser/ets/binary_operations-expected.txt @@ -44,40 +44,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 17, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 17, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 17, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 17, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 17, @@ -147,104 +115,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 18, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 18, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 18, - "column": 38, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 39, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 18, @@ -314,40 +186,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 19, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 19, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 19, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 19, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 19, @@ -417,76 +257,12 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 20, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 20, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 20, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 20, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 20, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 20, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 20, - "column": 35, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 13, "loc": { "start": { "line": 20, - "column": 26, + "column": 30, "program": "binary_operations.ets" }, "end": { @@ -552,40 +328,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 21, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 21, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 21, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 21, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 21, @@ -655,108 +399,12 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 22, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 22, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 22, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 22, - "column": 38, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 39, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 39, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": -14, "loc": { "start": { "line": 22, - "column": 26, + "column": 30, "program": "binary_operations.ets" }, "end": { @@ -822,40 +470,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 6.2, - "loc": { - "start": { - "line": 23, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 23, - "column": 32, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3.14, - "loc": { - "start": { - "line": 23, - "column": 35, - "program": "binary_operations.ets" - }, - "end": { - "line": 23, - "column": 39, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 19.468, "loc": { "start": { "line": 23, @@ -864,7 +480,7 @@ }, "end": { "line": 23, - "column": 39, + "column": 41, "program": "binary_operations.ets" } } @@ -900,7 +516,7 @@ }, "end": { "line": 23, - "column": 39, + "column": 41, "program": "binary_operations.ets" } } @@ -925,104 +541,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 6.2, - "loc": { - "start": { - "line": 24, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 33, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 3.7, - "loc": { - "start": { - "line": 24, - "column": 37, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 40, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8.18, - "loc": { - "start": { - "line": 24, - "column": 43, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 47, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 36, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 48, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 48, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2.2, - "loc": { - "start": { - "line": 24, - "column": 51, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 54, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 33.48, "loc": { "start": { "line": 24, @@ -1092,40 +612,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 4.2, - "loc": { - "start": { - "line": 25, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 25, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2.3, - "loc": { - "start": { - "line": 25, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 25, - "column": 37, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1.82609, "loc": { "start": { "line": 25, @@ -1134,7 +622,7 @@ }, "end": { "line": 25, - "column": 37, + "column": 39, "program": "binary_operations.ets" } } @@ -1170,7 +658,7 @@ }, "end": { "line": 25, - "column": 37, + "column": 39, "program": "binary_operations.ets" } } @@ -1195,136 +683,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 4.2, - "loc": { - "start": { - "line": 26, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "NumberLiteral", - "value": 2.2, - "loc": { - "start": { - "line": 26, - "column": 36, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 39, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 26, - "column": 42, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 45, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 35, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 46, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 46, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 3.3, - "loc": { - "start": { - "line": 26, - "column": 50, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 53, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 6.1, - "loc": { - "start": { - "line": 26, - "column": 56, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 59, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 49, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 60, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2.54098, "loc": { "start": { "line": 26, @@ -1394,40 +754,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "<<", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 27, - "column": 25, - "program": "binary_operations.ets" - }, - "end": { - "line": 27, - "column": 26, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 27, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 28, "loc": { "start": { "line": 27, @@ -1497,40 +825,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": ">>", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 28, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 28, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 28, - "column": 31, - "program": "binary_operations.ets" - }, - "end": { - "line": 28, - "column": 32, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 28, @@ -1600,40 +896,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": ">>>", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 29, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 29, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 29, - "column": 32, - "program": "binary_operations.ets" - }, - "end": { - "line": 29, - "column": 33, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 29, @@ -1703,40 +967,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "&", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 30, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 30, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 30, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 30, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 30, @@ -1790,56 +1022,24 @@ "type": "ClassProperty", "key": { "type": "Identifier", - "name": "bit2", - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 13, - "program": "binary_operations.ets" - }, - "end": { - "line": 31, - "column": 17, - "program": "binary_operations.ets" - } - } - }, - "value": { - "type": "BinaryExpression", - "operator": "|", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 31, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 31, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 31, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 31, - "column": 31, - "program": "binary_operations.ets" - } + "name": "bit2", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 13, + "program": "binary_operations.ets" + }, + "end": { + "line": 31, + "column": 17, + "program": "binary_operations.ets" } - }, + } + }, + "value": { + "type": "NumberLiteral", + "value": 7, "loc": { "start": { "line": 31, @@ -1909,40 +1109,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "^", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 32, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 32, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 32, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 32, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 32, @@ -2012,40 +1180,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "<", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 33, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 33, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 33, - "column": 32, - "program": "binary_operations.ets" - }, - "end": { - "line": 33, - "column": 33, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": true, "loc": { "start": { "line": 33, @@ -2115,40 +1251,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "<=", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 34, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 34, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 34, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 34, - "column": 34, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": true, "loc": { "start": { "line": 34, @@ -2218,40 +1322,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": ">=", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 35, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 35, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 35, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 35, - "column": 34, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 35, @@ -2321,40 +1393,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": ">", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 36, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 36, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 36, - "column": 32, - "program": "binary_operations.ets" - }, - "end": { - "line": 36, - "column": 33, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 36, @@ -2424,40 +1464,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 37, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 37, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 37, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 37, - "column": 34, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 37, @@ -2527,40 +1535,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "!=", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 38, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 38, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 38, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 38, - "column": 34, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": true, "loc": { "start": { "line": 38, @@ -2630,104 +1606,8 @@ } }, "value": { - "type": "LogicalExpression", - "operator": "&&", - "left": { - "type": "BinaryExpression", - "operator": "<", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 39, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 30, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 39, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 34, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 39, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": ">", - "left": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 39, - "column": 40, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 41, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 39, - "column": 44, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 45, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 39, - "column": 39, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 46, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 39, @@ -2797,104 +1677,8 @@ } }, "value": { - "type": "LogicalExpression", - "operator": "||", - "left": { - "type": "BinaryExpression", - "operator": "<", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 40, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 30, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 40, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 34, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 40, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": ">", - "left": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 40, - "column": 40, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 41, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 40, - "column": 44, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 45, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 40, - "column": 39, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 46, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": true, "loc": { "start": { "line": 40, diff --git a/ets2panda/test/parser/ets/binary_operations.ets b/ets2panda/test/parser/ets/binary_operations.ets index 308cb1ebe81f0b441129bb2744b9226e90222802..5c6aeef5091d660465fec54773cc33258dc13b9c 100644 --- a/ets2panda/test/parser/ets/binary_operations.ets +++ b/ets2panda/test/parser/ets/binary_operations.ets @@ -20,9 +20,9 @@ export class binary_operations { private sub2 : int = 8 - 3 + 8; private rem1 : int = 5 % 3; private rem2 : int = 5 % 3 - 2 * 8; - private mult1 : float = 6.2 * 3.14; + private mult1 : float = 6.2f * 3.14f; private mult2 : double = 6.2 * (3.7 + 8.18) / 2.2; - private div1 : float = 4.2 / 2.3; + private div1 : float = 4.2f / 2.3f; private div2 : double = 4.2 / (2.2 - 0.1) + (3.3 / 6.1); private lsh : int = 7 << 2; private rsh1 : int = 7 >> 2; diff --git a/ets2panda/test/parser/ets/boolean_cond-expected.txt b/ets2panda/test/parser/ets/boolean_cond-expected.txt index 5ede97c31639681fddc9431bcf09ff904c3370e0..f498e6d0d0aa72e83470b584a558f3b7857a6d74 100644 --- a/ets2panda/test/parser/ets/boolean_cond-expected.txt +++ b/ets2panda/test/parser/ets/boolean_cond-expected.txt @@ -248,40 +248,8 @@ { "type": "IfStatement", "test": { - "type": "BinaryExpression", - "operator": ">", - "left": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 20, - "column": 7, - "program": "boolean_cond.ets" - }, - "end": { - "line": 20, - "column": 8, - "program": "boolean_cond.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 20, - "column": 11, - "program": "boolean_cond.ets" - }, - "end": { - "line": 20, - "column": 12, - "program": "boolean_cond.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/cast_expressions-expected.txt b/ets2panda/test/parser/ets/cast_expressions-expected.txt index c7ca64e2b7c216bab5d73a13b3e74c4dfdf57267..6d76a9e8a4ff35ac8f8733737ca3da3d0781804e 100644 --- a/ets2panda/test/parser/ets/cast_expressions-expected.txt +++ b/ets2panda/test/parser/ets/cast_expressions-expected.txt @@ -504,38 +504,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 18, - "column": 30, - "program": "cast_expressions.ets" - }, - "end": { - "line": 18, - "column": 32, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 36, - "program": "cast_expressions.ets" - }, - "end": { - "line": 18, - "column": 40, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 18, @@ -2596,38 +2566,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 48, - "column": 33, - "program": "cast_expressions.ets" - }, - "end": { - "line": 48, - "column": 35, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 48, - "column": 39, - "program": "cast_expressions.ets" - }, - "end": { - "line": 48, - "column": 44, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 48, @@ -4428,8 +4368,8 @@ } }, "init": { - "type": "NumberLiteral", - "value": 42, + "type": "CharLiteral", + "value": "*", "loc": { "start": { "line": 76, @@ -4591,38 +4531,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 77, - "column": 30, - "program": "cast_expressions.ets" - }, - "end": { - "line": 77, - "column": 32, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 77, - "column": 36, - "program": "cast_expressions.ets" - }, - "end": { - "line": 77, - "column": 40, - "program": "cast_expressions.ets" - } - } - }, + "type": "CharLiteral", + "value": "*", "loc": { "start": { "line": 77, @@ -6586,38 +6496,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 106, - "column": 27, - "program": "cast_expressions.ets" - }, - "end": { - "line": 106, - "column": 29, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 106, - "column": 33, - "program": "cast_expressions.ets" - }, - "end": { - "line": 106, - "column": 36, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 106, @@ -8484,38 +8364,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 134, - "column": 30, - "program": "cast_expressions.ets" - }, - "end": { - "line": 134, - "column": 32, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 134, - "column": 36, - "program": "cast_expressions.ets" - }, - "end": { - "line": 134, - "column": 40, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 134, @@ -10285,38 +10135,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 161, - "column": 33, - "program": "cast_expressions.ets" - }, - "end": { - "line": 161, - "column": 35, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 161, - "column": 39, - "program": "cast_expressions.ets" - }, - "end": { - "line": 161, - "column": 44, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 161, @@ -11989,38 +11809,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 187, - "column": 36, - "program": "cast_expressions.ets" - }, - "end": { - "line": 187, - "column": 38, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 187, - "column": 42, - "program": "cast_expressions.ets" - }, - "end": { - "line": 187, - "column": 48, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 187, diff --git a/ets2panda/test/parser/ets/class_init-expected.txt b/ets2panda/test/parser/ets/class_init-expected.txt index a3a99d1115670602c19e8ddde7e40244701e20cc..e5d69c29a62fc2cd2f09842f98cb9fb9a5400c1a 100644 --- a/ets2panda/test/parser/ets/class_init-expected.txt +++ b/ets2panda/test/parser/ets/class_init-expected.txt @@ -166,40 +166,8 @@ } }, "right": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 30, - "loc": { - "start": { - "line": 20, - "column": 11, - "program": "class_init.ets" - }, - "end": { - "line": 20, - "column": 13, - "program": "class_init.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 99, - "loc": { - "start": { - "line": 20, - "column": 16, - "program": "class_init.ets" - }, - "end": { - "line": 20, - "column": 18, - "program": "class_init.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2970, "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt b/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt index 5d2945240a522c88cc46ee7fbce274b1343262b1..8783d8a8caa04bc45f52fa8e633d8ff13cc8e865 100644 --- a/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt +++ b/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt @@ -235,8 +235,8 @@ } }, "init": { - "type": "NumberLiteral", - "value": 100, + "type": "CharLiteral", + "value": "d", "loc": { "start": { "line": 17, @@ -301,56 +301,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 18, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 18, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 18, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 68, - "loc": { - "start": { - "line": 18, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 18, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "a", + "decorators": [], "loc": { "start": { "line": 18, @@ -496,56 +449,8 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 21, - "column": 15, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 21, - "column": 20, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 23, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 21, - "column": 24, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 68, - "loc": { - "start": { - "line": 21, - "column": 27, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 21, - "column": 29, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "NumberLiteral", + "value": 68, "loc": { "start": { "line": 21, @@ -723,56 +628,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 24, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 24, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 24, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 419, - "loc": { - "start": { - "line": 24, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 24, - "column": 31, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "c", + "decorators": [], "loc": { "start": { "line": 24, @@ -852,8 +710,8 @@ } }, "init": { - "type": "NumberLiteral", - "value": 3, + "type": "CharLiteral", + "value": "\u0003", "loc": { "start": { "line": 26, @@ -918,56 +776,8 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 27, - "column": 18, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 27, - "column": 23, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 26, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 27, - "column": 27, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 665, - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "NumberLiteral", + "value": 665, "loc": { "start": { "line": 27, @@ -1145,56 +955,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 30, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 30, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 30, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 30, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 665, - "loc": { - "start": { - "line": 30, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 30, - "column": 31, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "c", + "decorators": [], "loc": { "start": { "line": 30, @@ -1340,56 +1103,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 33, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 33, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 33, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 33, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 665419, - "loc": { - "start": { - "line": 33, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 33, - "column": 34, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "c", + "decorators": [], "loc": { "start": { "line": 33, @@ -1535,56 +1251,8 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 36, - "column": 19, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 36, - "column": 24, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "g", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 27, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 36, - "column": 28, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 30, - "loc": { - "start": { - "line": 36, - "column": 31, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 36, - "column": 33, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "NumberLiteral", + "value": 30, "loc": { "start": { "line": 36, @@ -1965,57 +1633,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 42, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 42, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 42, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 42, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 42, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 42, - "column": 29, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "a", + "decorators": [], "loc": { "start": { "line": 42, @@ -2274,57 +1894,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 46, - "column": 15, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 46, - "column": 20, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 46, - "column": 23, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 46, - "column": 24, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 46, - "column": 27, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 46, - "column": 28, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "b", + "decorators": [], "loc": { "start": { "line": 46, @@ -2617,7 +2189,7 @@ }, "end": { "line": 51, - "column": 24, + "column": 25, "program": "conditionalExpressionType.ets" } } @@ -2630,7 +2202,7 @@ }, "end": { "line": 51, - "column": 24, + "column": 25, "program": "conditionalExpressionType.ets" } } @@ -2645,7 +2217,7 @@ }, "end": { "line": 51, - "column": 25, + "column": 26, "program": "conditionalExpressionType.ets" } } @@ -3044,8 +2616,8 @@ } }, "init": { - "type": "NumberLiteral", - "value": 2, + "type": "CharLiteral", + "value": "\u0002", "loc": { "start": { "line": 56, @@ -3110,57 +2682,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 58, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 58, - "column": 22, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 58, - "column": 25, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 58, - "column": 26, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 58, - "column": 29, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 58, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "b", + "decorators": [], "loc": { "start": { "line": 58, @@ -3225,57 +2749,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 59, - "column": 15, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 59, - "column": 20, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 59, - "column": 23, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 59, - "column": 24, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 59, - "column": 27, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 59, - "column": 28, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "c", + "decorators": [], "loc": { "start": { "line": 59, @@ -3340,57 +2816,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 60, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 60, - "column": 22, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 60, - "column": 25, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 60, - "column": 26, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "d", - "decorators": [], - "loc": { - "start": { - "line": 60, - "column": 29, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 60, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "d", + "decorators": [], "loc": { "start": { "line": 60, @@ -3455,57 +2883,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 61, - "column": 18, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 61, - "column": 23, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "d", - "decorators": [], - "loc": { - "start": { - "line": 61, - "column": 26, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 61, - "column": 27, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "e", - "decorators": [], - "loc": { - "start": { - "line": 61, - "column": 30, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 61, - "column": 31, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "e", + "decorators": [], "loc": { "start": { "line": 61, @@ -3570,57 +2950,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 62, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 62, - "column": 22, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "e", - "decorators": [], - "loc": { - "start": { - "line": 62, - "column": 25, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 62, - "column": 26, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "f", - "decorators": [], - "loc": { - "start": { - "line": 62, - "column": 29, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 62, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "f", + "decorators": [], "loc": { "start": { "line": 62, @@ -3685,57 +3017,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 63, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 63, - "column": 22, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "f", - "decorators": [], - "loc": { - "start": { - "line": 63, - "column": 25, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 63, - "column": 26, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "g", - "decorators": [], - "loc": { - "start": { - "line": 63, - "column": 29, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 63, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "g", + "decorators": [], "loc": { "start": { "line": 63, diff --git a/ets2panda/test/parser/ets/conditionalExpressionType.ets b/ets2panda/test/parser/ets/conditionalExpressionType.ets index 1a17d452f63ed82b1f04aa36fa43b86ba2e28a3a..a3094001cdb4b1626b4a0a3094b97c041729cf7a 100644 --- a/ets2panda/test/parser/ets/conditionalExpressionType.ets +++ b/ets2panda/test/parser/ets/conditionalExpressionType.ets @@ -48,7 +48,7 @@ function unboxingCases(): void{ function dominantNumericCases(): void{ let a : double = 2.0; - let b : float = 2.0; + let b : float = 2.0f; let c : long = 2; let d : int = 2; let e : Short = 2; diff --git a/ets2panda/test/parser/ets/conversions-expected.txt b/ets2panda/test/parser/ets/conversions-expected.txt index de9e873fde2be36bd49965131f9ed277a44f1cb3..aa4456c66bf83ae97d55117670cca36995a51e3b 100644 --- a/ets2panda/test/parser/ets/conversions-expected.txt +++ b/ets2panda/test/parser/ets/conversions-expected.txt @@ -235,38 +235,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 17, - "column": 19, - "program": "conversions.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "conversions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 24, - "program": "conversions.ets" - }, - "end": { - "line": 17, - "column": 28, - "program": "conversions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/declare_enum-expected.txt b/ets2panda/test/parser/ets/declare_enum-expected.txt index ace3a9cf3788a8c5a40c6c6159c836a87a84c6fa..0e5f9ad8156a873734876f3abb94a93af73350c2 100644 --- a/ets2panda/test/parser/ets/declare_enum-expected.txt +++ b/ets2panda/test/parser/ets/declare_enum-expected.txt @@ -177,7 +177,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/default_parameter5-expected.txt b/ets2panda/test/parser/ets/default_parameter5-expected.txt index 9ab9f2a7d4ca7fd4e77c46b3edfbea1d0c1af0f3..e2e6805249dbc5982089cbe25a34ccb09d5bcd72 100644 --- a/ets2panda/test/parser/ets/default_parameter5-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter5-expected.txt @@ -861,7 +861,7 @@ "loc": { "start": { "line": 23, - "column": 12, + "column": 17, "program": "default_parameter5.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/default_parameter8-expected.txt b/ets2panda/test/parser/ets/default_parameter8-expected.txt index ec5ead42f2d8c35ddc2d17369ab61787b459caef..3a65cce5fb8bbccc28a94ec849eb588247fe0781 100644 --- a/ets2panda/test/parser/ets/default_parameter8-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter8-expected.txt @@ -709,38 +709,8 @@ } }, "alternate": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 99, - "loc": { - "start": { - "line": 21, - "column": 30, - "program": "default_parameter8.ets" - }, - "end": { - "line": 21, - "column": 32, - "program": "default_parameter8.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 24, - "program": "default_parameter8.ets" - }, - "end": { - "line": 21, - "column": 27, - "program": "default_parameter8.ets" - } - } - }, + "type": "NumberLiteral", + "value": 99, "loc": { "start": { "line": 1, diff --git a/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt b/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt index 190b9c3fe66e2ff19e195499a8da526d5c162ffe..ca48d97c207d903ab131e760fa32f2f791324d4a 100644 --- a/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt @@ -558,70 +558,8 @@ } }, "alternate": { - "type": "TSAsExpression", - "expression": { - "type": "StringLiteral", - "value": "default", - "loc": { - "start": { - "line": 16, - "column": 38, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 47, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 29, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 35, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 29, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 37, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 29, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 37, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, + "type": "StringLiteral", + "value": "default", "loc": { "start": { "line": 1, @@ -814,70 +752,8 @@ } }, "alternate": { - "type": "TSAsExpression", - "expression": { - "type": "StringLiteral", - "value": "another", - "loc": { - "start": { - "line": 16, - "column": 61, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 70, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 52, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 58, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 52, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 60, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 52, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 60, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, + "type": "StringLiteral", + "value": "another", "loc": { "start": { "line": 1, diff --git a/ets2panda/test/parser/ets/field_decl-expected.txt b/ets2panda/test/parser/ets/field_decl-expected.txt index 0ac292d2ba0ccaca18e2d14abe121b65c93b540f..689727a8d8966dcd05b51ffb80d3b6e42f605e02 100644 --- a/ets2panda/test/parser/ets/field_decl-expected.txt +++ b/ets2panda/test/parser/ets/field_decl-expected.txt @@ -416,7 +416,7 @@ }, "end": { "line": 23, - "column": 38, + "column": 39, "program": "field_decl.ets" } } @@ -452,7 +452,7 @@ }, "end": { "line": 23, - "column": 38, + "column": 39, "program": "field_decl.ets" } } diff --git a/ets2panda/test/parser/ets/field_decl.ets b/ets2panda/test/parser/ets/field_decl.ets index 68d3688c7dd1e941042e97ff14d7e12492e61255..2a2d52b1a4db5da2a28c5f955e030508a73eeeb6 100644 --- a/ets2panda/test/parser/ets/field_decl.ets +++ b/ets2panda/test/parser/ets/field_decl.ets @@ -20,7 +20,7 @@ export class field_decl { public d : boolean = true; f : short ; static g : long ; - static readonly pi : float = 3.14; + static readonly pi : float = 3.14f; public static readonly e : double = 2.71828; private readonly h : byte = 2; } diff --git a/ets2panda/test/parser/ets/float_pont_format_2-expected.txt b/ets2panda/test/parser/ets/float_pont_format_2-expected.txt index 850d7b2cc21cdb260306e09db04b1f8d9978da7e..bec8dfd0304237b8a70d9c74a406bb255b9fb892 100644 --- a/ets2panda/test/parser/ets/float_pont_format_2-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_2-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_2.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_2.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_2.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_2.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_3-expected.txt b/ets2panda/test/parser/ets/float_pont_format_3-expected.txt index 21d98fea126358a9f552056842d1764853f957b6..7ed81174d521c46f568f509326062b224ea392f7 100644 --- a/ets2panda/test/parser/ets/float_pont_format_3-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_3-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 1.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_3.ets" - }, - "end": { - "line": 17, - "column": 16, - "program": "float_pont_format_3.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 19, - "program": "float_pont_format_3.ets" - }, - "end": { - "line": 17, - "column": 21, - "program": "float_pont_format_3.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_4-expected.txt b/ets2panda/test/parser/ets/float_pont_format_4-expected.txt index db9f5816e99e3ff470ef137a5ab5f83962f47f5b..d6d8338179f1773ccfae01dbdc0aa807d22f1de0 100644 --- a/ets2panda/test/parser/ets/float_pont_format_4-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_4-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_4.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_4.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1.5, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_4.ets" - }, - "end": { - "line": 17, - "column": 21, - "program": "float_pont_format_4.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_5-expected.txt b/ets2panda/test/parser/ets/float_pont_format_5-expected.txt index 5624b9cbb9801ab2ba283cd4d0c32cafb89d83bc..4913b2533c134e861ba0fa200b587fb6cd5ac081 100644 --- a/ets2panda/test/parser/ets/float_pont_format_5-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_5-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 1.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_5.ets" - }, - "end": { - "line": 17, - "column": 16, - "program": "float_pont_format_5.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 19, - "program": "float_pont_format_5.ets" - }, - "end": { - "line": 17, - "column": 21, - "program": "float_pont_format_5.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_6-expected.txt b/ets2panda/test/parser/ets/float_pont_format_6-expected.txt index 3a786d9c44513b5e7ae9d0116e1968cca0d82141..0fafd5d120aa582b0969be54245ccd0e1229b5cc 100644 --- a/ets2panda/test/parser/ets/float_pont_format_6-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_6-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_6.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_6.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_6.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_6.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_7-expected.txt b/ets2panda/test/parser/ets/float_pont_format_7-expected.txt index a913834768cbadcb92d5f7af7976685cae63384e..99931a57f0d5a4c981cce0604a145a237cf3e3e4 100644 --- a/ets2panda/test/parser/ets/float_pont_format_7-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_7-expected.txt @@ -205,172 +205,12 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.7, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_7.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.4, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 25, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 29, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 31, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 17, - "column": 34, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 36, - "program": "float_pont_format_7.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 28, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "float_pont_format_7.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 40, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_7.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_7.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1.2, "loc": { "start": { "line": 17, - "column": 13, + "column": 18, "program": "float_pont_format_7.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/float_pont_format_8-expected.txt b/ets2panda/test/parser/ets/float_pont_format_8-expected.txt index f492de68b9ca6acd7130954270fbc7354d6b3a00..034dfbfa3ca98f4c544672af6a461367059c3832 100644 --- a/ets2panda/test/parser/ets/float_pont_format_8-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_8-expected.txt @@ -205,552 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.7, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.4, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 25, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 29, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 31, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 17, - "column": 34, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 36, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 28, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 40, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 47, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 49, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.7, - "loc": { - "start": { - "line": 17, - "column": 52, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 54, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 47, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 54, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.4, - "loc": { - "start": { - "line": 17, - "column": 57, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 59, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 63, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 65, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 17, - "column": 68, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 70, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 62, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 71, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 57, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 71, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 74, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 76, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 57, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 76, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 46, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 77, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 80, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 82, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 46, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 82, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.7, - "loc": { - "start": { - "line": 17, - "column": 85, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 87, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 46, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 87, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.4, - "loc": { - "start": { - "line": 17, - "column": 90, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 92, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 96, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 98, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 17, - "column": 101, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 103, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 95, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 104, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 90, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 104, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 107, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 109, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 90, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 109, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 45, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 110, - "program": "float_pont_format_8.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2.5, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_separator_1-expected.txt b/ets2panda/test/parser/ets/float_separator_1-expected.txt index 6457c933627ccc964a32a6f6cf2aa211228362df..f90de87c9c6a35759ca5b12b750ed84e8981807c 100644 --- a/ets2panda/test/parser/ets/float_separator_1-expected.txt +++ b/ets2panda/test/parser/ets/float_separator_1-expected.txt @@ -230,7 +230,7 @@ }, "end": { "line": 17, - "column": 38, + "column": 39, "program": "float_separator_1.ets" } } @@ -243,7 +243,7 @@ }, "end": { "line": 17, - "column": 38, + "column": 39, "program": "float_separator_1.ets" } } @@ -258,7 +258,7 @@ }, "end": { "line": 17, - "column": 38, + "column": 39, "program": "float_separator_1.ets" } } diff --git a/ets2panda/test/parser/ets/float_separator_1.ets b/ets2panda/test/parser/ets/float_separator_1.ets index 419d60864d457e21f2ac948685143bd20d2c5feb..568ef176d8ffc70e1920bb037eba2b3dda4e73a3 100644 --- a/ets2panda/test/parser/ets/float_separator_1.ets +++ b/ets2panda/test/parser/ets/float_separator_1.ets @@ -14,5 +14,5 @@ */ function main() { - let a: float = -0.0e2_147_483_647 + let a: float = -0.0e2_147_483_647f } diff --git a/ets2panda/test/parser/ets/for_with_break-expected.txt b/ets2panda/test/parser/ets/for_with_break-expected.txt index 25c3039b126a8e4f19edd8a29bd696b45573fe1a..257f20e53e4d571cb8d60833862b9fff820e1ae4 100644 --- a/ets2panda/test/parser/ets/for_with_break-expected.txt +++ b/ets2panda/test/parser/ets/for_with_break-expected.txt @@ -505,7 +505,7 @@ "loc": { "start": { "line": 19, - "column": 13, + "column": 17, "program": "for_with_break.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/forofUnboxing-expected.txt b/ets2panda/test/parser/ets/forofUnboxing-expected.txt index 10cc306b5c6a136c8ce86b3fb97bdc78927fd3ec..7efc172b3fd6f338139b4e8262eba673b8d040d2 100644 --- a/ets2panda/test/parser/ets/forofUnboxing-expected.txt +++ b/ets2panda/test/parser/ets/forofUnboxing-expected.txt @@ -450,38 +450,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 10, - "loc": { - "start": { - "line": 18, - "column": 33, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 35, - "program": "forofUnboxing.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 39, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 43, - "program": "forofUnboxing.ets" - } - } - }, + "type": "NumberLiteral", + "value": 10, "loc": { "start": { "line": 18, @@ -560,38 +530,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 12, - "loc": { - "start": { - "line": 18, - "column": 55, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 57, - "program": "forofUnboxing.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 61, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 65, - "program": "forofUnboxing.ets" - } - } - }, + "type": "NumberLiteral", + "value": 12, "loc": { "start": { "line": 18, @@ -670,38 +610,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 33, - "loc": { - "start": { - "line": 18, - "column": 77, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 79, - "program": "forofUnboxing.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 83, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 87, - "program": "forofUnboxing.ets" - } - } - }, + "type": "NumberLiteral", + "value": 33, "loc": { "start": { "line": 18, diff --git a/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt index 4714961b8794da066fa49754609aad26c881d440..dd55942add48bcfaa8e07bc1d6ec3f3fe92a38e1 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt @@ -1286,7 +1286,7 @@ "loc": { "start": { "line": 39, - "column": 15, + "column": 24, "program": "function_implicit_return_type8.ets" }, "end": { @@ -1451,7 +1451,7 @@ "loc": { "start": { "line": 40, - "column": 15, + "column": 24, "program": "function_implicit_return_type8.ets" }, "end": { @@ -1616,7 +1616,7 @@ "loc": { "start": { "line": 41, - "column": 15, + "column": 24, "program": "function_implicit_return_type8.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt index b9502a4e9991e475e49707a18b07c8aafd4b399f..3355f5dd6d7ba0489c59b9da150701964c874236 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt @@ -1673,7 +1673,7 @@ "loc": { "start": { "line": 43, - "column": 15, + "column": 24, "program": "function_implicit_return_type9.ets" }, "end": { @@ -1838,7 +1838,7 @@ "loc": { "start": { "line": 44, - "column": 15, + "column": 24, "program": "function_implicit_return_type9.ets" }, "end": { @@ -2003,7 +2003,7 @@ "loc": { "start": { "line": 45, - "column": 15, + "column": 24, "program": "function_implicit_return_type9.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt index 0f0b79893122df041613b015175524007968a109..c73c634d4e4c99939cca714afbe0db457ccd100f 100644 --- a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt @@ -696,7 +696,7 @@ }, "end": { "line": 16, - "column": 32, + "column": 33, "program": "imported_module_2.ets" } } @@ -732,7 +732,7 @@ }, "end": { "line": 16, - "column": 32, + "column": 33, "program": "imported_module_2.ets" } } diff --git a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets index b5508f11e48cfdb60591944353328bb4e1811050..cfbfbd87eddd1d49dff5130aca97e3ae7bf35e2d 100644 --- a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets +++ b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -export const flt: float = 2.345; +export const flt: float = 2.345f; export let c: int = 3; diff --git a/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt index b2003212002cfd90f02b6e95f55be89e306fd67b..f72675996ee7e28dc3b7aa46565248f647373a0a 100755 --- a/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt @@ -698,7 +698,7 @@ }, "end": { "line": 18, - "column": 33, + "column": 34, "program": "package_module_2.ets" } } @@ -734,7 +734,7 @@ }, "end": { "line": 18, - "column": 33, + "column": 34, "program": "package_module_2.ets" } } diff --git a/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt index b1d61276d998f51f6b8cece64749b90610cecfc8..c746d9151ee318a7352565a82d313e89e33b8f43 100755 --- a/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt @@ -224,7 +224,7 @@ }, "end": { "line": 18, - "column": 33, + "column": 34, "program": "package_module_2.ets" } } @@ -260,7 +260,7 @@ }, "end": { "line": 18, - "column": 33, + "column": 34, "program": "package_module_2.ets" } } @@ -295,7 +295,7 @@ }, "end": { "line": 18, - "column": 34, + "column": 35, "program": "package_module_1.ets" } } @@ -331,7 +331,7 @@ }, "end": { "line": 18, - "column": 34, + "column": 35, "program": "package_module_1.ets" } } diff --git a/ets2panda/test/parser/ets/import_tests/packages/package_module_2.ets b/ets2panda/test/parser/ets/import_tests/packages/package_module_2.ets index d7cfbc67158a812f89a8edaf79fc910bcc0808cf..4b828a1d6b4ddd31aadadecd54b36ba0d75b1d89 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/package_module_2.ets +++ b/ets2panda/test/parser/ets/import_tests/packages/package_module_2.ets @@ -15,4 +15,4 @@ package import_tests.packages; -export const flt: float = 1.2345; +export const flt: float = 1.2345f; diff --git a/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt b/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt index 4c37f7a5314935d5b25a1a9a757b2fd8cd5d638f..5773b160e076af94e479398db2f09cdadcf8dc97 100644 --- a/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt @@ -530,7 +530,7 @@ "loc": { "start": { "line": 22, - "column": 9, + "column": 13, "program": "labeledDoWhileStatement.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/labeledForStatement-expected.txt b/ets2panda/test/parser/ets/labeledForStatement-expected.txt index bb8876b63ced9239fd0ffdcd3cdaa38fa5241702..440198edf0fadeffa32ff4990ff1a2601bad7640 100644 --- a/ets2panda/test/parser/ets/labeledForStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledForStatement-expected.txt @@ -1111,7 +1111,7 @@ "loc": { "start": { "line": 29, - "column": 11, + "column": 15, "program": "labeledForStatement.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt b/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt index a5074ba1980618a08633c83c0f2a79dfd882b9ee..cefec5d02218b7a8100df687e65cc785fb129c82 100644 --- a/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt @@ -647,7 +647,7 @@ "loc": { "start": { "line": 23, - "column": 9, + "column": 13, "program": "labeledWhileStatement.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt index 59c102cdb8f2b0da33b11d02dd52fa430324babe..3e4cc5e503f1de725413858d98be61bdfb7f8fcd 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt @@ -1643,6 +1643,5 @@ } } } -TypeError: Reference to foo is ambiguous [lambda-type-inference-overloaded.ets:28:5] TypeError: The type of parameter 'x' cannot be inferred [lambda-type-inference-overloaded.ets:31:10] TypeError: The type of parameter 'y' cannot be inferred [lambda-type-inference-overloaded.ets:31:13] diff --git a/ets2panda/test/parser/ets/null_valid-expected.txt b/ets2panda/test/parser/ets/null_valid-expected.txt index f4d0b80cdb143ef46de7c502def756f237e15ac5..673f3a347aa3699a24d8d0901e72fab1ef1cb96a 100644 --- a/ets2panda/test/parser/ets/null_valid-expected.txt +++ b/ets2panda/test/parser/ets/null_valid-expected.txt @@ -205,9 +205,8 @@ } }, "right": { - "type": "Identifier", - "name": "n", - "decorators": [], + "type": "NullLiteral", + "value": null, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt b/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt index 06f443f4b1f6fbb45b36851a6978b8aa7f3a7fd8..04752bd0e51a737240602b90d2d5eeb4c85320c1 100644 --- a/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt +++ b/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt @@ -794,7 +794,7 @@ "loc": { "start": { "line": 22, - "column": 7, + "column": 12, "program": "parentheses_expression_value.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/rest_parameter_02-expected.txt b/ets2panda/test/parser/ets/rest_parameter_02-expected.txt index 6d7657dd104ae7e4027a3e4e7fd78e6ec9c9bad9..a1d39957a7d48c3d0e03c4c4df2ba419e04232d4 100644 --- a/ets2panda/test/parser/ets/rest_parameter_02-expected.txt +++ b/ets2panda/test/parser/ets/rest_parameter_02-expected.txt @@ -864,38 +864,8 @@ } }, "alternate": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 20, - "column": 40, - "program": "rest_parameter_02.ets" - }, - "end": { - "line": 20, - "column": 41, - "program": "rest_parameter_02.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 34, - "program": "rest_parameter_02.ets" - }, - "end": { - "line": 20, - "column": 37, - "program": "rest_parameter_02.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0, "loc": { "start": { "line": 1, diff --git a/ets2panda/test/parser/ets/rethrow-func-1-expected.txt b/ets2panda/test/parser/ets/rethrow-func-1-expected.txt index 76388e85f7e856dc52a03f3696a340312cb9c9d7..74a8f4c9f123482bc53f759e5daf5cf4b790751e 100644 --- a/ets2panda/test/parser/ets/rethrow-func-1-expected.txt +++ b/ets2panda/test/parser/ets/rethrow-func-1-expected.txt @@ -817,40 +817,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 26, - "column": 17, - "program": "rethrow-func-1.ets" - }, - "end": { - "line": 26, - "column": 18, - "program": "rethrow-func-1.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 26, - "column": 21, - "program": "rethrow-func-1.ets" - }, - "end": { - "line": 26, - "column": 22, - "program": "rethrow-func-1.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2147483647, "loc": { "start": { "line": 26, @@ -1307,3 +1275,4 @@ } } } +SyntaxError: Division by zero are not allowed. [rethrow-func-1.ets:26:17] diff --git a/ets2panda/test/parser/ets/string_template_1-expected.txt b/ets2panda/test/parser/ets/string_template_1-expected.txt index 2de19277093303c00dcb56973b1813d27e131af7..40bc249bce45c13c2d61aeb12493771837702306 100644 --- a/ets2panda/test/parser/ets/string_template_1-expected.txt +++ b/ets2panda/test/parser/ets/string_template_1-expected.txt @@ -428,7 +428,7 @@ "loc": { "start": { "line": 20, - "column": 11, + "column": 20, "program": "string_template_1.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/string_template_2-expected.txt b/ets2panda/test/parser/ets/string_template_2-expected.txt index 2574c1b4a29501449d343a2fb1c25d56fe539610..df3eabfe9182ef65828ab8b8f6e00e8923ab2745 100644 --- a/ets2panda/test/parser/ets/string_template_2-expected.txt +++ b/ets2panda/test/parser/ets/string_template_2-expected.txt @@ -205,97 +205,8 @@ } }, "init": { - "type": "TemplateLiteral", - "expressions": [ - { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 14, - "loc": { - "start": { - "line": 17, - "column": 47, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 49, - "program": "string_template_2.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 17, - "column": 50, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 51, - "program": "string_template_2.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 47, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 51, - "program": "string_template_2.ets" - } - } - } - ], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "(escaped expression) \${14/2} = ", - "cooked": "(escaped expression) ${14/2} = " - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 45, - "program": "string_template_2.ets" - } - } - }, - { - "type": "TemplateElement", - "value": { - "raw": "", - "cooked": "" - }, - "loc": { - "start": { - "line": 17, - "column": 52, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 52, - "program": "string_template_2.ets" - } - } - } - ], + "type": "StringLiteral", + "value": "(escaped expression) ${14/2} = 7", "loc": { "start": { "line": 17, @@ -394,9 +305,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "(escaped expression) ${14/2} = 7", "loc": { "start": { "line": 18, @@ -527,9 +437,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "(escaped expression) ${14/2} = 7", "loc": { "start": { "line": 20, @@ -544,9 +453,8 @@ } }, { - "type": "Identifier", - "name": "expected", - "decorators": [], + "type": "StringLiteral", + "value": "(escaped expression) ${14/2} = 7", "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/string_template_3-expected.txt b/ets2panda/test/parser/ets/string_template_3-expected.txt index b0c8377dd373ae5c54aaff09ab5973dd06bc106d..ea684bd5feebea1b6743de9a8d1d07df811e77f4 100644 --- a/ets2panda/test/parser/ets/string_template_3-expected.txt +++ b/ets2panda/test/parser/ets/string_template_3-expected.txt @@ -205,29 +205,8 @@ } }, "init": { - "type": "TemplateLiteral", - "expressions": [], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "(slash at curly braces) $\{true || false\}", - "cooked": "(slash at curly braces) ${true || false}" - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "string_template_3.ets" - }, - "end": { - "line": 17, - "column": 55, - "program": "string_template_3.ets" - } - } - } - ], + "type": "StringLiteral", + "value": "(slash at curly braces) ${true || false}", "loc": { "start": { "line": 17, @@ -326,9 +305,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "(slash at curly braces) ${true || false}", "loc": { "start": { "line": 18, @@ -393,97 +371,8 @@ } }, "init": { - "type": "TemplateLiteral", - "expressions": [ - { - "type": "LogicalExpression", - "operator": "||", - "left": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 19, - "column": 46, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 50, - "program": "string_template_3.ets" - } - } - }, - "right": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 19, - "column": 54, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 59, - "program": "string_template_3.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 46, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 59, - "program": "string_template_3.ets" - } - } - } - ], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "(slash at curly braces) ", - "cooked": "(slash at curly braces) " - }, - "loc": { - "start": { - "line": 19, - "column": 20, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 44, - "program": "string_template_3.ets" - } - } - }, - { - "type": "TemplateElement", - "value": { - "raw": "", - "cooked": "" - }, - "loc": { - "start": { - "line": 19, - "column": 60, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 60, - "program": "string_template_3.ets" - } - } - } - ], + "type": "StringLiteral", + "value": "(slash at curly braces) true", "loc": { "start": { "line": 19, @@ -548,9 +437,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "(slash at curly braces) ${true || false}", "loc": { "start": { "line": 20, @@ -565,9 +453,8 @@ } }, { - "type": "Identifier", - "name": "expected", - "decorators": [], + "type": "StringLiteral", + "value": "(slash at curly braces) true", "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/string_template_4-expected.txt b/ets2panda/test/parser/ets/string_template_4-expected.txt index 17b8cf3405a63dba7fbabdc5afb74852e5bd54a5..da47a2a4c00ed4b9f80d004b12349aef91076745 100644 --- a/ets2panda/test/parser/ets/string_template_4-expected.txt +++ b/ets2panda/test/parser/ets/string_template_4-expected.txt @@ -205,86 +205,8 @@ } }, "init": { - "type": "TemplateLiteral", - "expressions": [ - { - "type": "TemplateLiteral", - "expressions": [], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "backtick = \`", - "cooked": "backtick = `" - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "string_template_4.ets" - }, - "end": { - "line": 17, - "column": 36, - "program": "string_template_4.ets" - } - } - } - ], - "loc": { - "start": { - "line": 17, - "column": 22, - "program": "string_template_4.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "string_template_4.ets" - } - } - } - ], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "nested ", - "cooked": "nested " - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "string_template_4.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "string_template_4.ets" - } - } - }, - { - "type": "TemplateElement", - "value": { - "raw": "", - "cooked": "" - }, - "loc": { - "start": { - "line": 17, - "column": 38, - "program": "string_template_4.ets" - }, - "end": { - "line": 17, - "column": 38, - "program": "string_template_4.ets" - } - } - } - ], + "type": "StringLiteral", + "value": "nested backtick = `", "loc": { "start": { "line": 17, @@ -383,9 +305,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "nested backtick = `", "loc": { "start": { "line": 18, @@ -516,9 +437,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "nested backtick = `", "loc": { "start": { "line": 20, @@ -533,9 +453,8 @@ } }, { - "type": "Identifier", - "name": "expected", - "decorators": [], + "type": "StringLiteral", + "value": "nested backtick = `", "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/switch2-expected.txt b/ets2panda/test/parser/ets/switch2-expected.txt index f2edf576416bc4e62b134f724c5bc9be15f9af0c..4e12dd2d581295ae907efcaf8f88896e77f2d69d 100644 --- a/ets2panda/test/parser/ets/switch2-expected.txt +++ b/ets2panda/test/parser/ets/switch2-expected.txt @@ -829,3 +829,6 @@ } } } +TypeError: Switch case type 'int' is not comparable to discriminant type 'byte' [switch2.ets:21:8] +TypeError: Switch case type 'int' is not comparable to discriminant type 'byte' [switch2.ets:22:8] +TypeError: Switch case type 'int' is not comparable to discriminant type 'byte' [switch2.ets:25:8] diff --git a/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt b/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt index dd1cbe89ced3aff5ead3f32dc22496faaef26278..d1aa6c55817bb7e1d9c9d3b08c1ef0c264302150 100644 --- a/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt +++ b/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt @@ -476,3 +476,4 @@ } } } +TypeError: Switch case type 'int' is not comparable to discriminant type 'char' [switch_char_compare_num.ets:21:14] diff --git a/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt b/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt index 5d62c072a34dc0ab611cfb8c0b1b37a688f042e3..e8d302aebca0176d7d0add71146e45ef4be94bbf 100644 --- a/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt +++ b/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt @@ -315,7 +315,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member-expected.txt index c9dceaf4f62001a5bfe6590149dc3a383dc03bb7..ab089826dbdc70d377e415ad63ed21f6428a5990 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member-expected.txt @@ -693,43 +693,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Fgr", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 14, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 27, - "column": 17, - "program": "switch_readonly_member.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 18, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 27, - "column": 20, - "program": "switch_readonly_member.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "{", "loc": { "start": { "line": 27, @@ -777,43 +742,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Sqr", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 14, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 29, - "column": 17, - "program": "switch_readonly_member.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 18, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 29, - "column": 20, - "program": "switch_readonly_member.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "[", "loc": { "start": { "line": 29, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt index f8f43cea1ab1b0a8572f3f6ee2fda742216d235c..fd21a4ff30a053fdc8f7a07ef6174b8c589cc274 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt @@ -693,43 +693,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Fgr", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 14, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 27, - "column": 17, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 18, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 27, - "column": 20, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "{", "loc": { "start": { "line": 27, @@ -777,43 +742,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Sqr", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 14, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 29, - "column": 17, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 18, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 29, - "column": 20, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "[", "loc": { "start": { "line": 29, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt index e6f846ba4c25ac5d341179f4f4d9a3b04637d402..d9d12a2ab7b390955966cc8e04f9af04e44636b0 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt @@ -742,43 +742,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Fgr", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 14, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 29, - "column": 17, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 18, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 29, - "column": 20, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "{", "loc": { "start": { "line": 29, @@ -826,43 +791,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Sqr", - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 14, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 31, - "column": 17, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 18, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 31, - "column": 20, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "[", "loc": { "start": { "line": 31, diff --git a/ets2panda/test/parser/ets/test_type_alias6-expected.txt b/ets2panda/test/parser/ets/test_type_alias6-expected.txt index 3107be32be5857d1747434ca6f1f84ee8aef5a66..3714ac94d3e70d800c2140b38ebb92f5caecc0b2 100644 --- a/ets2panda/test/parser/ets/test_type_alias6-expected.txt +++ b/ets2panda/test/parser/ets/test_type_alias6-expected.txt @@ -447,4 +447,4 @@ } TypeError: Variable 'x' has already been declared. [test_type_alias6.ets:17:5] TypeError: Type name 'x' used in the wrong context [test_type_alias6.ets:17:5] -TypeError: Type 'double' cannot be assigned to type 'int' [test_type_alias6.ets:17:9] +TypeError: Type 'Double' cannot be assigned to type 'Int' [test_type_alias6.ets:17:9] diff --git a/ets2panda/test/parser/ets/this_cmp_object-expected.txt b/ets2panda/test/parser/ets/this_cmp_object-expected.txt index 68323c16cd6aaaac7d16fa50f6dcf46ea794078f..d770e9b0ceeb77733dbb57d9a3744cb3b6824680 100644 --- a/ets2panda/test/parser/ets/this_cmp_object-expected.txt +++ b/ets2panda/test/parser/ets/this_cmp_object-expected.txt @@ -161,53 +161,7 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "this_cmp_object.ets" - }, - "end": { - "line": 18, - "column": 30, - "program": "this_cmp_object.ets" - } - } - }, - "consequent": { - "type": "ThisExpression", - "loc": { - "start": { - "line": 18, - "column": 33, - "program": "this_cmp_object.ets" - }, - "end": { - "line": 18, - "column": 37, - "program": "this_cmp_object.ets" - } - } - }, - "alternate": { - "type": "ThisExpression", - "loc": { - "start": { - "line": 18, - "column": 40, - "program": "this_cmp_object.ets" - }, - "end": { - "line": 18, - "column": 44, - "program": "this_cmp_object.ets" - } - } - }, + "type": "ThisExpression", "loc": { "start": { "line": 18, @@ -353,7 +307,7 @@ "loc": { "start": { "line": 19, - "column": 12, + "column": 20, "program": "this_cmp_object.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt index f72997ce91c0e8c163c7518cf60103b9bdcbefd3..6934a433642d8af4802b195729dd606576bb4f89 100644 --- a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt +++ b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt @@ -574,9 +574,8 @@ } }, "property": { - "type": "Identifier", - "name": "index1", - "decorators": [], + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 21, @@ -672,9 +671,8 @@ } }, "property": { - "type": "Identifier", - "name": "index2", - "decorators": [], + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 22, diff --git a/ets2panda/test/parser/ets/tuple_type_1-expected.txt b/ets2panda/test/parser/ets/tuple_type_1-expected.txt index 753dcbb9638a645c8e2c33fa0ba4000d66d5b3c7..5cfa191987fecf943c04c1ee168937e6a14bcaa4 100644 --- a/ets2panda/test/parser/ets/tuple_type_1-expected.txt +++ b/ets2panda/test/parser/ets/tuple_type_1-expected.txt @@ -560,38 +560,8 @@ } }, { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 23, - "column": 31, - "program": "tuple_type_1.ets" - }, - "end": { - "line": 23, - "column": 32, - "program": "tuple_type_1.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 36, - "program": "tuple_type_1.ets" - }, - "end": { - "line": 23, - "column": 42, - "program": "tuple_type_1.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 23, diff --git a/ets2panda/test/parser/ets/unary_op-expected.txt b/ets2panda/test/parser/ets/unary_op-expected.txt index 10516d0b64527f41a9159f8e30e62c2ac679e95b..6671ec78a8b7e17dfb373688eb4349df6ba61c24 100644 --- a/ets2panda/test/parser/ets/unary_op-expected.txt +++ b/ets2panda/test/parser/ets/unary_op-expected.txt @@ -433,25 +433,8 @@ } }, "right": { - "type": "UnaryExpression", - "operator": "+", - "prefix": true, - "argument": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "unary_op.ets" - }, - "end": { - "line": 19, - "column": 11, - "program": "unary_op.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 19, @@ -824,26 +807,8 @@ } }, "right": { - "type": "UnaryExpression", - "operator": "!", - "prefix": true, - "argument": { - "type": "Identifier", - "name": "i", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "unary_op.ets" - }, - "end": { - "line": 25, - "column": 11, - "program": "unary_op.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 25, @@ -1162,25 +1127,8 @@ } }, "value": { - "type": "UnaryExpression", - "operator": "+", - "prefix": true, - "argument": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "unary_op.ets" - }, - "end": { - "line": 19, - "column": 11, - "program": "unary_op.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 19, @@ -1569,26 +1517,8 @@ } }, "value": { - "type": "UnaryExpression", - "operator": "!", - "prefix": true, - "argument": { - "type": "Identifier", - "name": "i", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "unary_op.ets" - }, - "end": { - "line": 25, - "column": 11, - "program": "unary_op.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 25, diff --git a/ets2panda/test/parser/ets/var_declare-expected.txt b/ets2panda/test/parser/ets/var_declare-expected.txt index e6c6ab3282f043e944e6b49a0d220c8ace43fb78..7b2fb7d830637c0cd707afcff4f79fe8709a407d 100644 --- a/ets2panda/test/parser/ets/var_declare-expected.txt +++ b/ets2panda/test/parser/ets/var_declare-expected.txt @@ -560,7 +560,7 @@ }, "end": { "line": 23, - "column": 32, + "column": 33, "program": "var_declare.ets" } } @@ -573,7 +573,7 @@ }, "end": { "line": 23, - "column": 32, + "column": 33, "program": "var_declare.ets" } } @@ -588,7 +588,7 @@ }, "end": { "line": 23, - "column": 33, + "column": 34, "program": "var_declare.ets" } } diff --git a/ets2panda/test/parser/ets/var_declare.ets b/ets2panda/test/parser/ets/var_declare.ets index 224c7e55e463d6932b1c3941efe6cccfaae52bd9..56429d9472adaf8a3ae03cbc37cdde5b3f53e7a8 100644 --- a/ets2panda/test/parser/ets/var_declare.ets +++ b/ets2panda/test/parser/ets/var_declare.ets @@ -20,6 +20,6 @@ class VarDeclareTest { b *= 10; let c : int , d : int = 5; const e : double = 2.781828; - const Pi : float = 3.14; + const Pi : float = 3.14f; } } diff --git a/ets2panda/test/runtime/ets/AliasPrimitive.ets b/ets2panda/test/runtime/ets/AliasPrimitive.ets index 8f1d2e43c607da4d75f865ca9c0f81dec151fc98..92c5c3601f6eb7baaaba78685f761da9ea94552d 100644 --- a/ets2panda/test/runtime/ets/AliasPrimitive.ets +++ b/ets2panda/test/runtime/ets/AliasPrimitive.ets @@ -16,23 +16,18 @@ type AliasPrimitive = T; type AliasAlias = AliasPrimitive; -function fn(p: double) -{ - assertEQ(p, 42) -} - function fn(p: Double) { - assertTrue(false) + assertEQ(p, 42) } function main() { - let v1 : double = new Int(42); // unboxing -> widening - fn(v1); + let v1 : double = new Int(42); // widening + fn(v1); - let v2 : AliasPrimitive = new Int(42); // unboxing -> widening - fn(v2); + let v2 : AliasPrimitive = new Int(42); // widening + fn(v2); - let v3 : AliasAlias = new Int(42); // unboxing -> widening - fn(v3); + let v3 : AliasAlias = new Int(42); // widening + fn(v3); } diff --git a/ets2panda/test/runtime/ets/ArrayLiteral.ets b/ets2panda/test/runtime/ets/ArrayLiteral.ets index a541cb9b164cc54ef58cabab049885aa02b41f75..138113de778dc01763ba5f2b8dacbf8012b74102 100644 --- a/ets2panda/test/runtime/ets/ArrayLiteral.ets +++ b/ets2panda/test/runtime/ets/ArrayLiteral.ets @@ -18,7 +18,7 @@ function main(): void { let b: short = 20000; let c: int = 2000000; let d: long = 200000000000; - let e: float = 2.2; + let e: float = 2.2f; let f: double = 2.2222222222; let g: double[] = [a, b, c, d, e, f]; assertEQ(g[0], 2) @@ -32,7 +32,7 @@ function main(): void { const i: short = 2; const j: int = 2; const k: long = 2; - const l: float = 2.0; + const l: float = 2.0f; const m: double = 2.0; const n: byte[] = [h, i, j, k, l, m]; assertEQ(n[0], 2) diff --git a/ets2panda/test/runtime/ets/CastPrimitive.ets b/ets2panda/test/runtime/ets/CastPrimitive.ets index 40b174bdfee1b0cf9dd786c590bcac8bb277ce51..07263656daa0be4823b6fee42ca04638ff20b858 100644 --- a/ets2panda/test/runtime/ets/CastPrimitive.ets +++ b/ets2panda/test/runtime/ets/CastPrimitive.ets @@ -30,7 +30,7 @@ function main(): void { assertEQ(a as char, c'\u0000') assertEQ(a as byte, 0) - let b : float = 70000.9921875; + let b : float = 70000.9921875f; assertEQ(b as double, 70000.9921875) assertEQ(b as long, 70000 ) // rounded, 70000 == 0x11170 assertEQ(b as int, 70000) diff --git a/ets2panda/test/runtime/ets/CastReference.ets b/ets2panda/test/runtime/ets/CastReference.ets index e5bab15d399d785cadb1306b3627e276d90202b8..e2adc3233a5fd50fa142d7f80b1052057aa38bd9 100644 --- a/ets2panda/test/runtime/ets/CastReference.ets +++ b/ets2panda/test/runtime/ets/CastReference.ets @@ -97,7 +97,7 @@ function primitive_reference_test(): void { let int_: int = 42; let Int_ = int_ as Int; assertTrue(Int_ instanceof Int) - assertEQ(Int_.intValue(), 42) + assertEQ(Int_.toInt(), 42) assertEQ(Int_.add(1) as int, 43) } diff --git a/ets2panda/test/runtime/ets/ConditionalExpression_01.ets b/ets2panda/test/runtime/ets/ConditionalExpression_01.ets index 9bf3f0fd1440b585cbb57cce4102372bdc27bc70..29f8e4dde0359f197fa45c38dd6090619dd9d72d 100644 --- a/ets2panda/test/runtime/ets/ConditionalExpression_01.ets +++ b/ets2panda/test/runtime/ets/ConditionalExpression_01.ets @@ -27,14 +27,14 @@ function main() { assertEQ(z2, 4.0) let x3 = (): int | undefined => { return 5; }(); - let y3: int = !x3 ? 3.1 : x3; - let z3: int = x3 ? x3 : 4.1; + let y3: int = !x3 ? 3.1 as int : x3; + let z3: int = x3 ? x3 : 4.1 as int; assertEQ(y3, 5) assertEQ(z3, 5) let x4 = (): int | undefined => { return undefined; }(); - let y4: int = x4 == undefined ? 3.1 : x4; - let z4: int = x4 != undefined ? x4 : 4.1; + let y4: int = x4 == undefined ? 3.1 as int : x4; + let z4: int = x4 != undefined ? x4 : 4.1 as int; assertEQ(y4, 3) assertEQ(z4, 4) } diff --git a/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets b/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets index 1b1698448db902e3cf097378fc38c24ac268d766..55e80f6b0734ace18915d116671fd95ae9e117d0 100644 --- a/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets +++ b/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets @@ -24,32 +24,28 @@ class A extends Numeric { this.value = value; } - public constructor(value: Int) { - this.value = value.intValue(); + public override toByte(): byte { + return Int.toByte(this.value); } - public override byteValue(): byte { - return this.value as byte; + public override toShort(): short { + return Int.toShort(this.value); } - public override shortValue(): short { - return this.value as short; - } - - public override intValue(): int { + public override toInt(): int { return this.value; } - public override longValue(): long { - return this.value as long; + public override toLong(): long { + return Int.toLong(this.value); } - public override floatValue(): float { - return this.value as float; + public override toFloat(): float { + return Int.toFloat(this.value); } - public override doubleValue(): double { - return this.value as double; + public override toDouble(): double { + return Int.toDouble(this.value); } public override toString(): String { diff --git a/ets2panda/test/runtime/ets/RegisterSpiller.ets b/ets2panda/test/runtime/ets/RegisterSpiller.ets index d83252e75f4306ebc383b3000c45a1326ff5bb45..3e1f984b85c411c23b0b6298b4820a31fea1fd01 100644 --- a/ets2panda/test/runtime/ets/RegisterSpiller.ets +++ b/ets2panda/test/runtime/ets/RegisterSpiller.ets @@ -28,7 +28,7 @@ function main(): void { let n2: int = 41; let n3: long = 42; - let n4: float = 43.43; + let n4: float = 43.43f; let n5: double = 44.44; let n6: double = random(); let n7: double = random() + 42; diff --git a/ets2panda/test/runtime/ets/UnaryExpression.ets b/ets2panda/test/runtime/ets/UnaryExpression.ets index 9e62a100e63c5ebff0b2ae214c203ae0200bdaeb..2b6bf0bc21999d647a04f375a379a7c40114de3c 100644 --- a/ets2panda/test/runtime/ets/UnaryExpression.ets +++ b/ets2panda/test/runtime/ets/UnaryExpression.ets @@ -49,7 +49,7 @@ function main(): void { a = -a; assertEQ(a, -30.0) - assertEQ(a.doubleValue(), -30.0) + assertEQ(a.toDouble(), -30.0) let c = +a; assertEQ(c, -30.0) @@ -64,7 +64,7 @@ function main(): void { a = -a; assertEQ(a, -40) - assertEQ(a.intValue(), -40) + assertEQ(a.toInt(), -40) let c = +a; assertEQ(c, -40) diff --git a/ets2panda/test/runtime/ets/UpdateExpression.ets b/ets2panda/test/runtime/ets/UpdateExpression.ets index edefa184679f8e26e363ab6b9eb398b81a40139c..7c764d28ced86b510f2bf18cb9a56b7e814caa10 100644 --- a/ets2panda/test/runtime/ets/UpdateExpression.ets +++ b/ets2panda/test/runtime/ets/UpdateExpression.ets @@ -40,30 +40,30 @@ function main(): void { let a: Double = new Double(30.0); let b = ++a; assertEQ(a, 31.0) - assertEQ(a.doubleValue(), 31.0) + assertEQ(a.toDouble(), 31.0) assertEQ(b, 31.0) - assertEQ(b.doubleValue(), 31.0) + assertEQ(b.toDouble(), 31.0) - assertEQ((++a).doubleValue(), 32.0) + assertEQ((++a).toDouble(), 32.0) assertEQ(a, 32.0) - assertEQ(a.doubleValue(), 32.0) + assertEQ(a.toDouble(), 32.0) assertEQ(b, 31.0) - assertEQ(b.doubleValue(), 31.0) + assertEQ(b.toDouble(), 31.0) } { let a: Int = new Int(40); let b = a++; assertEQ(a, 41) - assertEQ(a.intValue(), 41) + assertEQ(a.toInt(), 41) assertEQ(b, 40) - assertEQ(b.intValue(), 40) + assertEQ(b.toInt(), 40) - assertEQ((a++).intValue(), 41) + assertEQ((a++).toInt(), 41) assertEQ(a, 42) - assertEQ(a.intValue(), 42) + assertEQ(a.toInt(), 42) assertEQ(b, 40) - assertEQ(b.intValue(), 40) + assertEQ(b.toInt(), 40) } { @@ -71,9 +71,9 @@ function main(): void { let a: Int = new Int(50); let b = fn(a++); assertEQ(a, 51) - assertEQ(a.intValue(), 51) + assertEQ(a.toInt(), 51) assertEQ(b, 50) - assertEQ(b.intValue(), 50) + assertEQ(b.toInt(), 50) assertEQ(fn(++a), 52) assertEQ(a, 52) diff --git a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets b/ets2panda/test/runtime/ets/boxed_primitives_overloading.ets similarity index 60% rename from ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets rename to ets2panda/test/runtime/ets/boxed_primitives_overloading.ets index a12bbff68658e5df2093daa1abdc552d76bd1bff..7e710299282a37b1f6ef81cfc5cd4a3cf6063c1e 100644 --- a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets +++ b/ets2panda/test/runtime/ets/boxed_primitives_overloading.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * 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 @@ -13,17 +13,17 @@ * limitations under the License. */ -class C { - public met(...p: FixedArray): string { - return "nR" - } - public met(...p: FixedArray): string { - return "NR" - } +class A { + func(a: Double): String { return "of Double" } + func(a: Float): String { return "of Float" } + func(a: Int): String { return "of Int" } } -function main() { - let c: C = new C() - assertEQ(c.met(0.0), "nR") - assertEQ(c.met(new Number()), "NR") +function main(): int{ + let c1: A = new A(); + let helpbyte: Byte = new Byte(1 as byte); + if (c1.func(helpbyte) != "of Int") { + return 1; + } + return 0; } diff --git a/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets b/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets index 3f0f183b1f7217c37fd7c1ab42ecf0c0fae5f37d..0c0e95fb754b1c53d29f1507c67dc489a4ebf1a8 100644 --- a/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets +++ b/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets @@ -17,10 +17,6 @@ function intParam(a: int): int { return 0; } -function intParam(a: Int): int { - return 1; -} - function objParam(a: Object): int { return 2; } @@ -36,14 +32,10 @@ function retInt(a: Int): int { function main(): void { let a: int = 1; let b: Int = 2; - let c: int = intParam(a); - assertEQ(c, 0) - let d: int = intParam(b); - assertEQ(d, 1) - let e: Int = intParam(a); + let c: Int = intParam(a); assertEQ(c, 0) let f: Int = intParam(b); - assertEQ(d, 1) + assertEQ(f, 0) let g: int = objParam(a); assertEQ(g, 2) let h: int = objParam(b); diff --git a/ets2panda/test/runtime/ets/boxing_1.ets b/ets2panda/test/runtime/ets/boxing_1.ets index 4dd0b40fc810c6ffe563eac649963c4b838412f3..4a8f4492e8651222dede5555fef0c5c68411ed38 100644 --- a/ets2panda/test/runtime/ets/boxing_1.ets +++ b/ets2panda/test/runtime/ets/boxing_1.ets @@ -26,13 +26,13 @@ class A { } function main(): void { - assertEQ(global_Int_.intValue(), 2_000_000) - assertEQ((global_Object_Int_ as Int).intValue(), 2_000_001) - assertEQ(const_global_Int_.intValue(), 2_000_002) - assertEQ((const_global_Object_Int_ as Int).intValue(), 2_000_003) + assertEQ(global_Int_.toInt(), 2_000_000) + assertEQ((global_Object_Int_ as Int).toInt(), 2_000_001) + assertEQ(const_global_Int_.toInt(), 2_000_002) + assertEQ((const_global_Object_Int_ as Int).toInt(), 2_000_003) - assertEQ(A.Int_.intValue(), 2_000_004) - assertEQ((A.Object_Int_ as Int).intValue(), 2_000_005) - assertEQ(A.readonly_Int_.intValue(), 2_000_006) - assertEQ((A.readonly_Object_Int_ as Int).intValue(), 2_000_007) + assertEQ(A.Int_.toInt(), 2_000_004) + assertEQ((A.Object_Int_ as Int).toInt(), 2_000_005) + assertEQ(A.readonly_Int_.toInt(), 2_000_006) + assertEQ((A.readonly_Object_Int_ as Int).toInt(), 2_000_007) } diff --git a/ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts b/ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts new file mode 100644 index 0000000000000000000000000000000000000000..5e498766bb73978cda16393b6fcfb83649ac44ee --- /dev/null +++ b/ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts @@ -0,0 +1,35 @@ +/* + * 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. + */ + +class A {} + +function foo(a: Float): Float { + return a; +} + +function main(): int { + let c: A | Double = new Double(10.0 as double); + let b: Int = new Int(9 as int); + c = b + if (c != 9) { + return 1; + } + let k: Int = new Int(10 as int); + let v: Float = foo(k) + if (v.isNaN()) { + return 1; + } + return 0; +} diff --git a/ets2panda/test/runtime/ets/charToStringCast.ets b/ets2panda/test/runtime/ets/charToStringCast.ets index 0d4ed953f3633279c5b9522616397b5f4031a430..1fe3d11813952c5a51c4200fcd870d7cfbd85947 100644 --- a/ets2panda/test/runtime/ets/charToStringCast.ets +++ b/ets2panda/test/runtime/ets/charToStringCast.ets @@ -14,7 +14,7 @@ */ function main(): void { - let s:string = c'X' as string; + let s:string = c'X'.toString(); assertEQ(s, "X") -} \ No newline at end of file +} diff --git a/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets b/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets index 5b40ffe6e08fc44320e24bb463101e2274a90682..e316567081ad93c4a8f28ddc33ac55fddfbc3c92 100644 --- a/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets +++ b/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets @@ -45,6 +45,10 @@ function foo(p: F): int { return 6; } +function getTrue(): boolean { + return true +} + // #15276 foo(Object|null) and foo(Object) overloads function foo7(p: Object | null): int { return 7; @@ -59,30 +63,30 @@ function main(): void { function sameTypeLUB(): void { let a : A = new A(); let b : A = new A(); - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 2) } function objectLUB(): void { let a : A = new A(); let b : Int = 2; - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 1) let arr : Int[] | null = null; - let d = true ? a : arr; + let d = getTrue() ? a : arr; assertEQ(foo7(d), 7) } function forkSubtypeLUB(): void { let a : F = new F(); let b : D = new D(); - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 2) let d : A = new A(); - let e = true ? a : b; + let e = getTrue() ? a : b; assertEQ(foo(e), 2) let f : B = new B(); - let g = true ? a : f; + let g = getTrue() ? a : f; assertEQ(foo(g), 3) } diff --git a/ets2panda/test/runtime/ets/division-by-zero.ets b/ets2panda/test/runtime/ets/division-by-zero.ets index 3d774e0f85c7f0451142f6efe3132830eef47f7b..2f06cf1157ad5ee8a4fc4683a48586ce3db58d8a 100644 --- a/ets2panda/test/runtime/ets/division-by-zero.ets +++ b/ets2panda/test/runtime/ets/division-by-zero.ets @@ -16,34 +16,6 @@ function main() : void { let caught_counter = 0; - try { - let result : int = 1 / 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 1) - - try { - let result : long = 1 / 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 2) - - try { - let result : int = 1 % 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 3) - - try { - let result : long = 1 % 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 4) - let INT_ONE : int = 1; let INT_ZERO : int = 0; let LONG_ONE : long = 1; @@ -54,28 +26,28 @@ function main() : void { } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 5) + assertEQ(caught_counter, 1) try { let result : long = LONG_ONE / LONG_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 6) + assertEQ(caught_counter, 2) try { let result : int = INT_ONE % INT_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 7) + assertEQ(caught_counter, 3) try { let result : long = LONG_ONE % LONG_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 8) + assertEQ(caught_counter, 4) let DOUBLE_ONE : double = 1.0; let DOUBLE_ZERO : double = 0.0; diff --git a/ets2panda/test/runtime/ets/keyof_primitive_type.ets b/ets2panda/test/runtime/ets/keyof_primitive_type.ets index fdbaed33b76f0b275ed59b5d4d40555f7197a782..bb93cec92d90ed06bafa41ad7668eaac72593687 100644 --- a/ets2panda/test/runtime/ets/keyof_primitive_type.ets +++ b/ets2panda/test/runtime/ets/keyof_primitive_type.ets @@ -18,10 +18,10 @@ function main() : void { let c2:keyof number = "toPrecision" let c3:keyof number = "toLocaleString" let c4:keyof boolean = "valueOf" - let c5:keyof byte = "byteValue" - let c6:keyof short = "shortValue" - let c7:keyof int = "intValue" - let c8:keyof long = "longValue" - let c9:keyof float = "floatValue" - let c10:keyof double = "doubleValue" + let c5:keyof byte = "toByte" + let c6:keyof short = "toShort" + let c7:keyof int = "toInt" + let c8:keyof long = "toLong" + let c9:keyof float = "toFloat" + let c10:keyof double = "toDouble" } diff --git a/ets2panda/test/runtime/ets/local-class-capture-boxing.ets b/ets2panda/test/runtime/ets/local-class-capture-boxing.ets index 0ddecafe02f2695aca1947efa51947ec1365eaab..17712173f8ec78e6eeb6af0d32866e43bc57cb6c 100644 --- a/ets2panda/test/runtime/ets/local-class-capture-boxing.ets +++ b/ets2panda/test/runtime/ets/local-class-capture-boxing.ets @@ -56,7 +56,7 @@ class GlobalClass let l_short : short = 3; let l_int : int = 4; let l_long : long = 5; - let l_float : float = 6.0; + let l_float : float = 6.0f; let l_double : double = 7.0; let l_boolean : boolean = false; let l_char : char = c'x'; diff --git a/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets b/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets index b22d5bb64c4de397121cf8e3990ab6cf8d21cef2..d06cbc640e1aa21b127f71f11bd4f8456a364f48 100644 --- a/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets +++ b/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets @@ -56,7 +56,7 @@ class GlobalClass let l_short : short = 3; let l_int : int = 4; let l_long : long = 5; - let l_float : float = 6.0; + let l_float : float = 6.0f; let l_double : double = 7.0; let l_boolean : boolean = false; let l_char : char = c'x'; diff --git a/ets2panda/test/runtime/ets/primitive_to_boxed.ets b/ets2panda/test/runtime/ets/primitive_to_boxed.ets index 15e7c37f595360e8d2e78900dd5b05ec110274a4..b81a5231214b25d8b0fa1e0549e246c22bd2bdef 100644 --- a/ets2panda/test/runtime/ets/primitive_to_boxed.ets +++ b/ets2panda/test/runtime/ets/primitive_to_boxed.ets @@ -26,7 +26,7 @@ function fooShort() : Short { } function fooChar() : Char { - return "c"; + return c'c'; } @@ -66,7 +66,7 @@ function main() { let val2 : Short = fooShort() assertEQ(val2, c2) - let c3 : Char = 'c'; + let c3 : Char = c'c'; let val3 : Char = fooChar() assertEQ(val3, c3) @@ -82,7 +82,7 @@ function main() { let val6 : Float = fooFloat() assertEQ(val6, c6) - + let c7 : Double = 1; let val7 : Double = fooDouble() assertEQ(val7, c7) @@ -90,4 +90,4 @@ function main() { let c8 : Color = Color.Green; let val8 : Color = fooEnum(); assertEQ(c8, val8) -} \ No newline at end of file +} diff --git a/ets2panda/test/runtime/ets/skippedTest.ets b/ets2panda/test/runtime/ets/skippedTest.ets index 436327c4501077b732592ab4ca251e626b092eb6..2411180ddbe7c409c2409b48978508b82527f0ce 100644 --- a/ets2panda/test/runtime/ets/skippedTest.ets +++ b/ets2panda/test/runtime/ets/skippedTest.ets @@ -20,7 +20,7 @@ function main(): void { let c: String = "abc"; let n2: int = 41; let n3: long = 42; - let n4: float = 43.43; + let n4: float = 43.43f; let n5: double = 44.44; console.print(str); console.println(); diff --git a/ets2panda/test/runtime/ets/tuple_types_runtime.ets b/ets2panda/test/runtime/ets/tuple_types_runtime.ets index ea92f4de2fcb9695fb6e8c1a60b842a4b2ef7cb6..f787e31f4d090f9284498b5cbd30d5ebf372a332 100644 --- a/ets2panda/test/runtime/ets/tuple_types_runtime.ets +++ b/ets2panda/test/runtime/ets/tuple_types_runtime.ets @@ -77,7 +77,7 @@ function main(): void { let tup_10: [number, int, string, boolean, Object] = [1, 2, "I", false, new Object()]; let var_float: float = tup_10[1]; - let var_float_2: float = 2.0; + let var_float_2: float = 2.0f; assertEQ(var_float, var_float_2); let tup_11: [int, number, string, boolean, Object] = [6, 7, "J", true, 789]; diff --git a/ets2panda/test/runtime/ets/visible_signatures.ets b/ets2panda/test/runtime/ets/visible_signatures.ets index a4201f3d8d0efa181ce2012252aebcd15e61159c..0acd2259f5149e0d16365bca709b6ac9e7c58deb 100644 --- a/ets2panda/test/runtime/ets/visible_signatures.ets +++ b/ets2panda/test/runtime/ets/visible_signatures.ets @@ -14,39 +14,37 @@ */ class A { - foo(a: Double | undefined): Int { + foo(a: Long): Int { return 1; } - private foo(a: double): Int { + private foo(a: Int): Int { return 0; } - foo2(a: Int | undefined): Int { + foo2(a: Int): Int { return 1; } - private foo2(a: int): Int { + private foo2(a: Long): Int { return 0; } - foo3(a: Number | undefined): Int { + foo3(a: Long): Int { return 1; } - private foo3(a: number): Int { + private foo3(a: Int): Int { return 0; } - - foo4(a: Number | undefined): Int { + foo4(a: Int): Int { return 1; } - protected foo4(a: number): Int { + protected foo4(a: Long): Int { return 0; } - } function main(): void { - assertEQ(new A().foo(3.0), 1) + assertEQ(new A().foo(3), 1) assertEQ(new A().foo2(3), 1) - assertEQ(new A().foo3(3.0), 1) - assertEQ(new A().foo4(3.0), 1) + assertEQ(new A().foo3(3), 1) + assertEQ(new A().foo4(3), 1) } diff --git a/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt b/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt index bb991b21cc0e1c7221a26d21a1801bbffd551f58..0c7275c719a1d1f0b5780854bff3385a1635f540 100644 --- a/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt +++ b/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt @@ -108,3 +108,100 @@ ast/compiler/ets/lambda_infer_type/lambda_param_type_cannot_be_determined.ets # Issue: #24605 incorrect column ast/parser/ets/named_types_2.ets + +#24986 +ast/compiler/ets/extension_function_tests/extension_function_called_by_class.ets +ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets +ast/compiler/ets/extension_function_tests/extension_function_primitive.ets +ast/compiler/ets/ambiguous_signature02.ets +ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.ets +ast/compiler/ets/unionCommonMember_neg.ets +ast/parser/ets/FixedArray/MultipleParserErrors.ets +ast/parser/ets/FixedArray/for_of_02.ets +ast/parser/ets/FixedArray/invalidTypes.ets +ast/parser/ets/FixedArray/unexpected_token_31.ets +ast/parser/ets/FixedArray/unexpected_token_36.ets +ast/parser/ets/FixedArray/unexpected_token_42.ets +ast/parser/ets/FixedArray/unexpected_token_47.ets +ast/parser/ets/InvalidExpressions1.ets +ast/parser/ets/MultipleParserErrors.ets +ast/parser/ets/SmartCast_1.ets +ast/parser/ets/SmartCast_2.ets +ast/parser/ets/array_new_failed.ets +ast/parser/ets/constFloatInSwitch.ets +ast/parser/ets/enum28.ets +ast/parser/ets/enum29.ets +ast/parser/ets/enum30.ets +ast/parser/ets/enum31.ets +ast/parser/ets/enum7.ets +ast/parser/ets/for_of_04.ets +ast/parser/ets/function_implicit_return_type7.ets +ast/parser/ets/import_tests/import_name_conflicts/main_2.ets +ast/parser/ets/import_tests/import_name_conflicts/main_3.ets +ast/parser/ets/import_tests/import_name_conflicts/main_4.ets +ast/parser/ets/import_tests/import_name_conflicts/main_5.ets +ast/parser/ets/import_tests/import_name_conflicts/main_6.ets +ast/parser/ets/import_tests/import_name_conflicts/main_7.ets +ast/parser/ets/import_tests/import_name_conflicts/main_8.ets +ast/parser/ets/import_tests/import_type_error_in_class.ets +ast/parser/ets/import_tests/import_type_error_top_level.ets +ast/parser/ets/index_not_support_such_type.ets +ast/parser/ets/instanceof_with_not_object_type.ets +ast/parser/ets/interface_private_function_1.ets +ast/parser/ets/invalidEnums.ets +ast/parser/ets/keyof_annotation.ets +ast/parser/ets/keyof_array_tuple.ets +ast/parser/ets/keyof_parameter.ets +ast/parser/ets/lambda_infer_type_neg_1.ets +ast/parser/ets/lambda_omit_parentheses_parameter_neg_3.ets +ast/parser/ets/multi_typeerror_function_implicit_return_value.ets +ast/parser/ets/n_arrayHoldingNullValue.ets +ast/parser/ets/new_object_1.ets +ast/parser/ets/new_object_2.ets +ast/parser/ets/nonIntegralIndex.ets +ast/parser/ets/non_proper_index_method.ets +ast/parser/ets/overrideFuncWithGetter_n.ets +ast/parser/ets/override_method.ets +ast/parser/ets/partialPrimitiveConversion_n.ets +ast/parser/ets/partial_not_reference_type.ets +ast/parser/ets/predefined_non_primitive_types.ets +ast/parser/ets/primitive_type_method_1.ets +ast/parser/ets/primitive_type_method_2.ets +ast/parser/ets/privateSuperConstructorCall.ets +ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test1.ets +ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test4.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test3.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test4.ets +ast/parser/ets/recordIndexing.ets +ast/parser/ets/recordKeyTypeCheck01.ets +ast/parser/ets/record_object_value.ets +ast/parser/ets/return_null_and_type_not_match.ets +ast/parser/ets/return_type_non_match.ets +ast/parser/ets/returntype_override_primitive.ets +ast/parser/ets/single_statement_1.ets +ast/parser/ets/single_statement_2.ets +ast/parser/ets/switch_const_int_compare_char_duplicate.ets +ast/parser/ets/switch_num_compare_char_duplicate.ets +ast/parser/ets/switch_readonly_member_number_duplicate.ets +ast/parser/ets/trailing_comma_2.ets +ast/parser/ets/type_from_utility_type.ets +ast/parser/ets/type_references.ets +ast/parser/ets/types_decls.ets +ast/parser/ets/unexpected_token_29.ets +ast/parser/ets/unexpected_token_31.ets +ast/parser/ets/unexpected_token_35.ets +ast/parser/ets/unexpected_token_36.ets +ast/parser/ets/unexpected_token_41.ets +ast/parser/ets/unexpected_token_42.ets +ast/parser/ets/unexpected_token_47.ets +ast/parser/ets/unexpected_token_53.ets +ast/parser/ets/unexpected_token_55.ets +ast/parser/ets/unexpected_token_61.ets +ast/parser/ets/visible_signatures_1.ets +ast/parser/ets/wrong_context_class_1.ets +ast/parser/ets/wrong_context_class_2.ets +ast/parser/ets/wrong_context_function_1.ets +ast/parser/ets/wrong_context_function_2.ets +ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets +ast/parser/ets/ets_never_type_without_affect_other.ets +ast/parser/ets/non_constant_expression.ets diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index ed76e9c73b6951a8779e7e44bc463cc44da1d3e1..37923997cf4bb248ff87d425e6c4bbd9db0ad661 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -48,7 +48,6 @@ nullableType.ets #Issue 17949 #SyntaxError: Cannot find type 'C'. -lambdaWithLocalClassAccess.ets #Issue 21065 implementsClassPropertyUnionType1.ets @@ -61,23 +60,15 @@ optional_field.ets #Issue 22384 Object-type-in-binary-logical-expression.ets trailing-lambda.ets -unboxingBooleanConversion.ets BitwiseOperationsOnFloat.ets RecursiveTypeAlias11.ets boxingConversions3.ets -char-type.ets conversionFloatIntLong.ets conversionFromInfinity.ets -enum_const_variable.ets -local_enum03.ets non-const-capture.ets inallyCatchExecutedNormally.ets -finallyTryExecutedNormally.ets -finallyCatchExecutedNormally.ets -enumConstExpression.ets #Issue 48215 -implementsClassPropertyFunctionType_ObjectLiteralExpr.ets lambda_with_receiver/lambda_with_receiver_generics_return_this_rotate.ets lambda_with_receiver/lambda_with_receiver_return_this3.ets lambda_with_receiver/lambda_with_receiver_generics_return_this.ets @@ -85,13 +76,56 @@ lambda_with_receiver/lambda_with_receiver_trailing_in_class_method_return_this_r lambda_with_receiver/lambda_with_receiver_trailing_in_function_return_this_rotate.ets #Issue 23074 -# instance method used as value -FunctionType.ets -function_type_inference1.ets # generic bridges GenericBridges_01.ets GenericBridges_02.ets override_for_partial_01.ets +# Overloads involving primitives +Override-4.ets +# 22415 +lambda_type_with_rest_param.ets +lambda_with_rest_param.ets +lambda_with_restparameter.ets +lambda_with_restparameter_object.ets +lambda_with_restparameter_predefinedtypes.ets + +# Arrays of primitives used interchangeably with arrays of reference (in generics and forOf) +GenericArray_1.ets +array-object.ets + #HEAD FILE NO NEED TO RUN import_self_head_tests/B/test.d.ets + +#24986 +RecordKeyTypeCheck.ets +constant_char.ets +enum-initialize-with-enum1.ets +enum-initialize-with-enum2.ets +CastPrimitive.ets +nullishTypeCodesamples.ets +instanceof.ets + +# Rebase no-primitives pathch onto master with merger Array refactoring +AnnotationConstExpression.ets +annotation_tests/AnnotationForClass.ets +annotation_tests/AnnotationForLambdaExpression.ets +annotation_tests/AnnotationNoNeedToSetProperties03.ets +annotation_tests/AnnotationsFieldType03.ets +annotation_tests/AnnotationsFieldType04.ets +annotation_tests/EmitAnnotationToBytecode.ets +annotation_tests/annotationUsageSingleFileds05.ets +namespace_tests/namespace_with_annotations.ets +lambda_with_rest_param_resizablearray.ets +type_from_primitive_type.ets +lambda_with_rest_param_fixedarray.ets +lambda_with_restparameter_object_fixedarray.ets +lambda_with_restparameter_predefinedtypes_fixedarray.ets +annotation_tests/AnnotationForTypesInAnnotation.ets +annotation_tests/annotationUsageSingleFileds06.ets +annotation_tests/annotationUsageSingleFileds07.ets +enum-relational-operators.ets +local-enum-relational-operators.ets +rest_object_literal.ets +union_generic_class.ets +stringliteral_to_char.ets diff --git a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt index 3f8d5be2c2d294c5ce4fbaddea0e2df6748d536d..9a38c3a7f2b589e4d2ed365dc2991d5611c5ed51 100644 --- a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt @@ -22,3 +22,21 @@ parser/ts/test-tuple-type.ts parser/ts/test-type-literal.ts parser/ts/test_generic.ts compiler/ts/functionCall.ts + +#24986 +compiler/ets/dynamicLambdaJSValue.ets +parser/ets/switch2.ets +parser/ets/switch_char_compare_num.ets +ark_tests/parser/js/expressions/binary/test-binary-expression.js +ark_tests/parser/js/expressions/binary/test-logical-expression.js +ark_tests/parser/js/expressions/binary/test-nullish-coalescing.js +ark_tests/parser/js/expressions/conditional/test-conditional-expression.js +ark_tests/parser/js/expressions/test-grouping-level.js +ark_tests/parser/js/functions/declarations/test-function-return.js +parser/js/test-binary-expression.js +parser/js/test-conditional-expression.js +parser/js/test-grouping-level.js +parser/js/test-logical-expression.js +parser/js/test-nullish-coalescing.js +compiler/ets/dynamic_instanceof_error.ets +parser/ets/tuple_type_1.ets diff --git a/ets2panda/test/test-lists/parser/parser-js-ignored.txt b/ets2panda/test/test-lists/parser/parser-js-ignored.txt index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ebb05bf9f7282b228fdbacd04649c6fc3b3778a7 100644 --- a/ets2panda/test/test-lists/parser/parser-js-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-js-ignored.txt @@ -0,0 +1,17 @@ +#24986 +compiler/ets/dynamicLambdaJSValue.ets +parser/ets/switch2.ets +parser/ets/switch_char_compare_num.ets +ark_tests/parser/js/expressions/binary/test-binary-expression.js +ark_tests/parser/js/expressions/binary/test-logical-expression.js +ark_tests/parser/js/expressions/binary/test-nullish-coalescing.js +ark_tests/parser/js/expressions/conditional/test-conditional-expression.js +ark_tests/parser/js/expressions/test-grouping-level.js +ark_tests/parser/js/functions/declarations/test-function-return.js +parser/js/test-binary-expression.js +parser/js/test-conditional-expression.js +parser/js/test-grouping-level.js +parser/js/test-logical-expression.js +parser/js/test-nullish-coalescing.js +compiler/ets/dynamic_instanceof_error.ets +parser/ets/tuple_type_1.ets diff --git a/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp b/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp index 523d4aaba144219e95810aceddb2dde43af87fc2..a1998a7aace69106aacdd0e20914355b15366a71 100644 --- a/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp +++ b/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp @@ -91,36 +91,35 @@ public: void CheckLiteralArrayTable(pandasm::Program *program) { std::vector>> expectedLiteralArrayTable = { - {"ETSGLOBAL$Anno2$param$0", std::vector {VALUE_1, VALUE_2, VALUE_3, VALUE_4}}, - {"ETSGLOBAL$Anno3$param$1", std::vector {VALUE_1}}, - {"ETSGLOBAL$Anno3$param$2", std::vector {VALUE_2}}, + {"ETSGLOBAL$Anno2$param$0", std::vector {1U, 2U, 3U, 4U}}, + {"ETSGLOBAL$Anno3$param$1", std::vector {1U}}, + {"ETSGLOBAL$Anno3$param$2", std::vector {2U}}, {"ETSGLOBAL$Anno3$param$3", std::vector {std::string("ETSGLOBAL$Anno3$param$1"), std::string("ETSGLOBAL$Anno3$param$2")}}, - {"ETSGLOBAL$Anno3$param$4", std::vector {VALUE_2}}, - {"ETSGLOBAL$Anno3$param$5", std::vector {VALUE_3}}, + {"ETSGLOBAL$Anno3$param$4", std::vector {2U}}, + {"ETSGLOBAL$Anno3$param$5", std::vector {3U}}, {"ETSGLOBAL$Anno3$param$6", std::vector {std::string("ETSGLOBAL$Anno3$param$4"), std::string("ETSGLOBAL$Anno3$param$5")}}, - {"ETSGLOBAL$Anno3$param$7", std::vector {VALUE_3}}, - {"ETSGLOBAL$Anno3$param$8", std::vector {VALUE_4}}, + {"ETSGLOBAL$Anno3$param$7", std::vector {3U}}, + {"ETSGLOBAL$Anno3$param$8", std::vector {4U}}, {"ETSGLOBAL$Anno3$param$9", std::vector {std::string("ETSGLOBAL$Anno3$param$7"), std::string("ETSGLOBAL$Anno3$param$8")}}, {"ETSGLOBAL$Anno3$param$10", std::vector {std::string("ETSGLOBAL$Anno3$param$3"), std::string("ETSGLOBAL$Anno3$param$6"), std::string("ETSGLOBAL$Anno3$param$9")}}, - {"ETSGLOBAL.foo:void;$Anno2$value$11", - std::vector {VALUE_4, VALUE_5, VALUE_6, VALUE_7}}, - {"ETSGLOBAL.foo:void;$Anno3$param$12", std::vector {VALUE_1}}, - {"ETSGLOBAL.foo:void;$Anno3$param$13", std::vector {VALUE_2}}, + {"ETSGLOBAL.foo:void;$Anno2$value$11", std::vector {4U, 5U, 6U, 7U}}, + {"ETSGLOBAL.foo:void;$Anno3$param$12", std::vector {1U}}, + {"ETSGLOBAL.foo:void;$Anno3$param$13", std::vector {2U}}, {"ETSGLOBAL.foo:void;$Anno3$param$14", std::vector {std::string("ETSGLOBAL.foo:void;$Anno3$param$12"), std::string("ETSGLOBAL.foo:void;$Anno3$param$13")}}, - {"ETSGLOBAL.foo:void;$Anno3$param$15", std::vector {VALUE_2}}, - {"ETSGLOBAL.foo:void;$Anno3$param$16", std::vector {VALUE_3}}, + {"ETSGLOBAL.foo:void;$Anno3$param$15", std::vector {2U}}, + {"ETSGLOBAL.foo:void;$Anno3$param$16", std::vector {3U}}, {"ETSGLOBAL.foo:void;$Anno3$param$17", std::vector {std::string("ETSGLOBAL.foo:void;$Anno3$param$15"), std::string("ETSGLOBAL.foo:void;$Anno3$param$16")}}, - {"ETSGLOBAL.foo:void;$Anno3$param$18", std::vector {VALUE_3}}, - {"ETSGLOBAL.foo:void;$Anno3$param$19", std::vector {VALUE_4}}, + {"ETSGLOBAL.foo:void;$Anno3$param$18", std::vector {3U}}, + {"ETSGLOBAL.foo:void;$Anno3$param$19", std::vector {4U}}, {"ETSGLOBAL.foo:void;$Anno3$param$20", std::vector {std::string("ETSGLOBAL.foo:void;$Anno3$param$18"), std::string("ETSGLOBAL.foo:void;$Anno3$param$19")}}, diff --git a/ets2panda/test/unit/lsp/get_diagnostics.cpp b/ets2panda/test/unit/lsp/get_diagnostics.cpp index bfb46178f156eaba388b33ca9cf3ed228c8ad33f..8308130c359a2a0ac57f8701c18ee4fe39e31d54 100644 --- a/ets2panda/test/unit/lsp/get_diagnostics.cpp +++ b/ets2panda/test/unit/lsp/get_diagnostics.cpp @@ -62,7 +62,7 @@ add("1", 2);)"); ASSERT_EQ(result.diagnostic[thirdIndex].range_.end.character_, expectedFirstEndCharacter); ASSERT_EQ(result.diagnostic[thirdIndex].severity_, DiagnosticSeverity::Error); ASSERT_EQ(std::get(result.diagnostic[thirdIndex].code_), 1); - ASSERT_EQ(result.diagnostic[thirdIndex].message_, R"(Type '"hello"' cannot be assigned to type 'double')"); + ASSERT_EQ(result.diagnostic[thirdIndex].message_, R"(Type '"hello"' cannot be assigned to type 'Double')"); ASSERT_EQ(result.diagnostic[thirdIndex].codeDescription_.href_, "test code description"); auto const expectedSecondStartLine = 5; auto const expectedSecondStartCharacter = 5; @@ -74,7 +74,7 @@ add("1", 2);)"); ASSERT_EQ(result.diagnostic[0].range_.end.character_, expectedSecondEndCharacter); ASSERT_EQ(result.diagnostic[0].severity_, DiagnosticSeverity::Error); ASSERT_EQ(std::get(result.diagnostic[0].code_), 1); - ASSERT_EQ(result.diagnostic[0].message_, R"(Type '"1"' is not compatible with type 'double' at index 1)"); + ASSERT_EQ(result.diagnostic[0].message_, R"(Type '"1"' is not compatible with type 'Double' at index 1)"); ASSERT_EQ(result.diagnostic[0].codeDescription_.href_, "test code description"); } diff --git a/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp b/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp index d4dba0a4907857d8757e697a5c883a1eec7e4dea..8d50e2ec7a420ba39cd7deef0a93dca9f1f3dd5c 100644 --- a/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp +++ b/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp @@ -24,15 +24,17 @@ using ark::es2panda::lsp::Initializer; +static auto g_fileSource = + "let a: number;\nlet b: byte;\nlet c: short;\nlet d: int;\nlet e: long;\nlet f: " + "float;\nlet g: double;\nlet h: char;\nlet i: boolean;"; + +// CC-OFFNXT(huge_method) test function TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation1) { using ark::es2panda::ir::AstNode; using ark::es2panda::public_lib::Context; Initializer initializer = Initializer(); - es2panda_Context *ctx = - initializer.CreateContext("types.ets", ES2PANDA_STATE_CHECKED, - "let a: number;\nlet b: byte;\nlet c: short;\nlet d: int;\nlet e: long;\nlet f: " - "float;\nlet g: double;\nlet h: char;\nlet i: boolean;"); + es2panda_Context *ctx = initializer.CreateContext("types.ets", ES2PANDA_STATE_CHECKED, g_fileSource); ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); auto checker = reinterpret_cast(ctx)->checker->AsETSChecker(); @@ -40,47 +42,49 @@ TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation1) auto targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "a"; }); auto type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsDoubleType()); + std::cout << type->ToString() << std::endl; + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalDoubleBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "b"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsByteType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalByteBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "c"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsShortType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalShortBuiltinType())); + ; targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "d"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsIntType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalIntBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "e"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsLongType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalLongBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "f"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsFloatType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalFloatBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "g"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsDoubleType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalDoubleBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "h"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsCharType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalCharBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "i"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSBooleanType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalETSBooleanBuiltinType())); initializer.DestroyContext(ctx); } @@ -142,4 +146,4 @@ TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation2) type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); ASSERT_TRUE(type->IsETSUnionType()); initializer.DestroyContext(ctx); -} \ No newline at end of file +} diff --git a/ets2panda/test/unit/lsp/inlay_hints_test.cpp b/ets2panda/test/unit/lsp/inlay_hints_test.cpp index c9b480e473052680ca8d5ef136ed195e3fe94be3..8302541de29dae608e5da6a854cda36b56f6dd03 100644 --- a/ets2panda/test/unit/lsp/inlay_hints_test.cpp +++ b/ets2panda/test/unit/lsp/inlay_hints_test.cpp @@ -214,7 +214,7 @@ TEST_F(LSPInlayHintsTests, VisitFunctionDeclarationLikeForReturnTypeTest1) }; )"}; - const std::string doubleString = "double"; + const std::string doubleString = "Double"; const size_t addIndex = 89; const size_t multiplyIndex = 186; const size_t i0 = 0; diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_check.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_check.cpp index ca0a1a3dad9739573ff1032325da375cfa1e38bb..4ad3bd24fe234cea6eb7f6cf39ccd06a269fd601 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_check.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_check.cpp @@ -25,7 +25,7 @@ static es2panda_Impl *impl = nullptr; -static auto source = std::string("function main() { 1 + 2 }"); +static auto source = std::string("function main(): void { let v = 1; v + 2 }"); static es2panda_AstNode *binExpr = nullptr; static es2panda_Context *ctx = nullptr; @@ -53,7 +53,7 @@ static bool TestAstNodeCheck(es2panda_Context *context, es2panda_AstNode *root) auto *mainType = impl->AstNodeCheck(context, binExpr); std::cout << impl->TypeToStringConst(context, mainType) << std::endl; - return impl->TypeIsIntType(mainType); + return impl->TypeIsETSObjectType(mainType); // boxed Int } int main(int argc, char **argv) diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_transform_children_recursively.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_transform_children_recursively.cpp index 90bc552fa35b39c44e94605810f20f2a513beac9..dd16a6fdc4d9db34aea06a1abf81ed082bfc61f1 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_transform_children_recursively.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_transform_children_recursively.cpp @@ -30,6 +30,7 @@ es2panda_AstNode *Transform(es2panda_AstNode *ast) { if (g_impl->IsIdentifier(ast) && strcmp(g_impl->IdentifierName(g_ctx, ast), "main") == 0) { auto *id = g_impl->CreateIdentifier1(g_ctx, const_cast("foo")); + g_impl->AstNodeSetParent(g_ctx, id, g_impl->AstNodeParent(g_ctx, ast)); g_isFound = true; return id; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_as_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_as_expression.cpp index 38505a37c327f615bfe560c5ea211834ac905d70..cbbd90c2a4c47511af9a3352e06c1c827ba5c839 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_as_expression.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_as_expression.cpp @@ -125,6 +125,8 @@ void CreateAsExpression() auto typeAnnotation = impl->CreateETSPrimitiveType(context, primitiveType); auto *asExpr = impl->CreateTSAsExpression(context, numberLiteral, typeAnnotation, true); impl->VariableDeclaratorSetInit(context, variableDeclarator, asExpr); + impl->AstNodeSetParent(context, numberLiteral, asExpr); + impl->AstNodeSetParent(context, typeAnnotation, asExpr); impl->AstNodeSetParent(context, asExpr, variableDeclarator); impl->AstNodeSetParent(context, variableDeclarator, letStatement); } @@ -168,4 +170,4 @@ int main(int argc, char **argv) return 0; } -// NOLINTEND \ No newline at end of file +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_parameter_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_parameter_expression.cpp index a7aa23aa086d9945af9eef9f9d93f8bf3b021067..53f55b343ba3c3622cd9bce0b462922dbf621d75 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_parameter_expression.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_parameter_expression.cpp @@ -34,7 +34,9 @@ es2panda_AstNode *Transform(es2panda_AstNode *ast) auto *id = g_impl->CreateIdentifier2(g_ctx, const_cast("yyy"), g_impl->CreateETSPrimitiveType(g_ctx, PRIMITIVE_TYPE_INT)); auto param = g_impl->CreateETSParameterExpression(g_ctx, id, false); + g_impl->AstNodeSetParent(g_ctx, g_impl->IdentifierTypeAnnotationConst(g_ctx, id), id); g_impl->AstNodeSetParent(g_ctx, id, param); + g_impl->AstNodeSetParent(g_ctx, param, g_impl->AstNodeParent(g_ctx, ast)); g_isFound = true; return param; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_member_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_member_expression.cpp index ba03cef15b7362bd249d272e4d91bcb9e032ccbb..10774a84d5ac51987b5615fd98dd9be6ed737406 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_member_expression.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_member_expression.cpp @@ -94,8 +94,8 @@ static es2panda_AstNode *CreateMemberExpression() { es2panda_AstNode *instanceName = CreateIdentifierFromString(context, "a"); es2panda_AstNode *memberName = CreateIdentifierFromString(context, "age"); - es2panda_AstNode *memberExpr = - impl->CreateMemberExpression(context, instanceName, memberName, MEMBER_EXPRESSION_KIND_NONE, false, false); + es2panda_AstNode *memberExpr = impl->CreateMemberExpression(context, instanceName, memberName, + MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); impl->AstNodeSetParent(context, instanceName, memberExpr); impl->AstNodeSetParent(context, memberName, memberExpr); return memberExpr; @@ -123,8 +123,8 @@ static void CheckUpdateMemberExpression(es2panda_AstNode *programNode) { es2panda_AstNode *instanceName = CreateIdentifierFromString(context, "a"); es2panda_AstNode *memberName = CreateIdentifierFromString(context, "address"); - es2panda_AstNode *newMemberExpr = impl->UpdateMemberExpression(context, memberExpression, instanceName, memberName, - MEMBER_EXPRESSION_KIND_NONE, false, false); + es2panda_AstNode *newMemberExpr = impl->UpdateMemberExpression( + context, memberExpression, instanceName, memberName, MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); impl->AstNodeSetParent(context, instanceName, newMemberExpr); impl->AstNodeSetParent(context, memberName, newMemberExpr); es2panda_AstNode *newMemberStat = impl->CreateExpressionStatement(context, newMemberExpr); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method.cpp index e60ad40c6a611b787d10e143b45a1e21c28456c4..5a0619ead0cf68ed1020ad044d5269a4a91bf883 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method.cpp @@ -81,8 +81,8 @@ static es2panda_AstNode *CreateMemberExpression() { es2panda_AstNode *thisExpr = CreateThisExpression(); es2panda_AstNode *memberName = CreateIdentifierFromString(context, "x"); - es2panda_AstNode *memberExpr = - impl->CreateMemberExpression(context, thisExpr, memberName, MEMBER_EXPRESSION_KIND_NONE, false, false); + es2panda_AstNode *memberExpr = impl->CreateMemberExpression(context, thisExpr, memberName, + MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); impl->AstNodeSetParent(context, thisExpr, memberExpr); impl->AstNodeSetParent(context, memberName, memberExpr); return memberExpr; diff --git a/ets2panda/test/unit/rest_parameter_flag_test.cpp b/ets2panda/test/unit/rest_parameter_flag_test.cpp index 6a86bc31954191e0dd3d279ca74231b720e3f51e..026166d78b578892b17dcc7397be85f028d086c9 100644 --- a/ets2panda/test/unit/rest_parameter_flag_test.cpp +++ b/ets2panda/test/unit/rest_parameter_flag_test.cpp @@ -328,7 +328,9 @@ TEST_F(RestParameterTest, external_function_with_rest_parameter_0) TEST_F(RestParameterTest, external_function_with_rest_parameter_1) { - SetCurrentProgram(""); + SetCurrentProgram(R"( + let v = Math.max(0.0, 1.0, 2.0) // Ensure the func is actually called and reference processed by unboxLowering. + )"); CheckRestParameterFlag("escompat.Math.max:escompat.Array;f64;", true); } diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 86acf72939f40b803827e85969115500f1f370ff..5951a487077490391702cf525a81360ee87802c0 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -915,9 +915,9 @@ semantic: id: 227 message: "Array element at index {} with type '{}' is not compatible with the target array element type '{}'" -- name: INIT_NOT_ASSIGNABLE +- name: TYPEARG_TYPEPARAM_SUBTYPING id: 228 - message: "Type {} is not assignable to constraint type {}" + message: "Type argument '{}' should be a subtype of '{}'-constraint" - name: OVERLOADED_FUNCTION_REFERENCE id: 229 @@ -1111,8 +1111,24 @@ semantic: id: 279 message: "Tuple types with arity >16 are not yet implemented" -- name: UNION_METHOD_SIGNATURE +- name: CONSTANT_FLOATING_POINT_COVERSION + id: 279 + message: "Floating-point value cannot be converted" + +- name: CONSTANT_VALUE_OUT_OF_RANGE id: 280 + message: "Value is out of range" + +- name: WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION + id: 281 + message: "Wrong type of operands for binary expression" + +- name: WRONG_OPERAND_TYPE_FOR_UNARY_EXPRESSION + id: 282 + message: "Wrong operand type for unary expression" + +- name: UNION_METHOD_SIGNATURE + id: 283 message: "Union constituent types should have only one common method signature." - name: NOT_ALLOWED_THIS_IN_UNION_TYPE diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index f8a36487ecafeb8f129e7051f21b2ebd641536ab..f9ad711efb4d0f9ba2e4303659bd72125bb87b17 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1102,7 +1102,7 @@ syntax: - name: DIVISION_BY_ZERO id: 273 - message: "Division by zero are not allowed in Enum or Annotation." + message: "Division by zero are not allowed." - name: UNSUPPORTED_OPERATOR_FOR_STRING id: 274 diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index e7204d2d33947ee031a17c5dbb38e781159adecb..9a1d19e418585adcdfa8d51addc3911479889671 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -16,8 +16,11 @@ #include "helpers.h" #include +#include "checker/ETSchecker.h" + #include "parser/program/program.h" #include "varbinder/privateBinding.h" +#include "varbinder/ETSBinder.h" #include "lexer/token/letters.h" #include "ir/base/classDefinition.h" @@ -706,6 +709,57 @@ std::vector const &Helpers::StdLib() return stdlib; } +varbinder::Scope *Helpers::NearestScope(const ir::AstNode *ast) +{ + while (ast != nullptr && !ast->IsScopeBearer()) { + ast = ast->Parent(); + } + + return ast == nullptr ? nullptr : ast->Scope(); +} + +checker::ETSObjectType const *Helpers::ContainingClass(const ir::AstNode *ast) +{ + while (ast != nullptr && !ast->IsClassDefinition()) { + ast = ast->Parent(); + } + + return ast == nullptr ? nullptr : ast->AsClassDefinition()->TsType()->AsETSObjectType(); +} + +bool CheckTypeRelation(checker::ETSChecker *checker, checker::Type *super, checker::Type *sub) +{ + return checker->Relation()->IsSupertypeOf(super, sub); +} + +void Helpers::CheckLoweredNode(varbinder::ETSBinder *varBinder, checker::ETSChecker *checker, ir::AstNode *node) +{ + auto *scope = util::Helpers::NearestScope(node); + varBinder->ResolveReferencesForScopeWithContext(node, scope); + + auto *containingClass = ContainingClass(node); + checker::CheckerStatus newStatus = + (containingClass == nullptr) ? checker::CheckerStatus::NO_OPTS : checker::CheckerStatus::IN_CLASS; + if ((checker->Context().Status() & checker::CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK) != 0) { + newStatus |= checker::CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK; + } + auto checkerCtx = checker::SavedCheckerContext(checker, newStatus, containingClass); + auto scopeCtx = checker::ScopeContext(checker, scope); + + node->Check(checker); +} + +bool Helpers::IsNumericGlobalBuiltIn(checker::Type *type, checker::ETSChecker *checker) +{ + return CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalIntegerBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalShortBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalByteBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalCharBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalLongBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalFloatBuiltinType()); +} + bool Helpers::IsStdLib(const parser::Program *program) { // NOTE(rsipka): early check: if program is not in a package then it is not part of the stdlib either diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index 3ac27791612128135fbd33bb94c53a6fb131e477..b6cd9fe75e327c0e9c1669e77cd3751c37a839f2 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -30,6 +30,7 @@ class Program; namespace ark::es2panda::varbinder { class Variable; +class ETSBinder; } // namespace ark::es2panda::varbinder namespace ark::es2panda::checker { @@ -160,6 +161,14 @@ public: std::uint32_t index); static bool IsAsyncMethod(ir::AstNode const *node); + static varbinder::Scope *NearestScope(const ir::AstNode *ast); + static checker::ETSObjectType const *ContainingClass(const ir::AstNode *ast); + // Note: run varbinder and checker on the new node generated in lowering phases (without + // ClearTypesVariablesAndScopes) + static void CheckLoweredNode(varbinder::ETSBinder *varBinder, checker::ETSChecker *checker, ir::AstNode *node); + + static bool IsNumericGlobalBuiltIn(checker::Type *type, checker::ETSChecker *checker); + template static ArenaVector ConvertVector(const ArenaVector &src) { diff --git a/ets2panda/util/ustring.cpp b/ets2panda/util/ustring.cpp index 7a8d1ace6d23afd00f7bcc4c95c9e673a2dcbb88..4d4f7a0e1fa82fd21e42f9070d4b5ded1a43dab6 100644 --- a/ets2panda/util/ustring.cpp +++ b/ets2panda/util/ustring.cpp @@ -80,14 +80,6 @@ void StringView::Iterator::SkipCp() } } -bool StringView::IsConvertibleToChar() const -{ - Iterator it(*this); - size_t size = 0; - char32_t ch = it.PeekCp(&size); - return size == Length() && ch != Iterator::INVALID_CP; -} - } // namespace ark::es2panda::util // NOLINTNEXTLINE(cert-dcl58-cpp) diff --git a/ets2panda/util/ustring.h b/ets2panda/util/ustring.h index a1fc97e97df2f68fcbe2b002a74f5aa043fced25..d5d44e41b01193fb0f85114d774e79bc42f0c163 100644 --- a/ets2panda/util/ustring.h +++ b/ets2panda/util/ustring.h @@ -156,8 +156,6 @@ public: template static void Mutf8Encode(T *str, char32_t cu); - bool IsConvertibleToChar() const; - class Iterator { public: static char32_t constexpr INVALID_CP = std::numeric_limits::max(); diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index f430c8cd48fccc9209e0705f45c6f32bc410b65b..e6a3835eb4f1a2ef683c20c70bef216cda6cfd52 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -236,7 +236,10 @@ Variable *Scope::AddLocalTypeAliasVariable(ArenaAllocator *allocator, Decl *newD Variable *Scope::AddLocalClassVariable(ArenaAllocator *allocator, Decl *newDecl) { auto isNamespaceTransformed = newDecl->Node()->AsClassDefinition()->IsNamespaceTransformed(); - VariableFlags flag = isNamespaceTransformed ? VariableFlags::NAMESPACE : VariableFlags::CLASS; + auto isEnumTransformed = newDecl->Node()->AsClassDefinition()->IsEnumTransformed(); + VariableFlags flag = isNamespaceTransformed ? VariableFlags::NAMESPACE + : isEnumTransformed ? VariableFlags::ENUM_LITERAL + : VariableFlags::CLASS; auto *var = bindings_.insert({newDecl->Name(), allocator->New(newDecl, flag)}).first->second; newDecl->Node()->AsClassDefinition()->Ident()->SetVariable(var); return var; diff --git a/ets2panda/varbinder/variable.cpp b/ets2panda/varbinder/variable.cpp index 6768c7b88aae56e067f1441206db748a60ff059e..f58fab347276334076da8adea9d997d4ce7670e0 100644 --- a/ets2panda/varbinder/variable.cpp +++ b/ets2panda/varbinder/variable.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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 @@ -33,6 +33,8 @@ LocalVariable::LocalVariable(VariableFlags flags) : Variable(flags) {} const util::StringView &Variable::Name() const { + // Synthetic var has no decl_ + ES2PANDA_ASSERT(decl_ != nullptr); return decl_->Name(); }