From 3dcc7b418675fccba6ee3b735cd719fbf7f61e1e Mon Sep 17 00:00:00 2001 From: Boglarka Date: Tue, 3 Jun 2025 14:45:52 +0200 Subject: [PATCH] Add error for invalid typeof and instanceof Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IC9IO1 Reason: Typeof keyword in type annotation and instanceof with a type on the left side is invalid. Description: Added checks for these cases and error logging. Signed-off-by: Haag Boglarka --- ets2panda/checker/ets/validateHelpers.cpp | 7 ++++- ets2panda/parser/ETSparserTypes.cpp | 6 +++++ .../ast/parser/ets/instanceof_on_type.ets | 27 +++++++++++++++++++ .../ast/parser/ets/typeof_in_annotation.ets | 24 +++++++++++++++++ ets2panda/util/diagnostic/syntax.yaml | 10 ++++++- 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/instanceof_on_type.ets create mode 100644 ets2panda/test/ast/parser/ets/typeof_in_annotation.ets diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index f3ad9a385b..bd0a6ceb9b 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -129,7 +129,8 @@ bool ETSChecker::ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, const auto *const binaryExpr = ident->Parent()->AsBinaryExpression(); bool isFinished = false; - if (binaryExpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF && binaryExpr->Left() == ident) { + bool isInstanceOfKeyword = binaryExpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF; + if (isInstanceOfKeyword && binaryExpr->Left() == ident) { if (!IsReferenceType(type)) { std::ignore = TypeError(ident->Variable(), diagnostic::INSTANCEOF_NONOBJECT, {ident->Name()}, ident->Start()); @@ -145,6 +146,10 @@ bool ETSChecker::ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, } isFinished = true; } + if (isInstanceOfKeyword && ident->Variable()->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE | + varbinder::VariableFlags::TYPE_ALIAS)) { + LogError(diagnostic::WRONG_LEFT_OF_INSTANCEOF, {}, ident->Start()); + } return isFinished; } diff --git a/ets2panda/parser/ETSparserTypes.cpp b/ets2panda/parser/ETSparserTypes.cpp index c88b813839..2f51ebead2 100644 --- a/ets2panda/parser/ETSparserTypes.cpp +++ b/ets2panda/parser/ETSparserTypes.cpp @@ -514,6 +514,12 @@ bool ETSParser::ParseReadonlyInTypeAnnotation() ir::TypeNode *ETSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options) { const auto startPos = Lexer()->GetToken().Start(); + if ((*options & + (TypeAnnotationParsingOptions::DISALLOW_UNION | TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW)) == 0 && + Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_TYPEOF)) { + LogError(diagnostic::TYPEOF_IN_ANNOTATION); + return AllocBrokenType(Lexer()->GetToken().Loc()); + } // if there is prefix readonly parameter type, change the return result to ETSTypeReference, like Readonly<> if (!Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_READONLY)) { return ParseTypeAnnotationNoPreferParam(options); diff --git a/ets2panda/test/ast/parser/ets/instanceof_on_type.ets b/ets2panda/test/ast/parser/ets/instanceof_on_type.ets new file mode 100644 index 0000000000..cb4b9dcc7b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/instanceof_on_type.ets @@ -0,0 +1,27 @@ +/* + * 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 X {} +type B = X + +let a = (new X()) instanceof Object +let b = (new X()) instanceof X +let c = X instanceof Object +let d = X instanceof X +let f = B instanceof Object + +/* @@? 21:9 Error SyntaxError: The left operand of 'instanceof' operator cannot be a type. */ +/* @@? 22:9 Error SyntaxError: The left operand of 'instanceof' operator cannot be a type. */ +/* @@? 23:9 Error SyntaxError: The left operand of 'instanceof' operator cannot be a type. */ diff --git a/ets2panda/test/ast/parser/ets/typeof_in_annotation.ets b/ets2panda/test/ast/parser/ets/typeof_in_annotation.ets new file mode 100644 index 0000000000..2ab98e4b55 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/typeof_in_annotation.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. + */ + +let n1 = 42 +let s1 = "foo" +let n2: typeof n1 +let s2: typeof s1 + +/* @@? 18:16 Error SyntaxError: Result of 'typeof' operator is not supported to be used as type annotation. */ +/* @@? 18:16 Error SyntaxError: Unexpected token 'n1'. */ +/* @@? 19:16 Error SyntaxError: Result of 'typeof' operator is not supported to be used as type annotation. */ +/* @@? 19:16 Error SyntaxError: Unexpected token 's1'. */ diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index d18a5f9766..71a315ef06 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1234,4 +1234,12 @@ syntax: - name: OPTIONAL_VARIABLE id: 306 - message: "Optional variable is deprecated and no longer supported." \ No newline at end of file + message: "Optional variable is deprecated and no longer supported." + +- name: TYPEOF_IN_ANNOTATION + id: 307 + message: "Result of 'typeof' operator is not supported to be used as type annotation." + +- name: WRONG_LEFT_OF_INSTANCEOF + id: 308 + message: "The left operand of 'instanceof' operator cannot be a type." -- Gitee