From 3c61268c35f35a4d090a2699cb85c42cd59eb108 Mon Sep 17 00:00:00 2001 From: zmw Date: Wed, 9 Jul 2025 11:58:18 +0800 Subject: [PATCH] Fix annotation dot empty crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICL01K Description: Fix annotation dot empty crash Signed-off-by: zmw Change-Id: I7896637942b5a45396c0b93e8a64e72676889fa0 --- ets2panda/checker/ETSAnalyzer.cpp | 23 ++++++---- .../ir/statements/annotationDeclaration.cpp | 3 +- ets2panda/ir/statements/annotationUsage.cpp | 3 +- ets2panda/parser/ETSparserAnnotations.cpp | 42 +++++++++---------- .../ets/annotation_decl_dot_empty.ets | 21 ++++++++++ .../ets/annotation_dot_with_empty.ets | 23 ++++++++++ .../ast/compiler/ets/binary_operator_neg.ets | 9 ++-- .../parser/ets/interface_parser_error_1.ets | 5 ++- ets2panda/util/diagnostic/syntax.yaml | 4 ++ 9 files changed, 94 insertions(+), 39 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/annotation_decl_dot_empty.ets create mode 100644 ets2panda/test/ast/compiler/ets/annotation_dot_with_empty.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 7d86fab062..c3e5fd8f44 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2896,9 +2896,12 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const } } - auto *annoDecl = st->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); - if (annoDecl != st && annoDecl->IsDeclare()) { - checker->CheckAmbientAnnotation(st, annoDecl); + auto baseName = st->GetBaseName(); + if (!baseName->IsErrorPlaceHolder()) { + auto *annoDecl = baseName->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); + if (annoDecl != st && annoDecl->IsDeclare()) { + checker->CheckAmbientAnnotation(st, annoDecl); + } } return ReturnTypeForStatement(st); @@ -2912,13 +2915,17 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const ETSChecker *checker = GetETSChecker(); st->Expr()->Check(checker); - if (st->GetBaseName()->Variable() == nullptr || - !st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { - checker->LogError(diagnostic::NOT_AN_ANNOTATION, {st->GetBaseName()->Name()}, st->GetBaseName()->Start()); + auto *baseName = st->GetBaseName(); + if (baseName->Variable() == nullptr || !baseName->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { + if (!baseName->IsErrorPlaceHolder()) { + checker->LogError(diagnostic::NOT_AN_ANNOTATION, {baseName->Name()}, baseName->Start()); + } + + ES2PANDA_ASSERT(checker->IsAnyError()); return ReturnTypeForStatement(st); } - auto *annoDecl = st->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); + auto *annoDecl = baseName->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); annoDecl->Check(checker); ArenaUnorderedMap fieldMap {checker->ProgramAllocator()->Adapter()}; @@ -2940,7 +2947,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const checker->CheckSinglePropertyAnnotation(st, annoDecl); fieldMap.clear(); } else { - checker->CheckMultiplePropertiesAnnotation(st, st->GetBaseName()->Name(), fieldMap); + checker->CheckMultiplePropertiesAnnotation(st, baseName->Name(), fieldMap); } checker->ProcessRequiredFields(fieldMap, st, checker); diff --git a/ets2panda/ir/statements/annotationDeclaration.cpp b/ets2panda/ir/statements/annotationDeclaration.cpp index aab66f2db2..6444bc9758 100644 --- a/ets2panda/ir/statements/annotationDeclaration.cpp +++ b/ets2panda/ir/statements/annotationDeclaration.cpp @@ -111,8 +111,7 @@ Identifier *AnnotationDeclaration::GetBaseName() const if (expr_->IsIdentifier()) { return expr_->AsIdentifier(); } - auto *part = expr_->AsETSTypeReference()->Part(); - return part->Name()->AsTSQualifiedName()->Right(); + return expr_->AsETSTypeReference()->Part()->GetIdent(); } AstNode *AnnotationDeclaration::Construct(ArenaAllocator *allocator) diff --git a/ets2panda/ir/statements/annotationUsage.cpp b/ets2panda/ir/statements/annotationUsage.cpp index aee9d75d53..3c96c0a868 100644 --- a/ets2panda/ir/statements/annotationUsage.cpp +++ b/ets2panda/ir/statements/annotationUsage.cpp @@ -120,7 +120,6 @@ Identifier *AnnotationUsage::GetBaseName() const if (expr_->IsIdentifier()) { return expr_->AsIdentifier(); } - auto *part = expr_->AsETSTypeReference()->Part(); - return part->Name()->AsTSQualifiedName()->Right(); + return expr_->AsETSTypeReference()->Part()->GetIdent(); } } // namespace ark::es2panda::ir diff --git a/ets2panda/parser/ETSparserAnnotations.cpp b/ets2panda/parser/ETSparserAnnotations.cpp index 452d35330e..c60c05d6d9 100644 --- a/ets2panda/parser/ETSparserAnnotations.cpp +++ b/ets2panda/parser/ETSparserAnnotations.cpp @@ -56,26 +56,29 @@ ir::Expression *ETSParser::ParseAnnotationName() } }; auto save = Lexer()->Save(); + ir::Identifier *ident = nullptr; Lexer()->NextToken(); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { Lexer()->Rewind(save); expr = ExpectIdentifier(); - ES2PANDA_ASSERT(expr != nullptr); - setAnnotation(expr->AsIdentifier()); - return expr; - } - Lexer()->Rewind(save); - if (Lexer()->Lookahead() == '.') { - auto opt = TypeAnnotationParsingOptions::NO_OPTS; - expr = ParseTypeReference(&opt); - ES2PANDA_ASSERT(expr != nullptr); - setAnnotation(expr->AsETSTypeReference()->Part()->GetIdent()); + ident = expr->AsIdentifier(); } else { - expr = ExpectIdentifier(); - ES2PANDA_ASSERT(expr != nullptr); - setAnnotation(expr->AsIdentifier()); + Lexer()->Rewind(save); + if (Lexer()->Lookahead() == '.') { + auto opt = TypeAnnotationParsingOptions::NO_OPTS; + expr = ParseTypeReference(&opt); + ident = expr->AsETSTypeReference()->Part()->GetIdent(); + } else { + expr = ExpectIdentifier(); + ident = expr->AsIdentifier(); + } } + if (ident->IsBrokenExpression()) { + LogError(diagnostic::INVALID_ANNOTATION_NAME, {}, expr->Start()); + } + + setAnnotation(ident); return expr; } @@ -366,17 +369,14 @@ void ETSParser::ApplyAnnotationsToSpecificNodeType(ir::AstNode *node, ArenaVecto } } -static lexer::SourcePosition GetExpressionEndLoc(ir::Expression *expr) +static lexer::SourcePosition GetAnnotationExpressionEndLoc(ir::Expression *expr) { ES2PANDA_ASSERT(expr != nullptr); if (expr->IsIdentifier()) { return expr->AsIdentifier()->End(); } - auto *part = expr->AsETSTypeReference()->Part(); - if (part->Name()->IsBrokenExpression()) { - return part->Name()->End(); - } - return part->Name()->AsTSQualifiedName()->Right()->End(); + + return expr->AsETSTypeReference()->Part()->GetIdent()->End(); } ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() @@ -388,7 +388,7 @@ ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() ArenaVector properties(Allocator()->Adapter()); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && - !IsArrowFunctionExpressionStart() && IsAnnotationUsageStart(GetExpressionEndLoc(expr))) { + !IsArrowFunctionExpressionStart() && IsAnnotationUsageStart(GetAnnotationExpressionEndLoc(expr))) { Lexer()->NextToken(); // eat '(' if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { properties = ParseAnnotationProperties(flags); @@ -424,7 +424,7 @@ ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() auto *annotationUsage = AllocNode(expr, std::move(properties)); ES2PANDA_ASSERT(annotationUsage != nullptr); annotationUsage->AddModifier(flags); - annotationUsage->SetRange({startLoc, GetExpressionEndLoc(expr)}); + annotationUsage->SetRange({startLoc, GetAnnotationExpressionEndLoc(expr)}); return annotationUsage; } diff --git a/ets2panda/test/ast/compiler/ets/annotation_decl_dot_empty.ets b/ets2panda/test/ast/compiler/ets/annotation_decl_dot_empty.ets new file mode 100644 index 0000000000..c077a76fd0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_decl_dot_empty.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface Message. +{ +} + +/* @@? 16:12 Error SyntaxError: Invalid annotation name. */ +/* @@? 17:1 Error SyntaxError: Identifier expected. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_dot_with_empty.ets b/ets2panda/test/ast/compiler/ets/annotation_dot_with_empty.ets new file mode 100644 index 0000000000..195205770f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_dot_with_empty.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class MyTest { + @Consume. + private property1; +} + +/* @@? 17:6 Error SyntaxError: Invalid annotation name. */ +/* @@? 18:5 Error SyntaxError: Identifier expected. */ +/* @@? 18:22 Error SyntaxError: Field type annotation expected. */ diff --git a/ets2panda/test/ast/compiler/ets/binary_operator_neg.ets b/ets2panda/test/ast/compiler/ets/binary_operator_neg.ets index 8b71c849f8..4bee69637b 100644 --- a/ets2panda/test/ast/compiler/ets/binary_operator_neg.ets +++ b/ets2panda/test/ast/compiler/ets/binary_operator_neg.ets @@ -15,7 +15,8 @@ /* @@ label1 */@@/@ -/* @@@ label1 Error SyntaxError: Unexpected token '@@'. */ -/* @@? 21:93 Error SyntaxError: Identifier expected, got 'end of stream'. */ -/* @@? 21:93 Error SyntaxError: Unexpected token 'end of stream'. */ -/* @@? 21:93 Error SyntaxError: Annotations are not allowed on this type of declaration. */ \ No newline at end of file +/* @@@ label1 Error SyntaxError: Unexpected token '@@'. */ +/* @@? 23:1 Error SyntaxError: Identifier expected, got 'end of stream'. */ +/* @@? 23:1 Error SyntaxError: Invalid annotation name. */ +/* @@? 23:1 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 23:1 Error SyntaxError: Annotations are not allowed on this type of declaration. */ diff --git a/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets b/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets index afa196d8f3..2b2bf179a2 100644 --- a/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets +++ b/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets @@ -55,13 +55,14 @@ function mdin() { let a = new A(); /* @@? 24:20 Error TypeError: Interface name 'I' used in the wrong context */ /* @@? 24:22 Error SyntaxError: Unexpected token '{'. */ /* @@? 25:4 Error TypeError: Unresolved reference reanstructor */ -/* @@? 26:19 Error SyntaxError: Unexpected token '�ls'. */ /* @@? 26:19 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 26:19 Error SyntaxError: Unexpected token '�ls'. */ /* @@? 27:5 Error SyntaxError: Unexpected token 'A'. */ /* @@? 27:7 Error SyntaxError: Unexpected token '{'. */ /* @@? 28:5 Error SyntaxError: Identifier expected, got 'constructor'. */ +/* @@? 28:16 Error SyntaxError: Invalid annotation name. */ /* @@? 28:19 Error SyntaxError: Annotations are not allowed on this type of declaration. */ /* @@? 29:18 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 31:2 Error SyntaxError: Unexpected token '*'. */ /* @@? 32:1 Error SyntaxError: Nested functions are not allowed. */ -/* @@? 68:1 Error SyntaxError: Expected '}', got 'end of stream'. */ +/* @@? 69:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index a928afc8ed..72003d7cc4 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -456,6 +456,10 @@ syntax: id: 111 message: "Export declarations are not permitted in a namespace." +- name: INVALID_ANNOTATION_NAME + id: 329 + message: "Invalid annotation name." + - name: UNEXPECTED_TOKEN_ID id: 112 message: "Unexpected token, expected an identifier." -- Gitee