diff --git a/ets2panda/lexer/scripts/keywords.yaml b/ets2panda/lexer/scripts/keywords.yaml index 58cffbda4fbd75b568a2fadefcd37caf34866b09..da3b834e2669447fe7e4190ae1ac4c982ab45c6b 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 513242b3e4afd2f69dd0838b4d73dc46d2d34543..08f700f7705321e47ddc6d5c9fd5cd5aea7b7fd5 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 bff2cbec61e8ca9a642255a35da2c38a699fa4e7..f53fa9db0b392754eb882d41386fb20f2e44643d 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 d019c77f6ee3a4e7892b8bf6ecf7d51d3ab7492f..977747cfe4bda0a5f6572ddaf33907db100757f3 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 7a6e516d42d80c2b8f8bf4fb27d601ab37936774..1444d7db67e37613cb06141eb7ec365a72a7d924 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 46ad39e55c1155e8e58d8e5179d5278fe7e290aa..467fd3916f7de3e2e295f3fa9dc9dfc57b310df9 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 85d1c1fbf9e80b6d9045d25c5e6e0a15da8f7904..47cf51b8b1b1c7cf28e31b1c4fdc560a209753d1 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 686f313ee070e7f322ff87ed868b7a484d8be38d..7b40c520e4502ec79131d2a206f920bda7750497 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 a52c018c9981486973ab3bca26f22271103411b4..31c17e0cc894d95cfb988decab385f757e4d58c6 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 0da893731848a9ca3ba48665644ac591fe0e1053..8f81e7dbc795a24a5188d7b7e80fe4eb86cfaa11 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 cd695567f48bc564927ed812826a3bbf9e1e5e06..3a8746335e9a8e004ebdebdd4c4ee60288823d4f 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"); }