From 5f564bbc18320057abd339d3c0597f290eb12920 Mon Sep 17 00:00:00 2001 From: Klimentieva Date: Tue, 15 Jul 2025 15:26:10 +0300 Subject: [PATCH 1/2] Add FixedArray Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICRXZX Change-Id: Ic5f0a269f4521ccb1eb69acc8cc9d0479591a65e Signed-off-by: Klimentieva --- ets2panda/BUILD.gn | 3 + ets2panda/CMakeLists.txt | 1 + ets2panda/checker/ETSAnalyzer.cpp | 27 ++-- ets2panda/checker/SemanticAnalyzer.h | 1 + ets2panda/checker/TSAnalyzerUnreachable.cpp | 5 + ets2panda/checker/ets/function.cpp | 7 + ets2panda/checker/ets/helpers.cpp | 11 +- ets2panda/compiler/core/ETSCompiler.cpp | 52 +++++++ .../compiler/core/JSCompilerUnreachable.cpp | 5 + .../lowering/ets/arrayLiteralLowering.cpp | 39 +++++ .../lowering/ets/arrayLiteralLowering.h | 1 + .../compiler/lowering/ets/expandBrackets.cpp | 8 +- .../compiler/lowering/ets/expandBrackets.h | 5 +- .../compiler/lowering/ets/lambdaLowering.cpp | 4 +- .../compiler/lowering/ets/spreadLowering.cpp | 2 +- .../compiler/lowering/ets/unboxLowering.cpp | 2 +- ets2panda/ir/astNodeMapping.h | 1 + .../etsNewFixedArrayInstanceExpression.cpp | 146 ++++++++++++++++++ .../ets/etsNewFixedArrayInstanceExpression.h | 125 +++++++++++++++ ets2panda/parser/ETSparser.h | 1 + ets2panda/parser/ETSparserExpressions.cpp | 21 +++ ets2panda/public/CMakeLists.txt | 2 + ets2panda/public/es2panda_lib.cpp | 1 + .../public/headers_parser/supported_types.py | 1 + ets2panda/scripts/arkui.properties | 4 +- .../ets/FixedArray/double_as_index.ets | 27 ++++ .../FixedArray/newClassInstanceExpression.ets | 2 +- .../ast/parser/ets/FixedArray/StringFasta.ets | 4 +- .../predefined_non_primitive_types.ets | 2 +- .../ets/FixedArray/unexpected_token_36.ets | 2 +- ets2panda/test/runtime/ets/CastReference3.ets | 4 +- ets2panda/test/runtime/ets/CastReference4.ets | 2 +- .../ets/ManyLocalOutRegInstruction.ets | 2 +- ets2panda/test/runtime/ets/StringFasta.ets | 4 +- .../test/runtime/ets/array-new-catched.ets | 2 +- ets2panda/test/runtime/ets/instanceof.ets | 2 +- .../test/runtime/ets/invoke-with-rest.ets | 2 +- .../test/runtime/ets/nestedLambdaLet.ets | 2 +- ...ed_as_default_value_for_built_in_array.ets | 2 +- ...tsNewFixedArrayInstanceExpressionBuilder.h | 53 +++++++ 40 files changed, 544 insertions(+), 43 deletions(-) create mode 100644 ets2panda/ir/ets/etsNewFixedArrayInstanceExpression.cpp create mode 100644 ets2panda/ir/ets/etsNewFixedArrayInstanceExpression.h create mode 100644 ets2panda/test/ast/compiler/ets/FixedArray/double_as_index.ets create mode 100644 ets2panda/util/ast-builders/etsNewFixedArrayInstanceExpressionBuilder.h diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index bf31837fa5..f3f469f567 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -325,6 +325,7 @@ libes2panda_sources = [ "ir/ets/etsNeverType.cpp", "ir/ets/etsNewArrayInstanceExpression.cpp", "ir/ets/etsNewClassInstanceExpression.cpp", + "ir/ets/etsNewFixedArrayInstanceExpression.cpp", "ir/ets/etsNewMultiDimArrayInstanceExpression.cpp", "ir/ets/etsNonNullishTypeNode.cpp", "ir/ets/etsNullishTypes.cpp", @@ -655,6 +656,7 @@ HEADERS_TO_BE_PARSED = [ "ir/ets/etsPackageDeclaration.h", "ir/expressions/literals/regExpLiteral.h", "ir/ets/etsNewArrayInstanceExpression.h", + "ir/ets/etsNewFixedArrayInstanceExpression.h", "checker/types/ets/etsVoidType.h", "ir/base/metaProperty.h", "checker/types/type.h", @@ -937,6 +939,7 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/ir/ets/etsStructDeclaration.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsModuleBlock.yaml", "$LIBGEN_DIR/gen/headers/ir/ets/etsNewArrayInstanceExpression.yaml", + "$LIBGEN_DIR/gen/headers/ir/ets/etsNewFixedArrayInstanceExpression.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/loopStatement.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/annotationDeclaration.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/annotationUsage.yaml", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 582670d8f8..d5d26fb523 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -449,6 +449,7 @@ set(ES2PANDA_LIB_SRC ir/ets/etsIntrinsicNode.cpp ir/ets/etsKeyofType.cpp ir/ets/etsNewArrayInstanceExpression.cpp + ir/ets/etsNewFixedArrayInstanceExpression.cpp ir/ets/etsNewClassInstanceExpression.cpp ir/ets/etsNewMultiDimArrayInstanceExpression.cpp ir/ets/etsPackageDeclaration.cpp diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 716609bc6d..bda5b97a7a 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -557,21 +557,26 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const auto *elementType = expr->TypeReference()->GetType(checker); checker->ValidateArrayIndex(expr->Dimension(), true); - CheckArrayElementType(checker, expr); - auto *preferredType = GetAppropriatePreferredType( - expr->PreferredType(), [](Type *tp) -> bool { return tp->IsETSArrayType() || tp->IsETSResizableArrayType(); }); + expr->SetTsType(checker->CreateETSResizableArrayType(elementType)); - if (NeedCreateETSResizableArrayType(checker, expr->PreferredType()) || preferredType == nullptr || - preferredType->IsETSResizableArrayType()) { - expr->SetTsType(checker->CreateETSResizableArrayType(elementType)); - } else { - expr->SetTsType(checker->CreateETSArrayType(elementType)); - } - if (expr->TsType()->IsETSArrayType()) { - checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); + return expr->TsType(); +} + +checker::Type *ETSAnalyzer::Check(ir::ETSNewFixedArrayInstanceExpression *expr) const +{ + if (expr->TsType() != nullptr) { + return expr->TsType(); } + ETSChecker *checker = GetETSChecker(); + + auto *elementType = expr->TypeReference()->GetType(checker); + checker->ValidateArrayIndex(expr->Dimension(), true); + CheckArrayElementType(checker, expr); + expr->SetTsType(checker->CreateETSArrayType(elementType)); + checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); + return expr->TsType(); } diff --git a/ets2panda/checker/SemanticAnalyzer.h b/ets2panda/checker/SemanticAnalyzer.h index 1126ba93c0..a2162be07c 100644 --- a/ets2panda/checker/SemanticAnalyzer.h +++ b/ets2panda/checker/SemanticAnalyzer.h @@ -42,6 +42,7 @@ #include "ir/ets/etsImportDeclaration.h" #include "ir/ets/etsKeyofType.h" #include "ir/ets/etsNewArrayInstanceExpression.h" +#include "ir/ets/etsNewFixedArrayInstanceExpression.h" #include "ir/ets/etsNewClassInstanceExpression.h" #include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" #include "ir/ets/etsPackageDeclaration.h" diff --git a/ets2panda/checker/TSAnalyzerUnreachable.cpp b/ets2panda/checker/TSAnalyzerUnreachable.cpp index 43a987d1cb..1ecc61dcce 100644 --- a/ets2panda/checker/TSAnalyzerUnreachable.cpp +++ b/ets2panda/checker/TSAnalyzerUnreachable.cpp @@ -104,6 +104,11 @@ checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNewArrayInstanceExpress ES2PANDA_UNREACHABLE(); } +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNewFixedArrayInstanceExpression *expr) const +{ + ES2PANDA_UNREACHABLE(); +} + checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNewClassInstanceExpression *expr) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 7034998575..478d6e7151 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -477,6 +477,9 @@ static void ClearPreferredTypeForArray(checker::ETSChecker *checker, ir::Express argument->AsETSNewMultiDimArrayInstanceExpression()->CleanCheckInformation(); argument->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(checker, paramType, flags); + } else if (argument->IsETSNewFixedArrayInstanceExpression()) { + argument->AsETSNewFixedArrayInstanceExpression()->CleanCheckInformation(); + argument->AsETSNewFixedArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(checker, paramType, flags); } else { return; } @@ -2844,6 +2847,10 @@ bool ETSChecker::SetPreferredTypeBeforeValidate(Signature *substitutedSig, ir::E argument->AsETSNewArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(this, paramType, flags); } + if (argument->IsETSNewFixedArrayInstanceExpression()) { + argument->AsETSNewFixedArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(this, paramType, flags); + } + if (argument->IsETSNewMultiDimArrayInstanceExpression()) { argument->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(this, paramType, flags); } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index dd5d023d62..22845976de 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -762,12 +762,12 @@ static bool SetPreferredTypeForExpression(ETSChecker *checker, ir::Identifier *i init->SetPreferredType(PreferredObjectTypeFromAnnotation(annotationType)); } - if (init->IsETSNewArrayInstanceExpression() && annotationType != nullptr) { - init->SetPreferredType(annotationType); - } - if (init->IsETSNewMultiDimArrayInstanceExpression() && annotationType != nullptr) { + if ((init->IsETSNewArrayInstanceExpression() || init->IsETSNewFixedArrayInstanceExpression() || + init->IsETSNewMultiDimArrayInstanceExpression()) && + annotationType != nullptr) { init->SetPreferredType(annotationType); } + if (init->IsNumberLiteral() && annotationType != nullptr) { init->SetPreferredType(annotationType); } @@ -808,6 +808,9 @@ bool ETSChecker::CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, } else if (init->IsETSNewArrayInstanceExpression()) { annotationType = init->AsETSNewArrayInstanceExpression()->TypeReference()->GetType(this); annotationType = CreateETSResizableArrayType(annotationType); + } else if (init->IsETSNewFixedArrayInstanceExpression()) { + annotationType = init->AsETSNewFixedArrayInstanceExpression()->TypeReference()->GetType(this); + annotationType = CreateETSArrayType(annotationType); } else if (init->IsETSNewMultiDimArrayInstanceExpression()) { auto multiArray = init->AsETSNewMultiDimArrayInstanceExpression(); annotationType = multiArray->TypeReference()->GetType(this); diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 7f7059aeca..d8dc1676a1 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -161,6 +161,58 @@ void ETSCompiler::Compile(const ir::ETSNewArrayInstanceExpression *expr) const ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->TsType())); } +void ETSCompiler::Compile(const ir::ETSNewFixedArrayInstanceExpression *expr) const +{ + ETSGen *etsg = GetETSGen(); + auto const checker = const_cast(etsg->Checker()); + compiler::RegScope rs(etsg); + compiler::TargetTypeContext ttctx(etsg, checker->GlobalIntType()); + + expr->Dimension()->Compile(etsg); + + compiler::VReg arr = etsg->AllocReg(); + compiler::VReg dim = etsg->AllocReg(); + etsg->ApplyConversionAndStoreAccumulator(expr, dim, expr->Dimension()->TsType()); + etsg->NewArray(expr, arr, dim, expr->TsType()); + + const auto *elementType = expr->TypeReference()->TsType(); + const bool undefAssignable = checker->Relation()->IsSupertypeOf(elementType, checker->GlobalETSUndefinedType()); + if (elementType->IsETSPrimitiveType() || undefAssignable) { + // no-op + } else { + compiler::VReg countReg = etsg->AllocReg(); + auto *startLabel = etsg->AllocLabel(); + auto *endLabel = etsg->AllocLabel(); + etsg->MoveImmediateToRegister(expr, countReg, checker::TypeFlag::INT, static_cast(0)); + const auto indexReg = etsg->AllocReg(); + + etsg->SetLabel(expr, startLabel); + etsg->LoadAccumulator(expr, dim); + etsg->JumpCompareRegister(expr, countReg, endLabel); + + etsg->LoadAccumulator(expr, countReg); + etsg->StoreAccumulator(expr, indexReg); + + if (expr->Signature() != nullptr) { + const compiler::TargetTypeContext ttctx2(etsg, elementType); + static const ArenaVector ARGUMENTS(GetCodeGen()->Allocator()->Adapter()); + etsg->InitObject(expr, expr->Signature(), ARGUMENTS); + } else { + etsg->LoadAccumulatorPoison(expr, elementType); + } + etsg->StoreArrayElement(expr, arr, indexReg, elementType); + + etsg->IncrementImmediateRegister(expr, countReg, checker::TypeFlag::INT, static_cast(1)); + etsg->JumpTo(expr, startLabel); + etsg->SetLabel(expr, endLabel); + } + + etsg->SetVRegType(arr, expr->TsType()); + etsg->LoadAccumulator(expr, arr); + + ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->TsType())); +} + static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::ETSNewClassInstanceExpression *expr) { if (expr->GetSignature()->RestVar() != nullptr && (expr->GetSignature()->RestVar()->TsType()->IsETSArrayType() || diff --git a/ets2panda/compiler/core/JSCompilerUnreachable.cpp b/ets2panda/compiler/core/JSCompilerUnreachable.cpp index d38cf39039..94823468ad 100644 --- a/ets2panda/compiler/core/JSCompilerUnreachable.cpp +++ b/ets2panda/compiler/core/JSCompilerUnreachable.cpp @@ -133,6 +133,11 @@ void JSCompiler::Compile([[maybe_unused]] const ir::ETSNewArrayInstanceExpressio ES2PANDA_UNREACHABLE(); } +void JSCompiler::Compile([[maybe_unused]] const ir::ETSNewFixedArrayInstanceExpression *expr) const +{ + ES2PANDA_UNREACHABLE(); +} + void JSCompiler::Compile([[maybe_unused]] const ir::ETSNewClassInstanceExpression *expr) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp index 3d4f3e5b15..d288025a78 100644 --- a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp @@ -157,6 +157,42 @@ ir::AstNode *ArrayLiteralLowering::TryTransformNewArrayExprToRefArray(ir::ETSNew return loweringResult; } +ir::AstNode *ArrayLiteralLowering::TryTransformNewFixedArrayExprToRefArray( + ir::ETSNewFixedArrayInstanceExpression *newExpr) +{ + if (newExpr->TsType()->IsETSArrayType()) { + return newExpr; + } + ES2PANDA_ASSERT(newExpr->TsType()->IsETSResizableArrayType()); + + auto *arrayType = newExpr->TsType()->AsETSResizableArrayType()->ElementType(); + std::vector newStmts; + auto *genSymIdent = Gensym(Allocator()); + + std::stringstream ss; + ss << "let @@I1 = new FixedArray<@@T2>(@@E3.toDouble());"; + auto *type = checker_->AllocNode(arrayType, Allocator()); + auto *dimension = newExpr->Dimension()->Clone(Allocator(), nullptr); + newStmts.emplace_back(genSymIdent); + newStmts.emplace_back(type); + newStmts.emplace_back(dimension); + + ArenaVector statements(Allocator()->Adapter()); + auto *newArrStatement = parser_->CreateFormattedStatement(ss.str(), newStmts); + statements.emplace_back(newArrStatement); + auto newArrElementStatements = GenerateDefaultCallToConstructor(genSymIdent, arrayType); + statements.insert(statements.end(), newArrElementStatements.begin(), newArrElementStatements.end()); + auto returnStmt = parser_->CreateFormattedStatement("@@I1", genSymIdent->Clone(Allocator(), nullptr)); + statements.emplace_back(returnStmt); + auto *loweringResult = checker_->AllocNode(std::move(statements)); + loweringResult->SetRange(newExpr->Range()); + loweringResult->SetParent(newExpr->Parent()); + auto *scope = NearestScope(loweringResult->Parent()); + auto bscope = varbinder::LexicalScope::Enter(varbinder_, scope); + CheckLoweredNode(varbinder_, checker_, loweringResult); + return loweringResult; +} + ir::Statement *ArrayLiteralLowering::CreateNestedArrayCreationStatement(ArenaVector &identDims, size_t currentDim, checker::Type *type, ir::Expression *expr) @@ -253,6 +289,9 @@ bool ArrayLiteralLowering::PerformForModule(public_lib::Context *ctx, parser::Pr if (ast->IsETSNewArrayInstanceExpression()) { return TryTransformNewArrayExprToRefArray(ast->AsETSNewArrayInstanceExpression()); } + if (ast->IsETSNewFixedArrayInstanceExpression()) { + return TryTransformNewFixedArrayExprToRefArray(ast->AsETSNewFixedArrayInstanceExpression()); + } if (ast->IsETSNewMultiDimArrayInstanceExpression()) { return TryTransformNewMultiDimArrayToRefArray(ast->AsETSNewMultiDimArrayInstanceExpression()); } diff --git a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.h b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.h index ef2d297553..07b14af22c 100644 --- a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.h +++ b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.h @@ -38,6 +38,7 @@ private: checker::Type *type, ir::Expression *expr); ir::AstNode *TryTransformLiteralArrayToRefArray(ir::ArrayExpression *literalArray); ir::AstNode *TryTransformNewArrayExprToRefArray(ir::ETSNewArrayInstanceExpression *newExpr); + ir::AstNode *TryTransformNewFixedArrayExprToRefArray(ir::ETSNewFixedArrayInstanceExpression *newExpr); ArenaVector TransformDimVectorToIdentVector(ArenaVector &dimVector, ArenaVector &stmts); ir::AstNode *TryTransformNewMultiDimArrayToRefArray(ir::ETSNewMultiDimArrayInstanceExpression *newExpr); diff --git a/ets2panda/compiler/lowering/ets/expandBrackets.cpp b/ets2panda/compiler/lowering/ets/expandBrackets.cpp index 2f865dca1e..fd5b833cac 100644 --- a/ets2panda/compiler/lowering/ets/expandBrackets.cpp +++ b/ets2panda/compiler/lowering/ets/expandBrackets.cpp @@ -37,8 +37,8 @@ static constexpr char const CAST_NEW_DIMENSION_EXPRESSION[] = "(@@I1).toInt()"; static constexpr char const CAST_OLD_DIMENSION_EXPRESSION[] = "(@@E1).toInt()"; // NOLINTEND(modernize-avoid-c-arrays) -ir::Expression *ExpandBracketsPhase::ProcessNewArrayInstanceExpression( - public_lib::Context *ctx, ir::ETSNewArrayInstanceExpression *newInstanceExpression) const +ir::Expression *ExpandBracketsPhase::ProcessNewFixedArrayInstanceExpression( + public_lib::Context *ctx, ir::ETSNewFixedArrayInstanceExpression *newInstanceExpression) const { auto *const parser = ctx->parser->AsETSParser(); ES2PANDA_ASSERT(parser != nullptr); @@ -155,8 +155,8 @@ bool ExpandBracketsPhase::PerformForModule(public_lib::Context *ctx, parser::Pro { program->Ast()->TransformChildrenRecursively( [this, ctx](checker::AstNodePtr const ast) -> checker::AstNodePtr { - if (ast->IsETSNewArrayInstanceExpression()) { - return ProcessNewArrayInstanceExpression(ctx, ast->AsETSNewArrayInstanceExpression()); + if (ast->IsETSNewFixedArrayInstanceExpression()) { + return ProcessNewFixedArrayInstanceExpression(ctx, ast->AsETSNewFixedArrayInstanceExpression()); } if (ast->IsETSNewMultiDimArrayInstanceExpression()) { diff --git a/ets2panda/compiler/lowering/ets/expandBrackets.h b/ets2panda/compiler/lowering/ets/expandBrackets.h index 147e0e7cfa..4afebd0d8a 100644 --- a/ets2panda/compiler/lowering/ets/expandBrackets.h +++ b/ets2panda/compiler/lowering/ets/expandBrackets.h @@ -30,9 +30,8 @@ public: bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; private: - ir::Expression *ProcessNewArrayInstanceExpression(public_lib::Context *ctx, - ir::ETSNewArrayInstanceExpression *newInstanceExpression) const; - + ir::Expression *ProcessNewFixedArrayInstanceExpression( + public_lib::Context *ctx, ir::ETSNewFixedArrayInstanceExpression *newInstanceExpression) const; ir::Expression *ProcessNewMultiDimArrayInstanceExpression( public_lib::Context *ctx, ir::ETSNewMultiDimArrayInstanceExpression *newInstanceExpression) const; diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 333700f333..b6587af19b 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -691,7 +691,9 @@ static ArenaVector CreateRestArgumentsArrayReall statements << "let @@I1: int = @@I2.length - " << startIdx << ";" // CC-OFFNXT(G.FMT.06) false positive - << "let @@I3: FixedArray<@@T4> = new (@@T5)[@@I6];" + << "let @@I3: FixedArray<@@T4> = " + // CC-OFFNXT(G.FMT.06) false positive + << "new FixedArray<@@T5>(@@I6);" // CC-OFFNXT(G.FMT.06) false positive << "let @@I7 = @@I8 as FixedArray<@@T9>;" // CC-OFFNXT(G.FMT.06) false positive diff --git a/ets2panda/compiler/lowering/ets/spreadLowering.cpp b/ets2panda/compiler/lowering/ets/spreadLowering.cpp index 7bd6113966..d17b50734f 100644 --- a/ets2panda/compiler/lowering/ets/spreadLowering.cpp +++ b/ets2panda/compiler/lowering/ets/spreadLowering.cpp @@ -107,7 +107,7 @@ static ir::Identifier *CreateNewArrayDeclareStatement(public_lib::Context *ctx, if (array->TsType()->IsETSResizableArrayType()) { newArrayDeclareStr << "let @@I1: Array<@@T2> = new Array<@@T3>(@@I4);" << std::endl; } else { - newArrayDeclareStr << "let @@I1: FixedArray<@@T2> = new (@@T3)[@@I4];" << std::endl; + newArrayDeclareStr << "let @@I1: FixedArray<@@T2> = new FixedArray<@@T3>(@@I4);" << std::endl; } ES2PANDA_ASSERT(newArrayLengthId != nullptr); diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 0cf2d12eff..7e8ab8d916 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -1285,7 +1285,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { } } - void VisitETSNewArrayInstanceExpression(ir::ETSNewArrayInstanceExpression *nexpr) override + void VisitETSNewFixedArrayInstanceExpression(ir::ETSNewFixedArrayInstanceExpression *nexpr) override { auto unboxedType = MaybeRecursivelyUnboxType(uctx_, nexpr->TsType()); nexpr->SetTsType(unboxedType); diff --git a/ets2panda/ir/astNodeMapping.h b/ets2panda/ir/astNodeMapping.h index 34908d0e7c..3ae699385d 100644 --- a/ets2panda/ir/astNodeMapping.h +++ b/ets2panda/ir/astNodeMapping.h @@ -99,6 +99,7 @@ _(ETS_KEYOF_TYPE, ETSKeyofType) \ _(ETS_NEW_ARRAY_INSTANCE_EXPRESSION, ETSNewArrayInstanceExpression) \ _(ETS_NEW_MULTI_DIM_ARRAY_INSTANCE_EXPRESSION, ETSNewMultiDimArrayInstanceExpression) \ + _(ETS_NEW_FIXED_ARRAY_INSTANCE_EXPRESSION, ETSNewFixedArrayInstanceExpression) \ _(ETS_NEW_CLASS_INSTANCE_EXPRESSION, ETSNewClassInstanceExpression) \ _(ETS_IMPORT_DECLARATION, ETSImportDeclaration) \ _(ETS_PARAMETER_EXPRESSION, ETSParameterExpression) \ diff --git a/ets2panda/ir/ets/etsNewFixedArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewFixedArrayInstanceExpression.cpp new file mode 100644 index 0000000000..e93ee0d31a --- /dev/null +++ b/ets2panda/ir/ets/etsNewFixedArrayInstanceExpression.cpp @@ -0,0 +1,146 @@ +/* + * 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 "etsNewFixedArrayInstanceExpression.h" + +#include "checker/ETSchecker.h" +#include "checker/ets/typeRelationContext.h" +#include "checker/TSchecker.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" + +namespace ark::es2panda::ir { +void ETSNewFixedArrayInstanceExpression::TransformChildren(const NodeTransformer &cb, + std::string_view const transformationName) +{ + if (auto *transformedNode = cb(typeReference_); typeReference_ != transformedNode) { + typeReference_->SetTransformedNode(transformationName, transformedNode); + typeReference_ = static_cast(transformedNode); + } + + if (auto *transformedNode = cb(dimension_); dimension_ != transformedNode) { + dimension_->SetTransformedNode(transformationName, transformedNode); + dimension_ = transformedNode->AsExpression(); + } +} + +void ETSNewFixedArrayInstanceExpression::Iterate(const NodeTraverser &cb) const +{ + cb(typeReference_); + cb(dimension_); +} + +void ETSNewFixedArrayInstanceExpression::Dump(ir::AstDumper *dumper) const +{ + dumper->Add( + {{"type", "ETSNewFixedArrayInstanceExpression"}, {"typeReference", typeReference_}, {"dimension", dimension_}}); +} + +void ETSNewFixedArrayInstanceExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("new FixedArray"); + dumper->Add("<"); + ES2PANDA_ASSERT(typeReference_); + typeReference_->Dump(dumper); + dumper->Add(">"); + ES2PANDA_ASSERT(dimension_); + dumper->Add("("); + dimension_->Dump(dumper); + dumper->Add(")"); +} + +void ETSNewFixedArrayInstanceExpression::Compile(compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} +void ETSNewFixedArrayInstanceExpression::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} + +checker::Type *ETSNewFixedArrayInstanceExpression::Check(checker::TSChecker *checker) +{ + return checker->GetAnalyzer()->Check(this); +} + +checker::VerifiedType ETSNewFixedArrayInstanceExpression::Check(checker::ETSChecker *checker) +{ + return {this, checker->GetAnalyzer()->Check(this)}; +} + +ETSNewFixedArrayInstanceExpression *ETSNewFixedArrayInstanceExpression::Clone(ArenaAllocator *const allocator, + AstNode *const parent) +{ + auto *const typeRef = typeReference_ != nullptr ? typeReference_->Clone(allocator, nullptr) : nullptr; + auto *const dimension = dimension_ != nullptr ? dimension_->Clone(allocator, nullptr)->AsExpression() : nullptr; + auto *const clone = allocator->New(typeRef, dimension); + ES2PANDA_ASSERT(clone); + + if (typeRef != nullptr) { + typeRef->SetParent(clone); + } + + if (dimension != nullptr) { + dimension->SetParent(clone); + } + + if (parent != nullptr) { + clone->SetParent(parent); + } + + clone->defaultConstructorSignature_ = defaultConstructorSignature_; + clone->SetRange(Range()); + + return clone; +} + +void ETSNewFixedArrayInstanceExpression::ClearPreferredType() +{ + SetPreferredType(nullptr); + SetTsType(nullptr); +} + +void ETSNewFixedArrayInstanceExpression::CleanCheckInformation() +{ + SetPreferredType(nullptr); + SetTsType(nullptr); + if (dimension_ != nullptr) { + dimension_->CleanCheckInformation(); + } +} + +void ETSNewFixedArrayInstanceExpression::SetPreferredTypeBasedOnFuncParam(checker::ETSChecker *checker, + checker::Type *param, + checker::TypeRelationFlag flags) +{ + // NOTE (mmartin): This needs a complete solution + if (PreferredType() != nullptr) { + return; + } + + if (!param->IsETSArrayType()) { + return; + } + + auto *elementType = param->AsETSArrayType()->ElementType(); + + auto assignCtx = + checker::AssignmentContext(checker->Relation(), typeReference_, typeReference_->GetType(checker), elementType, + typeReference_->Start(), std::nullopt, checker::TypeRelationFlag::NO_THROW | flags); + if (assignCtx.IsAssignable()) { + SetPreferredType(param); + } +} +} // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ets/etsNewFixedArrayInstanceExpression.h b/ets2panda/ir/ets/etsNewFixedArrayInstanceExpression.h new file mode 100644 index 0000000000..cb03b44c0d --- /dev/null +++ b/ets2panda/ir/ets/etsNewFixedArrayInstanceExpression.h @@ -0,0 +1,125 @@ +/* + * 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_IR_ETS_NEW_FIXED_ARRAY_INSTANCE_EXPRESSION_H +#define ES2PANDA_IR_ETS_NEW_FIXED_ARRAY_INSTANCE_EXPRESSION_H + +#include "ir/expression.h" +#include "checker/types/type.h" + +namespace ark::es2panda::checker { +class ETSAnalyzer; +class Signature; +} // namespace ark::es2panda::checker + +namespace ark::es2panda::compiler { +class ETSCompiler; +} // namespace ark::es2panda::compiler + +namespace ark::es2panda::ir { + +class ETSNewFixedArrayInstanceExpression : public Expression { +public: + ETSNewFixedArrayInstanceExpression() = delete; + ~ETSNewFixedArrayInstanceExpression() override = default; + + NO_COPY_SEMANTIC(ETSNewFixedArrayInstanceExpression); + NO_MOVE_SEMANTIC(ETSNewFixedArrayInstanceExpression); + + explicit ETSNewFixedArrayInstanceExpression(ir::TypeNode *const typeReference, ir::Expression *const dimension) + : Expression(AstNodeType::ETS_NEW_FIXED_ARRAY_INSTANCE_EXPRESSION), + typeReference_(typeReference), + dimension_(dimension) + { + } + + [[nodiscard]] ir::TypeNode *TypeReference() noexcept + { + return typeReference_; + } + + [[nodiscard]] ir::TypeNode const *TypeReference() const noexcept + { + return typeReference_; + } + + [[nodiscard]] ir::Expression *Dimension() noexcept + { + return dimension_; + } + + [[nodiscard]] ir::Expression const *Dimension() const noexcept + { + return dimension_; + } + + [[nodiscard]] checker::Signature *Signature() const noexcept + { + return defaultConstructorSignature_; + } + + [[nodiscard]] checker::Signature *Signature() noexcept + { + return defaultConstructorSignature_; + } + + void SetDimension(ir::Expression *dimension) noexcept + { + dimension_ = dimension; + if (dimension_ != nullptr) { + dimension_->SetParent(this); + } + } + + void SetSignature(checker::Signature *signature) noexcept + { + defaultConstructorSignature_ = signature; + } + + [[nodiscard]] ETSNewFixedArrayInstanceExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; + + void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; + void Iterate(const NodeTraverser &cb) const override; + void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; + void Compile(compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; + checker::Type *Check(checker::TSChecker *checker) override; + checker::VerifiedType Check(checker::ETSChecker *checker) override; + void SetPreferredTypeBasedOnFuncParam(checker::ETSChecker *checker, checker::Type *param, + checker::TypeRelationFlag flags); + + void Accept(ASTVisitorT *v) override + { + v->Accept(this); + } + + void CleanUp() override + { + AstNode::CleanUp(); + defaultConstructorSignature_ = nullptr; + } + + void ClearPreferredType(); + void CleanCheckInformation() override; + +private: + ir::TypeNode *typeReference_; + ir::Expression *dimension_; + checker::Signature *defaultConstructorSignature_ {}; +}; +} // namespace ark::es2panda::ir + +#endif \ No newline at end of file diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 4e78635efd..822f3dca76 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -393,6 +393,7 @@ private: void ParseArgumentsNewExpression(ArenaVector &arguments, ir::TypeNode *typeReference); ir::Identifier *CreateInvokeIdentifier(); ir::Expression *ParseNewExpression() override; + ir::Expression *ParseFixedArrayNewExpression(ir::TypeNode *typeReference, lexer::SourcePosition start); ir::Expression *ParseAsyncExpression(); ir::Expression *ParseAwaitExpression(); ir::ArrayExpression *ParseArrayExpression(ExpressionParseFlags flags) override; diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 4fd573b45d..bbb9086af9 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -710,6 +710,23 @@ void ETSParser::ParseArgumentsNewExpression(ArenaVector &argum } } +ir::Expression *ETSParser::ParseFixedArrayNewExpression(ir::TypeNode *typeReference, lexer::SourcePosition start) +{ + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { + Lexer()->NextToken(); + ir::Expression *dimension = ParseExpression(); + auto endLoc = Lexer()->GetToken().End(); + ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); + if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { + auto *typeParams = typeReference->AsETSTypeReference()->Part()->TypeParams(); + typeReference = typeParams == nullptr ? typeReference : typeParams->Params().front(); + auto *arrInstance = AllocNode(typeReference, dimension); + arrInstance->SetRange({start, endLoc}); + return arrInstance; + } + } + return nullptr; +} ir::Expression *ETSParser::ParseNewExpression() { lexer::SourcePosition start = Lexer()->GetToken().Start(); @@ -722,6 +739,10 @@ ir::Expression *ETSParser::ParseNewExpression() auto typeReference = ParseTypeAnnotation(&options); ES2PANDA_ASSERT(typeReference != nullptr); + if (IsFixedArrayTypeNode(typeReference)) { + return ParseFixedArrayNewExpression(typeReference, start); + } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { Lexer()->NextToken(); ir::Expression *dimension = ParseExpression(); diff --git a/ets2panda/public/CMakeLists.txt b/ets2panda/public/CMakeLists.txt index 965ef9d300..270f06b537 100644 --- a/ets2panda/public/CMakeLists.txt +++ b/ets2panda/public/CMakeLists.txt @@ -162,6 +162,7 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/ir/ets/etsPackageDeclaration.h ${ES2PANDA_ROOT}/ir/expressions/literals/regExpLiteral.h ${ES2PANDA_ROOT}/ir/ets/etsNewArrayInstanceExpression.h + ${ES2PANDA_ROOT}/ir/ets/etsNewFixedArrayInstanceExpression.h ${ES2PANDA_ROOT}/checker/types/ets/etsVoidType.h ${ES2PANDA_ROOT}/ir/base/metaProperty.h ${ES2PANDA_ROOT}/checker/types/type.h @@ -445,6 +446,7 @@ set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/ir/ets/etsStructDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/ts/tsModuleBlock.yaml ${LIBGEN_DIR}/gen/headers/ir/ets/etsNewArrayInstanceExpression.yaml + ${LIBGEN_DIR}/gen/headers/ir/ets/etsNewFixedArrayInstanceExpression.yaml ${LIBGEN_DIR}/gen/headers/ir/statements/loopStatement.yaml ${LIBGEN_DIR}/gen/headers/ir/statements/annotationDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/statements/annotationUsage.yaml diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index ea052d5e3d..c716284bc4 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -47,6 +47,7 @@ #include "ir/base/methodDefinition.h" #include "ir/ets/etsNewClassInstanceExpression.h" #include "ir/ets/etsNewArrayInstanceExpression.h" +#include "ir/ets/etsNewFixedArrayInstanceExpression.h" #include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" #include "parser/ETSparser.h" #include "parser/context/parserContext.h" diff --git a/ets2panda/public/headers_parser/supported_types.py b/ets2panda/public/headers_parser/supported_types.py index c10aabea13..b2d863a7ea 100644 --- a/ets2panda/public/headers_parser/supported_types.py +++ b/ets2panda/public/headers_parser/supported_types.py @@ -91,6 +91,7 @@ ast_nodes_supported = [ "ETSUnionType", "ETSKeyofType", "ETSNewArrayInstanceExpression", + "ETSNewFixedArrayInstanceExpression", "ETSNewMultiDimArrayInstanceExpression", "ETSNewClassInstanceExpression", "ETSImportDeclaration", diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index 571ddd6790..58c2d2f875 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_11-array-callbacks-number2int +ARKUI_DEV_REPO=https://gitee.com/klimentievamaria/koala_projects.git +ARKUI_DEV_BRANCH=panda_rev_10-fixed-array ARKUI_DEST=koala-sig diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/double_as_index.ets b/ets2panda/test/ast/compiler/ets/FixedArray/double_as_index.ets new file mode 100644 index 0000000000..f0a6fd42d3 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/FixedArray/double_as_index.ets @@ -0,0 +1,27 @@ +/* + * 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. + */ + +let a: FixedArray = new int[10.1] +let b: FixedArray = new FixedArray(10.1) + +function bar(): number { + return 4.3 +} + +let c: FixedArray = new FixedArray(bar()) + +/* @@? 16:26 Error TypeError: Type 'Array' cannot be assigned to type 'FixedArray' */ +/* @@? 16:34 Error TypeError: Index fractional part should be zero. */ +/* @@? 17:46 Error TypeError: Index fractional part should be zero. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/newClassInstanceExpression.ets b/ets2panda/test/ast/compiler/ets/FixedArray/newClassInstanceExpression.ets index 7a854d51d5..e8af0383d1 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/newClassInstanceExpression.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/newClassInstanceExpression.ets @@ -15,7 +15,7 @@ class A { public static fun(): FixedArray { - return new int[10]; + return new FixedArray(10); } } diff --git a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets index 54308f81cd..f8cfe66860 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets @@ -82,13 +82,13 @@ export class StringFasta { return ret; } static fastaRandom(n : int, table : HashMap): int { - let line : FixedArray = new char[60]; + let line : FixedArray = new FixedArray(60) makeCumulative(table); let ret : int = 0; while(n > 0) { if (n < line.length) { - line = new char[n]; + line = new FixedArray(n) } for (let i : int = 0; i < line.length; i++) { let r : double = Random.rand(1); 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 e096d5945f..7541ea7ed8 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 @@ -33,7 +33,7 @@ let non_prim_c: Char = c'b'; let s: String = "abc"; // see 3.2.2 Array types -let a: FixedArray = new int[5]; +let a: FixedArray = new FixedArray(5) /* @@@ label Error TypeError: Variable 'non_prim_b' has already been declared. */ /* @@? 23:25 Error TypeError: Type 'Double' cannot be assigned to type 'Float' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets index 556218db5c..12197c6cc4 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets @@ -20,7 +20,7 @@ export class AccessNSieve { static isPrime: FixedArray public setup(): void { - AccessNSieve.isPrime = new boolean[(1 << AccessNSieve.n1) * AccessNSieve.n2 + 1]; + AccessNSieve.isPrime = new FixedArray((1 << AccessNSieve.n1) * AccessNSieve.n2 + 1) } private static nsieve(m: int): int { diff --git a/ets2panda/test/runtime/ets/CastReference3.ets b/ets2panda/test/runtime/ets/CastReference3.ets index e4c0300b0c..64b0f47f1d 100644 --- a/ets2panda/test/runtime/ets/CastReference3.ets +++ b/ets2panda/test/runtime/ets/CastReference3.ets @@ -29,7 +29,7 @@ function clear_accumlator_type(As: FixedArray): FixedArray { function main() { { - let As: FixedArray = new C[1]; + let As: FixedArray = new FixedArray(1); As[0] = new C(); As = clear_accumlator_type(As); // workaround for: @@ -43,7 +43,7 @@ function main() { { let caught = false; try { - let As: FixedArray = new A[1]; + let As: FixedArray = new FixedArray(1); let Bs = As as FixedArray; } catch (e: ClassCastError) { caught = true; diff --git a/ets2panda/test/runtime/ets/CastReference4.ets b/ets2panda/test/runtime/ets/CastReference4.ets index 1d6541d0c4..9b036c09e8 100644 --- a/ets2panda/test/runtime/ets/CastReference4.ets +++ b/ets2panda/test/runtime/ets/CastReference4.ets @@ -22,7 +22,7 @@ function clear_accumlator_type(Is: FixedArray): FixedArray { } function main() { - let As: FixedArray = new A[1]; + let As: FixedArray = new FixedArray(1); let Is: FixedArray = As as FixedArray; let caught = false; diff --git a/ets2panda/test/runtime/ets/ManyLocalOutRegInstruction.ets b/ets2panda/test/runtime/ets/ManyLocalOutRegInstruction.ets index 6f0b34ac0f..887dd4dd86 100644 --- a/ets2panda/test/runtime/ets/ManyLocalOutRegInstruction.ets +++ b/ets2panda/test/runtime/ets/ManyLocalOutRegInstruction.ets @@ -32,6 +32,6 @@ function main(): int { let x14 = 14; let x15 = 15; let x16 = 16; - let x:FixedArray = new int[10]; + let x: FixedArray = new FixedArray(10); return x[0]; } diff --git a/ets2panda/test/runtime/ets/StringFasta.ets b/ets2panda/test/runtime/ets/StringFasta.ets index a01f512d30..b1fbd7dd84 100644 --- a/ets2panda/test/runtime/ets/StringFasta.ets +++ b/ets2panda/test/runtime/ets/StringFasta.ets @@ -82,13 +82,13 @@ export class StringFasta { return ret; } static fastaRandom(n : int, table : HashMap): int { - let line : char[] = new char[60]; + let line = new FixedArray(60); makeCumulative(table); let ret : int = 0; while(n > 0) { if (n < line.length) { - line = new char[n]; + line = new FixedArray(n); } for (let i : int = 0; i < line.length; i++) { let r : double = Random.rand(1); diff --git a/ets2panda/test/runtime/ets/array-new-catched.ets b/ets2panda/test/runtime/ets/array-new-catched.ets index 320374a011..51b5af55a3 100644 --- a/ets2panda/test/runtime/ets/array-new-catched.ets +++ b/ets2panda/test/runtime/ets/array-new-catched.ets @@ -19,7 +19,7 @@ function baz(): number { function main(): void { let catched = false; try { - let a:FixedArray = new int[baz()] + let a: FixedArray = new FixedArray(baz()) } catch (e: TypeError) { catched = true } diff --git a/ets2panda/test/runtime/ets/instanceof.ets b/ets2panda/test/runtime/ets/instanceof.ets index be7a677bea..c22db0d562 100644 --- a/ets2panda/test/runtime/ets/instanceof.ets +++ b/ets2panda/test/runtime/ets/instanceof.ets @@ -43,7 +43,7 @@ function main(): void { arktest.assertTrue((intArr instanceof FixedArray)) arktest.assertTrue(!(intArr instanceof Int)) - let integerArr: FixedArray = new Int[10]; + let integerArr: FixedArray = new FixedArray(10); arktest.assertTrue(integerArr instanceof FixedArray) arktest.assertTrue(integerArr instanceof Object) diff --git a/ets2panda/test/runtime/ets/invoke-with-rest.ets b/ets2panda/test/runtime/ets/invoke-with-rest.ets index db6bc82f1b..81b13bb07e 100644 --- a/ets2panda/test/runtime/ets/invoke-with-rest.ets +++ b/ets2panda/test/runtime/ets/invoke-with-rest.ets @@ -16,7 +16,7 @@ class A { x: FixedArray constructor(x: T) { - this.x = new Any[1] + this.x = new FixedArray(1) this.x[0] = x as Any } diff --git a/ets2panda/test/runtime/ets/nestedLambdaLet.ets b/ets2panda/test/runtime/ets/nestedLambdaLet.ets index 9c10edab3b..b9be22ea12 100644 --- a/ets2panda/test/runtime/ets/nestedLambdaLet.ets +++ b/ets2panda/test/runtime/ets/nestedLambdaLet.ets @@ -113,7 +113,7 @@ function arrays(): void { force(() => { a3[3] = a2[2]; arktest.assertEQ(a0[0] + a0[1] + a0[2] + a0[3], 4) - a0 = new double[5]; + a0 = new FixedArray(5); arktest.assertEQ(a0.length, 5) arktest.assertEQ(a0[0] + a0[1] + a0[2] + a0[3] + a0[4], 0) arktest.assertEQ(a1[0] + a1[1] + a1[2] + a1[3], 4) diff --git a/ets2panda/test/runtime/ets/undefined_as_default_value_for_built_in_array.ets b/ets2panda/test/runtime/ets/undefined_as_default_value_for_built_in_array.ets index 67e67c3041..399495e0f8 100644 --- a/ets2panda/test/runtime/ets/undefined_as_default_value_for_built_in_array.ets +++ b/ets2panda/test/runtime/ets/undefined_as_default_value_for_built_in_array.ets @@ -27,7 +27,7 @@ function main(): int { arktest.assertTrue(y[i] instanceof undefined, "y[i] value has to be undefined.") } - let m : FixedArray = new int[33] + let m : FixedArray = new FixedArray(33) for (let i = 0; i < 33; i++) { arktest.assertEQ(m[i], 0, "m[i] value has to be 0.") } diff --git a/ets2panda/util/ast-builders/etsNewFixedArrayInstanceExpressionBuilder.h b/ets2panda/util/ast-builders/etsNewFixedArrayInstanceExpressionBuilder.h new file mode 100644 index 0000000000..bede54507c --- /dev/null +++ b/ets2panda/util/ast-builders/etsNewFixedArrayInstanceExpressionBuilder.h @@ -0,0 +1,53 @@ +/** + * 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_UTIL_INCLUDE_ETS_NEW_FIXED_ARRAY_INSTANCE_EXPRESSION_BUILDER +#define ES2PANDA_UTIL_INCLUDE_ETS_NEW_FIXED_ARRAY_INSTANCE_EXPRESSION_BUILDER + +#include "ir/ets/etsNewFixedArrayInstanceExpression.h" +#include "mem/arena_allocator.h" +#include "astBuilder.h" + +namespace ark::es2panda::ir { + +class ETSNewFixedArrayInstanceExpressionBuilder : public AstBuilder { +public: + explicit ETSNewFixedArrayInstanceExpressionBuilder(ark::ArenaAllocator *allocator) : AstBuilder(allocator) {} + + ETSNewFixedArrayInstanceExpressionBuilder &SetTypeReference(TypeNode *typeReference) + { + typeReference_ = typeReference; + return *this; + } + + ETSNewFixedArrayInstanceExpressionBuilder &SetTypeReference(Expression *dimension) + { + dimension_ = dimension; + return *this; + } + + ETSNewFixedArrayInstanceExpression *Build() + { + auto node = AllocNode(typeReference_, dimension_); + return node; + } + +private: + ir::TypeNode *typeReference_ {}; + ir::Expression *dimension_ {}; +}; + +} // namespace ark::es2panda::ir +#endif // ES2PANDA_UTIL_INCLUDE_ETS_NEW_FIXED_ARRAY_INSTANCE_EXPRESSION_BUILDER \ No newline at end of file -- Gitee From f8d03e06f35bb349cd0916ed80ef0a7e7ea56ed0 Mon Sep 17 00:00:00 2001 From: Klimentieva Date: Thu, 11 Sep 2025 15:36:50 +0300 Subject: [PATCH 2/2] Change-Id: I4620dacd43f592ce2e66379dd1c0c4deb7656ac2 Signed-off-by: Klimentieva --- .../compiler/lowering/ets/expandBrackets.cpp | 44 +++++++++++++++++++ .../compiler/lowering/ets/expandBrackets.h | 2 + 2 files changed, 46 insertions(+) diff --git a/ets2panda/compiler/lowering/ets/expandBrackets.cpp b/ets2panda/compiler/lowering/ets/expandBrackets.cpp index fd5b833cac..1b706b60c3 100644 --- a/ets2panda/compiler/lowering/ets/expandBrackets.cpp +++ b/ets2panda/compiler/lowering/ets/expandBrackets.cpp @@ -37,6 +37,47 @@ static constexpr char const CAST_NEW_DIMENSION_EXPRESSION[] = "(@@I1).toInt()"; static constexpr char const CAST_OLD_DIMENSION_EXPRESSION[] = "(@@E1).toInt()"; // NOLINTEND(modernize-avoid-c-arrays) +ir::Expression *ExpandBracketsPhase::ProcessNewArrayInstanceExpression( + public_lib::Context *ctx, ir::ETSNewArrayInstanceExpression *newInstanceExpression) const +{ + auto *const parser = ctx->parser->AsETSParser(); + ES2PANDA_ASSERT(parser != nullptr); + auto *const checker = ctx->GetChecker()->AsETSChecker(); + ES2PANDA_ASSERT(checker != nullptr); + auto *dimension = newInstanceExpression->Dimension(); + auto *dimType = dimension->TsType(); + ES2PANDA_ASSERT(dimType->IsETSObjectType()); + + if (!dimType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_FLOATING_POINT)) { + return newInstanceExpression; + } + + auto *scope = NearestScope(newInstanceExpression); + if (scope == nullptr) { + scope = checker->VarBinder()->VarScope() != nullptr ? checker->VarBinder()->VarScope() + : checker->VarBinder()->TopScope(); + } + auto expressionCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), scope); + + auto const identName = GenName(ctx->Allocator()); + auto *exprType = ctx->AllocNode(dimType, ctx->Allocator()); + auto *const newInstanceParent = newInstanceExpression->Parent(); + + auto *blockExpression = parser->CreateFormattedExpression(FORMAT_NEW_ARRAY_EXPRESSION, identName, exprType, + dimension, identName, newInstanceExpression); + blockExpression->SetParent(newInstanceParent); + + auto *castedDimension = parser->CreateFormattedExpression(CAST_NEW_DIMENSION_EXPRESSION, identName); + newInstanceExpression->SetDimension(castedDimension); + + newInstanceExpression->SetTsType(nullptr); + InitScopesPhaseETS::RunExternalNode(blockExpression, checker->VarBinder()); + checker->VarBinder()->AsETSBinder()->ResolveReferencesForScope(blockExpression, NearestScope(blockExpression)); + blockExpression->Check(checker); + + return blockExpression; +} + ir::Expression *ExpandBracketsPhase::ProcessNewFixedArrayInstanceExpression( public_lib::Context *ctx, ir::ETSNewFixedArrayInstanceExpression *newInstanceExpression) const { @@ -155,6 +196,9 @@ bool ExpandBracketsPhase::PerformForModule(public_lib::Context *ctx, parser::Pro { program->Ast()->TransformChildrenRecursively( [this, ctx](checker::AstNodePtr const ast) -> checker::AstNodePtr { + if (ast->IsETSNewArrayInstanceExpression()) { + return ProcessNewArrayInstanceExpression(ctx, ast->AsETSNewArrayInstanceExpression()); + } if (ast->IsETSNewFixedArrayInstanceExpression()) { return ProcessNewFixedArrayInstanceExpression(ctx, ast->AsETSNewFixedArrayInstanceExpression()); } diff --git a/ets2panda/compiler/lowering/ets/expandBrackets.h b/ets2panda/compiler/lowering/ets/expandBrackets.h index 4afebd0d8a..57969e19ea 100644 --- a/ets2panda/compiler/lowering/ets/expandBrackets.h +++ b/ets2panda/compiler/lowering/ets/expandBrackets.h @@ -30,6 +30,8 @@ public: bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; private: + ir::Expression *ProcessNewArrayInstanceExpression( + public_lib::Context *ctx, ir::ETSNewArrayInstanceExpression *newInstanceExpression) const; ir::Expression *ProcessNewFixedArrayInstanceExpression( public_lib::Context *ctx, ir::ETSNewFixedArrayInstanceExpression *newInstanceExpression) const; ir::Expression *ProcessNewMultiDimArrayInstanceExpression( -- Gitee