diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index f3ad9a385b9c4e0619ab024c454748e9602ecc35..bd0a6ceb9b58027730f2ebde7db6aea0b71936a5 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 c88b813839c23e8add2f6c176521551081589d0f..2f51ebead2ac920669349a8f9eed8f6b0ed44457 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 0000000000000000000000000000000000000000..cb4b9dcc7b05ba006d5618998dd5107762e997e5 --- /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 0000000000000000000000000000000000000000..2ab98e4b5510f88e510b477c9f16a13dacdfec91 --- /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 d18a5f97664b29d5d399fcedacb9e97511b96771..71a315ef06eb33e988f96e4faa60c6af959e421b 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."