diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index ac419780829ac500b474022a67e1415f61714986..912483f79bcbbab329882f1066142bc752afab00 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 9470d7b55537361ac3c3b95a7c878ebc08583373..8485fcb8a92c867842fd743c6bb5860895c3fcd1 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 ab0d9488be6a798fe2f8b97ce4687b24d08a7f62..9db4d7c4eebfb550a1817127194983d509447df3 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 9cab1ce5630749ec76b721cd94b4d776b37a7be1..8ff1484c9a0f81b830d6e0d7e523ef3f319547d3 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 4dfb816241d1c004ebe0558529349b293e5b0ccd..d557574b1bc50c056157ed2a9d0cc787a3f339bb 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 96df43fcc1f33e043141c271b29a786308ec7216..03e0e05f04a4423ef46d12d8684a9995f3dacf2d 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 9f14e85d7fa7c089b7f1c1e7bcc35a66eb8b9186..2dd3bcc4d384dffe98a8d932480adbd07eb8348b 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 03a7e6d1c463d34a907541074e364e95c53a8a63..614ba247a04931ba8eab171f8583020b5af16f9c 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 e5039dab24798bfc6de190180fb8667ca8649135..30afee7c84a02a126a788718ea3fe1849e710202 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 e11b6e372e54c1275ad27835a5c68007ede4bb8c..ed932759f1e29658bbbf8ae5e057363c36511850 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 2083c4dccaa05daba4b49c4ab913880707c3d6c7..51eea239a9d266224dfe8f6b90ddaabaf7b48219 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 202cd2eb034de427d95cb77b1043cd9a19487cbe..d6babe74e2f4fa69feae83c6a3588eeafae3f9d9 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 546b02a48e1ab2cb7ebaf4ce19d03fee1c44e6f9..c6a765934927dbc4706a7dd00eee9c715aef085d 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 6c9340e604b6733e8334c50a89a7d7d2e01e5079..dbe7888bd3157f32c9472d4f1f46440e37543bc4 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 0000000000000000000000000000000000000000..cb4abf4e4b1ce5e7df10424ca06dae12eb4efd6e --- /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 63a0ac76530450562953ede2c89b6d992687facb..805e48d36a54e7d8e615fcd379ea4cf33ba68b72 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 1d7eedb6958de480ac957b7de3d9f6c1efe555a4..ba8104c69c60e3ac8d3b1bcee35b917783ed3013 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 3dd68d7a0aa22a1d9c4019a09e270d3f9326967e..287d478fadf28dd294313b38d111f68ed4218302 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 bd13845b5d162ab3a67bb40f20c2cd87699578bb..8a455771328c78e3ffc8ba2112f25d0b95738e76 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 e4a821b340af24a391832f1176aee5f049ea11e4..0e278c7717a423cceb583033f69f6351e7ab76d6 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 c256f1c498cffaeb226a1bff20b5ba6e07dc57f6..f1f36f7f9d0833d1c0e42673a61838c73c226a88 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 f9914e471e68ef1fccc3e43470c0ec12cf833862..f311115cbc29644ac615149de473bd66950eab24 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 d81108f71015a74fbb106056746ebc57c0267d43..8ce5b0cf74740f8e569306ce11271def814956c7 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 c644162925ebb0c139b66785b95f876372d69d21..de4e3fdf6729a8928b6e019feebde0c25f5f26d7 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 ac44ff7bed369c2d0c7f711920612a0deaad84f4..15b3f59d87a1d76582ec9e0e4769bfa017a9da18 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 132aa5a9e967e52be61db637c42850ee99fc22e5..34f5058dc3dc36102ad0054940ad08c6ce88e0c1 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 431d9b26e7ffffcaaafe4f46e758a2dbc2a75a67..9048bfab597172f2f193d8dd7aaa32adbbbbb4ab 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 d753828bca0e282d6215443c5a7f79e000fa847d..f3513bf5c22622e99abf121d34294537961b2a82 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 98df189a01562df773af4bf3f23a9e4ad17ce2fe..e3a0d50f4f692084a8e72af4918bd10f91b3936f 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 3dd3df8a2421a73071904e5199bb9984e2072e67..b96319d26acb8a0f0651f5f763459d1a95b393d2 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 baee4d823928b8aa0ecca826f21817131229ae2d..ebc7cc91f38333fc1b899dbd6012e56461053b4b 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 8682358c98594d83fae3175e37cad770580dd662..68725d2426dcacaf7218da504e160b045ac5dc2f 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 e1e5db7aa786f2b44927206392789aedcc5c728b..38064584ed5ea638aff5b21a287f517b3d972127 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 96bd557ed2afacfd09ec9775fd06f10d5f422f15..f37b5e99abbdf1fd71237be4c3d45081578c0cc2 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 2e4a6583efc1bcdc4cae557c188cefc3403a69e4..22565e7767359ee45d201eb1396a5c86cf142900 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 72c099a00b306fd5d839d2e6f06f1efb9fc270bd..4352811adbf346484d63e2c926be750930e71859 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 3cd3b4c6f0f963a2049cd962a913a348c1113694..94eec292d12a549be07399b42691a15729ab5d59 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 26cdf7a6d8d4ac5c7bdfceec08565ed8c2dc4f80..db601fd02773d42fa93e7a947e706e6099cd7f13 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 9e109d0a2948bb3a3e2d4c33a388197ec6fa1965..615d41e67efdb5c55167c94a2180880c0bfbf141 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 4bd6b1d5d80f385481ab9157e4dee399d6b0bcc8..ee61b2ffbb3e199c1a425496c73ab7aefb761370 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 2e2f6e4c2be1c22ef74cb0f2f89a6dce255b74ee..adf5f9995a29246c22f47d27deced525c8c7dad4 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 0000000000000000000000000000000000000000..c014807ab8678987eea189d9dbd891de4decdf0f --- /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 0000000000000000000000000000000000000000..20254b4c4abedaa416032362a730ad1f48fa5c53 --- /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 0000000000000000000000000000000000000000..116319d87c102e61cf396682e007f59e1c886720 --- /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 0000000000000000000000000000000000000000..7366a14438bbb8b37b9fb06b271fcf8dc04e8c50 --- /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 0000000000000000000000000000000000000000..cef1fc93b97693522cc1f3ca84b5de4340017566 --- /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 0000000000000000000000000000000000000000..1f9f49b26b3142644b0fca2fa692ab3c9d8228e0 --- /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 0000000000000000000000000000000000000000..87409a234c5e621c9054c46dfd63262742598f2a --- /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 0000000000000000000000000000000000000000..7f02bc133e7733d59425d3a1e57a49a03ac9a56d --- /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 0000000000000000000000000000000000000000..590e0c98d2f0d4a7220d71ed3dea5cbcbdb62ad3 --- /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 0000000000000000000000000000000000000000..6e510af76718368245a6160a733cfcfd56f8bf09 --- /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 0000000000000000000000000000000000000000..f66a2826f7158e47a5ee1039e7f0645cfa39b5b8 --- /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 0000000000000000000000000000000000000000..623e1356825449dc7327c2f416ec6d64641e7b21 --- /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 0000000000000000000000000000000000000000..06bb3ea9a900979c2e6b1ec8afd2819a0ee7ab80 --- /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 0000000000000000000000000000000000000000..f2fd366091a00d8ccaaf6d2634c858bb9a4fc48e --- /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 0000000000000000000000000000000000000000..e01262354402f9f80c842530b3b6a7c247c4ff4c --- /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 0000000000000000000000000000000000000000..9faeaf1cdf3738e1c2ddb7c8bcc2282f88114545 --- /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 0000000000000000000000000000000000000000..62e1d82a90f11d2cdceb4655d68147cc2ba3f908 --- /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 0000000000000000000000000000000000000000..2466d82ec59c2553f9bf4ace60dfc396492d1c03 --- /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 0000000000000000000000000000000000000000..5f367bae9593b7963400ebd2d31571747f08631f --- /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 b5e60ee789d97da156178be05b0c8a34a1d8a2fe..15e8f174aff1501e92502251d13fcb99c77715e0 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 f7dbdda6ccc54480dbc820f6c9df1eb5307e6e67..8157c2bb72b2680f5c9b5cbfd60f7601e77651cc 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 ef6d37220638bcccf06918c0cb79f162d85e7b0a..0aa647199025fd7c040a6362375de7d4b7298bb5 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 1f2aabb2934d1ef5181cdba438e2dd0cc065601b..ca16300c45c33247c18515029527b917897dc3e9 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 326f63be0c287b27b8ae52b728416b10f08e9c62..d36c3915c27670ffa633504995624cbe761651ee 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 fc9d441c35c65e5e5488fe15572c4289c4d6b117..72f76a14faedb8c81073427767c90f1728d9a702 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 0000000000000000000000000000000000000000..ece6d9548a20685535939089052fd3c1b826fd9c --- /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 0000000000000000000000000000000000000000..18e9a248582b945c3e7b900bed7a04116b24ec84 --- /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 0000000000000000000000000000000000000000..782409ef8a3183a463a66d62e29439c56c2c2f56 --- /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 0000000000000000000000000000000000000000..c0a9fe39c17eefe9cdd1fe0b47a5ada05531df08 --- /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 0000000000000000000000000000000000000000..87bab0ec7006cba906851a8e5afe5503f801b445 --- /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 0000000000000000000000000000000000000000..60524855f7d4e97235bc64ddd6d93eb890cea145 --- /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 0000000000000000000000000000000000000000..884d1a3fff45e7530cf5290a56afbbf2798c5319 --- /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 0000000000000000000000000000000000000000..fa3c70c36b41b9e8f4594a8f4a4de67b6846a7dc --- /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 0000000000000000000000000000000000000000..63ad4fe8a6fa1f5dda87383bf549a9df2986c6cd --- /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 0000000000000000000000000000000000000000..8c52ca16c99247a1de305f71fb469f428ccf10fa --- /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 93acc4e2650cd292f9dd0c7f5a8dcaba71f9ea18..eae569da04559edcad05267f0f8562d9bc2ac88c 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 9a33940459acec1edf7a7afcec66236623561782..74854361b56721bfe398ac452b9da386c40b8e07 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 f70b7f7ad6967b234cc1da4c0fde736155bbda08..2ce33ffa8669e2cb965cb90e943ad669cfe7ad6e 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 d7bfc2d624d8dcf5c436a8c297e44b5c31ce28ab..fafd6ba8a5f77a4ed96b8fcb083fff8852d0c865 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 7882ef5275d20b09745b81182a0a57ee377ec260..d43fe9893de7d49e988c452c50c26029a47faa8a 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 0000000000000000000000000000000000000000..d02bf15656e4278facbbfa90db87eba14f3d6ce9 --- /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 24991d350c6385e854597c7df0bfca8525b05d83..2bc04867233ce932e40e17369e2456e1f7f67998 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 0000000000000000000000000000000000000000..331d9781a5e48d48f9e47507b6a9ec66e2462cd9 --- /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 0000000000000000000000000000000000000000..7091923a72859703d598fde26e39bc6df394fff4 --- /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 cd09414dc08ab3a8ee72f3acd4950e33a2008a0f..365f4ed0320a9f9c58973f1a93d0a03f8c5c6728 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 0000000000000000000000000000000000000000..3f8f4a5dbb0a36bc0e90d24da6abd57386080cf1 --- /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 0000000000000000000000000000000000000000..e9fe82401115c08a5803215c5afc1971ec731059 --- /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 fecec99377b15363f14f8a6636554c54f8b0da8a..9e5c47b4ad7cea2b50baec4d0b9f46c860bc1404 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 56eb3685889e0cfba0f774a451e87f7c88d3ed0c..44468c1d72ca24de532fffe4035380a5f2a723bb 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 ebfbe58dab5becd3c08185053412c41c8cdc83a0..7207c38c73efabeddcabc5342b1b1ca54550cd62 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 0ee7c50ac4fd3eeebb103724096e365fe8b5a6eb..a48043ade720dffeaa7612c0f0ddc2f931cfe44f 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 ebedd99a018c9cbcf83caa77da53f9dbfb4fe504..a6ea7d1dc73b8239324e9d6d5b0884390a8d363c 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 afa862c83790320cf7f7b38e36462c9855b0bf23..9d47b750837e3a654e8d30429b8ed514de325c99 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 e9e61cb3b908b510aa78322b7567b4f199ab1263..276b439e41c6803e492f8941be9be427156605e5 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 eb77bf848ab8a5021c1ce853df1ee7b7c66ee5a0..c0fe3e9879c42e05c5b568d25363bd4a963721c5 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 9d6cac438e20bbfa41bdc5270daad7fb72ede17a..c584590f4d3d1d3b57efe771acc3a0112f301ec9 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 3b5f17df07276754e6b9daa186734e99cbead6cc..515d65d467749ebe640f2d17aae98203aea7e4c0 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()) {