From d7ac2a48859d95dcadd1c034c7d1354acf832546 Mon Sep 17 00:00:00 2001 From: fcc Date: Mon, 30 Jun 2025 20:59:40 +0800 Subject: [PATCH] fix keyword readonly/declare/typeof Fix keyword readonly/declare/typeof. Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/ICH1W3 Signed-off-by: fcc --- ets2panda/lexer/scripts/keywords.yaml | 7 ++-- ets2panda/parser/ETSparserClasses.cpp | 42 ++++++++++++++++++- ets2panda/parser/ETSparserExpressions.cpp | 4 -- .../ast/compiler/ets/namespace_modifiers.ets | 2 +- .../ets/readonly/label_readonly_true.ets | 2 +- .../ets/readonly/readonly_static_var.ets | 2 +- .../test/ast/parser/ets/InvalidClasses.ets | 1 + .../ets/readonlyFunctionTypeAnnotation.ets | 4 +- .../test/ast/parser/ets/user_defined_14.ets | 5 ++- .../test/ast/parser/ets/user_defined_19.ets | 2 + .../runtime/ets/multiple_typeof_operator.ets | 6 --- 11 files changed, 57 insertions(+), 20 deletions(-) diff --git a/ets2panda/lexer/scripts/keywords.yaml b/ets2panda/lexer/scripts/keywords.yaml index 58cffbda4f..da3b834e26 100644 --- a/ets2panda/lexer/scripts/keywords.yaml +++ b/ets2panda/lexer/scripts/keywords.yaml @@ -452,7 +452,8 @@ keywords: - name: 'readonly' token: KEYW_READONLY - keyword_like: [as, ts, ets] + keyword: [ets] + keyword_like: [as, ts] - name: 'rethrows' token: KEYW_RETHROWS @@ -539,8 +540,8 @@ keywords: - name: 'typeof' token: KEYW_TYPEOF - keyword: [js, ts] - keyword_like: [ets] + keyword: [js, ts, ets] + keyword_like: [] flags: [unary] - name: 'u8' diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index 513242b3e4..08f700f770 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -982,6 +982,7 @@ ir::ClassDefinition *ETSParser::ParseClassDefinition(ir::ClassDefinitionModifier ir::ModifierFlags ETSParser::ParseInterfaceMethodModifiers() { if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || + Lexer()->GetToken().Type() == lexer::TokenType::KEYW_READONLY || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || Lexer()->GetToken().Type() == lexer::TokenType::KEYW_OVERLOAD) { @@ -1383,6 +1384,45 @@ void ETSParser::CreateImplicitConstructor([[maybe_unused]] ir::MethodDefinition properties.push_back(methodDef); } +static bool DeclareIsModifier(lexer::Lexer *lexer) +{ + bool result = false; + auto currentPos = lexer->Save(); + if (lexer->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) { + lexer->NextToken(); // eat 'declare' + switch (lexer->GetToken().KeywordType()) { + case lexer::TokenType::KEYW_LET: + case lexer::TokenType::KEYW_CONST: + case lexer::TokenType::KEYW_FUNCTION: + case lexer::TokenType::KEYW_CLASS: + case lexer::TokenType::KEYW_NAMESPACE: + case lexer::TokenType::KEYW_ENUM: + case lexer::TokenType::KEYW_ABSTRACT: + case lexer::TokenType::KEYW_FINAL: + case lexer::TokenType::KEYW_INTERFACE: + case lexer::TokenType::KEYW_TYPE: + case lexer::TokenType::KEYW_ASYNC: + case lexer::TokenType::KEYW_STRUCT: { + result = true; + break; + } + default: { + if (lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { + result = true; + break; + } + if (lexer->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && + lexer->GetToken().Ident().Is("module")) { + result = true; + break; + } + } + } + } + lexer->Rewind(currentPos); + return result; +} + std::pair ETSParser::ParseMemberModifiers() { auto memberModifiers = ir::ModifierFlags::STATIC | ir::ModifierFlags::PUBLIC; @@ -1406,7 +1446,7 @@ std::pair ETSParser::ParseMemberModifi lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); - if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) { + if (DeclareIsModifier(Lexer())) { CheckDeclare(); memberModifiers |= ir::ModifierFlags::DECLARE; } diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index bff2cbec61..f53fa9db0b 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -133,10 +133,6 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla { auto tokenFlags = lexer::NextTokenFlags::NONE; lexer::TokenType operatorType = Lexer()->GetToken().Type(); - if (operatorType == lexer::TokenType::LITERAL_IDENT && - Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPEOF) { - operatorType = lexer::TokenType::KEYW_TYPEOF; - } switch (operatorType) { case lexer::TokenType::PUNCTUATOR_MINUS: diff --git a/ets2panda/test/ast/compiler/ets/namespace_modifiers.ets b/ets2panda/test/ast/compiler/ets/namespace_modifiers.ets index d019c77f6e..977747cfe4 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_modifiers.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_modifiers.ets @@ -43,7 +43,7 @@ namespace M { /* @@? 18:18 Error SyntaxError: Unexpected token 'const'. */ /* @@? 23:14 Error SyntaxError: Unexpected token 'const'. */ -/* @@? 27:5 Error TypeError: Unresolved reference readonly */ +/* @@? 27:5 Error SyntaxError: Unexpected token 'readonly'. */ /* @@? 27:14 Error SyntaxError: Unexpected token 'R'. */ /* @@? 27:14 Error TypeError: Unresolved reference R */ /* @@? 27:16 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets b/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets index 7a6e516d42..1444d7db67 100644 --- a/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets +++ b/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets @@ -17,7 +17,7 @@ WE: readonly true; let: readonly; /* @@? 16:5 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 16:5 Error TypeError: Unresolved reference readonly */ +/* @@? 16:5 Error SyntaxError: Unexpected token 'readonly'. */ /* @@? 16:14 Error SyntaxError: Unexpected token 'true'. */ /* @@? 17:4 Error SyntaxError: Identifier expected, got ':'. */ /* @@? 17:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets index 46ad39e55c..467fd3916f 100644 --- a/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets @@ -15,7 +15,7 @@ readonly static S = c' '; -/* @@? 16:1 Error TypeError: Unresolved reference readonly */ +/* @@? 16:1 Error SyntaxError: Unexpected token 'readonly'. */ /* @@? 16:10 Error SyntaxError: Unexpected token 'static'. */ /* @@? 16:17 Error SyntaxError: Unexpected token 'S'. */ /* @@? 16:17 Error TypeError: Unresolved reference S */ diff --git a/ets2panda/test/ast/parser/ets/InvalidClasses.ets b/ets2panda/test/ast/parser/ets/InvalidClasses.ets index 85d1c1fbf9..47cf51b8b1 100644 --- a/ets2panda/test/ast/parser/ets/InvalidClasses.ets +++ b/ets2panda/test/ast/parser/ets/InvalidClasses.ets @@ -104,6 +104,7 @@ interface I1 { /* @@? 47:21 Error TypeError: Return type of async function must be 'Promise'. */ /* @@? 54:21 Error TypeError: Initializers are not allowed in ambient contexts: x */ /* @@? 54:23 Error SyntaxError: Initializers are not allowed in ambient contexts. */ +/* @@? 58:1 Error TypeError: Unresolved reference declare */ /* @@? 58:9 Error SyntaxError: Unexpected token 'native'. */ /* @@? 58:16 Error SyntaxError: 'native' flags must be used for functions only at top-level. */ /* @@? 58:22 Error TypeError: Native and Declare methods should have explicit return type. */ diff --git a/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets b/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets index 686f313ee0..7b40c520e4 100644 --- a/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets +++ b/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets @@ -17,11 +17,11 @@ func: readonly (Y : object | long [] ) => [ ] /* @@? 17:7 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 17:7 Error TypeError: Unresolved reference readonly */ +/* @@? 17:7 Error SyntaxError: Unexpected token 'readonly'. */ /* @@? 17:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 17:20 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:22 Error SyntaxError: Unexpected token 'object'. */ /* @@? 17:22 Error TypeError: Type name 'object' used in the wrong context */ /* @@? 17:22 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 17:39 Error SyntaxError: Unexpected token ')'. */ -/* @@? 17:42 Error SyntaxError: Unexpected token '=>'. */ \ No newline at end of file +/* @@? 17:42 Error SyntaxError: Unexpected token '=>'. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_14.ets b/ets2panda/test/ast/parser/ets/user_defined_14.ets index a52c018c99..31c17e0cc8 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_14.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_14.ets @@ -13,6 +13,9 @@ * limitations under the License. */ -class typeof{ +class /* @@ label */typeof { a : string = "15"; } + +/* @@@ label Error SyntaxError: Hard keyword 'typeof' cannot be used as identifier */ +/* @@@ label Error SyntaxError: Identifier expected, got 'typeof'. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_19.ets b/ets2panda/test/ast/parser/ets/user_defined_19.ets index 0da8937318..8f81e7dbc7 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_19.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_19.ets @@ -18,3 +18,5 @@ struct typeof{ } /* @@? 16:1 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ +/* @@? 16:8 Error SyntaxError: Hard keyword 'typeof' cannot be used as identifier */ +/* @@? 16:8 Error SyntaxError: Identifier expected, got 'typeof'. */ diff --git a/ets2panda/test/runtime/ets/multiple_typeof_operator.ets b/ets2panda/test/runtime/ets/multiple_typeof_operator.ets index cd695567f4..3a8746335e 100644 --- a/ets2panda/test/runtime/ets/multiple_typeof_operator.ets +++ b/ets2panda/test/runtime/ets/multiple_typeof_operator.ets @@ -27,10 +27,4 @@ function main() { let y = new Y(); arktest.assertEQ(typeof y, "object") - - let typeof: int = 0; - let x = typeof + 1 - ++typeof; - - arktest.assertEQ(typeof typeof, "number"); } -- Gitee