From 5943a1d06df4453e1f320ef1e3b255b475309564 Mon Sep 17 00:00:00 2001 From: tengtengh <10678859+tengtengh@user.noreply.gitee.com> Date: Sat, 26 Oct 2024 17:46:20 +0800 Subject: [PATCH] Implement annotations for more entity kinds Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IBB1UC Description: Implement annotations for more entity kinds in parser, binder and checker phase support annotation for more entity kinds (paser, binder, checker) : + interface declaration + interface property + interface method + class property + (local/global) variable declaration + type alias declaration + parameter expression Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: tengtengh --- ets2panda/BUILD.gn | 1 + ets2panda/checker/ETSAnalyzer.cpp | 23 ++--- ets2panda/checker/ETSchecker.h | 4 +- ets2panda/checker/ets/dynamic.cpp | 2 +- ets2panda/checker/ets/helpers.cpp | 2 +- ets2panda/checker/ets/object.cpp | 14 +-- ets2panda/checker/ets/typeCheckingHelpers.cpp | 21 ++++- .../lowering/ets/defaultParameterLowering.cpp | 3 +- .../compiler/lowering/ets/enumLowering.cpp | 2 +- .../ets/interfacePropertyDeclarations.cpp | 46 +++++++--- .../compiler/lowering/ets/lambdaLowering.cpp | 11 ++- .../topLevelStmts/globalDeclTransformer.cpp | 8 ++ .../lowering/scopesInit/scopesInitPhase.cpp | 17 ++-- .../methodBuilder.cpp | 8 +- ets2panda/ir/annotationAllowed.h | 86 +++++++++++++++++++ ets2panda/ir/base/classDefinition.cpp | 8 +- ets2panda/ir/base/classDefinition.h | 33 ++----- ets2panda/ir/base/classProperty.cpp | 26 +++++- ets2panda/ir/base/classProperty.h | 23 ++++- ets2panda/ir/base/scriptFunction.cpp | 11 ++- ets2panda/ir/base/scriptFunction.h | 27 +----- ets2panda/ir/ets/etsParameterExpression.cpp | 42 +++++++-- ets2panda/ir/ets/etsParameterExpression.h | 7 +- ets2panda/ir/statements/annotationUsage.cpp | 5 +- .../ir/statements/functionDeclaration.cpp | 8 +- ets2panda/ir/statements/functionDeclaration.h | 37 ++------ .../ir/statements/variableDeclaration.cpp | 18 +++- ets2panda/ir/statements/variableDeclaration.h | 6 +- ets2panda/ir/ts/tsEnumDeclaration.h | 3 +- ets2panda/ir/ts/tsInterfaceDeclaration.cpp | 16 ++++ ets2panda/ir/ts/tsInterfaceDeclaration.h | 6 +- ets2panda/ir/ts/tsTypeAliasDeclaration.cpp | 16 ++++ ets2panda/ir/ts/tsTypeAliasDeclaration.h | 22 +++++ ets2panda/parser/ETSparser.cpp | 26 +++++- ets2panda/parser/ETSparser.h | 9 +- ets2panda/parser/ETSparserClasses.cpp | 84 +++++++++++++++--- ets2panda/parser/ETSparserExpressions.cpp | 8 +- ets2panda/parser/ETSparserStatements.cpp | 19 +++- ets2panda/parser/parserImpl.h | 1 + ets2panda/parser/statementParser.cpp | 10 +++ ets2panda/public/CMakeLists.txt | 1 + ...ationUsage_duplicate_for_classproperty.sts | 26 ++++++ ...nnotationUsage_duplicate_for_interface.sts | 25 ++++++ ...ionUsage_duplicate_for_interfacemethod.sts | 26 ++++++ ...nUsage_duplicate_for_interfaceproperty.sts | 28 ++++++ ...notationUsage_duplicate_for_type_alias.sts | 31 +++++++ ...ationUsage_duplicate_for_variable_decl.sts | 32 +++++++ ...sage_excessive_param_for_classproperty.sts | 29 +++++++ ...age_excessive_param_for_function_param.sts | 27 ++++++ ...ionUsage_excessive_param_for_interface.sts | 33 +++++++ ...onUsage_excessive_param_for_type_alias.sts | 30 +++++++ ...sage_excessive_param_for_variable_decl.sts | 31 +++++++ ...notationUsage_missing_AT_for_interface.sts | 24 ++++++ ...otationUsage_missing_AT_for_type_alias.sts | 31 +++++++ ...tionUsage_missing_AT_for_variable_decl.sts | 30 +++++++ ...nUsage_missing_param_for_classproperty.sts | 29 +++++++ ...Usage_missing_param_for_function_param.sts | 31 +++++++ ...ationUsage_missing_param_for_interface.sts | 33 +++++++ ...tionUsage_missing_param_for_type_alias.sts | 30 +++++++ ...nUsage_missing_param_for_variable_decl.sts | 33 +++++++ .../test/ast/parser/ets/InvalidClasses.sts | 84 +++++++++--------- .../ast/parser/ets/InvalidStatements3.sts | 2 - .../annotationDecl_locally.sts | 4 +- .../annotationDecl_with_access_modifier03.sts | 2 +- .../annotationDecl_with_innerclass.sts | 13 ++- .../annotationDecl_with_method.sts | 18 ++-- ...ationUsage_bad_param_for_classproperty.sts | 28 ++++++ ...tionUsage_bad_param_for_function_param.sts | 25 ++++++ ...age_bad_param_for_global_variable_decl.sts | 25 ++++++ ...nnotationUsage_bad_param_for_interface.sts | 28 ++++++ ...ionUsage_bad_param_for_interfacemethod.sts | 27 ++++++ ...nUsage_bad_param_for_interfaceproperty.sts | 26 ++++++ ...sage_bad_param_for_local_variable_decl.sts | 27 ++++++ ...notationUsage_bad_param_for_type_alias.sts | 31 +++++++ ...tionUsage_missing_AT_for_classproperty.sts | 28 ++++++ ...ionUsage_missing_AT_for_function_param.sts | 53 ++++++++++++ .../annotationUsage_on_abstract_method.sts | 4 +- .../annotationUsage_on_annotationDecl.sts | 1 - .../annotationUsage_on_classFiled.sts | 4 +- .../annotationUsage_on_letDecl.sts | 3 +- .../annotationUsage_parser_bad_token01.sts | 6 +- .../AnnotationForClassProperty.sts | 34 ++++++++ .../AnnotationForFunction.sts | 4 +- .../AnnotationForFunctionParam.sts | 39 +++++++++ .../AnnotationForInterface.sts | 57 ++++++++++++ .../annotation_tests/AnnotationForMethod.sts | 2 +- .../AnnotationForTypeAliaDecl.sts | 58 +++++++++++++ .../AnnotationForVariableDecl.sts | 37 ++++++++ .../AnnotationNoNeedToSetProperties01.sts | 2 +- .../AnnotationNoNeedToSetProperties02.sts | 2 +- .../AnnotationNoNeedToSetProperties03.sts | 2 +- .../AnnotationsFieldType01.sts | 2 +- .../AnnotationsFieldType02.sts | 2 +- .../AnnotationsFieldType03.sts | 2 +- .../AnnotationsFieldType04.sts | 2 +- .../Muti-AnnotationsDefineAndUseForClass.sts | 2 +- .../ast_verifier_getter_setter_neg_test.cpp | 2 +- ets2panda/varbinder/ETSBinder.cpp | 4 + 98 files changed, 1682 insertions(+), 289 deletions(-) create mode 100644 ets2panda/ir/annotationAllowed.h create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_classproperty.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interface.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfacemethod.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_type_alias.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_classproperty.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_function_param.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_type_alias.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_interface.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_type_alias.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_variable_decl.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_classproperty.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_function_param.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_type_alias.sts create mode 100644 ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_classproperty.sts create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.sts create mode 100644 ets2panda/test/runtime/ets/annotation_tests/AnnotationForClassProperty.sts create mode 100644 ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunctionParam.sts create mode 100644 ets2panda/test/runtime/ets/annotation_tests/AnnotationForInterface.sts create mode 100644 ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.sts create mode 100644 ets2panda/test/runtime/ets/annotation_tests/AnnotationForVariableDecl.sts diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index ac41978082..912483f79b 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -561,6 +561,7 @@ HEADERS_TO_BE_PARSED = [ "checker/types/ts/arrayType.h", "ir/astNode.h", "ir/typed.h", + "ir/annotationAllowed.h", "ir/statements/ifStatement.h", "ir/ets/etsTuple.h", "ir/module/exportSpecifier.h", diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 9470d7b555..8485fcb8a9 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -78,6 +78,8 @@ checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const return st->TsType(); } + checker->CheckAnnotations(st->Annotations()); + checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), checker->Context().ContainingClass(), checker->Context().ContainingSignature()); @@ -144,15 +146,6 @@ static void HandleNativeAndAsyncMethods(ETSChecker *checker, ir::MethodDefinitio } } } -void ETSAnalyzer::CheckClassProperty(ETSChecker *checker, ir::ScriptFunction *scriptFunc) const -{ - ASSERT(scriptFunc != nullptr); - if (checker->CheckDuplicateAnnotations(scriptFunc->Annotations())) { - for (auto *it : scriptFunc->Annotations()) { - it->Check(checker); - } - } -} checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const { @@ -160,14 +153,14 @@ checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const auto *scriptFunc = node->Function(); - CheckClassProperty(checker, scriptFunc); - if (scriptFunc == nullptr) { checker->LogTypeError("Invalid function expression", node->Start()); node->SetTsType(checker->GlobalTypeError()); return node->TsType(); } + checker->CheckFunctionAnnotations(scriptFunc); + if (scriptFunc->IsProxy()) { return ReturnTypeForStatement(node); } @@ -2744,6 +2737,9 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const { ETSChecker *checker = GetETSChecker(); + + checker->CheckAnnotations(st->Annotations()); + for (auto *it : st->Declarators()) { it->Check(checker); } @@ -2875,6 +2871,8 @@ checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const checker::ETSObjectType *interfaceType = checker->BuildBasicInterfaceProperties(st); ASSERT(interfaceType != nullptr); + checker->CheckAnnotations(st->Annotations()); + interfaceType->SetSuperType(checker->GlobalETSObjectType()); checker->CheckInvokeMethodsLegitimacy(interfaceType); st->SetTsType(interfaceType); @@ -2951,6 +2949,9 @@ checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const { ETSChecker *checker = GetETSChecker(); + + checker->CheckAnnotations(st->Annotations()); + if (st->TypeParams() == nullptr) { const checker::SavedTypeRelationFlagsContext savedFlagsCtx( checker->Relation(), checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index ab0d9488be..9db4d7c4ee 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -209,7 +209,6 @@ public: void CheckInnerClassMembers(const ETSObjectType *classType); void CheckLocalClass(ir::ClassDefinition *classDef, CheckerStatus &checkerStatus); void CheckClassDefinition(ir::ClassDefinition *classDef); - void CheckClassAnnotations(ir::ClassDefinition *classDef); void CheckClassMembers(ir::ClassDefinition *classDef); void CheckConstructors(ir::ClassDefinition *classDef, ETSObjectType *classType); void FindAssignment(const ir::AstNode *node, const varbinder::LocalVariable *classVar, bool &initialized); @@ -521,7 +520,8 @@ public: bool ValidateAnnotationPropertyType(checker::Type *tsType); void ProcessRequiredFields(ArenaUnorderedMap &fieldMap, ir::AnnotationUsage *st, ETSChecker *checker) const; - bool CheckDuplicateAnnotations(const ArenaVector &annotations); + void CheckFunctionAnnotations(ir::ScriptFunction *scriptFunc); + void CheckAnnotations(const ArenaVector &annotations); void CheckAmbientAnnotation(ir::AnnotationDeclaration *annoImpl, ir::AnnotationDeclaration *annoDecl); bool CheckAmbientAnnotationFieldInitializerValue(ir::Expression *init, ir::Expression *expected); bool CheckAmbientAnnotationFieldInitializer(ir::Expression *init, ir::Expression *expected); diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index 9cab1ce563..8ff1484c9a 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -91,7 +91,7 @@ ir::ETSParameterExpression *ETSChecker::AddParam(util::StringView name, ir::Type type->SetParent(paramIdent); } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return AllocNode(paramIdent, nullptr); + return AllocNode(paramIdent, nullptr, Allocator()); } template diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 4dfb816241..d557574b1b 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2327,7 +2327,7 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A paramIdent->SetTsType(field->TsType()); } - auto *paramExpression = AllocNode(paramIdent, nullptr); + auto *paramExpression = AllocNode(paramIdent, nullptr, Allocator()); paramExpression->SetRange(paramIdent->Range()); auto *const paramVar = std::get<2>(paramScope->AddParamDecl(Allocator(), paramExpression)); paramExpression->SetVariable(paramVar); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 96df43fcc1..03e0e05f04 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1068,7 +1068,7 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) TransformProperties(classType); - CheckClassAnnotations(classDef); + CheckAnnotations(classDef->Annotations()); CheckClassMembers(classDef); if (classDef->IsGlobal() || classType->SuperType() == nullptr) { @@ -1082,18 +1082,6 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) CheckInvokeMethodsLegitimacy(classType); } -void ETSChecker::CheckClassAnnotations(ir::ClassDefinition *classDef) -{ - if (!CheckDuplicateAnnotations(classDef->Annotations())) { - return; - } - for (auto *it : classDef->Annotations()) { - if (!it->IsClassProperty()) { - it->Check(this); - } - } -} - void ETSChecker::CheckClassMembers(ir::ClassDefinition *classDef) { for (auto *it : classDef->Body()) { diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 9f14e85d7f..2dd3bcc4d3 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -846,8 +846,24 @@ void ETSChecker::CheckAmbientAnnotation(ir::AnnotationDeclaration *annoImpl, ir: } } -bool ETSChecker::CheckDuplicateAnnotations(const ArenaVector &annotations) +void ETSChecker::CheckFunctionAnnotations(ir::ScriptFunction *scriptFunc) { + CheckAnnotations(scriptFunc->Annotations()); + + if (!scriptFunc->Params().empty()) { + for (ir::Expression *param : scriptFunc->Params()) { + if (param->IsETSParameterExpression()) { + CheckAnnotations(param->AsETSParameterExpression()->Annotations()); + } + } + } +} + +void ETSChecker::CheckAnnotations(const ArenaVector &annotations) +{ + if (annotations.empty()) { + return; + } std::unordered_set seenAnnotations; for (const auto &anno : annotations) { auto annoName = anno->GetBaseName()->Name(); @@ -855,11 +871,10 @@ bool ETSChecker::CheckDuplicateAnnotations(const ArenaVectorStart()); - return false; } seenAnnotations.insert(annoName); + anno->Check(this); } - return true; } void ETSChecker::CheckAnnotationPropertyType(ir::ClassProperty *property) diff --git a/ets2panda/compiler/lowering/ets/defaultParameterLowering.cpp b/ets2panda/compiler/lowering/ets/defaultParameterLowering.cpp index 03a7e6d1c4..614ba247a0 100644 --- a/ets2panda/compiler/lowering/ets/defaultParameterLowering.cpp +++ b/ets2panda/compiler/lowering/ets/defaultParameterLowering.cpp @@ -321,7 +321,8 @@ void DefaultParameterLowering::ProcessGlobalFunctionDefinition(ir::MethodDefinit auto *ident = expr->AsETSParameterExpression()->Ident()->Clone(checker->Allocator(), nullptr)->AsIdentifier(); - auto *funcParam = checker->AllocNode(ident->AsIdentifier(), nullptr); + auto *funcParam = checker->AllocNode(ident->AsIdentifier(), nullptr, + checker->Allocator()); ASSERT(ident->TypeAnnotation()->Parent() == ident); // prepare args list for overloade method definition diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index e5039dab24..30afee7c84 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -32,7 +32,7 @@ namespace { ir::TypeNode *const typeAnnotation) { auto *const paramIdent = checker->AllocNode(name, typeAnnotation, checker->Allocator()); - auto *const param = checker->AllocNode(paramIdent, nullptr); + auto *const param = checker->AllocNode(paramIdent, nullptr, checker->Allocator()); return param; } diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index e11b6e372e..ed932759f1 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -66,19 +66,11 @@ void TransformOptionalFieldTypeAnnotation(checker::ETSChecker *const checker, ir } // namespace -static ir::MethodDefinition *GenerateGetterOrSetter(checker::ETSChecker *const checker, varbinder::ETSBinder *varbinder, - ir::ClassProperty *const field, bool isSetter) +static ir::FunctionSignature GenerateGetterOrSetterSignature(checker::ETSChecker *const checker, + varbinder::ETSBinder *varbinder, + ir::ClassProperty *const field, bool isSetter, + varbinder::FunctionParamScope *paramScope) { - auto classScope = NearestScope(field); - auto *paramScope = checker->Allocator()->New(checker->Allocator(), classScope); - auto *functionScope = checker->Allocator()->New(checker->Allocator(), paramScope); - - functionScope->BindParamScope(paramScope); - paramScope->BindFunctionScope(functionScope); - - auto flags = ir::ModifierFlags::PUBLIC; - flags |= ir::ModifierFlags::ABSTRACT; - TransformOptionalFieldTypeAnnotation(checker, field); ArenaVector params(checker->Allocator()->Adapter()); @@ -90,7 +82,8 @@ static ir::MethodDefinition *GenerateGetterOrSetter(checker::ETSChecker *const c auto classCtx = varbinder::LexicalScope::Enter(varbinder, paramScope); InitScopesPhaseETS::RunExternalNode(paramIdent, varbinder); - auto *const paramExpression = checker->AllocNode(paramIdent, nullptr); + auto *const paramExpression = + checker->AllocNode(paramIdent, nullptr, checker->Allocator()); paramExpression->SetRange(paramIdent->Range()); auto *const paramVar = std::get<2>(paramScope->AddParamDecl(checker->Allocator(), paramExpression)); @@ -100,7 +93,24 @@ static ir::MethodDefinition *GenerateGetterOrSetter(checker::ETSChecker *const c params.push_back(paramExpression); } - auto signature = ir::FunctionSignature(nullptr, std::move(params), isSetter ? nullptr : field->TypeAnnotation()); + return ir::FunctionSignature(nullptr, std::move(params), isSetter ? nullptr : field->TypeAnnotation()); +} + +static ir::MethodDefinition *GenerateGetterOrSetter(checker::ETSChecker *const checker, varbinder::ETSBinder *varbinder, + ir::ClassProperty *const field, bool isSetter) +{ + auto classScope = NearestScope(field); + auto *paramScope = checker->Allocator()->New(checker->Allocator(), classScope); + auto *functionScope = checker->Allocator()->New(checker->Allocator(), paramScope); + + functionScope->BindParamScope(paramScope); + paramScope->BindFunctionScope(functionScope); + + auto flags = ir::ModifierFlags::PUBLIC; + flags |= ir::ModifierFlags::ABSTRACT; + + ir::FunctionSignature signature = GenerateGetterOrSetterSignature(checker, varbinder, field, isSetter, paramScope); + auto *func = checker->AllocNode( checker->Allocator(), ir::ScriptFunction::ScriptFunctionData { nullptr, std::move(signature), // CC-OFF(G.FMT.02) project code style @@ -132,6 +142,14 @@ static ir::MethodDefinition *GenerateGetterOrSetter(checker::ETSChecker *const c paramScope->BindNode(func); functionScope->BindNode(func); + if (!field->Annotations().empty()) { + ArenaVector functionAnnotations(checker->Allocator()->Adapter()); + for (auto *annotationUsage : field->Annotations()) { + functionAnnotations.push_back(annotationUsage->Clone(checker->Allocator(), method)->AsAnnotationUsage()); + } + method->Function()->SetAnnotations(std::move(functionAnnotations)); + } + return method; } diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 2083c4dcca..51eea239a9 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -170,7 +170,8 @@ ParamsAndVarMap CreateLambdaCalleeParameters(public_lib::Context *ctx, const Cal auto *newType = capturedVar->TsType()->Substitute(checker->Relation(), calleeParameterInfo.substitution); auto newId = util::NodeAllocator::ForceSetParent( allocator, capturedVar->Name(), allocator->New(newType), allocator); - auto param = util::NodeAllocator::ForceSetParent(allocator, newId, nullptr); + auto param = + util::NodeAllocator::ForceSetParent(allocator, newId, nullptr, allocator); auto [_, var] = varBinder->AddParamDecl(param); (void)_; var->SetTsType(newType); @@ -502,7 +503,8 @@ static void CreateLambdaClassConstructor(public_lib::Context *ctx, ir::ClassDefi auto *substitutedType = type->Substitute(checker->Relation(), substitution); auto *id = util::NodeAllocator::ForceSetParent( allocator, name, allocator->New(substitutedType), allocator); - auto *param = util::NodeAllocator::ForceSetParent(allocator, id, nullptr); + auto *param = + util::NodeAllocator::ForceSetParent(allocator, id, nullptr, allocator); params.push_back(param); }; @@ -608,7 +610,8 @@ static void CreateLambdaClassInvoke(public_lib::Context *ctx, LambdaInfo const * auto *type = wrapToObject ? anyType : lparam->TsType()->Substitute(checker->Relation(), lciInfo->substitution); auto *id = util::NodeAllocator::ForceSetParent( allocator, lparam->Name(), allocator->New(type), allocator); - auto *param = util::NodeAllocator::ForceSetParent(allocator, id, nullptr); + auto *param = + util::NodeAllocator::ForceSetParent(allocator, id, nullptr, allocator); params.push_back(param); } @@ -858,7 +861,7 @@ static ir::ScriptFunction *GetWrappingLambdaParentFunction(public_lib::Context * params.push_back(util::NodeAllocator::ForceSetParent( allocator, allocator->New(p->Name(), allocator->New(p->TsType()), allocator), - nullptr)); + nullptr, allocator)); } auto *func = util::NodeAllocator::ForceSetParent( allocator, allocator, diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp index 202cd2eb03..d6babe74e2 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp @@ -72,6 +72,14 @@ void GlobalDeclTransformer::VisitVariableDeclaration(ir::VariableDeclaration *va varDecl->Modifiers(), allocator_, false); field->SetRange(declarator->Range()); + if (!varDecl->Annotations().empty()) { + ArenaVector propAnnotations(allocator_->Adapter()); + for (auto *annotationUsage : varDecl->Annotations()) { + propAnnotations.push_back(annotationUsage->Clone(allocator_, field)->AsAnnotationUsage()); + } + field->SetAnnotations(std::move(propAnnotations)); + } + if (varDecl->IsExported() && varDecl->HasExportAlias()) { field->AddAstNodeFlags(ir::AstNodeFlags::HAS_EXPORT_ALIAS); } diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index 546b02a48e..c6a7659349 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -1065,6 +1065,7 @@ void InitScopesPhaseETS::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration CallNode(interfaceDecl->Extends()); auto localScope = LexicalScopeCreateOrEnter(VarBinder(), interfaceDecl); CallNode(interfaceDecl->Body()); + CallNode(interfaceDecl->Annotations()); BindScopeNode(localScope.GetScope(), interfaceDecl); } auto name = FormInterfaceOrEnumDeclarationIdBinding(interfaceDecl->Id()); @@ -1180,18 +1181,10 @@ void InitScopesPhaseETS::VisitClassProperty(ir::ClassProperty *classProp) { auto curScope = VarBinder()->GetScope(); const auto name = classProp->Key()->AsIdentifier()->Name(); - if (classProp->IsClassStaticBlock()) { - ASSERT(curScope->IsClassScope()); - auto classCtx = varbinder::LexicalScope::Enter( - VarBinder(), curScope->AsClassScope()->StaticMethodScope()); - auto *var = classProp->Id()->Variable(); - if (var == nullptr) { - var = std::get<1>(VarBinder()->NewVarDecl(classProp->Start(), Allocator(), - classProp->Id()->Name(), classProp)); - } - var->AddFlag(varbinder::VariableFlags::METHOD); - classProp->AsClassStaticBlock()->Function()->Id()->SetVariable(var); - } else if (classProp->IsConst()) { + + ASSERT(!classProp->IsClassStaticBlock()); + + if (classProp->IsConst()) { ASSERT(curScope->Parent() != nullptr); const auto initializer = classProp->Value(); if (initializer == nullptr && curScope->Parent()->IsGlobalScope() && !classProp->IsDeclare()) { diff --git a/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp b/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp index 6c9340e604..dbe7888bd3 100644 --- a/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp +++ b/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp @@ -114,15 +114,15 @@ ir::AstNode *MethodBuilder::Build() && void MethodBuilder::CollectParametersAndReturnType() { auto parameters = GetFunctionParameters(checker_, mda_); - auto *checker = checker_->Allocator(); + auto *allocator = checker_->Allocator(); // Start from 1, because 0 is return type for (size_t idx = 1U; idx < parameters.size(); ++idx) { - util::UString paramName(GetFieldName(idx), checker); + util::UString paramName(GetFieldName(idx), allocator); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *paramIdent = checker_->AllocNode(paramName.View(), parameters[idx], checker); + auto *paramIdent = checker_->AllocNode(paramName.View(), parameters[idx], allocator); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *param = checker_->AllocNode(paramIdent, nullptr); + auto *param = checker_->AllocNode(paramIdent, nullptr, allocator); params_.push_back(param); } diff --git a/ets2panda/ir/annotationAllowed.h b/ets2panda/ir/annotationAllowed.h new file mode 100644 index 0000000000..cb4abf4e4b --- /dev/null +++ b/ets2panda/ir/annotationAllowed.h @@ -0,0 +1,86 @@ +/** + * 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. + */ + +#ifndef ES2PANDA_IR_ANNOTATION_ALLOWED_H +#define ES2PANDA_IR_ANNOTATION_ALLOWED_H + +#include "ir/astNode.h" +#include "ir/statement.h" +#include "ir/statements/annotationUsage.h" + +namespace ark::es2panda::ir { + +template +class AnnotationAllowed : public T { +public: + AnnotationAllowed() = delete; + ~AnnotationAllowed() override = default; + + NO_COPY_OPERATOR(AnnotationAllowed); + NO_MOVE_SEMANTIC(AnnotationAllowed); + + [[nodiscard]] ArenaVector &Annotations() noexcept + { + return annotations_; + } + + [[nodiscard]] const ArenaVector &Annotations() const noexcept + { + return annotations_; + } + + void SetAnnotations(ArenaVector &&annotations) + { + annotations_ = std::move(annotations); + for (ir::AnnotationUsage *anno : annotations_) { + anno->SetParent(this); + } + } + +protected: + explicit AnnotationAllowed(AstNodeType const type, ArenaVector &&annotations) + : T(type), annotations_(std::move(annotations)) + { + } + explicit AnnotationAllowed(AstNodeType const type, ModifierFlags const flags, + ArenaVector &&annotations) + : T(type, flags), annotations_(std::move(annotations)) + { + } + explicit AnnotationAllowed(AstNodeType const type, ArenaAllocator *const allocator) + : T(type), annotations_(allocator->Adapter()) + { + } + explicit AnnotationAllowed(AstNodeType const type, ModifierFlags const flags, ArenaAllocator *const allocator) + : T(type, flags), annotations_(allocator->Adapter()) + { + } + + void AddAnnotations(AnnotationUsage *const annotations) + { + annotations_.emplace_back(annotations); + } + + AnnotationAllowed(AnnotationAllowed const &other) + : T(static_cast(other)), annotations_(other.annotations_.get_allocator()) + { + } + +private: + ArenaVector annotations_; +}; +} // namespace ark::es2panda::ir + +#endif diff --git a/ets2panda/ir/base/classDefinition.cpp b/ets2panda/ir/base/classDefinition.cpp index 63a0ac7653..805e48d36a 100644 --- a/ets2panda/ir/base/classDefinition.cpp +++ b/ets2panda/ir/base/classDefinition.cpp @@ -92,7 +92,7 @@ void ClassDefinition::TransformChildren(const NodeTransformer &cb, std::string_v } } - for (auto *&it : VectorIterationGuard(annotations_)) { + for (auto *&it : VectorIterationGuard(Annotations())) { if (auto *transformedNode = cb(it); it != transformedNode) { it->SetTransformedNode(transformationName, transformedNode); it = transformedNode->AsAnnotationUsage(); @@ -140,7 +140,7 @@ void ClassDefinition::Iterate(const NodeTraverser &cb) const cb(implements_[ix]); } - for (auto *it : VectorIterationGuard(annotations_)) { + for (auto *it : VectorIterationGuard(Annotations())) { cb(it); } @@ -172,7 +172,7 @@ void ClassDefinition::Dump(ir::AstDumper *dumper) const {"superClass", AstDumper::Nullish(superClass_)}, {"superTypeParameters", AstDumper::Optional(superTypeParams_)}, {"implements", implements_}, - {"annotations", AstDumper::Optional(annotations_)}, + {"annotations", AstDumper::Optional(Annotations())}, {"constructor", AstDumper::Optional(ctor_)}, {"body", body_, propFilter}}); } @@ -197,7 +197,7 @@ void ClassDefinition::DumpBody(ir::SrcDumper *dumper) const void ClassDefinition::Dump(ir::SrcDumper *dumper) const { - for (auto *anno : annotations_) { + for (auto *anno : Annotations()) { anno->Dump(dumper); } ASSERT(ident_ != nullptr); diff --git a/ets2panda/ir/base/classDefinition.h b/ets2panda/ir/base/classDefinition.h index 1d7eedb695..ba8104c69c 100644 --- a/ets2panda/ir/base/classDefinition.h +++ b/ets2panda/ir/base/classDefinition.h @@ -18,6 +18,7 @@ #include "varbinder/scope.h" #include "varbinder/variable.h" +#include "ir/annotationAllowed.h" #include "ir/astNode.h" #include "ir/expressions/identifier.h" #include "ir/srcDump.h" @@ -61,7 +62,7 @@ struct enumbitops::IsAllowedType : namespace ark::es2panda::ir { -class ClassDefinition : public TypedAstNode { +class ClassDefinition : public AnnotationAllowed { public: ClassDefinition() = delete; ~ClassDefinition() override = default; @@ -74,7 +75,8 @@ public: ArenaVector &&implements, MethodDefinition *ctor, Expression *superClass, ArenaVector &&body, ClassDefinitionModifiers modifiers, ModifierFlags flags, Language lang) - : TypedAstNode(AstNodeType::CLASS_DEFINITION, flags), + : AnnotationAllowed(AstNodeType::CLASS_DEFINITION, flags, + ArenaVector(body.get_allocator())), privateId_(privateId), ident_(ident), typeParams_(typeParams), @@ -88,14 +90,13 @@ public: capturedVars_(body_.get_allocator()), localVariableIsNeeded_(body_.get_allocator()), localIndex_(classCounter_++), - localPrefix_("$" + std::to_string(localIndex_)), - annotations_(body_.get_allocator()) + localPrefix_("$" + std::to_string(localIndex_)) { } // CC-OFFNXT(G.FUN.01-CPP) solid logic explicit ClassDefinition(ArenaAllocator *allocator, Identifier *ident, ArenaVector &&body, ClassDefinitionModifiers modifiers, ModifierFlags flags, Language lang) - : TypedAstNode(AstNodeType::CLASS_DEFINITION, flags), + : AnnotationAllowed(AstNodeType::CLASS_DEFINITION, flags, allocator), ident_(ident), implements_(allocator->Adapter()), body_(std::move(body)), @@ -104,14 +105,13 @@ public: capturedVars_(allocator->Adapter()), localVariableIsNeeded_(allocator->Adapter()), localIndex_(classCounter_++), - localPrefix_("$" + std::to_string(localIndex_)), - annotations_(body_.get_allocator()) + localPrefix_("$" + std::to_string(localIndex_)) { } explicit ClassDefinition(ArenaAllocator *allocator, Identifier *ident, ClassDefinitionModifiers modifiers, ModifierFlags flags, Language lang) - : TypedAstNode(AstNodeType::CLASS_DEFINITION, flags), + : AnnotationAllowed(AstNodeType::CLASS_DEFINITION, flags, allocator), ident_(ident), implements_(allocator->Adapter()), body_(allocator->Adapter()), @@ -120,8 +120,7 @@ public: capturedVars_(allocator->Adapter()), localVariableIsNeeded_(allocator->Adapter()), localIndex_(classCounter_++), - localPrefix_("$" + std::to_string(localIndex_)), - annotations_(body_.get_allocator()) + localPrefix_("$" + std::to_string(localIndex_)) { } @@ -359,19 +358,6 @@ public: return capturedVars_.erase(var) != 0; } - const ArenaVector &Annotations() const - { - return annotations_; - } - - void SetAnnotations(ArenaVector &&annotations) - { - annotations_ = std::move(annotations); - for (auto anno : annotations_) { - anno->SetParent(this); - } - } - void SetOrigEnumDecl(ir::TSEnumDeclaration *enumDecl) { origEnumDecl_ = enumDecl; @@ -441,7 +427,6 @@ private: static int classCounter_; const int localIndex_ {}; const std::string localPrefix_ {}; - ArenaVector annotations_; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/base/classProperty.cpp b/ets2panda/ir/base/classProperty.cpp index 3dd68d7a0a..287d478fad 100644 --- a/ets2panda/ir/base/classProperty.cpp +++ b/ets2panda/ir/base/classProperty.cpp @@ -50,6 +50,13 @@ void ClassProperty::TransformChildren(const NodeTransformer &cb, std::string_vie it = transformedNode->AsDecorator(); } } + + for (auto *&it : Annotations()) { + if (auto *transformedNode = cb(it); it != transformedNode) { + it->SetTransformedNode(transformationName, transformedNode); + it = transformedNode->AsAnnotationUsage(); + } + } } void ClassProperty::Iterate(const NodeTraverser &cb) const @@ -67,6 +74,10 @@ void ClassProperty::Iterate(const NodeTraverser &cb) const for (auto *it : VectorIterationGuard(decorators_)) { cb(it); } + + for (auto *it : Annotations()) { + cb(it); + } } void ClassProperty::Dump(ir::AstDumper *dumper) const @@ -83,11 +94,16 @@ void ClassProperty::Dump(ir::AstDumper *dumper) const {"computed", isComputed_}, {"typeAnnotation", AstDumper::Optional(typeAnnotation_)}, {"definite", IsDefinite()}, - {"decorators", decorators_}}); + {"decorators", decorators_}, + {"annotations", AstDumper::Optional(Annotations())}}); } void ClassProperty::Dump(ir::SrcDumper *dumper) const { + for (auto *anno : Annotations()) { + anno->Dump(dumper); + } + if (Parent() != nullptr && Parent()->IsClassDefinition() && !Parent()->AsClassDefinition()->IsLocal()) { if (IsPrivate()) { dumper->Add("private "); @@ -174,6 +190,14 @@ ClassProperty *ClassProperty::Clone(ArenaAllocator *const allocator, AstNode *co clone->AddDecorator(decorator->Clone(allocator, clone)); } + if (!annotations_.empty()) { + ArenaVector annotationUsages {allocator->Adapter()}; + for (auto *annotationUsage : annotations_) { + annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage()); + } + clone->SetAnnotations(std::move(annotationUsages)); + } + return clone; } diff --git a/ets2panda/ir/base/classProperty.h b/ets2panda/ir/base/classProperty.h index bd13845b5d..8a45577132 100644 --- a/ets2panda/ir/base/classProperty.h +++ b/ets2panda/ir/base/classProperty.h @@ -17,6 +17,7 @@ #define ES2PANDA_PARSER_INCLUDE_AST_CLASS_PROPERTY_H #include "ir/base/classElement.h" +#include "ir/statements/annotationUsage.h" namespace ark::es2panda::checker { class ETSAnalyzer; @@ -37,7 +38,8 @@ public: explicit ClassProperty(Expression *const key, Expression *const value, TypeNode *const typeAnnotation, ModifierFlags const modifiers, ArenaAllocator *const allocator, bool const isComputed) : ClassElement(AstNodeType::CLASS_PROPERTY, key, value, modifiers, allocator, isComputed), - typeAnnotation_(typeAnnotation) + typeAnnotation_(typeAnnotation), + annotations_(allocator->Adapter()) { } @@ -73,8 +75,27 @@ public: v->Accept(this); } + [[nodiscard]] ArenaVector &Annotations() noexcept + { + return annotations_; + } + + [[nodiscard]] const ArenaVector &Annotations() const noexcept + { + return annotations_; + } + + void SetAnnotations(ArenaVector &&annotations) + { + annotations_ = std::move(annotations); + for (auto anno : annotations_) { + anno->SetParent(this); + } + } + private: TypeNode *typeAnnotation_; + ArenaVector annotations_; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/base/scriptFunction.cpp b/ets2panda/ir/base/scriptFunction.cpp index e4a821b340..0e278c7717 100644 --- a/ets2panda/ir/base/scriptFunction.cpp +++ b/ets2panda/ir/base/scriptFunction.cpp @@ -24,13 +24,12 @@ namespace ark::es2panda::ir { ScriptFunction::ScriptFunction(ArenaAllocator *allocator, ScriptFunctionData &&data) - : AstNode(AstNodeType::SCRIPT_FUNCTION, data.flags), + : AnnotationAllowed(AstNodeType::SCRIPT_FUNCTION, data.flags, allocator), irSignature_(std::move(data.signature)), body_(data.body), funcFlags_(data.funcFlags), lang_(data.lang), - returnStatements_(allocator->Adapter()), - annotations_(allocator->Adapter()) + returnStatements_(allocator->Adapter()) { for (auto *param : irSignature_.Params()) { param->SetParent(this); @@ -110,7 +109,7 @@ void ScriptFunction::TransformChildren(const NodeTransformer &cb, std::string_vi } } - for (auto *&it : VectorIterationGuard(annotations_)) { + for (auto *&it : VectorIterationGuard(Annotations())) { if (auto *transformedNode = cb(it); it != transformedNode) { it->SetTransformedNode(transformationName, transformedNode); it = transformedNode->AsAnnotationUsage(); @@ -127,7 +126,7 @@ void ScriptFunction::Iterate(const NodeTraverser &cb) const if (body_ != nullptr) { cb(body_); } - for (auto *it : VectorIterationGuard(annotations_)) { + for (auto *it : VectorIterationGuard(Annotations())) { cb(it); } } @@ -158,7 +157,7 @@ void ScriptFunction::Dump(ir::AstDumper *dumper) const {"typeParameters", AstDumper::Optional(irSignature_.TypeParams())}, {"declare", AstDumper::Optional(IsDeclare())}, {"body", AstDumper::Optional(body_)}, - {"annotations", AstDumper::Optional(annotations_)}, + {"annotations", AstDumper::Optional(Annotations())}, {"throwMarker", AstDumper::Optional(throwMarker)}}); } diff --git a/ets2panda/ir/base/scriptFunction.h b/ets2panda/ir/base/scriptFunction.h index c256f1c498..f1f36f7f9d 100644 --- a/ets2panda/ir/base/scriptFunction.h +++ b/ets2panda/ir/base/scriptFunction.h @@ -17,6 +17,7 @@ #define ES2PANDA_PARSER_INCLUDE_AST_SCRIPT_FUNCTION_H #include "checker/types/signature.h" +#include "ir/annotationAllowed.h" #include "ir/statements/annotationUsage.h" #include "ir/statements/returnStatement.h" #include "ir/astNode.h" @@ -35,7 +36,7 @@ class TSTypeParameterDeclaration; class TypeNode; class AnnotationUsage; -class ScriptFunction : public AstNode { +class ScriptFunction : public AnnotationAllowed { public: // Need to reduce the number of constructor parameters to pass OHOS CI code check struct ScriptFunctionData { @@ -320,29 +321,6 @@ public: return lang_; } - [[nodiscard]] ArenaVector &Annotations() noexcept - { - return annotations_; - } - - [[nodiscard]] const ArenaVector &Annotations() const noexcept - { - return annotations_; - } - - void SetAnnotations(ArenaVector &&annotations) - { - annotations_ = std::move(annotations); - for (auto anno : annotations_) { - anno->SetParent(this); - } - } - - void AddAnnotations(AnnotationUsage *const annotations) - { - annotations_.emplace_back(annotations); - } - [[nodiscard]] ScriptFunction *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -369,7 +347,6 @@ private: checker::Signature *signature_ {}; es2panda::Language lang_; ArenaVector returnStatements_; - ArenaVector annotations_; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ets/etsParameterExpression.cpp b/ets2panda/ir/ets/etsParameterExpression.cpp index f9914e471e..f311115cbc 100644 --- a/ets2panda/ir/ets/etsParameterExpression.cpp +++ b/ets2panda/ir/ets/etsParameterExpression.cpp @@ -28,8 +28,9 @@ namespace ark::es2panda::ir { -ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, Expression *const initializer) - : Expression(AstNodeType::ETS_PARAMETER_EXPRESSION), initializer_(initializer) +ETSParameterExpression::ETSParameterExpression(AnnotatedExpression *const identOrSpread, Expression *const initializer, + ArenaAllocator *const allocator) + : AnnotationAllowed(AstNodeType::ETS_PARAMETER_EXPRESSION, allocator), initializer_(initializer) { ASSERT(identOrSpread != nullptr); identOrSpread->SetParent(this); @@ -128,6 +129,13 @@ void ETSParameterExpression::TransformChildren(const NodeTransformer &cb, std::s initializer_ = transformedNode->AsExpression(); } } + + for (auto *&it : Annotations()) { + if (auto *transformedNode = cb(it); it != transformedNode) { + it->SetTransformedNode(transformationName, transformedNode); + it = transformedNode->AsAnnotationUsage(); + } + } } void ETSParameterExpression::Iterate(const NodeTraverser &cb) const @@ -141,20 +149,32 @@ void ETSParameterExpression::Iterate(const NodeTraverser &cb) const if (IsDefault()) { cb(initializer_); } + + for (auto *it : Annotations()) { + cb(it); + } } void ETSParameterExpression::Dump(ir::AstDumper *const dumper) const { if (!IsRestParameter()) { - dumper->Add( - {{"type", "ETSParameterExpression"}, {"name", ident_}, {"initializer", AstDumper::Optional(initializer_)}}); + dumper->Add({{"type", "ETSParameterExpression"}, + {"name", ident_}, + {"initializer", AstDumper::Optional(initializer_)}, + {"annotations", AstDumper::Optional(Annotations())}}); } else { - dumper->Add({{"type", "ETSParameterExpression"}, {"rest parameter", spread_}}); + dumper->Add({{"type", "ETSParameterExpression"}, + {"rest parameter", spread_}, + {"annotations", AstDumper::Optional(Annotations())}}); } } void ETSParameterExpression::Dump(ir::SrcDumper *const dumper) const { + for (auto *anno : Annotations()) { + anno->Dump(dumper); + } + if (IsRestParameter()) { spread_->Dump(dumper); } else { @@ -204,7 +224,8 @@ ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allo auto *const initializer = initializer_ != nullptr ? initializer_->Clone(allocator, nullptr)->AsExpression() : nullptr; - if (auto *const clone = allocator->New(identOrSpread, initializer); clone != nullptr) { + if (auto *const clone = allocator->New(identOrSpread, initializer, allocator); + clone != nullptr) { identOrSpread->SetParent(clone); if (initializer != nullptr) { @@ -216,6 +237,15 @@ ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allo } clone->SetRequiredParams(extraValue_); + + if (!Annotations().empty()) { + ArenaVector annotationUsages {allocator->Adapter()}; + for (auto *annotationUsage : Annotations()) { + annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage()); + } + clone->SetAnnotations(std::move(annotationUsages)); + } + return clone; } diff --git a/ets2panda/ir/ets/etsParameterExpression.h b/ets2panda/ir/ets/etsParameterExpression.h index d81108f710..8ce5b0cf74 100644 --- a/ets2panda/ir/ets/etsParameterExpression.h +++ b/ets2panda/ir/ets/etsParameterExpression.h @@ -16,7 +16,9 @@ #ifndef ES2PANDA_IR_EXPRESSION_ETS_PARAMETER_EXPRESSION_H #define ES2PANDA_IR_EXPRESSION_ETS_PARAMETER_EXPRESSION_H +#include "ir/annotationAllowed.h" #include "ir/expression.h" +#include "ir/statements/annotationUsage.h" namespace ark::es2panda::checker { class ETSAnalyzer; @@ -24,7 +26,7 @@ class ETSAnalyzer; namespace ark::es2panda::ir { -class ETSParameterExpression final : public Expression { +class ETSParameterExpression final : public AnnotationAllowed { public: ETSParameterExpression() = delete; ~ETSParameterExpression() override = default; @@ -32,7 +34,8 @@ public: NO_COPY_SEMANTIC(ETSParameterExpression); NO_MOVE_SEMANTIC(ETSParameterExpression); - explicit ETSParameterExpression(AnnotatedExpression *identOrSpread, Expression *initializer); + explicit ETSParameterExpression(AnnotatedExpression *identOrSpread, Expression *initializer, + ArenaAllocator *const allocator); // NOTE (csabahurton): friend relationship can be removed once there are getters for private fields friend class checker::ETSAnalyzer; diff --git a/ets2panda/ir/statements/annotationUsage.cpp b/ets2panda/ir/statements/annotationUsage.cpp index c644162925..de4e3fdf67 100644 --- a/ets2panda/ir/statements/annotationUsage.cpp +++ b/ets2panda/ir/statements/annotationUsage.cpp @@ -88,8 +88,11 @@ AnnotationUsage *AnnotationUsage::Clone(ArenaAllocator *const allocator, AstNode } for (auto *property : properties_) { - clone->AddProperty(property); + clone->AddProperty(property->Clone(allocator, clone)); } + + clone->SetRange(range_); + clone->SetScope(propertiesScope_); return clone; } diff --git a/ets2panda/ir/statements/functionDeclaration.cpp b/ets2panda/ir/statements/functionDeclaration.cpp index ac44ff7bed..15b3f59d87 100644 --- a/ets2panda/ir/statements/functionDeclaration.cpp +++ b/ets2panda/ir/statements/functionDeclaration.cpp @@ -32,7 +32,7 @@ void FunctionDeclaration::TransformChildren(const NodeTransformer &cb, std::stri } } - for (auto *&it : VectorIterationGuard(annotations_)) { + for (auto *&it : VectorIterationGuard(Annotations())) { if (auto *transformedNode = cb(it); it != transformedNode) { it->SetTransformedNode(transformationName, transformedNode); it = transformedNode->AsAnnotationUsage(); @@ -51,7 +51,7 @@ void FunctionDeclaration::Iterate(const NodeTraverser &cb) const cb(it); } - for (auto *it : VectorIterationGuard(annotations_)) { + for (auto *it : VectorIterationGuard(Annotations())) { cb(it); } @@ -62,13 +62,13 @@ void FunctionDeclaration::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", func_->IsOverload() ? "TSDeclareFunction" : "FunctionDeclaration"}, {"decorators", AstDumper::Optional(decorators_)}, - {"annotations", AstDumper::Optional(annotations_)}, + {"annotations", AstDumper::Optional(Annotations())}, {"function", func_}}); } void FunctionDeclaration::Dump(ir::SrcDumper *dumper) const { - for (auto *anno : annotations_) { + for (auto *anno : Annotations()) { anno->Dump(dumper); } if (func_->IsNative()) { diff --git a/ets2panda/ir/statements/functionDeclaration.h b/ets2panda/ir/statements/functionDeclaration.h index 132aa5a9e9..34f5058dc3 100644 --- a/ets2panda/ir/statements/functionDeclaration.h +++ b/ets2panda/ir/statements/functionDeclaration.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_IR_STATEMENT_FUNCTION_DECLARATION_H #define ES2PANDA_IR_STATEMENT_FUNCTION_DECLARATION_H +#include "ir/annotationAllowed.h" #include "ir/statement.h" #include "ir/statements/annotationUsage.h" @@ -23,24 +24,22 @@ namespace ark::es2panda::ir { class ScriptFunction; class AnnotationUsage; -class FunctionDeclaration : public Statement { +class FunctionDeclaration : public AnnotationAllowed { public: explicit FunctionDeclaration(ArenaAllocator *allocator, ScriptFunction *func, ArenaVector &&annotations, bool isAnonymous = false) - : Statement(AstNodeType::FUNCTION_DECLARATION), + : AnnotationAllowed(AstNodeType::FUNCTION_DECLARATION, std::move(annotations)), decorators_(allocator->Adapter()), func_(func), - isAnonymous_(isAnonymous), - annotations_(std::move(annotations)) + isAnonymous_(isAnonymous) { } explicit FunctionDeclaration(ArenaAllocator *allocator, ScriptFunction *func, bool isAnonymous = false) - : Statement(AstNodeType::FUNCTION_DECLARATION), + : AnnotationAllowed(AstNodeType::FUNCTION_DECLARATION, allocator), decorators_(allocator->Adapter()), func_(func), - isAnonymous_(isAnonymous), - annotations_(allocator->Adapter()) + isAnonymous_(isAnonymous) { } @@ -69,29 +68,6 @@ public: return !inTs; } - [[nodiscard]] ArenaVector &Annotations() noexcept - { - return annotations_; - } - - [[nodiscard]] const ArenaVector &Annotations() const noexcept - { - return annotations_; - } - - void SetAnnotations(ArenaVector &&annotations) - { - annotations_ = std::move(annotations); - for (auto anno : annotations_) { - anno->SetParent(this); - } - } - - void AddAnnotations(AnnotationUsage *const annotations) - { - annotations_.emplace_back(annotations); - } - void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; @@ -110,7 +86,6 @@ private: ArenaVector decorators_; ScriptFunction *func_; const bool isAnonymous_; - ArenaVector annotations_; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/statements/variableDeclaration.cpp b/ets2panda/ir/statements/variableDeclaration.cpp index 431d9b26e7..9048bfab59 100644 --- a/ets2panda/ir/statements/variableDeclaration.cpp +++ b/ets2panda/ir/statements/variableDeclaration.cpp @@ -36,6 +36,13 @@ void VariableDeclaration::TransformChildren(const NodeTransformer &cb, std::stri } } + for (auto *&it : VectorIterationGuard(Annotations())) { + if (auto *transformedNode = cb(it); it != transformedNode) { + it->SetTransformedNode(transformationName, transformedNode); + it = transformedNode->AsAnnotationUsage(); + } + } + for (auto *&it : VectorIterationGuard(declarators_)) { if (auto *transformedNode = cb(it); it != transformedNode) { it->SetTransformedNode(transformationName, transformedNode); @@ -50,6 +57,10 @@ void VariableDeclaration::Iterate(const NodeTraverser &cb) const cb(it); } + for (auto *it : VectorIterationGuard(Annotations())) { + cb(it); + } + for (auto *it : VectorIterationGuard(declarators_)) { cb(it); } @@ -81,11 +92,16 @@ void VariableDeclaration::Dump(ir::AstDumper *dumper) const {"declarations", declarators_}, {"kind", kind}, {"decorators", AstDumper::Optional(decorators_)}, + {"annotations", AstDumper::Optional(Annotations())}, {"declare", AstDumper::Optional(IsDeclare())}}); } void VariableDeclaration::Dump(ir::SrcDumper *dumper) const { + for (auto *anno : Annotations()) { + anno->Dump(dumper); + } + switch (kind_) { case VariableDeclarationKind::CONST: dumper->Add("const "); @@ -115,7 +131,7 @@ void VariableDeclaration::Dump(ir::SrcDumper *dumper) const VariableDeclaration::VariableDeclaration([[maybe_unused]] Tag const tag, VariableDeclaration const &other, ArenaAllocator *const allocator) - : Statement(static_cast(other)), + : AnnotationAllowed(static_cast const &>(other)), kind_(other.kind_), decorators_(allocator->Adapter()), declarators_(allocator->Adapter()) diff --git a/ets2panda/ir/statements/variableDeclaration.h b/ets2panda/ir/statements/variableDeclaration.h index d753828bca..f3513bf5c2 100644 --- a/ets2panda/ir/statements/variableDeclaration.h +++ b/ets2panda/ir/statements/variableDeclaration.h @@ -16,12 +16,14 @@ #ifndef ES2PANDA_IR_STATEMENT_VARIABLE_DECLARATION_H #define ES2PANDA_IR_STATEMENT_VARIABLE_DECLARATION_H +#include "ir/annotationAllowed.h" #include "ir/statement.h" +#include "ir/statements/annotationUsage.h" namespace ark::es2panda::ir { class VariableDeclarator; -class VariableDeclaration : public Statement { +class VariableDeclaration : public AnnotationAllowed { private: struct Tag {}; @@ -30,7 +32,7 @@ public: explicit VariableDeclaration(VariableDeclarationKind kind, ArenaAllocator *allocator, ArenaVector &&declarators) - : Statement(AstNodeType::VARIABLE_DECLARATION), + : AnnotationAllowed(AstNodeType::VARIABLE_DECLARATION, allocator), kind_(kind), decorators_(allocator->Adapter()), declarators_(std::move(declarators)) diff --git a/ets2panda/ir/ts/tsEnumDeclaration.h b/ets2panda/ir/ts/tsEnumDeclaration.h index 98df189a01..e3a0d50f4f 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.h +++ b/ets2panda/ir/ts/tsEnumDeclaration.h @@ -16,8 +16,9 @@ #ifndef ES2PANDA_IR_TS_ENUM_DECLARATION_H #define ES2PANDA_IR_TS_ENUM_DECLARATION_H -#include "varbinder/scope.h" #include "ir/statement.h" +#include "ir/statements/annotationUsage.h" +#include "varbinder/scope.h" namespace ark::es2panda::varbinder { class EnumVariable; diff --git a/ets2panda/ir/ts/tsInterfaceDeclaration.cpp b/ets2panda/ir/ts/tsInterfaceDeclaration.cpp index 3dd3df8a24..b96319d26a 100644 --- a/ets2panda/ir/ts/tsInterfaceDeclaration.cpp +++ b/ets2panda/ir/ts/tsInterfaceDeclaration.cpp @@ -41,6 +41,13 @@ void TSInterfaceDeclaration::TransformChildren(const NodeTransformer &cb, std::s } } + for (auto *&it : Annotations()) { + if (auto *transformedNode = cb(it); it != transformedNode) { + it->SetTransformedNode(transformationName, transformedNode); + it = transformedNode->AsAnnotationUsage(); + } + } + if (auto *transformedNode = cb(id_); id_ != transformedNode) { id_->SetTransformedNode(transformationName, transformedNode); id_ = transformedNode->AsIdentifier(); @@ -72,6 +79,10 @@ void TSInterfaceDeclaration::Iterate(const NodeTraverser &cb) const cb(it); } + for (auto *it : Annotations()) { + cb(it); + } + cb(id_); if (typeParams_ != nullptr) { @@ -89,6 +100,7 @@ void TSInterfaceDeclaration::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", "TSInterfaceDeclaration"}, {"decorators", AstDumper::Optional(decorators_)}, + {"annotations", AstDumper::Optional(Annotations())}, {"body", body_}, {"id", id_}, {"extends", extends_}, @@ -99,6 +111,10 @@ void TSInterfaceDeclaration::Dump(ir::SrcDumper *dumper) const { ASSERT(id_); + for (auto *anno : Annotations()) { + anno->Dump(dumper); + } + if (IsDeclare()) { dumper->Add("declare "); } diff --git a/ets2panda/ir/ts/tsInterfaceDeclaration.h b/ets2panda/ir/ts/tsInterfaceDeclaration.h index baee4d8239..ebc7cc91f3 100644 --- a/ets2panda/ir/ts/tsInterfaceDeclaration.h +++ b/ets2panda/ir/ts/tsInterfaceDeclaration.h @@ -17,7 +17,9 @@ #define ES2PANDA_IR_TS_INTERFACE_DECLARATION_H #include "varbinder/scope.h" +#include "ir/annotationAllowed.h" #include "ir/statement.h" +#include "ir/statements/annotationUsage.h" namespace ark::es2panda::varbinder { class Variable; @@ -29,7 +31,7 @@ class TSInterfaceBody; class TSInterfaceHeritage; class TSTypeParameterDeclaration; -class TSInterfaceDeclaration : public TypedStatement { +class TSInterfaceDeclaration : public AnnotationAllowed { public: // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) struct ConstructorData { @@ -44,7 +46,7 @@ public: explicit TSInterfaceDeclaration(ArenaAllocator *allocator, ArenaVector &&extends, ConstructorData &&data) - : TypedStatement(AstNodeType::TS_INTERFACE_DECLARATION), + : AnnotationAllowed(AstNodeType::TS_INTERFACE_DECLARATION, allocator), decorators_(allocator->Adapter()), id_(data.id), typeParams_(data.typeParams), diff --git a/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp b/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp index 8682358c98..68725d2426 100644 --- a/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp +++ b/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp @@ -36,6 +36,13 @@ void TSTypeAliasDeclaration::TransformChildren(const NodeTransformer &cb, std::s } } + for (auto *&it : Annotations()) { + if (auto *transformedNode = cb(it); it != transformedNode) { + it->SetTransformedNode(transformationName, transformedNode); + it = transformedNode->AsAnnotationUsage(); + } + } + if (auto *transformedNode = cb(id_); id_ != transformedNode) { id_->SetTransformedNode(transformationName, transformedNode); id_ = transformedNode->AsIdentifier(); @@ -62,6 +69,10 @@ void TSTypeAliasDeclaration::Iterate(const NodeTraverser &cb) const cb(it); } + for (auto *it : Annotations()) { + cb(it); + } + cb(id_); if (typeParams_ != nullptr) { @@ -77,6 +88,7 @@ void TSTypeAliasDeclaration::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", "TSTypeAliasDeclaration"}, {"decorators", AstDumper::Optional(decorators_)}, + {"annotations", AstDumper::Optional(Annotations())}, {"id", id_}, {"typeAnnotation", AstDumper::Optional(TypeAnnotation())}, {"typeParameters", AstDumper::Optional(typeParams_)}}); @@ -85,6 +97,10 @@ void TSTypeAliasDeclaration::Dump(ir::AstDumper *dumper) const void TSTypeAliasDeclaration::Dump(ir::SrcDumper *dumper) const { ASSERT(id_); + for (auto *anno : Annotations()) { + anno->Dump(dumper); + } + dumper->Add("type "); id_->Dump(dumper); if (typeParams_ != nullptr) { diff --git a/ets2panda/ir/ts/tsTypeAliasDeclaration.h b/ets2panda/ir/ts/tsTypeAliasDeclaration.h index e1e5db7aa7..38064584ed 100644 --- a/ets2panda/ir/ts/tsTypeAliasDeclaration.h +++ b/ets2panda/ir/ts/tsTypeAliasDeclaration.h @@ -18,6 +18,7 @@ #include "ir/statement.h" #include "ir/typed.h" +#include "ir/statements/annotationUsage.h" namespace ark::es2panda::varbinder { class Variable; @@ -33,6 +34,7 @@ public: TypeNode *typeAnnotation) : AnnotatedStatement(AstNodeType::TS_TYPE_ALIAS_DECLARATION, typeAnnotation), decorators_(allocator->Adapter()), + annotations_(allocator->Adapter()), id_(id), typeParams_(typeParams), typeParamTypes_(allocator->Adapter()) @@ -42,6 +44,7 @@ public: explicit TSTypeAliasDeclaration(ArenaAllocator *allocator, Identifier *id) : AnnotatedStatement(AstNodeType::TS_TYPE_ALIAS_DECLARATION), decorators_(allocator->Adapter()), + annotations_(allocator->Adapter()), id_(id), typeParams_(nullptr), typeParamTypes_(allocator->Adapter()) @@ -98,6 +101,24 @@ public: return typeParamTypes_; } + [[nodiscard]] ArenaVector &Annotations() noexcept + { + return annotations_; + } + + [[nodiscard]] const ArenaVector &Annotations() const noexcept + { + return annotations_; + } + + void SetAnnotations(ArenaVector &&annotations) + { + annotations_ = std::move(annotations); + for (AnnotationUsage *anno : annotations_) { + anno->SetParent(this); + } + } + void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; @@ -114,6 +135,7 @@ public: private: ArenaVector decorators_; + ArenaVector annotations_; Identifier *id_; TSTypeParameterDeclaration *typeParams_; ArenaVector typeParamTypes_; diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 96bd557ed2..f37b5e99ab 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -721,7 +721,7 @@ ir::AstNode *ETSParser::ParseAnnotationProperty(ir::Identifier *fieldName, ir::M return field; } -ArenaVector ETSParser::ParseAnnotations(ir::ModifierFlags &flags, bool isTopLevelSt) +ArenaVector ETSParser::ParseAnnotations(bool isTopLevelSt) { ArenaVector annotations(Allocator()->Adapter()); bool hasMoreAnnotations = true; @@ -734,7 +734,9 @@ ArenaVector ETSParser::ParseAnnotations(ir::ModifierFlags if (!isTopLevelSt) { LogSyntaxError("Annotations can only be declared at the top level."); } - flags |= ir::ModifierFlags::ANNOTATION_DECLARATION; + + // For now we don't support use Annotation before AnnotationDecl, + // program will only reach here after LogSyntaxError return annotations; } @@ -745,7 +747,6 @@ ArenaVector ETSParser::ParseAnnotations(ir::ModifierFlags Lexer()->NextToken(); } } - flags |= ir::ModifierFlags::ANNOTATION_USAGE; return annotations; } @@ -1665,8 +1666,25 @@ ir::ETSUnionType *ETSParser::CreateOptionalParameterTypeNode(ir::TypeNode *typeA return unionType; } +ir::Expression *ETSParser::ParseFunctionParameterAnnotations() +{ + Lexer()->NextToken(); // eat '@' + + auto annotations = ParseAnnotations(false); + auto savePos = Lexer()->GetToken().Start(); + ir::Expression *result = ParseFunctionParameter(); + if (result != nullptr) { + ApplyAnnotationsToNode(result, std::move(annotations), savePos); + } + return result; +} + ir::Expression *ETSParser::ParseFunctionParameter() { + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { + return ParseFunctionParameterAnnotations(); + } + auto *const paramIdent = GetAnnotatedExpressionFromParam(); if (paramIdent == nullptr) { // Error processing. return nullptr; @@ -1720,7 +1738,7 @@ ir::Expression *ETSParser::CreateParameterThis(ir::TypeNode *typeAnnotation) typeAnnotation->SetParent(paramIdent); paramIdent->SetTsTypeAnnotation(typeAnnotation); - auto *paramExpression = AllocNode(paramIdent, nullptr); + auto *paramExpression = AllocNode(paramIdent, nullptr, Allocator()); paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); return paramExpression; diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 2e4a6583ef..22565e7767 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -138,8 +138,8 @@ public: (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); return CreateFormattedStatements(sourceCode, insertingNodes); } - ir::Statement *ParseAnnotation(StatementParsingFlags flags, ir::ModifierFlags memberModifiers); - ArenaVector ParseAnnotations(ir::ModifierFlags &flags, bool isTopLevelSt = true); + ir::Statement *ParseTopLevelAnnotation(StatementParsingFlags flags, ir::ModifierFlags memberModifiers); + ArenaVector ParseAnnotations(bool isTopLevelSt); ir::ClassDeclaration *CreateFormattedClassDeclaration(std::string_view sourceCode, std::vector &insertingNodes, bool allowStatic = false); @@ -274,6 +274,8 @@ private: ir::ETSScript *ParseETSGlobalScript(lexer::SourcePosition startLoc, ArenaVector &statements); ir::AstNode *ParseImportDefaultSpecifier(ArenaVector *specifiers) override; + void *ApplyAnnotationsToClassElement(ir::AstNode *property, ArenaVector &&annotations, + lexer::SourcePosition pos); ir::MethodDefinition *ParseClassGetterSetterMethod(const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags memberModifiers); @@ -348,17 +350,20 @@ private: ir::Statement *ParseImportDeclaration(StatementParsingFlags flags) override; ir::Statement *ParseExportDeclaration(StatementParsingFlags flags) override; ir::AnnotatedExpression *ParseVariableDeclaratorKey(VariableParsingFlags flags) override; + ir::Statement *ParseAnnotationsInStatement(StatementParsingFlags flags) override; ir::VariableDeclarator *ParseVariableDeclarator(ir::Expression *init, lexer::SourcePosition startLoc, VariableParsingFlags flags) override; ir::VariableDeclarator *ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags, const lexer::SourcePosition &startLoc) override; ir::AstNode *ParseTypeLiteralOrInterfaceMember() override; + ir::AstNode *ParseAnnotationsInInterfaceBody(); void ParseNameSpaceSpecifier(ArenaVector *specifiers, bool isReExport = false); bool CheckModuleAsModifier(); ir::Expression *ParseFunctionParameterExpression(ir::AnnotatedExpression *paramIdent, ir::ETSUndefinedType *defaultUndef); std::pair TypeAnnotationValue(ir::TypeNode *typeAnnotation); ir::ETSParameterExpression *ParseFunctionParameterTail(ir::AnnotatedExpression *paramIdent, bool defaultUndefined); + ir::Expression *ParseFunctionParameterAnnotations(); ir::Expression *ParseFunctionParameter() override; ir::AnnotatedExpression *GetAnnotatedExpressionFromParam(); ir::ETSUnionType *CreateOptionalParameterTypeNode(ir::TypeNode *typeAnnotation, ir::ETSUndefinedType *defaultUndef); diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index 72c099a00b..4352811adb 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -536,14 +536,33 @@ void ETSParser::ApplyAnnotationsToNode(ir::AstNode *node, ArenaVectorIsMethodDefinition()) { - node->AsMethodDefinition()->Function()->SetAnnotations(std::move(annotations)); - } else if (node->IsClassDeclaration()) { - node->AsClassDeclaration()->Definition()->SetAnnotations(std::move(annotations)); - } else if (node->IsFunctionDeclaration()) { - node->AsFunctionDeclaration()->SetAnnotations(std::move(annotations)); - } else { - LogSyntaxError("Annotations are not allowed on this type of declaration.", pos); + switch (node->Type()) { + case ir::AstNodeType::METHOD_DEFINITION: + node->AsMethodDefinition()->Function()->SetAnnotations(std::move(annotations)); + break; + case ir::AstNodeType::CLASS_DECLARATION: + node->AsClassDeclaration()->Definition()->SetAnnotations(std::move(annotations)); + break; + case ir::AstNodeType::FUNCTION_DECLARATION: + node->AsFunctionDeclaration()->SetAnnotations(std::move(annotations)); + break; + case ir::AstNodeType::TS_INTERFACE_DECLARATION: + node->AsTSInterfaceDeclaration()->SetAnnotations(std::move(annotations)); + break; + case ir::AstNodeType::CLASS_PROPERTY: + node->AsClassProperty()->SetAnnotations(std::move(annotations)); + break; + case ir::AstNodeType::VARIABLE_DECLARATION: + node->AsVariableDeclaration()->SetAnnotations(std::move(annotations)); + break; + case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: + node->AsTSTypeAliasDeclaration()->SetAnnotations(std::move(annotations)); + break; + case ir::AstNodeType::ETS_PARAMETER_EXPRESSION: + node->AsETSParameterExpression()->SetAnnotations(std::move(annotations)); + break; + default: + LogSyntaxError("Annotations are not allowed on this type of declaration.", pos); } } } @@ -556,7 +575,7 @@ ir::AstNode *ETSParser::ParseClassElement(const ArenaVector &prop ArenaVector annotations(Allocator()->Adapter()); if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_AT)) { - annotations = ParseAnnotations(flags, false); + annotations = ParseAnnotations(false); } ir::ModifierFlags memberModifiers = ir::ModifierFlags::NONE; @@ -600,14 +619,38 @@ ir::AstNode *ETSParser::ParseClassElement(const ArenaVector &prop } default: { auto *property = ParseInnerRest(properties, modifiers, memberModifiers, startLoc); - if (property != nullptr) { - ApplyAnnotationsToNode(property, std::move(annotations), savePos); - } + ApplyAnnotationsToClassElement(property, std::move(annotations), savePos); return property; } } } +void *ETSParser::ApplyAnnotationsToClassElement(ir::AstNode *property, ArenaVector &&annotations, + lexer::SourcePosition pos) +{ + if (property == nullptr) { + return nullptr; + } + + if (annotations.empty()) { + return property; + } + + if (property->IsTSInterfaceBody()) { + for (auto *node : property->AsTSInterfaceBody()->Body()) { + ArenaVector cloneAnnotations(Allocator()->Adapter()); + for (auto *annotationUsage : annotations) { + cloneAnnotations.push_back(annotationUsage->Clone(Allocator(), node)->AsAnnotationUsage()); + } + ApplyAnnotationsToNode(node, std::move(cloneAnnotations), pos); + } + } else { + ApplyAnnotationsToNode(property, std::move(annotations), pos); + } + + return property; +} + ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector &properties, const ir::ClassDefinitionModifiers modifiers, const ir::ModifierFlags memberModifiers) @@ -937,8 +980,25 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i return method; } +ir::AstNode *ETSParser::ParseAnnotationsInInterfaceBody() +{ + Lexer()->NextToken(); // eat '@' + + auto annotations = ParseAnnotations(false); + auto savePos = Lexer()->GetToken().Start(); + ir::AstNode *result = ParseTypeLiteralOrInterfaceMember(); + if (result != nullptr) { + ApplyAnnotationsToNode(result, std::move(annotations), savePos); + } + return result; +} + ir::AstNode *ETSParser::ParseTypeLiteralOrInterfaceMember() { + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { + return ParseAnnotationsInInterfaceBody(); + } + auto startLoc = Lexer()->GetToken().Start(); if (Lexer()->Lookahead() != lexer::LEX_CHAR_LEFT_PAREN && Lexer()->Lookahead() != lexer::LEX_CHAR_LESS_THAN && diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 3cd3b4c6f0..94eec292d1 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -90,7 +90,7 @@ ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpress return nullptr; } - paramExpression = AllocNode(paramIdent->AsIdentifier(), defaultValue); + paramExpression = AllocNode(paramIdent->AsIdentifier(), defaultValue, Allocator()); std::string value = GetArgumentsSourceView(Lexer(), lexerPos); paramExpression->SetLexerSaved(util::UString(value, Allocator()).View()); @@ -108,14 +108,14 @@ ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpress return std::make_pair(defaultUndef != nullptr ? AllocNode() : nullptr, "undefined"); }(); - paramExpression = - AllocNode(paramIdent->AsIdentifier(), std::get<0>(typeAnnotationValue)); + paramExpression = AllocNode(paramIdent->AsIdentifier(), + std::get<0>(typeAnnotationValue), Allocator()); if (defaultUndef != nullptr) { paramExpression->SetLexerSaved(util::UString(std::get<1>(typeAnnotationValue), Allocator()).View()); } paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); } else { - paramExpression = AllocNode(paramIdent->AsRestElement(), nullptr); + paramExpression = AllocNode(paramIdent->AsRestElement(), nullptr, Allocator()); paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); } return paramExpression; diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index 26cdf7a6d8..db601fd027 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -168,7 +168,7 @@ static ir::Statement *ValidateExportableStatement(ETSParser *parser, ir::Stateme return stmt; } -ir::Statement *ETSParser::ParseAnnotation(StatementParsingFlags flags, ir::ModifierFlags memberModifiers) +ir::Statement *ETSParser::ParseTopLevelAnnotation(StatementParsingFlags flags, ir::ModifierFlags memberModifiers) { ir::Statement *result = nullptr; @@ -176,7 +176,7 @@ ir::Statement *ETSParser::ParseAnnotation(StatementParsingFlags flags, ir::Modif if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_INTERFACE) { result = ParseAnnotationDeclaration(memberModifiers); } else { - auto annotations = ParseAnnotations(memberModifiers); + auto annotations = ParseAnnotations(true); auto savePos = Lexer()->GetToken().Start(); result = ParseTopLevelDeclStatement(flags); if (result != nullptr) { @@ -221,7 +221,7 @@ ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags result = ParseTypeDeclaration(false); break; case lexer::TokenType::PUNCTUATOR_AT: - result = ParseAnnotation(flags, memberModifiers); + result = ParseTopLevelAnnotation(flags, memberModifiers); break; case lexer::TokenType::LITERAL_IDENT: { result = ParseIdentKeyword(); @@ -248,6 +248,19 @@ ir::Statement *ETSParser::ParseTopLevelStatement() return result; } +ir::Statement *ETSParser::ParseAnnotationsInStatement(StatementParsingFlags flags) +{ + Lexer()->NextToken(); // eat '@' + + auto annotations = ParseAnnotations(false); + auto savePos = Lexer()->GetToken().Start(); + ir::Statement *result = ParseStatement(flags); + if (result != nullptr) { + ApplyAnnotationsToNode(result, std::move(annotations), savePos); + } + return result; +} + ArenaVector ETSParser::ParseTopLevelDeclaration() { auto topStatements = ParseTopLevelStatements(); diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index 9e109d0a29..615d41e67e 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -392,6 +392,7 @@ protected: virtual ir::Statement *ParseConstStatement(StatementParsingFlags flags); virtual ir::AnnotatedExpression *ParseVariableDeclaratorKey(VariableParsingFlags flags); + virtual ir::Statement *ParseAnnotationsInStatement(StatementParsingFlags flags); virtual ir::VariableDeclarator *ParseVariableDeclarator(ir::Expression *init, lexer::SourcePosition startLoc, VariableParsingFlags flags); virtual ir::VariableDeclarator *ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags, diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index 4bd6b1d5d8..ee61b2ffbb 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -191,11 +191,21 @@ ir::Statement *ParserImpl::ParseStatementBasedOnTokenType(StatementParsingFlags return ParseEnumDeclaration(); case lexer::TokenType::KEYW_INTERFACE: return ParseInterfaceDeclaration(false); + case lexer::TokenType::PUNCTUATOR_AT: + if (IsETSParser()) { + return ParseAnnotationsInStatement(flags); + } + [[fallthrough]]; default: return ParseExpressionStatement(flags); } } +ir::Statement *ParserImpl::ParseAnnotationsInStatement([[maybe_unused]] StatementParsingFlags flags) +{ + UNREACHABLE(); +} + ir::Statement *ParserImpl::ParseVarStatement() { auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::VAR); diff --git a/ets2panda/public/CMakeLists.txt b/ets2panda/public/CMakeLists.txt index 2e2f6e4c2b..adf5f9995a 100644 --- a/ets2panda/public/CMakeLists.txt +++ b/ets2panda/public/CMakeLists.txt @@ -97,6 +97,7 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/checker/types/ts/arrayType.h ${ES2PANDA_ROOT}/ir/astNode.h ${ES2PANDA_ROOT}/ir/typed.h + ${ES2PANDA_ROOT}/ir/annotationAllowed.h ${ES2PANDA_ROOT}/ir/statements/ifStatement.h ${ES2PANDA_ROOT}/ir/ets/etsTuple.h ${ES2PANDA_ROOT}/ir/module/exportSpecifier.h diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_classproperty.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_classproperty.sts new file mode 100644 index 0000000000..c014807ab8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_classproperty.sts @@ -0,0 +1,26 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string + testProperty2: number +} + +class A{ + @MyAnno({testProperty1: "Bob", testProperty2: 1}) + @MyAnno({testProperty1: "Jim", testProperty2: 0}) + x : int +} + +/* @@? 22:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interface.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interface.sts new file mode 100644 index 0000000000..20254b4c4a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interface.sts @@ -0,0 +1,25 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string + testProperty2: number +} + +@MyAnno({testProperty1: "Bob", testProperty2: 1}) +@MyAnno({testProperty1: "Jim", testProperty2: 0}) +interface itf { +} + +/* @@? 21:2 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfacemethod.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfacemethod.sts new file mode 100644 index 0000000000..116319d87c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfacemethod.sts @@ -0,0 +1,26 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string + testProperty2: number +} + +interface itf { + @MyAnno({testProperty1: "Bob", testProperty2: 1}) + @MyAnno({testProperty1: "Jim", testProperty2: 0}) + foo() : void +} + +/* @@? 22:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.sts new file mode 100644 index 0000000000..7366a14438 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.sts @@ -0,0 +1,28 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string + testProperty2: number +} + +interface itf { + @MyAnno({testProperty1: "Bob", testProperty2: 1}) + @MyAnno({testProperty1: "Jim", testProperty2: 0}) + x : int +} + +/* @@? 22:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ +/* @@? 22:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ +/* @@? 22:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_type_alias.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_type_alias.sts new file mode 100644 index 0000000000..cef1fc93b9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_type_alias.sts @@ -0,0 +1,31 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string + testProperty2: number +} + +@MyAnno({testProperty1: "Bob", testProperty2: 1}) +@MyAnno({testProperty1: "Jim", testProperty2: 0}) +type t1 = int + +function main() : void { + @MyAnno({testProperty1: "Bob", testProperty2: 1}) + @MyAnno({testProperty1: "Jim", testProperty2: 0}) + type t2 = Array +} + +/* @@? 26:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ +/* @@? 21:2 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.sts new file mode 100644 index 0000000000..1f9f49b26b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.sts @@ -0,0 +1,32 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string + testProperty2: number +} + +@MyAnno({testProperty1: "Bob", testProperty2: 1}) +@MyAnno({testProperty1: "Jim", testProperty2: 0}) +let x1 = 1, y1 = "abc" + +function main() : void { + @MyAnno({testProperty1: "Bob", testProperty2: 1}) + @MyAnno({testProperty1: "Jim", testProperty2: 0}) + let x2 = 1, y2 = "abc" +} + +/* @@? 21:2 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ +/* @@? 21:2 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ +/* @@? 26:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_classproperty.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_classproperty.sts new file mode 100644 index 0000000000..87409a234c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_classproperty.sts @@ -0,0 +1,29 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +class B{ + @MyAnno({testProperty1:"", testProperty2: "", testProperty3: ""}) + x0 : int + @MyAnno({testProperty1:"", testProperty2: "", testProperty3: ""}) + y : string +} + +/* @@? 22:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 24:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_function_param.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_function_param.sts new file mode 100644 index 0000000000..7f02bc133e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_function_param.sts @@ -0,0 +1,27 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +function foo(@MyAnno({testProperty1:"", testProperty2: "", testProperty3: "", testProperty4: ""}) x: int, + @MyAnno({testProperty1:"", testProperty2: "", testProperty3: "", testProperty4: ""}) y: boolean) { + +} + +/* @@? 21:15 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 22:15 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.sts new file mode 100644 index 0000000000..590e0c98d2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.sts @@ -0,0 +1,33 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +@MyAnno({testProperty1:"", testProperty2: "", testProperty3: "", testProperty4: ""}) +interface itf { + @MyAnno({testProperty1:"", testProperty2: "", testProperty3: "", testProperty4: ""}) + foo(): void + @MyAnno({testProperty1:"", testProperty2: "", testProperty3: "", testProperty4: ""}) + x : int +} + +/* @@? 21:2 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 23:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 25:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 25:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 25:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_type_alias.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_type_alias.sts new file mode 100644 index 0000000000..6e510af767 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_type_alias.sts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +@MyAnno({testProperty1:"", testProperty2: "", testProperty3: ""}) +type t1 = int; + +function main() : void { + @MyAnno({testProperty1:"", testProperty2: "", testProperty3: ""}) + type t2 = Array +} + +/* @@? 25:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 21:2 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.sts new file mode 100644 index 0000000000..f66a2826f7 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.sts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +@MyAnno({testProperty1:"", testProperty2: "", testProperty3: ""}) +let x1 = 1, y1 = "abc" + +function main() : void { + @MyAnno({testProperty1:"", testProperty2: "", testProperty3: ""}) + let x2 = 1, y2 = "abc" +} + +/* @@? 21:2 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 21:2 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ +/* @@? 25:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_interface.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_interface.sts new file mode 100644 index 0000000000..623e135682 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_interface.sts @@ -0,0 +1,24 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string +} + +MyAnno({testProperty1: ""}) +interface itf { +} + +/* @@? 19:1 Error TypeError: Annotation missing '@' symbol before annotation name. */ +/* @@? 19:1 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_type_alias.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_type_alias.sts new file mode 100644 index 0000000000..06bb3ea9a9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_type_alias.sts @@ -0,0 +1,31 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string +} + +MyAnno({testProperty1: ""}) +type t1 = int + +function main() : void { + MyAnno({testProperty1: ""}) + type t2 = int +} + + +/* @@? 19:1 Error TypeError: Annotation missing '@' symbol before annotation name. */ +/* @@? 19:1 Error TypeError: This expression is not callable. */ +/* @@? 23:5 Error TypeError: Annotation missing '@' symbol before annotation name. */ +/* @@? 23:5 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_variable_decl.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_variable_decl.sts new file mode 100644 index 0000000000..f2fd366091 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_variable_decl.sts @@ -0,0 +1,30 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string +} + +MyAnno({testProperty1: ""}) +let x1 = 1, y1 = 2 + +function main() : void { + MyAnno({testProperty1: ""}) + let x2 = 1, y2 = 2 +} + +/* @@? 19:1 Error TypeError: Annotation missing '@' symbol before annotation name. */ +/* @@? 19:1 Error TypeError: This expression is not callable. */ +/* @@? 23:5 Error TypeError: Annotation missing '@' symbol before annotation name. */ +/* @@? 23:5 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_classproperty.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_classproperty.sts new file mode 100644 index 0000000000..e012623544 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_classproperty.sts @@ -0,0 +1,29 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +class B{ + @MyAnno({testProperty1:""}) + x0 : int + @MyAnno({testProperty1:""}) + y0 : string +} + +/* @@? 22:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 24:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_function_param.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_function_param.sts new file mode 100644 index 0000000000..9faeaf1cdf --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_function_param.sts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +function foo0(@MyAnno x: int, @MyAnno({testProperty2: ""}) y: string = "a") { +} + +function foo1(@MyAnno({testProperty1: ""}) x: int, @MyAnno({testProperty2: ""}) y: string = "a") { +} + +/* @@? 21:16 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 21:16 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ +/* @@? 21:32 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ +/* @@? 24:16 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 24:53 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.sts new file mode 100644 index 0000000000..62e1d82a90 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.sts @@ -0,0 +1,33 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +@MyAnno({testProperty2: ""}) +interface itf { + @MyAnno({testProperty1:""}) + foo(): void + @MyAnno({testProperty1:""}) + x : int +} + +/* @@? 21:2 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ +/* @@? 23:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 25:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 25:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 25:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_type_alias.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_type_alias.sts new file mode 100644 index 0000000000..2466d82ec5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_type_alias.sts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +@MyAnno({testProperty1:""}) +type t1 = int; + +function main() : void { + @MyAnno({testProperty1:""}) + type t2 = Array +} + +/* @@? 25:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 21:2 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.sts b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.sts new file mode 100644 index 0000000000..5f367bae95 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.sts @@ -0,0 +1,33 @@ +/* + * 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. + */ + +@interface MyAnno { + testProperty1: string + testProperty2: string +} + +@MyAnno() +let x1 = 1, y1 = "abc" + +function main() : void { + @MyAnno({testProperty2: ""}) + let x2 = 1, y2 = "abc" +} + +/* @@? 21:2 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 21:2 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ +/* @@? 21:2 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ +/* @@? 21:2 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ +/* @@? 25:6 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidClasses.sts b/ets2panda/test/ast/parser/ets/InvalidClasses.sts index b5e60ee789..15e8f174af 100644 --- a/ets2panda/test/ast/parser/ets/InvalidClasses.sts +++ b/ets2panda/test/ast/parser/ets/InvalidClasses.sts @@ -78,45 +78,45 @@ interface I1 { x: number = } -/* @@? 17:12 Error SyntaxError: Duplicated modifier is not allowed */ -/* @@? 18:12 Error SyntaxError: Duplicated modifier is not allowed */ -/* @@? 22:12 Error SyntaxError: Access modifier must precede field and method modifiers. */ -/* @@? 26:18 Error SyntaxError: Native method cannot be async */ -/* @@? 27:20 Error SyntaxError: Abstract method cannot be async */ -/* @@? 35:5 Error SyntaxError: Only one static block is allowed */ -/* @@? 38:10 Error SyntaxError: Duplicated modifier is not allowed */ -/* @@? 41:5 Error SyntaxError: The special predefined method '$_get' cannot be asynchronous. */ -/* @@? 41:5 Error SyntaxError: The special predefined method '$_get' should have exactly one required parameter. */ -/* @@? 45:5 Error SyntaxError: The special predefined method '$_set' cannot be asynchronous. */ -/* @@? 45:5 Error SyntaxError: The special predefined method '$_set' should have exactly two required parameters. */ -/* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' cannot be asynchronous. */ -/* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' should not have parameters. */ -/* @@? 54:23 Error SyntaxError: Initializers are not allowed in ambient contexts. */ -/* @@? 58:9 Error SyntaxError: Unexpected token. */ -/* @@? 58:16 Error SyntaxError: 'native' flags must be used for functions only at top-level. */ -/* @@? 58:24 Error SyntaxError: Unexpected token, expected: '('. */ -/* @@? 58:25 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 60:1 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 60:11 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ -/* @@? 60:11 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 60:12 Error SyntaxError: Unexpected token ')'. */ -/* @@? 60:12 Error SyntaxError: Unexpected token ')'. */ -/* @@? 60:13 Error SyntaxError: Unexpected token ':'. */ -/* @@? 60:20 Error SyntaxError: Unexpected token '{'. */ -/* @@? 66:18 Error SyntaxError: Private interface methods must have body */ -/* @@? 67:9 Error SyntaxError: Unexpected token, expected 'private' or identifier */ -/* @@? 67:16 Error SyntaxError: Identifier expected */ -/* @@? 67:16 Error SyntaxError: Unexpected token, expected 'private' or identifier */ -/* @@? 67:24 Error SyntaxError: Private interface methods must have body */ -/* @@? 72:5 Error SyntaxError: Unexpected token, expected 'private' or identifier */ -/* @@? 72:13 Error SyntaxError: Interface fields must have type annotation. */ -/* @@? 72:14 Error SyntaxError: Invalid Type */ -/* @@? 72:14 Error SyntaxError: Unexpected token: '}'. */ -/* @@? 74:9 Error SyntaxError: Unexpected token 'identification literal'. */ -/* @@? 74:16 Error SyntaxError: Unexpected token ':'. */ -/* @@? 74:16 Error SyntaxError: Unexpected token ':'. */ -/* @@? 74:25 Error SyntaxError: Unexpected token '{'. */ -/* @@? 75:9 Error SyntaxError: return keyword should be used in function body */ -/* @@? 78:8 Error SyntaxError: Label must be followed by a loop statement */ -/* @@? 79:1 Error SyntaxError: Unexpected token '}'. */ -/* @@? 79:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 17:12 Error SyntaxError: Duplicated modifier is not allowed */ +/* @@? 18:12 Error SyntaxError: Duplicated modifier is not allowed */ +/* @@? 22:12 Error SyntaxError: Access modifier must precede field and method modifiers. */ +/* @@? 26:18 Error SyntaxError: Native method cannot be async */ +/* @@? 27:20 Error SyntaxError: Abstract method cannot be async */ +/* @@? 35:5 Error SyntaxError: Only one static block is allowed */ +/* @@? 38:10 Error SyntaxError: Duplicated modifier is not allowed */ +/* @@? 41:5 Error SyntaxError: The special predefined method '$_get' cannot be asynchronous. */ +/* @@? 41:5 Error SyntaxError: The special predefined method '$_get' should have exactly one required parameter. */ +/* @@? 45:5 Error SyntaxError: The special predefined method '$_set' cannot be asynchronous. */ +/* @@? 45:5 Error SyntaxError: The special predefined method '$_set' should have exactly two required parameters. */ +/* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' cannot be asynchronous. */ +/* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' should not have parameters. */ +/* @@? 54:23 Error SyntaxError: Initializers are not allowed in ambient contexts. */ +/* @@? 58:9 Error SyntaxError: Unexpected token. */ +/* @@? 58:16 Error SyntaxError: 'native' flags must be used for functions only at top-level. */ +/* @@? 58:24 Error SyntaxError: Unexpected token, expected: '('. */ +/* @@? 58:25 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 60:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 60:11 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 60:11 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 60:12 Error SyntaxError: Unexpected token ')'. */ +/* @@? 60:12 Error SyntaxError: Unexpected token ')'. */ +/* @@? 60:13 Error SyntaxError: Unexpected token ':'. */ +/* @@? 60:20 Error SyntaxError: Unexpected token '{'. */ +/* @@? 66:18 Error SyntaxError: Private interface methods must have body */ +/* @@? 67:9 Error SyntaxError: Unexpected token, expected 'private' or identifier */ +/* @@? 67:16 Error SyntaxError: Identifier expected */ +/* @@? 67:16 Error SyntaxError: Unexpected token, expected 'private' or identifier */ +/* @@? 67:24 Error SyntaxError: Private interface methods must have body */ +/* @@? 72:5 Error SyntaxError: Unexpected token, expected 'private' or identifier */ +/* @@? 72:13 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 72:14 Error SyntaxError: Invalid Type */ +/* @@? 72:14 Error SyntaxError: Unexpected token: '}'. */ +/* @@? 74:9 Error SyntaxError: Unexpected token 'identification literal'. */ +/* @@? 74:16 Error SyntaxError: Unexpected token ':'. */ +/* @@? 74:16 Error SyntaxError: Unexpected token ':'. */ +/* @@? 74:25 Error SyntaxError: Unexpected token '{'. */ +/* @@? 75:9 Error SyntaxError: return keyword should be used in function body */ +/* @@? 78:8 Error SyntaxError: Label must be followed by a loop statement */ +/* @@? 79:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 79:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidStatements3.sts b/ets2panda/test/ast/parser/ets/InvalidStatements3.sts index f7dbdda6cc..8157c2bb72 100644 --- a/ets2panda/test/ast/parser/ets/InvalidStatements3.sts +++ b/ets2panda/test/ast/parser/ets/InvalidStatements3.sts @@ -50,10 +50,8 @@ for (let i = 1 in [0, 1, 2]) {} /* @@? 29:7 Error SyntaxError: Unexpected token 'identification literal', expected '(' */ /* @@? 29:13 Error SyntaxError: Unexpected token '{', expected ')'. */ /* @@? 31:9 Error SyntaxError: Unexpected token 'let'. */ -/* @@? 31:9 Error SyntaxError: Unexpected token 'let'. */ /* @@? 34:5 Error SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list */ /* @@? 38:5 Error SyntaxError: Annotation declaration can not have access modifier */ /* @@? 38:5 Error SyntaxError: Unexpected token 'private'. */ -/* @@? 38:13 Error SyntaxError: Unexpected token '@'. */ /* @@? 42:16 Error SyntaxError: for-in loop variable declaration may not have an initializer */ /* @@? 42:16 Error SyntaxError: Unexpected token: 'in'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_locally.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_locally.sts index ef6d372206..0aa6471990 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_locally.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_locally.sts @@ -17,5 +17,5 @@ class A{ } -/* @@? 16:6 Error SyntaxError: Annotations can only be declared at the top level. */ -/* @@? 16:6 Error SyntaxError: Local type declaration (class, struct, interface and enum) support is not yet implemented. */ +/* @@? 16:6 Error SyntaxError: Annotations can only be declared at the top level. */ +/* @@? 16:6 Error SyntaxError: Local type declaration (class, struct, interface and enum) support is not yet implemented. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier03.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier03.sts index 1f2aabb293..ca16300c45 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier03.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier03.sts @@ -19,4 +19,4 @@ /* @@@ label Error SyntaxError: Unexpected token: 'static'. */ /* @@@ label1 Error SyntaxError: Unexpected token: '@'. */ -/* @@@ label1 Error SyntaxError: Unexpected token '@'. */ +/* @@? 15:38 Error SyntaxError: Annotations can only be declared at the top level. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.sts index 326f63be0c..d36c3915c2 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.sts @@ -17,10 +17,9 @@ class A{} } - -/* @@? 17:5 Error SyntaxError: Identifier expected, got ''. */ -/* @@? 17:11 Error SyntaxError: Missing type annotation for property. */ -/* @@? 17:12 Error SyntaxError: Missing type annotation for property 'A'. */ -/* @@? 17:12 Error SyntaxError: Identifier expected, got '{'. */ -/* @@? 17:13 Error SyntaxError: Missing type annotation for property. */ -/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 17:5 Error SyntaxError: Identifier expected, got ''. */ +/* @@? 17:11 Error SyntaxError: Missing type annotation for property. */ +/* @@? 17:12 Error SyntaxError: Missing type annotation for property 'A'. */ +/* @@? 17:12 Error SyntaxError: Identifier expected, got '{'. */ +/* @@? 17:13 Error SyntaxError: Missing type annotation for property. */ +/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_method.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_method.sts index fc9d441c35..72f76a14fa 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_method.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_method.sts @@ -18,12 +18,12 @@ } -/* @@? 17:8 Error SyntaxError: Annotation can not have method as property */ -/* @@? 17:8 Error SyntaxError: Missing type annotation for property 'foo'. */ -/* @@? 17:8 Error SyntaxError: Identifier expected, got '('. */ -/* @@? 17:9 Error SyntaxError: Missing type annotation for property. */ -/* @@? 17:9 Error SyntaxError: Identifier expected, got ')'. */ -/* @@? 17:10 Error SyntaxError: Missing type annotation for property. */ -/* @@? 17:10 Error SyntaxError: Identifier expected, got '{'. */ -/* @@? 17:11 Error SyntaxError: Missing type annotation for property. */ -/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 17:8 Error SyntaxError: Annotation can not have method as property */ +/* @@? 17:8 Error SyntaxError: Missing type annotation for property 'foo'. */ +/* @@? 17:8 Error SyntaxError: Identifier expected, got '('. */ +/* @@? 17:9 Error SyntaxError: Missing type annotation for property. */ +/* @@? 17:9 Error SyntaxError: Identifier expected, got ')'. */ +/* @@? 17:10 Error SyntaxError: Missing type annotation for property. */ +/* @@? 17:10 Error SyntaxError: Identifier expected, got '{'. */ +/* @@? 17:11 Error SyntaxError: Missing type annotation for property. */ +/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.sts new file mode 100644 index 0000000000..ece6d9548a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.sts @@ -0,0 +1,28 @@ +/* + * 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. + */ + +class A{} + +@interface MyAnno { + testProperty1: string +} + +class B{ + @MyAnno({testProperty1: A}) + x : int, y : int +} + +/* @@? 23:29 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ +/* @@? 24:12 Error SyntaxError: Unexpected token: ','. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.sts new file mode 100644 index 0000000000..18e9a24858 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.sts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +class A{} + +@interface MyAnno { + testProperty1: string +} + +function foo(@MyAnno({testProperty1: A}) x: int) { +} + +/* @@? 22:38 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.sts new file mode 100644 index 0000000000..782409ef8a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.sts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +class A{} + +@interface MyAnno { + testProperty1: string +} + +@MyAnno({testProperty1: A}) +let x = "abc" + +/* @@? 22:25 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.sts new file mode 100644 index 0000000000..c0a9fe39c1 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.sts @@ -0,0 +1,28 @@ +/* + * 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. + */ + +class A{} + +@interface MyAnno { + testProperty1: string +} + +@MyAnno({testProperty1: A}) +interface itf { + x : int + foo() : string +} + +/* @@? 22:25 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.sts new file mode 100644 index 0000000000..87bab0ec70 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.sts @@ -0,0 +1,27 @@ +/* + * 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. + */ + +class A{} + +@interface MyAnno { + testProperty1: string +} + +interface itf { + @MyAnno({testProperty1: A}) + foo() : string +} + +/* @@? 23:29 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.sts new file mode 100644 index 0000000000..60524855f7 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.sts @@ -0,0 +1,26 @@ +/* + * 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. + */ + +class A{} + +@interface MyAnno { + testProperty1: string +} + +interface itf { + @MyAnno({testProperty1: A}) + x: int +} +/* @@? 23:29 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.sts new file mode 100644 index 0000000000..884d1a3fff --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.sts @@ -0,0 +1,27 @@ +/* + * 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. + */ + +class A{} + +@interface MyAnno { + testProperty1: string +} + +function main():void { + @MyAnno({testProperty1: A}) + let x = "abc" +} + +/* @@? 23:29 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.sts new file mode 100644 index 0000000000..fa3c70c36b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.sts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +class A{} + +@interface MyAnno { + testProperty1: string +} + +@MyAnno({testProperty1: A}) +type t1 = int + +function main(): void { + @MyAnno({testProperty1: A}) + type t2 = int +} + +/* @@? 22:25 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ +/* @@? 26:29 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_classproperty.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_classproperty.sts new file mode 100644 index 0000000000..63ad4fe8a6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_classproperty.sts @@ -0,0 +1,28 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string +} + +class A{ + MyAnno({testProperty1: ""}) + x : int +} + +/* @@? 20:12 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 20:30 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 20:31 Error SyntaxError: Unexpected token ')'. */ +/* @@? 21:9 Error SyntaxError: Label must be followed by a loop statement */ +/* @@? 22:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.sts new file mode 100644 index 0000000000..8c52ca16c9 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.sts @@ -0,0 +1,53 @@ +/* + * 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. + */ +@interface MyAnno { + testProperty1: string +} + +function foo(MyAnno({testProperty1: ""}) x: int) { +} + +function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: string) { +} + +function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: string) { +} + +/* @@? 19:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 19:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 19:42 Error SyntaxError: Unexpected token 'identification literal'. */ +/* @@? 19:45 Error SyntaxError: Label must be followed by a loop statement */ +/* @@? 19:48 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:48 Error SyntaxError: Unexpected token ')'. */ +/* @@? 22:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 22:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 22:42 Error SyntaxError: Unexpected token 'identification literal'. */ +/* @@? 22:45 Error SyntaxError: Label must be followed by a loop statement */ +/* @@? 22:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:78 Error SyntaxError: Unexpected token 'identification literal'. */ +/* @@? 22:81 Error SyntaxError: Label must be followed by a loop statement */ +/* @@? 22:87 Error SyntaxError: Unexpected token ')'. */ +/* @@? 22:87 Error SyntaxError: Unexpected token ')'. */ +/* @@? 25:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 25:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 25:42 Error SyntaxError: Unexpected token 'identification literal'. */ +/* @@? 25:45 Error SyntaxError: Label must be followed by a loop statement */ +/* @@? 25:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 25:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 25:78 Error SyntaxError: Unexpected token 'identification literal'. */ +/* @@? 25:81 Error SyntaxError: Label must be followed by a loop statement */ +/* @@? 25:87 Error SyntaxError: Unexpected token ')'. */ +/* @@? 25:87 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.sts index 93acc4e265..eae569da04 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.sts @@ -25,5 +25,5 @@ abstract class A { abstract foo2() //CTE } -/* @@? 25:14 Error SyntaxError: Annotations cannot be applied to an abstract class or method. */ -/* @@? 25:14 Error SyntaxError: Annotations are not allowed on an abstract class or methods. */ +/* @@? 25:14 Error SyntaxError: Annotations cannot be applied to an abstract class or method. */ +/* @@? 25:14 Error SyntaxError: Annotations are not allowed on an abstract class or methods. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_annotationDecl.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_annotationDecl.sts index 9a33940459..74854361b5 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_annotationDecl.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_annotationDecl.sts @@ -24,4 +24,3 @@ } /* @@? 21:2 Error SyntaxError: Annotations cannot be applied to an annotation declaration. */ -/* @@? 21:2 Error SyntaxError: Annotations are not allowed on this type of declaration. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_classFiled.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_classFiled.sts index f70b7f7ad6..2ce33ffa86 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_classFiled.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_classFiled.sts @@ -19,7 +19,5 @@ class A{ @MyAnno1({testProperty1: "123", testProperty2: 123}) - /* @@ label */a:string = "" + a:string = "" } - -/* @@@ label Error SyntaxError: Annotations are not allowed on this type of declaration. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_letDecl.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_letDecl.sts index d7bfc2d624..fafd6ba8a5 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_letDecl.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_letDecl.sts @@ -18,6 +18,5 @@ } @MyAnno1({testProperty1: "123", testProperty2: 123}) -/* @@ label */let a:string = "" +let a:string = "" -/* @@@ label Error SyntaxError: Annotations are not allowed on this type of declaration. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.sts b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.sts index 7882ef5275..d43fe9893d 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.sts +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.sts @@ -19,6 +19,6 @@ @MyAnno("123", "1") class A{} -/* @@? 19:14 Error SyntaxError: Unexpected token, expected: ')'. */ -/* @@? 19:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:19 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:14 Error SyntaxError: Unexpected token, expected: ')'. */ +/* @@? 19:19 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:19 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForClassProperty.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForClassProperty.sts new file mode 100644 index 0000000000..d02bf15656 --- /dev/null +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForClassProperty.sts @@ -0,0 +1,34 @@ +/* + * 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. +*/ + +@interface Anno { + name: string = "Jim" + id: int = 1 +} + +class A { + @Anno + x0 : int + @Anno() + x1 : string = "" + @Anno({name : "2"}) + x2 : int = 2 + @Anno({name : "2", id : 1}) + x3 : boolean = true +} + +function main(): void { + let a : A = new A() +} diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunction.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunction.sts index 24991d350c..2bc0486723 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunction.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunction.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface FuncAuthor { authorName: string = "Jim" } @@ -23,4 +23,4 @@ function foo():void {} function main(): void { -} \ No newline at end of file +} diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunctionParam.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunctionParam.sts new file mode 100644 index 0000000000..331d9781a5 --- /dev/null +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunctionParam.sts @@ -0,0 +1,39 @@ +/* + * 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. +*/ + +// Annotation declaration: +@interface Anno { + name: string = "Jim" + id: int = 1 +} +@interface Anno2 { + name: string +} + +function foo1(@Anno x : int, @Anno2({name: "name1"}) y : int) { +} +function foo2(@Anno() x : int, @Anno2({name: "name2"}) y : int) { +} +function foo3(@Anno({}) x : int, @Anno2({name: "name3"}) y : int) { +} +function foo4(@Anno() @Anno2({name: "name4"}) x : int, @Anno @Anno2({name: "name4"}) y : int) { +} + +function main() { + foo1(1, 2) + foo2(3, 4) + foo3(5, 6) + foo4(7, 8) +} diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForInterface.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForInterface.sts new file mode 100644 index 0000000000..7091923a72 --- /dev/null +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForInterface.sts @@ -0,0 +1,57 @@ +/* + * 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. +*/ + +@interface Anno { + name: string = "" + id: int = 1 +} + +@Anno +interface itf0 { + @Anno + x1 : int + + @Anno() + x2 : string + + @Anno({name : "2"}) + x3 : double + + @Anno({id : 1}) + x4 : boolean + + @Anno({name : "2", id : 1}) + x5 : int[] +} + +@Anno() +interface itf1 { +} + +@Anno({name : "2"}) +interface itf2 { +} + +@Anno({id : 1}) +interface itf3 { +} + +@Anno({name : "2", id : 1}) +interface itf4 { +} + + +function main(): void { +} diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForMethod.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForMethod.sts index cd09414dc0..365f4ed032 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForMethod.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForMethod.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface FuncAuthor { authorName: string = "Jim" } diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.sts new file mode 100644 index 0000000000..3f8f4a5dbb --- /dev/null +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.sts @@ -0,0 +1,58 @@ +/* + * 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. +*/ + +// Annotation declaration: +@interface Anno { + name: string = "Jim" + id: int = 1 +} +@interface Anno2 { + name: string +} + +@Anno +type t1 = int + +@Anno() +type t2 = int[] + +@Anno({name : "2"}) +type t3 = string + +@Anno({id : 1}) +type t4 = boolean + +@Anno({name : "2", id : 1}) +@Anno2({name : "ab"}) +type t5 = double + +// Annotation use: +function main(): void { + @Anno + type t6 = int[] + + @Anno() + type t7 = int + + @Anno({name : "2"}) + type t8 = Array + + @Anno({id : 1}) + type t9 = Array + + @Anno({name : "2", id : 1}) + @Anno2({name : "ab"}) + type t10 = string[] +} diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForVariableDecl.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForVariableDecl.sts new file mode 100644 index 0000000000..e9fe824011 --- /dev/null +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForVariableDecl.sts @@ -0,0 +1,37 @@ +/* + * 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. +*/ + +@interface Anno { + name: string = "Jim" + id: int = 1 +} + +@Anno() +let x6 = 1, y6 = 10 + +function main(): void { + @Anno + let x0 = 1 + @Anno + let x1 = 1, y1 = 2 + @Anno() + let x2 = 1, y2 = 2 + @Anno({name : "1"}) + let x3 = 1, y3 = 2 + @Anno({id : 2}) + let x4 = 1, y4 = 2 + @Anno({name : "1", id : 2}) + let x5 = 1, y5 = 2 +} diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties01.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties01.sts index fecec99377..9e5c47b4ad 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties01.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties01.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface MyAnno { } diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties02.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties02.sts index 56eb368588..44468c1d72 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties02.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties02.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface ClassAuthor { authorName: string = "Jim" authorAge: number = -35 diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties03.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties03.sts index ebfbe58dab..7207c38c73 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties03.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties03.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface ClassAuthor { authorName: string = "Jim" authorAge: number = 35 diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType01.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType01.sts index 0ee7c50ac4..a48043ade7 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType01.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType01.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface ClassAuthor { authorName: string authorAge: number diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType02.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType02.sts index ebedd99a01..a6ea7d1dc7 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType02.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType02.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface ClassAuthor { authorName: string = "Jim" authorAge: number = 35 diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType03.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType03.sts index afa862c837..9d47b75083 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType03.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType03.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface ClassAuthor { authorName: string = "Jim" authorAge: number = 35 diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType04.sts b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType04.sts index e9e61cb3b9..276b439e41 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType04.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType04.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface ClassAuthor { authorName: string = "Jim" authorAge: number = 35 diff --git a/ets2panda/test/runtime/ets/annotation_tests/Muti-AnnotationsDefineAndUseForClass.sts b/ets2panda/test/runtime/ets/annotation_tests/Muti-AnnotationsDefineAndUseForClass.sts index eb77bf848a..c0fe3e9879 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/Muti-AnnotationsDefineAndUseForClass.sts +++ b/ets2panda/test/runtime/ets/annotation_tests/Muti-AnnotationsDefineAndUseForClass.sts @@ -13,7 +13,7 @@ * limitations under the License. */ -// Annotation declaretion: +// Annotation declaration: @interface ClassAuthor { authorName: string } diff --git a/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp b/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp index 9d6cac438e..c584590f4d 100644 --- a/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp @@ -198,7 +198,7 @@ TEST_F(ASTVerifierTest, ValidateGetterArguments) // Create argument auto *ident = checker.AllocNode("ident", Allocator()); - auto *param = checker.AllocNode(ident, nullptr); + auto *param = checker.AllocNode(ident, nullptr, Allocator()); // Add argument to getter ast->IterateRecursively([param](ark::es2panda::ir::AstNode *child) { diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 3b5f17df07..515d65d467 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -303,6 +303,10 @@ void ETSBinder::ResolveInterfaceDeclaration(ir::TSInterfaceDeclaration *decl) ResolveReference(extend); } + for (auto *anno : decl->Annotations()) { + ResolveReference(anno); + } + auto scopeCtx = LexicalScope::Enter(this, decl->Scope()->AsClassScope()); for (auto *stmt : decl->Body()->Body()) { -- Gitee