diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 60c32ea888d672fd753514e638086c66492cc36b..fc19cb6a9110fcc42a3f82f638492329cbd8e79c 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -240,7 +240,7 @@ libes2panda_sources = [ "compiler/lowering/ets/extensionAccessorLowering.cpp", "compiler/lowering/ets/genericBridgesLowering.cpp", "compiler/lowering/ets/gradualTypeNarrowing.cpp", - "compiler/lowering/ets/insertOptionalParametersAnnotation.cpp", + "compiler/lowering/ets/insertParametersAnnotation.cpp", "compiler/lowering/ets/interfaceObjectLiteralLowering.cpp", "compiler/lowering/ets/interfacePropertyDeclarations.cpp", "compiler/lowering/ets/lambdaLowering.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 73d465ae3641b94bb806b297268f3b89e79e5884..f356de9fce0ca3fe05f9cba9fdf5447de303d78b 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -295,7 +295,7 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/spreadLowering.cpp compiler/lowering/ets/objectIndexAccess.cpp compiler/lowering/ets/objectIterator.cpp - compiler/lowering/ets/insertOptionalParametersAnnotation.cpp + compiler/lowering/ets/insertParametersAnnotation.cpp compiler/lowering/ets/interfacePropertyDeclarations.cpp compiler/lowering/ets/opAssignment.cpp compiler/lowering/ets/ambientLowering.cpp diff --git a/ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.cpp b/ets2panda/compiler/lowering/ets/insertParametersAnnotation.cpp similarity index 60% rename from ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.cpp rename to ets2panda/compiler/lowering/ets/insertParametersAnnotation.cpp index 44d8ae95b58bd29592efd3b26f3324cb7d6890cf..9efb86c137c7568158deb1dbbce2f6121d5dd94e 100644 --- a/ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.cpp +++ b/ets2panda/compiler/lowering/ets/insertParametersAnnotation.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "insertOptionalParametersAnnotation.h" +#include "insertParametersAnnotation.h" #include "compiler/lowering/util.h" namespace ark::es2panda::compiler { @@ -30,20 +30,39 @@ static ir::Identifier *GenDefaultAnnoId(ArenaAllocator *allocator) return UAlloc::ForceSetParent(allocator, Signatures::DEFAULT_ANNO_FOR_FUNC, allocator); } +static ir::Identifier *GenReadonlyAnnoQualifiedLeft(ArenaAllocator *allocator) +{ + return UAlloc::ForceSetParent(allocator, Signatures::READONLY_ANNO_QUALIFIED_LEFT, allocator); +} + +static ir::Identifier *GenReadonlyAnnoId(ArenaAllocator *allocator) +{ + return UAlloc::ForceSetParent(allocator, Signatures::READONLY_ANNO_FOR_PARAMETER, allocator); +} + static ir::Identifier *GenDefaultPropId(ArenaAllocator *allocator, util::StringView const name) { return UAlloc::ForceSetParent(allocator, name, allocator); } +static ir::ETSTypeReference *GenAnnoNameRef(ArenaAllocator *allocator, ir::Identifier *qualifier, + ir::Identifier *refName) +{ + auto qualifiedAnnoName = UAlloc::ForceSetParent(allocator, qualifier, refName, allocator); + auto refPart = + UAlloc::ForceSetParent(allocator, qualifiedAnnoName, nullptr, nullptr, allocator); + auto annoRef = UAlloc::ForceSetParent(allocator, refPart, allocator); + return annoRef; +} + static ir::ETSTypeReference *GenDefaultAnnoNameRef(ArenaAllocator *allocator) { - auto defaultQualifiedAnnoName = UAlloc::ForceSetParent( - allocator, GenAnnoQualifiedLeft(allocator), GenDefaultAnnoId(allocator), allocator); - auto defaultRefPart = UAlloc::ForceSetParent(allocator, defaultQualifiedAnnoName, nullptr, - nullptr, allocator); + return GenAnnoNameRef(allocator, GenAnnoQualifiedLeft(allocator), GenDefaultAnnoId(allocator)); +} - auto defaultRef = UAlloc::ForceSetParent(allocator, defaultRefPart, allocator); - return defaultRef; +static ir::ETSTypeReference *GenReadonlyAnnoNameRef(ArenaAllocator *allocator) +{ + return GenAnnoNameRef(allocator, GenReadonlyAnnoQualifiedLeft(allocator), GenReadonlyAnnoId(allocator)); } static ir::AstNode *GenMinArgCountItem(ArenaAllocator *allocator, const int32_t requiredArgs) @@ -87,7 +106,27 @@ static ir::AstNode *CreateDefaultAnnotationUsageForFunction(public_lib::Context return util::NodeAllocator::ForceSetParent(allocator, defaultRef, std::move(properties)); } -static void TryInsertDefaultAnnotation(public_lib::Context *ctx, ir::AstNode *node) +static void CreateReadonlyAnnotationUsageForFunctionParams(public_lib::Context *ctx, const ir::ScriptFunction *func) +{ + auto allocator = ctx->allocator; + for (auto const param : func->Params()) { + if (!param->IsETSParameterExpression()) { + ES2PANDA_ASSERT(param->IsIdentifier() && param->AsIdentifier()->IsErrorPlaceHolder()); + return; + } + auto *typeAnnot = param->AsETSParameterExpression()->Ident()->TypeAnnotation(); + if (typeAnnot != nullptr && typeAnnot->IsReadonlyType()) { + ir::ETSTypeReference *readonlyRef = GenReadonlyAnnoNameRef(allocator); + auto *annotUsage = + util::NodeAllocator::ForceSetParent(allocator, readonlyRef, allocator); + param->AsETSParameterExpression()->EmplaceAnnotations(annotUsage); + annotUsage->SetParent(param); + RefineSourceRanges(annotUsage); + } + } +} + +static void TryInsertParametersAnnotation(public_lib::Context *ctx, ir::AstNode *node) { if (!node->IsMethodDefinition()) { return; @@ -96,6 +135,8 @@ static void TryInsertDefaultAnnotation(public_lib::Context *ctx, ir::AstNode *no auto methodDef = node->AsMethodDefinition(); if (!methodDef->IsConstructor() && !methodDef->IsAbstract() && methodDef->Function() != nullptr) { auto methodFunc = methodDef->Function(); + CreateReadonlyAnnotationUsageForFunctionParams(ctx, methodFunc); + auto defaultAnno = CreateDefaultAnnotationUsageForFunction(ctx, methodFunc); if (defaultAnno != nullptr) { methodFunc->EmplaceAnnotations(defaultAnno->AsAnnotationUsage()); @@ -105,20 +146,20 @@ static void TryInsertDefaultAnnotation(public_lib::Context *ctx, ir::AstNode *no } } -bool InsertOptionalParametersAnnotation::PerformForModule(public_lib::Context *ctx, parser::Program *program) +bool InsertParametersAnnotation::PerformForModule(public_lib::Context *ctx, parser::Program *program) { if (program->Extension() != ScriptExtension::ETS) { return true; } - if (program->GetFlag(parser::ProgramFlags::AST_HAS_OPTIONAL_PARAMETER_ANNOTATION)) { + if (program->GetFlag(parser::ProgramFlags::AST_HAS_PARAMETERS_ANNOTATION)) { return true; } program->Ast()->IterateRecursivelyPostorder( - [ctx](ir::AstNode *node) -> void { TryInsertDefaultAnnotation(ctx, node); }); + [ctx](ir::AstNode *node) -> void { TryInsertParametersAnnotation(ctx, node); }); - program->SetFlag(parser::ProgramFlags::AST_HAS_OPTIONAL_PARAMETER_ANNOTATION); + program->SetFlag(parser::ProgramFlags::AST_HAS_PARAMETERS_ANNOTATION); return true; } diff --git a/ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.h b/ets2panda/compiler/lowering/ets/insertParametersAnnotation.h similarity index 88% rename from ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.h rename to ets2panda/compiler/lowering/ets/insertParametersAnnotation.h index 780d43d5140956454ed94e286fabae3f2622bbff..3881e54b7ea76d892a5e3273c805101831755955 100644 --- a/ets2panda/compiler/lowering/ets/insertOptionalParametersAnnotation.h +++ b/ets2panda/compiler/lowering/ets/insertParametersAnnotation.h @@ -20,11 +20,11 @@ namespace ark::es2panda::compiler { -class InsertOptionalParametersAnnotation : public PhaseForDeclarations { +class InsertParametersAnnotation : public PhaseForDeclarations { public: std::string_view Name() const override { - return "InsertOptionalParametersAnnotation"; + return "InsertParametersAnnotation"; } bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index bc06d4dca05f3330a9e819c17f7670afad16f645..a67b6cec2245b2ac83d7b43137ec336a7f5754a9 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -42,7 +42,7 @@ #include "compiler/lowering/ets/extensionAccessorLowering.h" #include "compiler/lowering/ets/genericBridgesLowering.h" #include "compiler/lowering/ets/gradualTypeNarrowing.h" -#include "compiler/lowering/ets/insertOptionalParametersAnnotation.h" +#include "compiler/lowering/ets/insertParametersAnnotation.h" #include "compiler/lowering/ets/interfaceObjectLiteralLowering.h" #include "compiler/lowering/ets/interfacePropertyDeclarations.h" #include "compiler/lowering/ets/lambdaLowering.h" @@ -107,7 +107,7 @@ std::vector GetETSPhaseList() new TopLevelStatements, new ResizableArrayConvert, new ExpressionLambdaConstructionPhase, - new InsertOptionalParametersAnnotation, + new InsertParametersAnnotation, new DefaultParametersInConstructorLowering, new DefaultParametersLowering, new AmbientLowering, diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 15dfcdbfe96bd5c3900cd74d7e3162fbbc665e31..0afe4f90552bc7f51f1594a98f56092fa0ed4268 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -222,6 +222,10 @@ defines: ref: DEFAULT_ANNO_FOR_FUNC - name: 'minArgCount' ref: MIN_ARGSCOUNT_OF_FUNC + - name: 'parameters' + ref: READONLY_ANNO_QUALIFIED_LEFT + - name: 'ReadonlyAnnotation' + ref: READONLY_ANNO_FOR_PARAMETER - name: 'gensym%%_anonymous_const' ref: EXPORT_DEFAULT_CONSTANT_ANONYMOUSLY - name: 'toByte' diff --git a/ets2panda/parser/program/program.h b/ets2panda/parser/program/program.h index 50563781160126cab72ffe51ab8c72685be37cbf..5d76bcc4a83e308995647cec03ea2af7f17af42b 100644 --- a/ets2panda/parser/program/program.h +++ b/ets2panda/parser/program/program.h @@ -65,7 +65,7 @@ enum class ProgramFlags : uint32_t { AST_STRING_CONSTANT_LOWERED = 1U << 6U, AST_IDENTIFIER_ANALYZED = 1U << 7U, AST_HAS_SCOPES_INITIALIZED = 1U << 8U, - AST_HAS_OPTIONAL_PARAMETER_ANNOTATION = 1U << 9U, + AST_HAS_PARAMETERS_ANNOTATION = 1U << 9U, }; class Program {