From 15c0496fbc60f961e0f52d9812d2d400bb354cb4 Mon Sep 17 00:00:00 2001 From: Istvan Romai Date: Thu, 12 Jun 2025 10:11:30 +0200 Subject: [PATCH] Compiler diagnostic improvement arkts-no-conditional-types Modified the parser to give more elaborate error message if the user tries to use conditional type alias Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICEP2P Internal issue: #22506 Change-Id: Ic7b8df98b235d4ac9192f5e545dc74e7b17f9073 Signed-off-by: Istvan Romai --- ets2panda/parser/ETSparser.cpp | 3 ++- ets2panda/parser/ETSparser.h | 1 + ets2panda/parser/ETSparserTypes.cpp | 10 ++++++++ ets2panda/parser/parserImpl.h | 3 ++- .../compiler/ets/conditional-type-alias.ets | 24 +++++++++++++++++++ ets2panda/util/diagnostic/semantic.yaml | 5 ++++ 6 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/conditional-type-alias.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index a5b2030b29..dd6f25d4ab 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -832,7 +832,8 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() ExpectToken(lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; + TypeAnnotationParsingOptions options = + TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::TYPE_ALIAS_CONTEXT; ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); if (typeAnnotation == nullptr) { return nullptr; diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index d52a0f8706..7e53c08a80 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -283,6 +283,7 @@ private: ir::TypeNode *ParsePotentialFunctionalType(TypeAnnotationParsingOptions *options, ir::TSTypeParameterDeclaration *typeParamDecl = nullptr); std::pair ParseNonNullableType(TypeAnnotationParsingOptions *options); + void CheckForConditionalTypeError(TypeAnnotationParsingOptions options, lexer::TokenType tokenType); std::pair GetTypeAnnotationFromToken(TypeAnnotationParsingOptions *options); std::pair GetTypeAnnotationFromArrowFunction(TypeAnnotationParsingOptions *options); std::pair GetTypeAnnotationFromParentheses( diff --git a/ets2panda/parser/ETSparserTypes.cpp b/ets2panda/parser/ETSparserTypes.cpp index 3b0f7ea5c6..d8399cde7c 100644 --- a/ets2panda/parser/ETSparserTypes.cpp +++ b/ets2panda/parser/ETSparserTypes.cpp @@ -324,6 +324,15 @@ std::pair ETSParser::ParseNonNullableType(TypeAnnotationPa return std::make_pair(AllocNode(typeAnnotation, Allocator()), true); } +// Helper function to reduce line count of GetTypeAnnotationFromToken(...) +void ETSParser::CheckForConditionalTypeError(TypeAnnotationParsingOptions options, lexer::TokenType tokenType) +{ + if ((options & TypeAnnotationParsingOptions::TYPE_ALIAS_CONTEXT) != 0 && + (tokenType == lexer::TokenType::KEYW_EXTENDS || tokenType == lexer::TokenType::PUNCTUATOR_QUESTION_MARK)) { + LogError(diagnostic::ERROR_ARKTS_NO_CONDITIONAL_TYPES); + } +} + // CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic // Just to reduce the size of ParseTypeAnnotation(...) method std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnotationParsingOptions *options) @@ -335,6 +344,7 @@ std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnota if (IsPrimitiveType(Lexer()->GetToken().KeywordType()) || Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { auto typeAnnotation = ParseLiteralIdent(options); + CheckForConditionalTypeError(*options, Lexer()->GetToken().Type()); if (((*options) & TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL) != 0 && (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword())) { return std::make_pair(typeAnnotation, false); diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index ab10f02797..686e9d9a4d 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -65,7 +65,8 @@ enum class TypeAnnotationParsingOptions : uint32_t { DISALLOW_UNION = 1U << 15U, POTENTIAL_NEW_ARRAY = 1U << 16U, ANNOTATION_NOT_ALLOW = 1U << 17U, - INSTANCEOF = 1U << 18U + INSTANCEOF = 1U << 18U, + TYPE_ALIAS_CONTEXT = 1U << 19U }; class ParserImpl { diff --git a/ets2panda/test/ast/compiler/ets/conditional-type-alias.ets b/ets2panda/test/ast/compiler/ets/conditional-type-alias.ets new file mode 100644 index 0000000000..d852f65291 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/conditional-type-alias.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +// (arkts-no-conditional-types) +type X = T extends number ? T : string + +/* @@? 17:15 Error SyntaxError: Unexpected token 'extends'. */ +/* @@? 17:15 Error TypeError: Conditional type aliases are not supported. Introduce a new type with constraints explicitly, or rewrite logic using Object! */ +/* @@? 17:23 Error SyntaxError: Unexpected token 'number'. */ +/* @@? 17:23 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 17:32 Error TypeError: Unresolved reference T */ +/* @@? 17:36 Error TypeError: Type name 'string' used in the wrong context */ diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 4912fbec17..92fcef300d 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -439,6 +439,11 @@ semantic: id: 35 message: "Invalid enumeration value type." +- name: ERROR_ARKTS_NO_CONDITIONAL_TYPES + id: 136365 + message: "Conditional type aliases are not supported. Introduce a new type with constraints explicitly, or rewrite logic + using Object!" + - name: ERROR_ARKTS_NO_DECLARATION_MERGING id: 341 message: "Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in -- Gitee