From cd9aa767a10565bf4682833d949ee0df48521a07 Mon Sep 17 00:00:00 2001 From: Csaba Hurton Date: Fri, 9 Feb 2024 15:35:18 +0100 Subject: [PATCH 01/13] Fix segfault on duplication of `()` Instead of segfault, SyntaxError is thrown. Update solution of I8Y4D1 (internal issue: 14796) to allow abstract interface methods to have no return type annotation. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I91JUF Testing: - 2 new test cases - updated an expected file of a related compile test - tested on cts-, functional-, runtime tests and regression tests suits Resolve internal issue #15623. Change-Id: I7c2c9646568ab18559b0bdd17b093f0db72f857f Signed-off-by: Csaba Hurton --- ets2panda/parser/ETSparser.cpp | 36 +-- ets2panda/parser/ETSparser.h | 2 - ...ation_setter_supposed_to_fail-expected.txt | 1 + ...sis_invocation_setter_supposed_to_fail.ets | 18 ++ ...s_invocation_supposed_to_fail-expected.txt | 1 + ...arenthesis_invocation_supposed_to_fail.ets | 19 ++ ...ce_abstract_noreturn_function-expected.txt | 279 +++++++++++++++++- 7 files changed, 321 insertions(+), 35 deletions(-) create mode 100644 ets2panda/test/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail-expected.txt create mode 100644 ets2panda/test/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail.ets create mode 100644 ets2panda/test/parser/ets/double_parenthesis_invocation_supposed_to_fail-expected.txt create mode 100644 ets2panda/test/parser/ets/double_parenthesis_invocation_supposed_to_fail.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 64c8dc0a2c..850aa26bc2 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1466,34 +1466,6 @@ ir::ClassProperty *ETSParser::ParseInterfaceField() return field; } -lexer::SourcePosition ETSParser::ParseEndLocInterfaceMethod(lexer::LexerPosition startPos, ir::ScriptFunction *func, - ir::MethodDefinitionKind methodKind) -{ - if (func->HasBody()) { - return func->Body()->End(); - } - - if (func->ReturnTypeAnnotation() == nullptr) { - auto backupPos = Lexer()->Save(); - Lexer()->Rewind(startPos); - - while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { - Lexer()->NextToken(); - } - - auto endLoc = Lexer()->GetToken().End(); - Lexer()->Rewind(backupPos); - - if (methodKind != ir::MethodDefinitionKind::SET) { - ThrowSyntaxError("Interface method must have a return type", endLoc); - } - - return endLoc; - } - - return func->ReturnTypeAnnotation()->End(); -} - ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, ir::MethodDefinitionKind methodKind) { ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); @@ -1504,7 +1476,6 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i FunctionContext functionContext(this, ParserStatus::FUNCTION); lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); - lexer::LexerPosition startPos = Lexer()->Save(); auto [signature, throwMarker] = ParseFunctionSignature(ParserStatus::NEED_RETURN_TYPE); @@ -1538,9 +1509,10 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i if ((flags & ir::ModifierFlags::STATIC) == 0 && body == nullptr) { func->AddModifier(ir::ModifierFlags::ABSTRACT); } - - auto endLoc = ParseEndLocInterfaceMethod(startPos, func, methodKind); - func->SetRange({startLoc, endLoc}); + func->SetRange({startLoc, body != nullptr ? body->End() + : func->ReturnTypeAnnotation() != nullptr ? func->ReturnTypeAnnotation()->End() + : func->Params().empty() ? Lexer()->GetToken().End() + : (*func->Params().end())->End()}); auto *funcExpr = AllocNode(func); funcExpr->SetRange(func->Range()); diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index b01b9c51f9..d37cadf82e 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -161,8 +161,6 @@ private: ir::TypeNode *ParseFunctionReturnType(ParserStatus status) override; ir::ScriptFunctionFlags ParseFunctionThrowMarker(bool isRethrowsAllowed) override; ir::Expression *CreateParameterThis(util::StringView className) override; - lexer::SourcePosition ParseEndLocInterfaceMethod(lexer::LexerPosition startPos, ir::ScriptFunction *func, - ir::MethodDefinitionKind methodKind); ir::TypeNode *ConvertToOptionalUnionType(ir::TypeNode *typeNode); // NOLINTNEXTLINE(google-default-arguments) void ParseClassFieldDefinition(ir::Identifier *fieldName, ir::ModifierFlags modifiers, diff --git a/ets2panda/test/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail-expected.txt b/ets2panda/test/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail-expected.txt new file mode 100644 index 0000000000..20ce10fd5a --- /dev/null +++ b/ets2panda/test/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail-expected.txt @@ -0,0 +1 @@ +SyntaxError: Unexpected token [double_parenthesis_invocation_setter_supposed_to_fail.ets:17:25] diff --git a/ets2panda/test/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail.ets b/ets2panda/test/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail.ets new file mode 100644 index 0000000000..de54a7a367 --- /dev/null +++ b/ets2panda/test/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 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. + */ + +interface Test { + set color(s: string)() +} diff --git a/ets2panda/test/parser/ets/double_parenthesis_invocation_supposed_to_fail-expected.txt b/ets2panda/test/parser/ets/double_parenthesis_invocation_supposed_to_fail-expected.txt new file mode 100644 index 0000000000..50f3d601f4 --- /dev/null +++ b/ets2panda/test/parser/ets/double_parenthesis_invocation_supposed_to_fail-expected.txt @@ -0,0 +1 @@ +SyntaxError: Unexpected token [double_parenthesis_invocation_supposed_to_fail.ets:18:11] diff --git a/ets2panda/test/parser/ets/double_parenthesis_invocation_supposed_to_fail.ets b/ets2panda/test/parser/ets/double_parenthesis_invocation_supposed_to_fail.ets new file mode 100644 index 0000000000..55146bdd7d --- /dev/null +++ b/ets2panda/test/parser/ets/double_parenthesis_invocation_supposed_to_fail.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 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. + */ + +interface Test { + proc() // passes + proc()() // throws SyntaxError +} diff --git a/ets2panda/test/parser/ets/interface_abstract_noreturn_function-expected.txt b/ets2panda/test/parser/ets/interface_abstract_noreturn_function-expected.txt index 385bb8e930..93dec65326 100644 --- a/ets2panda/test/parser/ets/interface_abstract_noreturn_function-expected.txt +++ b/ets2panda/test/parser/ets/interface_abstract_noreturn_function-expected.txt @@ -1 +1,278 @@ -SyntaxError: Interface method must have a return type [interface_abstract_noreturn_function.ets:17:10] +{ + "type": "Program", + "statements": [ + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "declare": true, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 18, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "id": { + "type": "Identifier", + "name": "I", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 19, + "column": 1 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 19, + "column": 1 + } + } +} -- Gitee From e9ec3bc23f94349ab69d7c7f782a7927991e827e Mon Sep 17 00:00:00 2001 From: Gergo Csizi Date: Mon, 12 Feb 2024 10:13:44 +0100 Subject: [PATCH 02/13] Fix using tuple with long indexing Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I91LK1 Internal issue: #15493 Test: new parser test Change-Id: If4a8e1bfaa7eea9b7571551eacf7179c10b4f43f Signed-off-by: Gergo Csizi --- ets2panda/checker/ETSchecker.h | 4 +- ets2panda/checker/ets/object.cpp | 25 +- .../compiler/lowering/ets/tupleLowering.cpp | 4 +- ets2panda/ir/expressions/memberExpression.cpp | 8 +- .../ets/tupleIndexWithLargeInt-expected.txt | 611 +++++++++++++ .../parser/ets/tupleIndexWithLargeInt.ets | 21 + .../ets/tupleIndexWithNumbers-expected.txt | 857 ++++++++++++++++++ .../test/parser/ets/tupleIndexWithNumbers.ets | 24 + 8 files changed, 1543 insertions(+), 11 deletions(-) create mode 100644 ets2panda/test/parser/ets/tupleIndexWithLargeInt-expected.txt create mode 100644 ets2panda/test/parser/ets/tupleIndexWithLargeInt.ets create mode 100644 ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt create mode 100644 ets2panda/test/parser/ets/tupleIndexWithNumbers.ets diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index fd21462dd1..13251995c9 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -149,9 +149,9 @@ public: void ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set *extendsSet, const lexer::SourcePosition &pos); void ResolveDeclaredMembersOfObject(const ETSObjectType *type); - int32_t GetTupleElementAccessValue(const Type *type) const; + int32_t GetTupleElementAccessValue(const Type *type, const lexer::SourcePosition &pos); void ValidateArrayIndex(ir::Expression *expr, bool relaxed = false); - void ValidateTupleIndex(const ETSTupleType *tuple, const ir::MemberExpression *expr); + void ValidateTupleIndex(const ETSTupleType *tuple, ir::MemberExpression *expr); ETSObjectType *CheckThisOrSuperAccess(ir::Expression *node, ETSObjectType *classType, std::string_view msg); void CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type); ETSTypeParameter *SetUpParameterType(ir::TSTypeParameter *param); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 4f945aa89b..21661758cd 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1069,7 +1069,7 @@ void ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) } } -int32_t ETSChecker::GetTupleElementAccessValue(const Type *const type) const +int32_t ETSChecker::GetTupleElementAccessValue(const Type *const type, const lexer::SourcePosition &pos) { ASSERT(type->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_NUMERIC)); @@ -1083,14 +1083,31 @@ int32_t ETSChecker::GetTupleElementAccessValue(const Type *const type) const case TypeFlag::INT: { return type->AsIntType()->GetValue(); } + case TypeFlag::LONG: { + if (auto val = type->AsLongType()->GetValue(); + val <= std::numeric_limits::max() && val >= std::numeric_limits::min()) { + return static_cast(val); + } + + ThrowTypeError("Element accessor value is out of tuple size bounds.", pos); + + break; + } default: { UNREACHABLE(); } } } -void ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, const ir::MemberExpression *const expr) +void ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberExpression *const expr) { + auto *const expressionType = expr->Property()->Check(this); + auto const *const unboxedExpressionType = ETSBuiltinTypeAsPrimitiveType(expressionType); + + if (expressionType->IsETSObjectType() && (unboxedExpressionType != nullptr)) { + expr->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedExpressionType)); + } + const auto *const exprType = expr->Property()->TsType(); ASSERT(exprType != nullptr); @@ -1098,11 +1115,11 @@ void ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, const ir::M ThrowTypeError("Only constant expression allowed for element access on tuples.", expr->Property()->Start()); } - if (!exprType->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX)) { + if (!exprType->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX | TypeFlag::LONG)) { ThrowTypeError("Only integer type allowed for element access on tuples.", expr->Property()->Start()); } - const int32_t exprValue = GetTupleElementAccessValue(exprType); + auto exprValue = GetTupleElementAccessValue(exprType, expr->Property()->Start()); if (((exprValue >= tuple->GetTupleSize()) && !tuple->HasSpreadType()) || (exprValue < 0)) { ThrowTypeError("Element accessor value is out of tuple size bounds.", expr->Property()->Start()); } diff --git a/ets2panda/compiler/lowering/ets/tupleLowering.cpp b/ets2panda/compiler/lowering/ets/tupleLowering.cpp index 78c4f11f0d..2a2d77bb0e 100644 --- a/ets2panda/compiler/lowering/ets/tupleLowering.cpp +++ b/ets2panda/compiler/lowering/ets/tupleLowering.cpp @@ -70,8 +70,8 @@ static ir::Expression *ConvertTupleUpdate(checker::ETSChecker *const checker, ir // -------------- // Compute necessary types and OpaqueTypeNodes - auto *const tupleTypeAtIdx = argumentType->AsETSTupleType()->GetTypeAtIndex( - checker->GetTupleElementAccessValue(argument->AsMemberExpression()->Property()->TsType())); + auto *const tupleTypeAtIdx = argumentType->AsETSTupleType()->GetTypeAtIndex(checker->GetTupleElementAccessValue( + argument->AsMemberExpression()->Property()->TsType(), argument->AsMemberExpression()->Property()->Start())); auto *const tupleElementTypeNode = checker->AllocNode(argumentType->AsETSTupleType()->ElementType()); diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index a81cdae4a7..fc42331da9 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -318,8 +318,8 @@ checker::Type *MemberExpression::CheckTupleAccessMethod(checker::ETSChecker *che { ASSERT(baseType->IsETSTupleType()); - auto *const tupleTypeAtIdx = - baseType->AsETSTupleType()->GetTypeAtIndex(checker->GetTupleElementAccessValue(Property()->TsType())); + auto *const tupleTypeAtIdx = baseType->AsETSTupleType()->GetTypeAtIndex( + checker->GetTupleElementAccessValue(Property()->TsType(), Property()->Start())); if ((!Parent()->IsAssignmentExpression() || Parent()->AsAssignmentExpression()->Left() != this) && (!Parent()->IsUpdateExpression())) { @@ -335,7 +335,9 @@ checker::Type *MemberExpression::CheckTupleAccessMethod(checker::ETSChecker *che checker::Type *MemberExpression::CheckComputed(checker::ETSChecker *checker, checker::Type *baseType) { if (baseType->IsETSArrayType() || baseType->IsETSDynamicType()) { - checker->ValidateArrayIndex(property_); + if (!baseType->IsETSTupleType()) { + checker->ValidateArrayIndex(property_); + } if (baseType->IsETSTupleType()) { checker->ValidateTupleIndex(baseType->AsETSTupleType(), this); diff --git a/ets2panda/test/parser/ets/tupleIndexWithLargeInt-expected.txt b/ets2panda/test/parser/ets/tupleIndexWithLargeInt-expected.txt new file mode 100644 index 0000000000..08fd364eb5 --- /dev/null +++ b/ets2panda/test/parser/ets/tupleIndexWithLargeInt-expected.txt @@ -0,0 +1,611 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "index", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2147483648, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "tuple", + "typeAnnotation": { + "type": "ETSTuple", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 19, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 19, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 19, + "column": 30 + } + } + } + ], + "spreadType": null, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 32 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 12 + } + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 19, + "column": 34 + }, + "end": { + "line": 19, + "column": 35 + } + } + }, + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 19, + "column": 37 + }, + "end": { + "line": 19, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 33 + }, + "end": { + "line": 19, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 39 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 39 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "tuple", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 8 + } + } + }, + "property": { + "type": "Identifier", + "name": "index", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 20, + "column": 18 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 20 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} +TypeError: Element accessor value is out of tuple size bounds. [tupleIndexWithLargeInt.ets:20:9] diff --git a/ets2panda/test/parser/ets/tupleIndexWithLargeInt.ets b/ets2panda/test/parser/ets/tupleIndexWithLargeInt.ets new file mode 100644 index 0000000000..58475e8a90 --- /dev/null +++ b/ets2panda/test/parser/ets/tupleIndexWithLargeInt.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 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. + */ + +const index = 2147483648; + +function main(): void { + let tuple: [number, number] = [0, 0] + tuple[index] = 2; +} diff --git a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt new file mode 100644 index 0000000000..75281d4ec0 --- /dev/null +++ b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt @@ -0,0 +1,857 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "index1", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 18 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "index2", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "tuple", + "typeAnnotation": { + "type": "ETSTuple", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 15 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 15 + }, + "end": { + "line": 20, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 15 + }, + "end": { + "line": 20, + "column": 22 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 23 + }, + "end": { + "line": 20, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 23 + }, + "end": { + "line": 20, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 23 + }, + "end": { + "line": 20, + "column": 30 + } + } + } + ], + "spreadType": null, + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 12 + } + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 35 + } + } + }, + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 20, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 33 + }, + "end": { + "line": 20, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 39 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 39 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "tuple", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 8 + } + } + }, + "property": { + "type": "Identifier", + "name": "index1", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 15 + } + } + }, + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 21, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 21 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "tuple", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 3 + }, + "end": { + "line": 22, + "column": 8 + } + } + }, + "property": { + "type": "Identifier", + "name": "index2", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 15 + } + } + }, + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 3 + }, + "end": { + "line": 22, + "column": 16 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 22, + "column": 19 + }, + "end": { + "line": 22, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 3 + }, + "end": { + "line": 22, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 3 + }, + "end": { + "line": 22, + "column": 21 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "tuple", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 3 + }, + "end": { + "line": 23, + "column": 8 + } + } + }, + "property": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 10 + } + } + }, + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 23, + "column": 3 + }, + "end": { + "line": 23, + "column": 11 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 23, + "column": 14 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 3 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 3 + }, + "end": { + "line": 23, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 25, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/tupleIndexWithNumbers.ets b/ets2panda/test/parser/ets/tupleIndexWithNumbers.ets new file mode 100644 index 0000000000..6e396c94ec --- /dev/null +++ b/ets2panda/test/parser/ets/tupleIndexWithNumbers.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 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. + */ + +const index1: int = 1 +const index2: long = 1 + +function main(): void { + let tuple: [number, number] = [0, 0] + tuple[index1] = 2; + tuple[index2] = 2; + tuple[1] = 2; +} -- Gitee From 4b221c82947a1e121ee7b5713efef6f966cd583a Mon Sep 17 00:00:00 2001 From: Vivien Voros Date: Wed, 21 Feb 2024 10:01:27 +0100 Subject: [PATCH 03/13] Incorrect boxing and verifier error on implicit boxing conversion Solve boxing converson from long to Float and Double. Support conversion from byte to char. Solve the verifier error on implicit boxing conversion. Fixes internal issue #15660 Fixes internal issue #15749 Fixes internal issue #15752 Change-Id: I7d33ce00b1607fac075c78f76a5f5a3104294640 Signed-off-by: Vivien Voros --- ets2panda/checker/ets/wideningConverter.h | 6 +- ets2panda/checker/types/ets/charType.cpp | 6 +- ets2panda/checker/types/typeFlag.h | 1 + ets2panda/compiler/core/ETSGen.cpp | 48 + ets2panda/compiler/core/ETSGen.h | 1 + .../ets/boxingConversion10-expected.txt | 393 ++++++ .../test/compiler/ets/boxingConversion10.ets | 17 + .../ets/boxingConversion5-expected.txt | 661 ++++++++++ .../test/compiler/ets/boxingConversion5.ets | 19 + .../ets/boxingConversion6-expected.txt | 1063 +++++++++++++++++ .../test/compiler/ets/boxingConversion6.ets | 22 + .../ets/boxingConversion7-expected.txt | 795 ++++++++++++ .../test/compiler/ets/boxingConversion7.ets | 20 + .../ets/boxingConversion8-expected.txt | 795 ++++++++++++ .../test/compiler/ets/boxingConversion8.ets | 20 + .../ets/boxingConversion9-expected.txt | 527 ++++++++ .../test/compiler/ets/boxingConversion9.ets | 18 + .../test/parser/ets/conversions-expected.txt | 556 +++++++++ ets2panda/test/parser/ets/conversions.ets | 23 + .../test/runtime/ets/boxingConversions.ets | 20 + .../test/runtime/ets/boxingConversions2.ets | 21 + .../test/runtime/ets/boxingConversions3.ets | 31 + .../test/runtime/ets/boxingConversions4.ets | 27 + .../test/runtime/ets/boxingConversions5.ets | 25 + 24 files changed, 5111 insertions(+), 4 deletions(-) create mode 100644 ets2panda/test/compiler/ets/boxingConversion10-expected.txt create mode 100644 ets2panda/test/compiler/ets/boxingConversion10.ets create mode 100644 ets2panda/test/compiler/ets/boxingConversion5-expected.txt create mode 100644 ets2panda/test/compiler/ets/boxingConversion5.ets create mode 100644 ets2panda/test/compiler/ets/boxingConversion6-expected.txt create mode 100644 ets2panda/test/compiler/ets/boxingConversion6.ets create mode 100644 ets2panda/test/compiler/ets/boxingConversion7-expected.txt create mode 100644 ets2panda/test/compiler/ets/boxingConversion7.ets create mode 100644 ets2panda/test/compiler/ets/boxingConversion8-expected.txt create mode 100644 ets2panda/test/compiler/ets/boxingConversion8.ets create mode 100644 ets2panda/test/compiler/ets/boxingConversion9-expected.txt create mode 100644 ets2panda/test/compiler/ets/boxingConversion9.ets create mode 100644 ets2panda/test/parser/ets/conversions-expected.txt create mode 100644 ets2panda/test/parser/ets/conversions.ets create mode 100644 ets2panda/test/runtime/ets/boxingConversions.ets create mode 100644 ets2panda/test/runtime/ets/boxingConversions2.ets create mode 100644 ets2panda/test/runtime/ets/boxingConversions3.ets create mode 100644 ets2panda/test/runtime/ets/boxingConversions4.ets create mode 100644 ets2panda/test/runtime/ets/boxingConversions5.ets diff --git a/ets2panda/checker/ets/wideningConverter.h b/ets2panda/checker/ets/wideningConverter.h index fc02acc57c..667a1268da 100644 --- a/ets2panda/checker/ets/wideningConverter.h +++ b/ets2panda/checker/ets/wideningConverter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2024 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 @@ -70,6 +70,10 @@ private: void ApplyGlobalWidening() { switch (ETSChecker::ETSChecker::ETSType(Target())) { + case TypeFlag::CHAR: { + ApplyGlobalWidening(TypeFlag::WIDENABLE_TO_CHAR); + break; + } case TypeFlag::SHORT: { ApplyGlobalWidening(TypeFlag::WIDENABLE_TO_SHORT); break; diff --git a/ets2panda/checker/types/ets/charType.cpp b/ets2panda/checker/types/ets/charType.cpp index af5f073a65..6e38ac62c4 100644 --- a/ets2panda/checker/types/ets/charType.cpp +++ b/ets2panda/checker/types/ets/charType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2024 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 @@ -16,7 +16,7 @@ #include "charType.h" #include "checker/ets/conversion.h" -#include "checker/ets/narrowingConverter.h" +#include "checker/ets/narrowingWideningConverter.h" namespace ark::es2panda::checker { void CharType::Identical(TypeRelation *relation, Type *other) @@ -31,7 +31,7 @@ void CharType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *s if (relation->ApplyUnboxing()) { relation->GetChecker()->AsETSChecker()->AddUnboxingFlagToPrimitiveType(relation, source, this); } - NarrowingConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); + NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } bool CharType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) diff --git a/ets2panda/checker/types/typeFlag.h b/ets2panda/checker/types/typeFlag.h index 7f90671517..54f6541d5f 100644 --- a/ets2panda/checker/types/typeFlag.h +++ b/ets2panda/checker/types/typeFlag.h @@ -105,6 +105,7 @@ enum class TypeFlag : uint64_t { NARROWABLE_TO_SHORT = CHAR | INT | NARROWABLE_TO_INT, NARROWABLE_TO_BYTE = CHAR | NARROWABLE_TO_CHAR, WIDENABLE_TO_SHORT = BYTE, + WIDENABLE_TO_CHAR = BYTE, WIDENABLE_TO_INT = CHAR | SHORT | WIDENABLE_TO_SHORT, WIDENABLE_TO_LONG = INT | WIDENABLE_TO_INT, WIDENABLE_TO_FLOAT = LONG | WIDENABLE_TO_LONG, diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index d000ebdbcc..ec269411c3 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -1154,6 +1154,31 @@ void ETSGen::ApplyCast(const ir::AstNode *node, const checker::Type *targetType) } } +void ETSGen::ApplyCastToBoxingFlags(const ir::AstNode *node, const ir::BoxingUnboxingFlags targetType) +{ + switch (targetType) { + case ir::BoxingUnboxingFlags::BOX_TO_DOUBLE: { + CastToDouble(node); + break; + } + case ir::BoxingUnboxingFlags::BOX_TO_FLOAT: { + CastToFloat(node); + break; + } + case ir::BoxingUnboxingFlags::BOX_TO_LONG: { + CastToLong(node); + break; + } + case ir::BoxingUnboxingFlags::BOX_TO_INT: { + CastToInt(node); + break; + } + default: { + break; + } + } +} + void ETSGen::EmitUnboxedCall(const ir::AstNode *node, std::string_view signatureFlag, const checker::Type *const targetType, const checker::Type *const boxedType) { @@ -1225,6 +1250,8 @@ void ETSGen::EmitBoxingConversion(const ir::AstNode *node) RegScope rs(this); + ApplyCastToBoxingFlags(node, boxingFlag); + switch (boxingFlag) { case ir::BoxingUnboxingFlags::BOX_TO_BOOLEAN: { Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_VALUE_OF, dummyReg_, 0); @@ -1523,6 +1550,9 @@ void ETSGen::CastToByte([[maybe_unused]] const ir::AstNode *node) Sa().Emit(node); break; } + case checker::TypeFlag::ETS_OBJECT: { + break; + } default: { UNREACHABLE(); } @@ -1567,6 +1597,9 @@ void ETSGen::CastToChar([[maybe_unused]] const ir::AstNode *node) Sa().Emit(node); break; } + case checker::TypeFlag::ETS_OBJECT: { + break; + } default: { UNREACHABLE(); } @@ -1614,6 +1647,9 @@ void ETSGen::CastToShort([[maybe_unused]] const ir::AstNode *node) Sa().Emit(node); break; } + case checker::TypeFlag::ETS_OBJECT: { + break; + } default: { UNREACHABLE(); } @@ -1648,6 +1684,9 @@ void ETSGen::CastToDouble(const ir::AstNode *node) Sa().Emit(node); break; } + case checker::TypeFlag::ETS_OBJECT: { + break; + } case checker::TypeFlag::ETS_DYNAMIC_TYPE: { CastDynamicTo(node, checker::TypeFlag::DOUBLE); ASSERT(GetAccumulatorType() == Checker()->GlobalDoubleType()); @@ -1692,6 +1731,9 @@ void ETSGen::CastToFloat(const ir::AstNode *node) Sa().Emit(node); break; } + case checker::TypeFlag::ETS_OBJECT: { + break; + } default: { UNREACHABLE(); } @@ -1731,6 +1773,9 @@ void ETSGen::CastToLong(const ir::AstNode *node) Sa().Emit(node); break; } + case checker::TypeFlag::ETS_OBJECT: { + break; + } default: { UNREACHABLE(); } @@ -1771,6 +1816,9 @@ void ETSGen::CastToInt(const ir::AstNode *node) Sa().Emit(node); break; } + case checker::TypeFlag::ETS_OBJECT: { + break; + } default: { UNREACHABLE(); } diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index b06ec78733..3b0df38dd1 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -388,6 +388,7 @@ public: void ApplyConversionCast(const ir::AstNode *node, const checker::Type *targetType); void ApplyConversion(const ir::AstNode *node, const checker::Type *targetType); void ApplyCast(const ir::AstNode *node, const checker::Type *targetType); + void ApplyCastToBoxingFlags(const ir::AstNode *node, const ir::BoxingUnboxingFlags targetType); void EmitUnboxingConversion(const ir::AstNode *node); void EmitBoxingConversion(const ir::AstNode *node); void SwapBinaryOpArgs(const ir::AstNode *node, VReg lhs); diff --git a/ets2panda/test/compiler/ets/boxingConversion10-expected.txt b/ets2panda/test/compiler/ets/boxingConversion10-expected.txt new file mode 100644 index 0000000000..d98e8464d8 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion10-expected.txt @@ -0,0 +1,393 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 18, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/boxingConversion10.ets b/ets2panda/test/compiler/ets/boxingConversion10.ets new file mode 100644 index 0000000000..dd7ab35c09 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion10.ets @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 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 f: float = 0 +let d: Double = f diff --git a/ets2panda/test/compiler/ets/boxingConversion5-expected.txt b/ets2panda/test/compiler/ets/boxingConversion5-expected.txt new file mode 100644 index 0000000000..6a014d9448 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion5-expected.txt @@ -0,0 +1,661 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 17 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Long", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Float", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 16 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 20, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/boxingConversion5.ets b/ets2panda/test/compiler/ets/boxingConversion5.ets new file mode 100644 index 0000000000..3dffd07ea7 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion5.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 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 i: int = 1 +let s: Long = i +let f: Float = i +let d: Double = i diff --git a/ets2panda/test/compiler/ets/boxingConversion6-expected.txt b/ets2panda/test/compiler/ets/boxingConversion6-expected.txt new file mode 100644 index 0000000000..75236298dc --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion6-expected.txt @@ -0,0 +1,1063 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 19, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 16 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 17 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 15 + }, + "end": { + "line": 22, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 22, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Short", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Long", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Float", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8 + }, + "end": { + "line": 21, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 8 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 8 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Char", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 8 + }, + "end": { + "line": 22, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 23, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/boxingConversion6.ets b/ets2panda/test/compiler/ets/boxingConversion6.ets new file mode 100644 index 0000000000..53de11807a --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion6.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 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 b: byte = 0 +let s: Short = b +let i: Int = b +let l: Long = b +let f: Float = b +let d: Double = b +let c: Char = b diff --git a/ets2panda/test/compiler/ets/boxingConversion7-expected.txt b/ets2panda/test/compiler/ets/boxingConversion7-expected.txt new file mode 100644 index 0000000000..871abeb111 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion7-expected.txt @@ -0,0 +1,795 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "CharLiteral", + "value": "a", + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 16 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Long", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Float", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/boxingConversion7.ets b/ets2panda/test/compiler/ets/boxingConversion7.ets new file mode 100644 index 0000000000..49f3bfd890 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion7.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 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 c: char = c'a' +let i: Int = c +let l: Long = c +let f: Float = c +let d: Double = c diff --git a/ets2panda/test/compiler/ets/boxingConversion8-expected.txt b/ets2panda/test/compiler/ets/boxingConversion8-expected.txt new file mode 100644 index 0000000000..5dc1ed2966 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion8-expected.txt @@ -0,0 +1,795 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 16 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Long", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Float", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/boxingConversion8.ets b/ets2panda/test/compiler/ets/boxingConversion8.ets new file mode 100644 index 0000000000..fa8ed17b83 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion8.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 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 s: short = 2 +let i: Int = s +let l: Long = s +let f: Float = s +let d: Double = s diff --git a/ets2panda/test/compiler/ets/boxingConversion9-expected.txt b/ets2panda/test/compiler/ets/boxingConversion9-expected.txt new file mode 100644 index 0000000000..7aef561a49 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion9-expected.txt @@ -0,0 +1,527 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "right": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "l", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Float", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 19, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/boxingConversion9.ets b/ets2panda/test/compiler/ets/boxingConversion9.ets new file mode 100644 index 0000000000..1ead7fdb02 --- /dev/null +++ b/ets2panda/test/compiler/ets/boxingConversion9.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 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 l: long = 0 +let f: Float = l +let d: Double = l diff --git a/ets2panda/test/parser/ets/conversions-expected.txt b/ets2panda/test/parser/ets/conversions-expected.txt new file mode 100644 index 0000000000..017c717b8d --- /dev/null +++ b/ets2panda/test/parser/ets/conversions-expected.txt @@ -0,0 +1,556 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "s", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 10 + } + } + }, + "init": { + "type": "TSAsExpression", + "expression": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 20 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "d", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 10 + } + } + }, + "init": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 20 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "operator": "!=", + "left": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 10 + } + } + }, + "right": { + "type": "CharLiteral", + "value": "", + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 20, + "column": 16 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 25 + }, + "end": { + "line": 21, + "column": 6 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 21, + "column": 6 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 22, + "column": 12 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 23, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/conversions.ets b/ets2panda/test/parser/ets/conversions.ets new file mode 100644 index 0000000000..3b70a253c6 --- /dev/null +++ b/ets2panda/test/parser/ets/conversions.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 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. + */ + +function main(): int { + let s: byte = 0 as byte + let d: char = s + if (d != c'\u0000') { + return 1; + } + return 0; +} diff --git a/ets2panda/test/runtime/ets/boxingConversions.ets b/ets2panda/test/runtime/ets/boxingConversions.ets new file mode 100644 index 0000000000..84ec2215f5 --- /dev/null +++ b/ets2panda/test/runtime/ets/boxingConversions.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 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. + */ + +function main() { + let s: long = 1 + let d: Double = s + assert(d.unboxed() == 1.0) +} diff --git a/ets2panda/test/runtime/ets/boxingConversions2.ets b/ets2panda/test/runtime/ets/boxingConversions2.ets new file mode 100644 index 0000000000..df3ccd70c7 --- /dev/null +++ b/ets2panda/test/runtime/ets/boxingConversions2.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 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. + */ + +function main() { + let s1: int = 0 + let d1: Float = s1 + assert(d1.unboxed() == 0.0) +} + diff --git a/ets2panda/test/runtime/ets/boxingConversions3.ets b/ets2panda/test/runtime/ets/boxingConversions3.ets new file mode 100644 index 0000000000..ea605e66c4 --- /dev/null +++ b/ets2panda/test/runtime/ets/boxingConversions3.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 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. + */ + +function main() { + let b: byte = 1.0 + let s: Short = b + let i: Int = b + let l: Long = b + let f: Float = b + let d: Double = b + let c: Char = b + assert(s.unboxed() == 1.0) + assert(i.unboxed() == 1.0) + assert(l.unboxed() == 1.0) + assert(f.unboxed() == 1.0) + assert(d.unboxed() == 1.0) + assert(c.unboxed() == 1.0) +} + diff --git a/ets2panda/test/runtime/ets/boxingConversions4.ets b/ets2panda/test/runtime/ets/boxingConversions4.ets new file mode 100644 index 0000000000..20742c3c6a --- /dev/null +++ b/ets2panda/test/runtime/ets/boxingConversions4.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 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. + */ + +function main() { + let c: char = c'a' + let i: Int = c + let l: Long = c + let f: Float = c + let d: Double = c + assert(i.unboxed() == 97) + assert(l.unboxed() == 97) + assert(f.unboxed() == 97.0) + assert(d.unboxed() == 97.0) +} + diff --git a/ets2panda/test/runtime/ets/boxingConversions5.ets b/ets2panda/test/runtime/ets/boxingConversions5.ets new file mode 100644 index 0000000000..91ce9168a2 --- /dev/null +++ b/ets2panda/test/runtime/ets/boxingConversions5.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 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. + */ + +function main() { + let i: int = 1 + let l: Long = i + let f: Float = i + let d: Double = i + + assert(l.unboxed() == 1) + assert(f.unboxed() == 1.0) + assert(d.unboxed() == 1.0) +} -- Gitee From a63746f1d6fcc1e71683645b6afaf7c9c4440b46 Mon Sep 17 00:00:00 2001 From: Csaba Osztrogonac Date: Mon, 11 Mar 2024 08:00:04 +0100 Subject: [PATCH 04/13] Update expected files after void refactoring and line-info fix Change-Id: I32b58ae23bf66d5857248d80e018ccc074a4b6b7 Signed-off-by: Csaba Osztrogonac --- .../ets/boxingConversion10-expected.txt | 8 ++--- .../ets/boxingConversion5-expected.txt | 16 +++++----- .../ets/boxingConversion6-expected.txt | 28 ++++++++-------- .../ets/boxingConversion7-expected.txt | 20 ++++++------ .../ets/boxingConversion8-expected.txt | 20 ++++++------ .../ets/boxingConversion9-expected.txt | 12 +++---- .../ets/tupleIndexWithLargeInt-expected.txt | 32 ++----------------- .../ets/tupleIndexWithNumbers-expected.txt | 32 ++----------------- 8 files changed, 56 insertions(+), 112 deletions(-) diff --git a/ets2panda/test/compiler/ets/boxingConversion10-expected.txt b/ets2panda/test/compiler/ets/boxingConversion10-expected.txt index d98e8464d8..305e19af47 100644 --- a/ets2panda/test/compiler/ets/boxingConversion10-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion10-expected.txt @@ -118,7 +118,7 @@ "loc": { "start": { "line": 16, - "column": 1 + "column": 5 }, "end": { "line": 16, @@ -175,7 +175,7 @@ "loc": { "start": { "line": 17, - "column": 1 + "column": 5 }, "end": { "line": 17, @@ -275,7 +275,7 @@ }, "end": { "line": 16, - "column": 13 + "column": 17 } } }, @@ -352,7 +352,7 @@ }, "end": { "line": 17, - "column": 16 + "column": 18 } } } diff --git a/ets2panda/test/compiler/ets/boxingConversion5-expected.txt b/ets2panda/test/compiler/ets/boxingConversion5-expected.txt index 6a014d9448..23d54930c8 100644 --- a/ets2panda/test/compiler/ets/boxingConversion5-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion5-expected.txt @@ -118,7 +118,7 @@ "loc": { "start": { "line": 16, - "column": 1 + "column": 5 }, "end": { "line": 16, @@ -175,7 +175,7 @@ "loc": { "start": { "line": 17, - "column": 1 + "column": 5 }, "end": { "line": 17, @@ -232,7 +232,7 @@ "loc": { "start": { "line": 18, - "column": 1 + "column": 5 }, "end": { "line": 18, @@ -289,7 +289,7 @@ "loc": { "start": { "line": 19, - "column": 1 + "column": 5 }, "end": { "line": 19, @@ -389,7 +389,7 @@ }, "end": { "line": 16, - "column": 11 + "column": 15 } } }, @@ -466,7 +466,7 @@ }, "end": { "line": 17, - "column": 14 + "column": 16 } } }, @@ -543,7 +543,7 @@ }, "end": { "line": 18, - "column": 15 + "column": 17 } } }, @@ -620,7 +620,7 @@ }, "end": { "line": 19, - "column": 16 + "column": 18 } } } diff --git a/ets2panda/test/compiler/ets/boxingConversion6-expected.txt b/ets2panda/test/compiler/ets/boxingConversion6-expected.txt index 75236298dc..28d3661654 100644 --- a/ets2panda/test/compiler/ets/boxingConversion6-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion6-expected.txt @@ -118,7 +118,7 @@ "loc": { "start": { "line": 16, - "column": 1 + "column": 5 }, "end": { "line": 16, @@ -175,7 +175,7 @@ "loc": { "start": { "line": 17, - "column": 1 + "column": 5 }, "end": { "line": 17, @@ -232,7 +232,7 @@ "loc": { "start": { "line": 18, - "column": 1 + "column": 5 }, "end": { "line": 18, @@ -289,7 +289,7 @@ "loc": { "start": { "line": 19, - "column": 1 + "column": 5 }, "end": { "line": 19, @@ -346,7 +346,7 @@ "loc": { "start": { "line": 20, - "column": 1 + "column": 5 }, "end": { "line": 20, @@ -403,7 +403,7 @@ "loc": { "start": { "line": 21, - "column": 1 + "column": 5 }, "end": { "line": 21, @@ -460,7 +460,7 @@ "loc": { "start": { "line": 22, - "column": 1 + "column": 5 }, "end": { "line": 22, @@ -560,7 +560,7 @@ }, "end": { "line": 16, - "column": 12 + "column": 16 } } }, @@ -637,7 +637,7 @@ }, "end": { "line": 17, - "column": 15 + "column": 17 } } }, @@ -714,7 +714,7 @@ }, "end": { "line": 18, - "column": 13 + "column": 15 } } }, @@ -791,7 +791,7 @@ }, "end": { "line": 19, - "column": 14 + "column": 16 } } }, @@ -868,7 +868,7 @@ }, "end": { "line": 20, - "column": 15 + "column": 17 } } }, @@ -945,7 +945,7 @@ }, "end": { "line": 21, - "column": 16 + "column": 18 } } }, @@ -1022,7 +1022,7 @@ }, "end": { "line": 22, - "column": 14 + "column": 16 } } } diff --git a/ets2panda/test/compiler/ets/boxingConversion7-expected.txt b/ets2panda/test/compiler/ets/boxingConversion7-expected.txt index 871abeb111..0dbd157105 100644 --- a/ets2panda/test/compiler/ets/boxingConversion7-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion7-expected.txt @@ -118,7 +118,7 @@ "loc": { "start": { "line": 16, - "column": 1 + "column": 5 }, "end": { "line": 16, @@ -175,7 +175,7 @@ "loc": { "start": { "line": 17, - "column": 1 + "column": 5 }, "end": { "line": 17, @@ -232,7 +232,7 @@ "loc": { "start": { "line": 18, - "column": 1 + "column": 5 }, "end": { "line": 18, @@ -289,7 +289,7 @@ "loc": { "start": { "line": 19, - "column": 1 + "column": 5 }, "end": { "line": 19, @@ -346,7 +346,7 @@ "loc": { "start": { "line": 20, - "column": 1 + "column": 5 }, "end": { "line": 20, @@ -446,7 +446,7 @@ }, "end": { "line": 16, - "column": 12 + "column": 19 } } }, @@ -523,7 +523,7 @@ }, "end": { "line": 17, - "column": 13 + "column": 15 } } }, @@ -600,7 +600,7 @@ }, "end": { "line": 18, - "column": 14 + "column": 16 } } }, @@ -677,7 +677,7 @@ }, "end": { "line": 19, - "column": 15 + "column": 17 } } }, @@ -754,7 +754,7 @@ }, "end": { "line": 20, - "column": 16 + "column": 18 } } } diff --git a/ets2panda/test/compiler/ets/boxingConversion8-expected.txt b/ets2panda/test/compiler/ets/boxingConversion8-expected.txt index 5dc1ed2966..b88cf9cea5 100644 --- a/ets2panda/test/compiler/ets/boxingConversion8-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion8-expected.txt @@ -118,7 +118,7 @@ "loc": { "start": { "line": 16, - "column": 1 + "column": 5 }, "end": { "line": 16, @@ -175,7 +175,7 @@ "loc": { "start": { "line": 17, - "column": 1 + "column": 5 }, "end": { "line": 17, @@ -232,7 +232,7 @@ "loc": { "start": { "line": 18, - "column": 1 + "column": 5 }, "end": { "line": 18, @@ -289,7 +289,7 @@ "loc": { "start": { "line": 19, - "column": 1 + "column": 5 }, "end": { "line": 19, @@ -346,7 +346,7 @@ "loc": { "start": { "line": 20, - "column": 1 + "column": 5 }, "end": { "line": 20, @@ -446,7 +446,7 @@ }, "end": { "line": 16, - "column": 13 + "column": 17 } } }, @@ -523,7 +523,7 @@ }, "end": { "line": 17, - "column": 13 + "column": 15 } } }, @@ -600,7 +600,7 @@ }, "end": { "line": 18, - "column": 14 + "column": 16 } } }, @@ -677,7 +677,7 @@ }, "end": { "line": 19, - "column": 15 + "column": 17 } } }, @@ -754,7 +754,7 @@ }, "end": { "line": 20, - "column": 16 + "column": 18 } } } diff --git a/ets2panda/test/compiler/ets/boxingConversion9-expected.txt b/ets2panda/test/compiler/ets/boxingConversion9-expected.txt index 7aef561a49..ac8bfdfce8 100644 --- a/ets2panda/test/compiler/ets/boxingConversion9-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion9-expected.txt @@ -118,7 +118,7 @@ "loc": { "start": { "line": 16, - "column": 1 + "column": 5 }, "end": { "line": 16, @@ -175,7 +175,7 @@ "loc": { "start": { "line": 17, - "column": 1 + "column": 5 }, "end": { "line": 17, @@ -232,7 +232,7 @@ "loc": { "start": { "line": 18, - "column": 1 + "column": 5 }, "end": { "line": 18, @@ -332,7 +332,7 @@ }, "end": { "line": 16, - "column": 12 + "column": 16 } } }, @@ -409,7 +409,7 @@ }, "end": { "line": 17, - "column": 15 + "column": 17 } } }, @@ -486,7 +486,7 @@ }, "end": { "line": 18, - "column": 16 + "column": 18 } } } diff --git a/ets2panda/test/parser/ets/tupleIndexWithLargeInt-expected.txt b/ets2panda/test/parser/ets/tupleIndexWithLargeInt-expected.txt index 08fd364eb5..a98abacd94 100644 --- a/ets2panda/test/parser/ets/tupleIndexWithLargeInt-expected.txt +++ b/ets2panda/test/parser/ets/tupleIndexWithLargeInt-expected.txt @@ -212,35 +212,7 @@ "expression": false, "params": [], "returnType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "void", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 18 - }, - "end": { - "line": 18, - "column": 22 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 18 - }, - "end": { - "line": 18, - "column": 24 - } - } - }, + "type": "ETSPrimitiveType", "loc": { "start": { "line": 18, @@ -248,7 +220,7 @@ }, "end": { "line": 18, - "column": 24 + "column": 22 } } }, diff --git a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt index 75281d4ec0..bfebac37fb 100644 --- a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt +++ b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt @@ -288,35 +288,7 @@ "expression": false, "params": [], "returnType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "void", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 18 - }, - "end": { - "line": 19, - "column": 22 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 18 - }, - "end": { - "line": 19, - "column": 24 - } - } - }, + "type": "ETSPrimitiveType", "loc": { "start": { "line": 19, @@ -324,7 +296,7 @@ }, "end": { "line": 19, - "column": 24 + "column": 22 } } }, -- Gitee From eaa8e6f02b39a189c2713f785cf29e160730c286 Mon Sep 17 00:00:00 2001 From: Robert Sipka Date: Wed, 6 Mar 2024 12:31:49 +0100 Subject: [PATCH 05/13] [ArkTs] Refactor import path handling and parse sources methods Refactoring the path resolver methods for import paths Remove unused methods which remained from previous path handling/resolving Eliminate circular source parsing Simplify the current path handler in the importPathManager class Signed-off-by: Robert Sipka Accept-Changeset: 12935:fe:1986:rt:0 --- ets2panda/BUILD.gn | 2 +- ets2panda/CMakeLists.txt | 2 +- ets2panda/checker/ETSAnalyzer.cpp | 2 +- ets2panda/checker/ets/helpers.cpp | 2 +- .../ets/topLevelStmts/importExportDecls.cpp | 6 +- .../ets/topLevelStmts/importExportDecls.h | 2 +- ets2panda/parser/ETSparser.cpp | 65 ++-- ets2panda/parser/ETSparser.h | 20 +- ets2panda/util/helpers.cpp | 88 +---- ets2panda/util/helpers.h | 10 +- ...{pathHandler.cpp => importPathManager.cpp} | 330 +++++++++--------- ets2panda/util/importPathManager.h | 87 +++++ ets2panda/util/pathHandler.h | 200 ----------- ets2panda/varbinder/ETSBinder.cpp | 2 +- ets2panda/varbinder/ETSBinder.h | 20 +- 15 files changed, 335 insertions(+), 503 deletions(-) rename ets2panda/util/{pathHandler.cpp => importPathManager.cpp} (31%) create mode 100644 ets2panda/util/importPathManager.h delete mode 100644 ets2panda/util/pathHandler.h diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 1ff9bd5d16..1ab4045678 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -375,8 +375,8 @@ libes2panda_sources = [ "util/bitset.cpp", "util/errorHandler.cpp", "util/helpers.cpp", + "util/importPathManager.cpp", "util/path.cpp", - "util/pathHandler.cpp", "util/plugin.cpp", "util/ustring.cpp", "varbinder/ASBinder.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 764781d68c..3fe5b5afef 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -453,8 +453,8 @@ set(ES2PANDA_LIB_SRC util/bitset.cpp util/errorHandler.cpp util/helpers.cpp + util/importPathManager.cpp util/path.cpp - util/pathHandler.cpp util/ustring.cpp test/utils/panda_executable_path_getter.cpp ) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index b700a4b1c0..489dbee2b5 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1571,7 +1571,7 @@ checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const return type; } - auto [moduleName, isPackageModule] = checker->VarBinder()->AsETSBinder()->GetModuleNameFromSource(importPath); + auto [moduleName, isPackageModule] = checker->VarBinder()->AsETSBinder()->GetModuleInfo(importPath); std::vector syntheticNames = checker->GetNameForSynteticObjectType(moduleName); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 42584966af..ec52dab75d 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1491,7 +1491,7 @@ void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjT auto *etsBinder = static_cast(VarBinder()); auto extRecords = etsBinder->GetGlobalRecordTable()->Program()->ExternalSources(); - auto [name, isPackageModule] = etsBinder->GetModuleNameFromSource(importPath); + auto [name, isPackageModule] = etsBinder->GetModuleInfo(importPath); auto res = extRecords.find(name); ASSERT(res != extRecords.end()); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp index 3a75d17ee5..eb13cef95e 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp @@ -15,14 +15,14 @@ #include "compiler/lowering/ets/topLevelStmts/importExportDecls.h" #include "ir/ets/etsReExportDeclaration.h" +#include "util/importPathManager.h" namespace ark::es2panda::compiler { void ImportExportDecls::ParseDefaultSources() { - auto imports = - parser_->ParseDefaultSources(DEFAULT_IMPORT_SOURCE_FILE, defaultImportSource_, util::PathHandler::StdLib()); - varbinder_->FillSourceList(parser_->GetPathes()); + auto imports = parser_->ParseDefaultSources(DEFAULT_IMPORT_SOURCE_FILE, defaultImportSource_); + varbinder_->SetModuleList(parser_->ModuleList()); varbinder_->SetDefaultImports(std::move(imports)); } diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h index 1bcead43e3..950558ea54 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h @@ -37,7 +37,7 @@ class ImportExportDecls : ir::visitor::EmptyAstVisitor { return importStdlibFile; } - const std::string defaultImportSource_ = CreateDefaultImportSource(util::PathHandler::StdLib()); + const std::string defaultImportSource_ = CreateDefaultImportSource(util::Helpers::StdLib()); public: ImportExportDecls() = default; diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 850aa26bc2..2521168da7 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -153,7 +153,9 @@ void ETSParser::ParseProgram(ScriptKind kind) statements.emplace_back(decl); } auto script = ParseETSGlobalScript(startLoc, statements); - GetProgram()->VarBinder()->AsETSBinder()->FillSourceList(this->GetPathes()); + + AddExternalSource(ParseSources()); + GetProgram()->VarBinder()->AsETSBinder()->SetModuleList(this->ModuleList()); GetProgram()->SetAst(script); } @@ -165,8 +167,6 @@ ir::ETSScript *ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, A auto topLevelStatements = ParseTopLevelDeclaration(); statements.insert(statements.end(), topLevelStatements.begin(), topLevelStatements.end()); - AddExternalSource(ParseSources(pathHandler_->GetParseList())); - auto *etsScript = AllocNode(Allocator(), std::move(statements), GetProgram()); etsScript->SetRange({startLoc, Lexer()->GetToken().End()}); return etsScript; @@ -187,8 +187,7 @@ void ETSParser::AddExternalSource(const std::vector &programs) } ArenaVector ETSParser::ParseDefaultSources(std::string_view srcFile, - std::string_view importSrc, - const std::vector &paths) + std::string_view importSrc) { auto isp = InnerSourceParser(this); SourceFile source(srcFile, importSrc); @@ -200,33 +199,35 @@ ArenaVector ETSParser::ParseDefaultSources(std::stri auto statements = ParseImportDeclarations(); GetContext().Status() &= ~ParserStatus::IN_DEFAULT_IMPORTS; - pathHandler_->CollectDefaultSources(paths); - AddExternalSource(ParseSources(pathHandler_->GetParseList())); + AddExternalSource(ParseSources()); return statements; } -std::vector ETSParser::ParseSources(const ArenaVector &paths) +std::vector ETSParser::ParseSources() { std::vector programs; - for (const auto &path : paths) { - pathHandler_->MarkAsParsed(path); - } + auto &parseList = importPathManager_->ParseList(); - for (const auto &path : paths) { - std::ifstream inputStream(path.Mutf8()); - - const auto data = pathHandler_->GetImportData(path, Extension()); + // This parse list `paths` can grow in the meantime, so keep this index-based iteration + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t idx = 0; idx < parseList.size(); idx++) { + // check if already parsed + if (parseList[idx].isParsed) { + continue; + } + std::ifstream inputStream(parseList[idx].sourcePath.Mutf8()); + const auto data = importPathManager_->GetImportData(parseList[idx].sourcePath, Extension()); if (!data.hasDecl) { continue; } - if (GetProgram()->SourceFilePath().Is(path.Mutf8())) { + if (GetProgram()->SourceFilePath().Is(parseList[idx].sourcePath.Mutf8())) { break; } if (inputStream.fail()) { - ThrowSyntaxError({"Failed to open file: ", path.Mutf8()}); + ThrowSyntaxError({"Failed to open file: ", parseList[idx].sourcePath.Mutf8()}); } std::stringstream ss; @@ -235,16 +236,19 @@ std::vector ETSParser::ParseSources(const ArenaVectorNew(externalSource, Allocator()); - pathHandler_->MarkAsParsed(path); - auto newProg = ParseSource({path.Utf8(), extSrc->View().Utf8(), path.Utf8(), false}); + auto newProg = ParseSource( + {parseList[idx].sourcePath.Utf8(), extSrc->View().Utf8(), parseList[idx].sourcePath.Utf8(), false}); + programs.emplace_back(newProg); GetContext().SetLanguage(currentLang); } + return programs; } parser::Program *ETSParser::ParseSource(const SourceFile &sourceFile) { + importPathManager_->MarkAsParsed(sourceFile.filePath); auto *program = Allocator()->New(Allocator(), GetProgram()->VarBinder()); auto esp = ExternalSourceParser(this, program); auto lexer = InitLexer(sourceFile); @@ -2339,11 +2343,13 @@ ir::ETSPackageDeclaration *ETSParser::ParsePackageDeclaration() if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_PACKAGE) { if (!IsETSModule() && GetProgram()->IsEntryPoint()) { - pathHandler_->SetModuleName(GetProgram()->AbsoluteName(), util::StringView(""), false); + // NOTE(rsipka): consider adding a filename name as module name to entry points as well + importPathManager_->InsertModuleInfo(GetProgram()->AbsoluteName(), + util::ImportPathManager::ModuleInfo {util::StringView(""), false}); return nullptr; } - pathHandler_->SetModuleName(GetProgram()->AbsoluteName(), GetProgram()->FileName(), false); - // NOTE(rsipka): setPackage should be eliminated from here, and should be reconsider its usage from program + importPathManager_->InsertModuleInfo(GetProgram()->AbsoluteName(), + util::ImportPathManager::ModuleInfo {GetProgram()->FileName(), false}); GetProgram()->SetPackageName(GetProgram()->FileName()); return nullptr; } @@ -2361,8 +2367,12 @@ ir::ETSPackageDeclaration *ETSParser::ParsePackageDeclaration() name->IsIdentifier() ? name->AsIdentifier()->Name() : name->AsTSQualifiedName()->ToString(Allocator()); GetProgram()->SetPackageName(packageName); - pathHandler_->SetModuleName(GetProgram()->AbsoluteName(), packageName, true); // NOTE: rid of it - pathHandler_->SetModuleName(GetProgram()->ResolvedFilePath(), packageName, true); + // NOTE(rsipka): handle these two cases, check that is it really required + importPathManager_->InsertModuleInfo(GetProgram()->AbsoluteName(), + util::ImportPathManager::ModuleInfo {packageName, true}); + importPathManager_->InsertModuleInfo(GetProgram()->ResolvedFilePath(), + util::ImportPathManager::ModuleInfo {packageName, true}); + return packageDeclaration; } @@ -2382,10 +2392,13 @@ ir::ImportSource *ETSParser::ParseSourceFromClause(bool requireFrom) ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_STRING); auto importPath = Lexer()->GetToken().Ident(); - auto resolvedImportPath = pathHandler_->AddPath(GetProgram()->AbsoluteName(), importPath); + + auto resolvedImportPath = importPathManager_->ResolvePath(GetProgram()->AbsoluteName(), importPath); + importPathManager_->AddToParseList(resolvedImportPath, + (GetContext().Status() & ParserStatus::IN_DEFAULT_IMPORTS) != 0U); auto *resolvedSource = AllocNode(resolvedImportPath); - auto importData = pathHandler_->GetImportData(resolvedImportPath, Extension()); + auto importData = importPathManager_->GetImportData(resolvedImportPath, Extension()); auto *source = AllocNode(importPath); source->SetRange(Lexer()->GetToken().Loc()); diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index d37cadf82e..9dc53f0199 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -19,7 +19,7 @@ #include #include "parserFlags.h" #include "util/arktsconfig.h" -#include "util/pathHandler.h" +#include "util/importPathManager.h" #include "TypedParser.h" namespace ark::es2panda::ir { @@ -44,9 +44,7 @@ public: ETSParser(Program *program, const CompilerOptions &options, ParserStatus status = ParserStatus::NO_OPTS) : TypedParser(program, options, status), globalProgram_(GetProgram()) { - pathHandler_ = std::make_unique(Allocator()); - pathHandler_->SetArkTsConfig(ArkTSConfig()); - pathHandler_->SetStdLib(GetOptions().stdLib); + importPathManager_ = std::make_unique(Allocator(), ArkTSConfig(), GetOptions().stdLib); } ETSParser() = delete; @@ -60,9 +58,9 @@ public: return true; } - ArenaUnorderedMap GetPathes() const + const ArenaMap &ModuleList() const { - return pathHandler_->GetPathes(); + return importPathManager_->ModuleList(); } // Methods to create AST node(s) from the specified string (part of valid ETS-code!) @@ -109,8 +107,7 @@ public: return CreateFormattedStatements(sourceCode, insertingNodes, fileName); } - ArenaVector ParseDefaultSources(std::string_view srcFile, std::string_view importSrc, - const std::vector &paths); + ArenaVector ParseDefaultSources(std::string_view srcFile, std::string_view importSrc); private: void ParseProgram(ScriptKind kind) override; @@ -125,8 +122,7 @@ private: void ParseNamedExportSpecifiers(ArenaVector *specifiers, bool defaultExport); void ParseUserSources(std::vector userParths); ArenaVector ParseTopLevelDeclaration(); - std::tuple, bool> CollectUserSources(const std::string &path); - std::vector ParseSources(const ArenaVector &paths); + std::vector ParseSources(); std::tuple> ParseFromClause(bool requireFrom); ArenaVector ParseNamedSpecifiers(); ArenaVector ParseImportDeclarations(); @@ -317,7 +313,7 @@ private: bool IsExternal() const override { - return pathHandler_->IsStdLib(GetProgram()); + return util::Helpers::IsStdLib(GetProgram()); } // NOLINTNEXTLINE(google-default-arguments) @@ -355,7 +351,7 @@ private: private: parser::Program *globalProgram_; std::vector insertingNodes_ {}; - std::unique_ptr pathHandler_ {nullptr}; + std::unique_ptr importPathManager_ {nullptr}; }; class ExternalSourceParser { diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index 8a22728336..4c20f7511a 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -160,24 +160,6 @@ util::StringView Helpers::ToStringView(ArenaAllocator *allocator, int32_t number return str.View(); } -bool Helpers::IsRelativePath(const std::string &path) -{ - auto pathDelimiter = ark::os::file::File::GetPathDelim(); - - std::string currentDirReference = "."; - std::string parentDirReference = ".."; - - currentDirReference.append(pathDelimiter); - parentDirReference.append(pathDelimiter); - - return ((path.find(currentDirReference) == 0) || (path.find(parentDirReference) == 0)); -} - -bool Helpers::IsCompatibleExtension(const std::string &extension) -{ - return extension == ".ets" || extension == ".ts"; -} - bool Helpers::EndsWith(const std::string &str, const std::string &suffix) { if (str.length() < suffix.length()) { @@ -187,61 +169,6 @@ bool Helpers::EndsWith(const std::string &str, const std::string &suffix) return str.find(suffix, expectPos) == expectPos; } -std::string Helpers::GetSourcePath(const std::string &path) -{ - std::string fullFilePath = path; - std::string importExtension; - if (!ark::os::file::File::IsRegularFile(path) && (ark::os::GetAbsolutePath(path).empty())) { - importExtension = ".ets"; - fullFilePath = path + importExtension; - if (!ark::os::file::File::IsRegularFile(fullFilePath)) { - importExtension = ".ts"; - fullFilePath = path + importExtension; - if (!ark::os::file::File::IsRegularFile(fullFilePath)) { - return path; - } - } - } - std::string absFilePath = ark::os::GetAbsolutePath(fullFilePath); - absFilePath.erase(absFilePath.find(importExtension), importExtension.size()); - return absFilePath; -} - -std::string Helpers::TruncateCompatibleExtension(const std::string &path) -{ - const size_t extensionIndex = path.find_last_of('.'); - if (extensionIndex != std::string::npos && IsCompatibleExtension(path.substr(extensionIndex, path.length()))) { - return path.substr(0, extensionIndex); - } - - return path; -} - -util::StringView Helpers::TruncateCompatibleExtension(const util::StringView &path) -{ - const size_t extensionIndex = path.Mutf8().find_last_of('.'); - if (extensionIndex != std::string::npos && - IsCompatibleExtension(path.Mutf8().substr(extensionIndex, path.Mutf8().length()))) { - return path.Substr(0, extensionIndex); - } - - return path; -} - -bool Helpers::IsRealPath(const std::string &path) -{ - if (!ark::os::file::File::IsRegularFile(path) && (ark::os::GetAbsolutePath(path).empty())) { - auto importExtension = ".ets"; - if (!ark::os::file::File::IsRegularFile(path + importExtension)) { - importExtension = ".ts"; - if (!ark::os::file::File::IsRegularFile(path + importExtension)) { - return false; - } - } - } - return true; -} - const ir::ScriptFunction *Helpers::GetContainingConstructor(const ir::AstNode *node) { const ir::ScriptFunction *iter = GetContainingFunction(node); @@ -722,4 +649,19 @@ std::pair Helpers::SplitSignature(std::strin return {className, methodName}; } +std::vector &Helpers::StdLib() +{ + static std::vector stdlib {"std/core", "std/math", "std/containers", "std/time", + "std/interop/js", "std/debug", "std/debug/concurrency", "escompat"}; + return stdlib; +} + +bool Helpers::IsStdLib(const parser::Program *program) +{ + const auto &stdlib = StdLib(); + auto fileFolder = program->GetPackageName().Mutf8(); + std::replace(fileFolder.begin(), fileFolder.end(), '.', '/'); + return std::count(stdlib.begin(), stdlib.end(), fileFolder) != 0; +} + } // namespace ark::es2panda::util diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index 0c6342fa18..0a6e95f64c 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -20,6 +20,7 @@ #include "mem/pool_manager.h" #include "util/ustring.h" #include "ir/module/importSpecifier.h" +#include "parser/program/program.h" #include #include @@ -115,13 +116,7 @@ public: static util::StringView ToStringView(ArenaAllocator *allocator, double number); static util::StringView ToStringView(ArenaAllocator *allocator, int32_t number); static util::StringView ToStringView(ArenaAllocator *allocator, uint32_t number); - static bool IsRelativePath(const std::string &path); - static bool IsRealPath(const std::string &path); - static bool IsCompatibleExtension(const std::string &extension); static bool EndsWith(const std::string &str, const std::string &suffix); - static std::string GetSourcePath(const std::string &path); - static std::string TruncateCompatibleExtension(const std::string &path); - static util::StringView TruncateCompatibleExtension(const util::StringView &path); static const ir::ScriptFunction *GetContainingConstructor(const ir::AstNode *node); static const ir::ScriptFunction *GetContainingConstructor(const ir::ClassProperty *node); @@ -206,6 +201,9 @@ public: static std::pair SplitSignature(std::string_view signature); + static std::vector &StdLib(); + static bool IsStdLib(const parser::Program *program); + private: template static void Log(Elements &&...elems); diff --git a/ets2panda/util/pathHandler.cpp b/ets2panda/util/importPathManager.cpp similarity index 31% rename from ets2panda/util/pathHandler.cpp rename to ets2panda/util/importPathManager.cpp index 27b566e7c0..9b3ecd26f8 100644 --- a/ets2panda/util/pathHandler.cpp +++ b/ets2panda/util/importPathManager.cpp @@ -13,13 +13,8 @@ * limitations under the License. */ -#include "pathHandler.h" -#include "libpandabase/os/filesystem.h" -#include - -#if defined PANDA_TARGET_MOBILE -#define USE_UNIX_SYSCALL -#endif +#include "importPathManager.h" +#include #ifdef USE_UNIX_SYSCALL #include @@ -34,20 +29,77 @@ namespace fs = std::filesystem; namespace fs = std::experimental::filesystem; #endif #endif - namespace ark::es2panda::util { +constexpr size_t SUPPORTED_INDEX_FILES_SIZE = 2; +constexpr size_t SUPPORTED_EXTENSIONS_SIZE = 2; + static bool IsCompitableExtension(const std::string &extension) { return extension == ".ets" || extension == ".ts"; } -void PathHandler::UnixWalkThroughDirectory([[maybe_unused]] const StringView &directory) +StringView ImportPathManager::ResolvePath(const StringView ¤tModulePath, const StringView &importPath) const { + if (importPath.Empty()) { + throw Error(ErrorType::GENERIC, "", "Import path cannot be empty"); + } + + if (IsRelativePath(importPath)) { + const size_t pos = currentModulePath.Mutf8().find_last_of(pathDelimiter_); + ASSERT(pos != std::string::npos); + + auto currentDirectory = currentModulePath.Mutf8().substr(0, pos); + auto resolvedPath = UString(currentDirectory, allocator_); + resolvedPath.Append(pathDelimiter_); + resolvedPath.Append(importPath.Mutf8()); + + return AppendExtensionOrIndexFileIfOmitted(resolvedPath.View()); + } + + std::string baseUrl; + if (importPath.Mutf8()[0] == pathDelimiter_.at(0)) { + baseUrl = arktsConfig_->BaseUrl(); + baseUrl.append(importPath.Mutf8(), 0, importPath.Mutf8().length()); + return AppendExtensionOrIndexFileIfOmitted(UString(baseUrl, allocator_).View()); + } + + auto &dynamicPaths = arktsConfig_->DynamicPaths(); + if (auto it = dynamicPaths.find(importPath.Mutf8()); it != dynamicPaths.cend() && !it->second.HasDecl()) { + return AppendExtensionOrIndexFileIfOmitted(importPath); + } + + const size_t pos = importPath.Mutf8().find(pathDelimiter_); + bool containsDelim = (pos != std::string::npos); + auto rootPart = containsDelim ? importPath.Substr(0, pos) : importPath; + if (!stdLib_.empty() && + (rootPart.Is("std") || rootPart.Is("escompat"))) { // Get std or escompat path from CLI if provided + baseUrl = stdLib_ + pathDelimiter_.at(0) + rootPart.Mutf8(); + } else { + ASSERT(arktsConfig_ != nullptr); + auto resolvedPath = arktsConfig_->ResolvePath(importPath.Mutf8()); + if (!resolvedPath) { + throw Error(ErrorType::GENERIC, "", + "Can't find prefix for '" + importPath.Mutf8() + "' in " + arktsConfig_->ConfigPath()); + } + + return AppendExtensionOrIndexFileIfOmitted(UString(resolvedPath.value(), allocator_).View()); + } + + if (containsDelim) { + baseUrl.append(1, pathDelimiter_.at(0)); + baseUrl.append(importPath.Mutf8(), rootPart.Mutf8().length() + 1, importPath.Mutf8().length()); + } + + return UString(baseUrl, allocator_).View(); +} + #ifdef USE_UNIX_SYSCALL - DIR *dir = opendir(directory.Mutf8().c_str()); +void ImportPathManager::UnixWalkThroughDirectoryAndAddToParseList(const StringView &directoryPath, bool isDefaultImport) +{ + DIR *dir = opendir(directoryPath.Mutf8().c_str()); if (dir == nullptr) { - throw Error(ErrorType::GENERIC, "", "Cannot open folder: " + directory.Mutf8()); + throw Error(ErrorType::GENERIC, "", "Cannot open folder: " + directoryPath.Mutf8()); } struct dirent *entry; @@ -62,108 +114,112 @@ void PathHandler::UnixWalkThroughDirectory([[maybe_unused]] const StringView &di continue; } - std::string filePath = directory.Mutf8() + "/" + entry->d_name; - StringView sourcePath = util::UString(filePath, allocator_).View(); - if (fileName == "Object.ets") { - pathes_.insert({sourcePath, ParseInfo(allocator_, true)}); - } else { - pathes_.insert({sourcePath, ParseInfo(allocator_)}); - } + std::string filePath = directoryPath.Mutf8() + "/" + entry->d_name; + AddToParseList(UString(filePath, allocator_).View(), isDefaultImport); } closedir(dir); -#endif + return; } +#endif -StringView PathHandler::AddPath(const StringView &callerPath, const StringView &path) +void ImportPathManager::AddToParseList(const StringView &resolvedPath, bool isDefaultImport) { - auto resolvedPath = ResolveSourcePath(callerPath, path); - if (!ark::os::file::File::IsDirectory(resolvedPath.Mutf8())) { - pathes_.insert({resolvedPath, ParseInfo(allocator_)}); - return resolvedPath; - } + if (ark::os::file::File::IsDirectory(resolvedPath.Mutf8())) { +#ifdef USE_UNIX_SYSCALL + UnixWalkThroughDirectoryAndAddToParseList(resolvedPath, isDefaultImport); +#else + for (auto const &entry : fs::directory_iterator(resolvedPath.Mutf8())) { + if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { + continue; + } - pathes_.insert({resolvedPath, ParseInfo(allocator_)}); + AddToParseList(UString(entry.path().string(), allocator_).View(), isDefaultImport); + } + return; +#endif + } - bool hasIndexFile = false; - std::string indexFile = resolvedPath.Mutf8() + pathDelimiter_.data() + "index.ets"; - if (ark::os::file::File::IsRegularFile(indexFile)) { - hasIndexFile = true; - } else { - indexFile = resolvedPath.Mutf8() + pathDelimiter_.data() + "index.ts"; - if (ark::os::file::File::IsRegularFile(indexFile)) { - hasIndexFile = true; + for (const auto &parseInfo : parseList_) { + if (parseInfo.sourcePath == resolvedPath) { + return; } } - if (hasIndexFile) { - StringView indexFilePath = util::UString(indexFile, allocator_).View(); - pathes_.insert({indexFilePath, ParseInfo(allocator_)}); - return indexFilePath; + auto &dynamicPaths = arktsConfig_->DynamicPaths(); + if (auto it = dynamicPaths.find(resolvedPath.Mutf8()); it != dynamicPaths.cend()) { + parseList_.emplace(parseList_.begin(), ParseInfo {resolvedPath, false}); + return; } -#ifdef USE_UNIX_SYSCALL - UnixWalkThroughDirectory(resolvedPath); -#else - for (auto const &entry : fs::directory_iterator(resolvedPath.Mutf8())) { - if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { - continue; - } + if (!ark::os::file::File::IsRegularFile(resolvedPath.Mutf8())) { + throw Error(ErrorType::GENERIC, "", "Not an available source path: " + resolvedPath.Mutf8()); + } - StringView sourcePath = util::UString(entry.path().string(), allocator_).View(); - if (entry.path().filename().string() == "Object.ets") { - pathes_.insert({sourcePath, ParseInfo(allocator_, true)}); - } else { - pathes_.insert({sourcePath, ParseInfo(allocator_)}); + if (isDefaultImport) { + int position = resolvedPath.Mutf8().find_last_of(pathDelimiter_); + if (resolvedPath.Substr(position + 1, resolvedPath.Length()).Is("Object.ets")) { + parseList_.emplace(parseList_.begin(), ParseInfo {resolvedPath, false}); + return; } } -#endif - return resolvedPath; + + parseList_.emplace_back(ParseInfo {resolvedPath, false}); } -void PathHandler::CollectDefaultSources(const std::vector &stdlib) +const ArenaVector &ImportPathManager::ParseList() { - for (auto const &path : stdlib) { - StringView callerPath = util::UString(allocator_).View(); - StringView stdlibPath = ResolveSourcePath(callerPath, util::UString(path, allocator_).View()); - pathes_.insert({stdlibPath, ParseInfo(allocator_)}); -#ifdef USE_UNIX_SYSCALL - UnixWalkThroughDirectory(stdlibPath); -#else - for (auto const &entry : fs::directory_iterator(stdlibPath.Mutf8())) { - if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { - continue; - } + return parseList_; +} - // NOTE(rsipka): seems to me a duplicated check, since it was already in pathes_ - StringView sourcePath = util::UString(entry.path().string(), allocator_).View(); - if (entry.path().filename().string() == "Object.ets") { - pathes_.insert({sourcePath, ParseInfo(allocator_, true)}); - } else { - pathes_.insert({sourcePath, ParseInfo(allocator_)}); - } +ImportPathManager::ImportData ImportPathManager::GetImportData(const util::StringView &path, + const ScriptExtension &extension) const +{ + const auto &dynamicPaths = arktsConfig_->DynamicPaths(); + auto key = ark::os::NormalizePath(path.Mutf8()); + + auto it = dynamicPaths.find(key); + if (it == dynamicPaths.cend()) { + key = ark::os::RemoveExtension(key); + } + + while (it == dynamicPaths.cend() && !key.empty()) { + it = dynamicPaths.find(key); + if (it != dynamicPaths.cend()) { + break; } -#endif + key = ark::os::GetParentDir(key); + } + + if (it != dynamicPaths.cend()) { + return {it->second.GetLanguage(), key, it->second.HasDecl()}; } + + return {ToLanguage(extension), path.Mutf8(), true}; } -ArenaVector PathHandler::GetParseList() const +void ImportPathManager::InsertModuleInfo(const util::StringView &path, + const util::ImportPathManager::ModuleInfo &moduleInfo) { - ArenaVector parseableSources(allocator_->Adapter()); - for (const auto [path, info] : pathes_) { - if (!info.IsParsed() && !ark::os::file::File::IsDirectory(path.Mutf8())) { - // NOTE(rsipka): it should be handled in a better way - if (info.IsObjectfile()) { - parseableSources.emplace(parseableSources.begin(), path); - } else { - parseableSources.emplace_back(path); - } + moduleList_.insert({path, moduleInfo}); +} + +const ArenaMap &ImportPathManager::ModuleList() const +{ + return moduleList_; +} + +void ImportPathManager::MarkAsParsed(const StringView &path) +{ + for (auto &parseInfo : parseList_) { + if (parseInfo.sourcePath == path) { + parseInfo.isParsed = true; + return; } } - return parseableSources; } -bool PathHandler::IsRelativePath(const StringView &path) const +bool ImportPathManager::IsRelativePath(const StringView &path) const { std::string currentDirReference = "."; std::string parentDirReference = ".."; @@ -174,109 +230,51 @@ bool PathHandler::IsRelativePath(const StringView &path) const return ((path.Mutf8().find(currentDirReference) == 0) || (path.Mutf8().find(parentDirReference) == 0)); } -StringView PathHandler::GetParentFolder(const StringView &path) const +StringView ImportPathManager::GetRealPath(const StringView &path) const { - const size_t pos = path.Mutf8().find_last_of(pathDelimiter_); - if (pos != std::string::npos) { - return util::UString(path.Mutf8().substr(0, pos + 1), allocator_).View(); + const std::string realPath = ark::os::GetAbsolutePath(path.Mutf8()); + if (realPath.empty() || realPath == path.Mutf8()) { + return path; } - return util::UString(allocator_).View(); + return UString(realPath, allocator_).View(); } -StringView PathHandler::AppendExtension(const StringView &path) const +StringView ImportPathManager::AppendExtensionOrIndexFileIfOmitted(const StringView &path) const { StringView realPath = GetRealPath(path); - if (ark::os::file::File::IsDirectory(realPath.Mutf8()) || ark::os::file::File::IsRegularFile(realPath.Mutf8())) { + if (ark::os::file::File::IsRegularFile(realPath.Mutf8())) { return realPath; } - std::string importExtension = ".ets"; - if (!ark::os::file::File::IsRegularFile(path.Mutf8() + importExtension)) { - importExtension = ".ts"; - if (!ark::os::file::File::IsRegularFile(path.Mutf8() + importExtension)) { - // NOTE(rsipka): this check should be eliminated - auto &dynamicPaths = arktsConfig_->DynamicPaths(); - if (auto it = dynamicPaths.find(path.Mutf8()); it != dynamicPaths.cend()) { - return path; + if (ark::os::file::File::IsDirectory(realPath.Mutf8())) { + // Supported index files: keep this checking order + std::array supportedIndexFiles = {"index.ets", "index.ts"}; + for (const auto &indexFile : supportedIndexFiles) { + std::string indexFilePath = realPath.Mutf8() + pathDelimiter_.data() + indexFile; + if (ark::os::file::File::IsRegularFile(indexFilePath)) { + return GetRealPath(UString(indexFilePath, allocator_).View()); } - - throw Error(ErrorType::GENERIC, "", "Not supported path: " + path.Mutf8()); } - } - - return GetRealPath(util::UString(path.Mutf8().append(importExtension), allocator_).View()); -} - -StringView PathHandler::GetRealPath(const StringView &path) const -{ - const std::string realPath = ark::os::GetAbsolutePath(path.Mutf8()); - if (realPath.empty()) { - return path; - } - - if (realPath == path.Mutf8()) { - return path; - } - return util::UString(realPath, allocator_).View(); -} - -StringView PathHandler::ResolveSourcePath(const StringView &callerPath, const StringView &path) const -{ - if (IsRelativePath(path)) { - const size_t pos = callerPath.Mutf8().find_last_of(pathDelimiter_); - ASSERT(pos != std::string::npos); - auto parentFolder = callerPath.Mutf8().substr(0, pos); - auto resolvedPath = util::UString(parentFolder, allocator_); - resolvedPath.Append(pathDelimiter_); - resolvedPath.Append(path.Mutf8()); - return AppendExtension(resolvedPath.View()); + return realPath; } - std::string baseUrl; - if (path.Mutf8().find('/') == 0) { - baseUrl = arktsConfig_->BaseUrl(); - baseUrl.append(path.Mutf8(), 0, path.Mutf8().length()); - return AppendExtension(util::UString(baseUrl, allocator_).View()); - } + // Supported extensions: keep this checking order + std::array supportedExtensions = {".ets", ".ts"}; - auto &dynamicPaths = arktsConfig_->DynamicPaths(); - if (auto it = dynamicPaths.find(path.Mutf8()); it != dynamicPaths.cend() && !it->second.HasDecl()) { - return AppendExtension(path); - } - - const size_t pos = path.Mutf8().find(pathDelimiter_); - bool containsDelim = (pos != std::string::npos); - auto rootPart = containsDelim ? path.Substr(0, pos) : path; - if (rootPart.Is("std") && !stdLib_.empty()) { // Get std path from CLI if provided - baseUrl = stdLib_ + "/std"; - } else if (rootPart.Is("escompat") && !stdLib_.empty()) { // Get escompat path from CLI if provided - baseUrl = stdLib_ + "/escompat"; - } else { - ASSERT(arktsConfig_ != nullptr); - auto resolvedPath = arktsConfig_->ResolvePath(path.Mutf8()); - if (!resolvedPath) { - throw Error(ErrorType::GENERIC, "", - "Can't find prefix for '" + path.Mutf8() + "' in " + arktsConfig_->ConfigPath()); + for (const auto &extension : supportedExtensions) { + if (ark::os::file::File::IsRegularFile(path.Mutf8() + extension)) { + return GetRealPath(UString(path.Mutf8().append(extension), allocator_).View()); } - - return AppendExtension(util::UString(resolvedPath.value(), allocator_).View()); } - if (containsDelim) { - baseUrl.append(1, pathDelimiter_.at(0)); - baseUrl.append(path.Mutf8(), rootPart.Mutf8().length() + 1, path.Mutf8().length()); + auto &dynamicPaths = arktsConfig_->DynamicPaths(); + if (auto it = dynamicPaths.find(path.Mutf8()); it != dynamicPaths.cend()) { + return path; } - return util::UString(baseUrl, allocator_).View(); -} - -std::vector &PathHandler::StdLib() -{ - static std::vector stdlib {"std/core", "std/math", "std/containers", "std/time", - "std/interop/js", "std/debug", "std/debug/concurrency", "escompat"}; - return stdlib; + throw Error(ErrorType::GENERIC, "", "Not supported path: " + path.Mutf8()); } } // namespace ark::es2panda::util diff --git a/ets2panda/util/importPathManager.h b/ets2panda/util/importPathManager.h new file mode 100644 index 0000000000..ceddf99643 --- /dev/null +++ b/ets2panda/util/importPathManager.h @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2024 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. + */ + +#ifndef ES2PANDA_UTIL_IMPORT_PATH_MANAGER_H +#define ES2PANDA_UTIL_IMPORT_PATH_MANAGER_H + +#if defined PANDA_TARGET_MOBILE +#define USE_UNIX_SYSCALL +#endif + +#include "util/arktsconfig.h" +#include "util/ustring.h" +#include "es2panda.h" + +namespace ark::es2panda::util { + +class ImportPathManager { +public: + struct ImportData { + Language lang; + std::string module; + bool hasDecl; + }; + + struct ParseInfo { + StringView sourcePath; + bool isParsed; + }; + + struct ModuleInfo { + StringView moduleName; + bool isPackageModule; + }; + + ImportPathManager(ark::ArenaAllocator *allocator, std::shared_ptr arktsConfig, std::string stdLib) + : allocator_(allocator), + arktsConfig_(std::move(arktsConfig)), + stdLib_(std::move(stdLib)), + parseList_(allocator->Adapter()), + moduleList_(allocator->Adapter()) + { + } + + NO_COPY_SEMANTIC(ImportPathManager); + NO_MOVE_SEMANTIC(ImportPathManager); + ImportPathManager() = delete; + ~ImportPathManager() = default; + + StringView ResolvePath(const StringView ¤tModulePath, const StringView &importPath) const; + void AddToParseList(const StringView &path, bool isDefaultImport); + const ArenaVector &ParseList(); + ImportData GetImportData(const util::StringView &path, const ScriptExtension &extension) const; + void InsertModuleInfo(const util::StringView &path, const ModuleInfo &moduleInfo); + const ArenaMap &ModuleList() const; + void MarkAsParsed(const StringView &path); + +private: + bool IsRelativePath(const StringView &path) const; + StringView GetRealPath(const StringView &path) const; + StringView AppendExtensionOrIndexFileIfOmitted(const StringView &path) const; +#ifdef USE_UNIX_SYSCALL + void UnixWalkThroughDirectoryAndAddToParseList(const StringView &directoryPath, bool isDefaultImport); +#endif + + ArenaAllocator *allocator_ {nullptr}; + std::shared_ptr arktsConfig_ {nullptr}; + std::string stdLib_ {}; + ArenaVector parseList_; + ArenaMap moduleList_; + std::string_view pathDelimiter_ {ark::os::file::File::GetPathDelim()}; +}; + +} // namespace ark::es2panda::util + +#endif // ES2PANDA_UTIL_IMPORT_PATH_MANAGER_H diff --git a/ets2panda/util/pathHandler.h b/ets2panda/util/pathHandler.h deleted file mode 100644 index b850cc23e8..0000000000 --- a/ets2panda/util/pathHandler.h +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Copyright (c) 2024 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. - */ - -#ifndef ES2PANDA_UTIL_PATH_HANDLER_H -#define ES2PANDA_UTIL_PATH_HANDLER_H - -#include -#include - -#include "es2panda.h" -#include "parser/program/program.h" -#include "util/arktsconfig.h" -#include "util/ustring.h" -#include - -namespace ark::es2panda::util { - -class ParseInfo { -public: - explicit ParseInfo(ark::ArenaAllocator *allocator, bool isObjectFile = false) - : isObjectFile_(isObjectFile), isParsed_(false), moduleName_(allocator), isPackageModule_(false) - { - } - - ParseInfo() = delete; - - bool IsParsed() const - { - return isParsed_; - } - - void MarkAsParsed() - { - isParsed_ = true; - } - - StringView ModuleName() const - { - return moduleName_.View(); - } - - bool IsObjectfile() const - { - return isObjectFile_; - } - - bool IsPackageModule() const - { - return isPackageModule_; - } - - void SetModuleName(const StringView &moduleName, bool isPackageModule) - { - if (moduleName_.View().Empty()) { - moduleName_.Append(moduleName); - isPackageModule_ = isPackageModule; - } - } - -private: - bool isObjectFile_; - bool isParsed_; - util::UString moduleName_; - bool isPackageModule_; -}; - -class PathHandler { -public: - struct ImportData { - Language lang; - std::string module; - bool hasDecl; - }; - - static std::vector &StdLib(); - - ImportData GetImportData(util::StringView path, ScriptExtension extension) - { - const auto &dynamicPaths = arktsConfig_->DynamicPaths(); - auto key = ark::os::NormalizePath(path.Mutf8()); - - auto it = dynamicPaths.find(key); - if (it == dynamicPaths.cend()) { - key = ark::os::RemoveExtension(key); - } - - while (it == dynamicPaths.cend() && !key.empty()) { - it = dynamicPaths.find(key); - if (it != dynamicPaths.cend()) { - break; - } - key = ark::os::GetParentDir(key); - } - - if (it != dynamicPaths.cend()) { - return {it->second.GetLanguage(), key, it->second.HasDecl()}; - } - return {ToLanguage(extension), path.Mutf8(), true}; - } - - bool IsStdLib(const parser::Program *program) const - { - const auto &stdlib = StdLib(); - auto fileFolder = program->GetPackageName().Mutf8(); - std::replace(fileFolder.begin(), fileFolder.end(), '.', '/'); - return std::count(stdlib.begin(), stdlib.end(), fileFolder) != 0; - } - - explicit PathHandler(ark::ArenaAllocator *allocator) : allocator_(allocator), pathes_(allocator->Adapter()) {} - - StringView AddPath(const StringView &callerPath, const StringView &path); - ArenaVector GetParseList() const; - void CollectDefaultSources(const std::vector &stdlib); - - void MarkAsParsed(const StringView &path) - { - auto it = pathes_.find(path); - if (it != pathes_.end()) { - it->second.MarkAsParsed(); - } - } - - bool IsParsed(const std::string &path) - { - auto pathView = util::UString(path, allocator_).View(); - auto it = pathes_.find(pathView); - if (it != pathes_.end()) { - return it->second.IsParsed(); - } - - return false; - } - - void MarkAsParsed(const std::string &path) - { - auto pathView = util::UString(path, allocator_).View(); - auto it = pathes_.find(pathView); - if (it != pathes_.end()) { - it->second.MarkAsParsed(); - } - } - - void SetModuleName(const StringView &path, const StringView &moduleName, bool isPackageModule) - { - auto it = pathes_.find(path); - if (it != pathes_.end()) { - it->second.SetModuleName(moduleName, isPackageModule); - } - } - - void SetStdLib(const std::string &stdLib) - { - stdLib_ = stdLib; - } - - void SetArkTsConfig(std::shared_ptr arktsConfig) - { - arktsConfig_ = std::move(arktsConfig); - } - - ArenaUnorderedMap &GetPathes() - { - return pathes_; - } - - NO_COPY_SEMANTIC(PathHandler); - NO_MOVE_SEMANTIC(PathHandler); - PathHandler() = delete; - ~PathHandler() = default; - -private: - bool IsRelativePath(const StringView &path) const; - StringView GetParentFolder(const StringView &path) const; - StringView ResolveSourcePath(const StringView &callerPath, const StringView &path) const; - StringView AppendExtension(const StringView &path) const; - StringView GetRealPath(const StringView &path) const; - void UnixWalkThroughDirectory(const StringView &directory); - - ArenaAllocator *allocator_; - ArenaUnorderedMap pathes_; - std::string stdLib_ = {}; - std::shared_ptr arktsConfig_ = {nullptr}; - std::string_view pathDelimiter_ = ark::os::file::File::GetPathDelim(); -}; - -} // namespace ark::es2panda::util - -#endif // ES2PANDA_UTIL_PATH_HANDLER_H diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 13cef4418b..36ef4f1eec 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -686,7 +686,7 @@ ArenaVector ETSBinder::GetExternalProgram(const util::StringV { const auto &extRecords = globalRecordTable_.Program()->ExternalSources(); - auto [name, _] = GetModuleNameFromSource(sourceName); + auto [name, _] = GetModuleInfo(sourceName); auto res = extRecords.find(name); if (res == extRecords.end()) { ThrowError(importPath->Start(), "Cannot find import: " + importPath->Str().Mutf8()); diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 496a87b176..128fedd761 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -20,7 +20,7 @@ #include "varbinder/recordTable.h" #include "ir/ets/etsImportDeclaration.h" #include "ir/ets/etsReExportDeclaration.h" -#include "util/pathHandler.h" +#include "util/importPathManager.h" namespace ark::es2panda::varbinder { @@ -47,7 +47,7 @@ public: lambdaObjects_(Allocator()->Adapter()), dynamicImportVars_(Allocator()->Adapter()), importSpecifiers_(Allocator()->Adapter()), - sourceList_(Allocator()->Adapter()) + moduleList_(Allocator()->Adapter()) { InitImplicitThisParam(); } @@ -207,18 +207,16 @@ public: defaultExport_ = defaultExport; } - void FillSourceList(const ArenaUnorderedMap &pathes) + void SetModuleList(const ArenaMap &moduleList) { - for (const auto path : pathes) { - sourceList_.emplace(path.first, std::tuple(path.second.ModuleName(), - path.second.IsPackageModule())); - } + moduleList_ = moduleList; } - std::tuple GetModuleNameFromSource(const util::StringView &path) const + util::ImportPathManager::ModuleInfo GetModuleInfo(const util::StringView &path) const { - auto it = sourceList_.find(path); - ASSERT(it != sourceList_.end()); + auto it = moduleList_.find(path); + + ASSERT(it != moduleList_.end()); return it->second; } @@ -253,7 +251,7 @@ private: DynamicImportVariables dynamicImportVars_; ir::Identifier *thisParam_ {}; ArenaVector> importSpecifiers_; - ArenaUnorderedMap> sourceList_; + ArenaMap moduleList_; ir::AstNode *defaultExport_ {}; }; -- Gitee From 7f3bfc8cfa7f3d98d018a2ffb6bab0209234cd8e Mon Sep 17 00:00:00 2001 From: Gabor Aron Takacs Date: Fri, 1 Mar 2024 11:24:34 +0100 Subject: [PATCH 06/13] Float.NaN and Dobule.NaN must be falsey Change-Id: I91b53cae1934b1d3fbb51299419900102ea94141 Signed-off-by: Gabor Aron Takacs Accept-Changeset: 12868:fe:1950:rt:0 --- ets2panda/checker/types/ets/doubleType.h | 3 ++- ets2panda/checker/types/ets/floatType.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ets2panda/checker/types/ets/doubleType.h b/ets2panda/checker/types/ets/doubleType.h index f59ce9da59..e7e7dde792 100644 --- a/ets2panda/checker/types/ets/doubleType.h +++ b/ets2panda/checker/types/ets/doubleType.h @@ -54,7 +54,8 @@ public: std::tuple ResolveConditionExpr() const override { - return {IsConstantType(), value_ != 0}; + // isNan = !(value_ == value_) + return {IsConstantType(), (value_ != 0) && (value_ == value_)}; } private: diff --git a/ets2panda/checker/types/ets/floatType.h b/ets2panda/checker/types/ets/floatType.h index 1deb5bbf0e..61f04f8e0b 100644 --- a/ets2panda/checker/types/ets/floatType.h +++ b/ets2panda/checker/types/ets/floatType.h @@ -54,7 +54,8 @@ public: std::tuple ResolveConditionExpr() const override { - return {IsConstantType(), value_ != 0}; + // isNan = !(value_ == value_) + return {IsConstantType(), (value_ != 0) && (value_ == value_)}; } private: -- Gitee From 8828ceb9124a88e866d59b1e5abfa8462d91d303 Mon Sep 17 00:00:00 2001 From: Peter Siket Date: Mon, 4 Mar 2024 15:00:41 +0100 Subject: [PATCH 07/13] Add missing accumulator store. Issue: #I95R8C Internal issue: #15766 Change-Id: I8bf7b07dcd83ba27132d13388de52732fdaeec6d Signed-off-by: Peter Siket Accept-Changeset: 12822:fe:1943:rt:0 --- ets2panda/compiler/core/ETSCompiler.cpp | 2 +- ets2panda/test/runtime/ets/15766.ets | 31 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/runtime/ets/15766.ets diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index f7d9c68b16..23b067caa1 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -971,7 +971,7 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const } else if (expr->Callee()->IsSuperExpression() || expr->Callee()->IsThisExpression()) { ASSERT(!isReference && expr->IsETSConstructorCall()); expr->Callee()->Compile(etsg); // ctor is not a value! - etsg->SetVRegType(calleeReg, etsg->GetAccumulatorType()); + etsg->StoreAccumulator(expr, calleeReg); EmitCall(expr, calleeReg, isStatic, signature, isReference); } else { ASSERT(isReference); diff --git a/ets2panda/test/runtime/ets/15766.ets b/ets2panda/test/runtime/ets/15766.ets new file mode 100644 index 0000000000..7ae5757c93 --- /dev/null +++ b/ets2panda/test/runtime/ets/15766.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 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 E { + constructor() {} +} + +class AE extends E { + constructor() { + super() + let a = 3; + } +} + +function main() : int +{ + let ae = new AE(); + return 0; +} -- Gitee From 47dc74bf268c10daa6b9453073c82493152e54b3 Mon Sep 17 00:00:00 2001 From: Martin Sajti Date: Thu, 22 Feb 2024 18:20:30 +0100 Subject: [PATCH 08/13] Fix async lambda boxing Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I97KY7 Internal issue: #14209 Test: build, new checker tests Signed-off-by: Martin Sajti Accept-Changeset: 12700:fe:1893:rt:0 --- ets2panda/checker/ets/function.cpp | 7 +++- .../test/runtime/ets/async_lambda_box.ets | 37 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/runtime/ets/async_lambda_box.ets diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 4209abe398..ad7093bf74 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -3032,11 +3032,16 @@ varbinder::FunctionParamScope *ETSChecker::CopyParams(const ArenaVectorClone(Allocator(), paramOld->Parent())->AsETSParameterExpression(); auto *const var = std::get<1>(VarBinder()->AddParamDecl(paramNew)); + + if (paramNew->Variable()->HasFlag(varbinder::VariableFlags::BOXED)) { + var->AddFlag(varbinder::VariableFlags::BOXED); + } + var->SetTsType(paramOld->Ident()->Variable()->TsType()); var->SetScope(paramCtx.GetScope()); paramNew->SetVariable(var); - paramNew->SetTsType(paramOld->TsType()); + paramNew->SetTsType(MaybeBoxedType(paramOld->Ident()->Variable())); outParams.emplace_back(paramNew); } diff --git a/ets2panda/test/runtime/ets/async_lambda_box.ets b/ets2panda/test/runtime/ets/async_lambda_box.ets new file mode 100644 index 0000000000..8127963d2b --- /dev/null +++ b/ets2panda/test/runtime/ets/async_lambda_box.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 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. + */ + +type asyncLambda = () => Promise + +async function asyncFunc(): Promise { + return true; +} + +function callAsyncLambda(): void { + let is_call_async_lambda: boolean = false; + + let async_lambda: asyncLambda = async (): Promise => { + await asyncFunc(); + is_call_async_lambda = true; + } + + assert(is_call_async_lambda == false); + await async_lambda(); + assert(is_call_async_lambda == true); +} + +function main(): void { + callAsyncLambda(); +} -- Gitee From 0ec9e414067dc7b7b8dfa5d81e20b7dcbac66652 Mon Sep 17 00:00:00 2001 From: Martin Sajti Date: Mon, 12 Feb 2024 15:29:53 +0100 Subject: [PATCH 09/13] Fix generic function type import Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I97L1Q Internal issue: #15580 Test: build, new checker tests Signed-off-by: Martin Sajti Accept-Changeset: 12661:fe:1876:rt:0 --- ets2panda/checker/ETSAnalyzer.cpp | 13 +- ets2panda/checker/ets/helpers.cpp | 10 +- .../checker/types/ets/etsFunctionType.cpp | 3 + ets2panda/checker/types/typeRelation.h | 5 + .../generic_typealias_func_type-expected.txt | 563 +++++++++++++ .../generic_typealias_func_type.ets | 20 + ...neric_typealias_func_type_lib-expected.txt | 781 ++++++++++++++++++ .../generic_typealias_func_type_lib.ets | 20 + 8 files changed, 1408 insertions(+), 7 deletions(-) create mode 100644 ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 489dbee2b5..31c307af92 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2328,12 +2328,17 @@ checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const const checker::SavedTypeRelationFlagsContext savedFlagsCtx( checker->Relation(), checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS); - st->TypeAnnotation()->Check(checker); + if (st->TypeAnnotation()->TsType() == nullptr) { + st->TypeAnnotation()->Check(checker); + } return nullptr; } - st->SetTypeParameterTypes(checker->CreateTypeForTypeParameters(st->TypeParams())); + if (st->TypeParameterTypes().empty()) { + st->SetTypeParameterTypes(checker->CreateTypeForTypeParameters(st->TypeParams())); + } + for (auto *const param : st->TypeParams()->Params()) { const auto *const res = st->TypeAnnotation()->FindChild([¶m](const ir::AstNode *const node) { if (!node->IsIdentifier()) { @@ -2353,7 +2358,9 @@ checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const const checker::SavedTypeRelationFlagsContext savedFlagsCtx(checker->Relation(), checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS); - st->TypeAnnotation()->Check(checker); + if (st->TypeAnnotation()->TsType() == nullptr) { + st->TypeAnnotation()->Check(checker); + } return nullptr; } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index ec52dab75d..f69cae8f86 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2249,7 +2249,7 @@ bool ETSChecker::IsSameDeclarationType(varbinder::LocalVariable *target, varbind void ETSChecker::AddBoxingFlagToPrimitiveType(TypeRelation *relation, Type *target) { auto boxingResult = PrimitiveTypeAsETSBuiltinType(target); - if (boxingResult != nullptr) { + if ((boxingResult != nullptr) && !relation->OnlyCheckBoxingUnboxing()) { relation->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(boxingResult)); relation->Result(true); } @@ -2258,7 +2258,7 @@ void ETSChecker::AddBoxingFlagToPrimitiveType(TypeRelation *relation, Type *targ void ETSChecker::AddUnboxingFlagToPrimitiveType(TypeRelation *relation, Type *source, Type *self) { auto unboxingResult = UnboxingConverter(this, relation, source, self).Result(); - if ((unboxingResult != nullptr) && relation->IsTrue()) { + if ((unboxingResult != nullptr) && relation->IsTrue() && !relation->OnlyCheckBoxingUnboxing()) { relation->GetNode()->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxingResult)); } } @@ -2298,7 +2298,9 @@ void ETSChecker::CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *so ASSERT(relation != nullptr); checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx( relation, (relation->ApplyWidening() ? TypeRelationFlag::WIDENING : TypeRelationFlag::NONE) | - (relation->ApplyNarrowing() ? TypeRelationFlag::NARROWING : TypeRelationFlag::NONE)); + (relation->ApplyNarrowing() ? TypeRelationFlag::NARROWING : TypeRelationFlag::NONE) | + (relation->OnlyCheckBoxingUnboxing() ? TypeRelationFlag::ONLY_CHECK_BOXING_UNBOXING + : TypeRelationFlag::NONE)); auto *boxedSourceType = relation->GetChecker()->AsETSChecker()->PrimitiveTypeAsETSBuiltinType(source); if (boxedSourceType == nullptr) { return; @@ -2309,7 +2311,7 @@ void ETSChecker::CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *so return; } relation->IsAssignableTo(boxedSourceType, target); - if (relation->IsTrue() && !relation->OnlyCheckBoxingUnboxing()) { + if (relation->IsTrue()) { AddBoxingFlagToPrimitiveType(relation, boxedSourceType); } else { auto unboxedTargetType = ETSBuiltinTypeAsPrimitiveType(target); diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index 2727488971..3e49d99add 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -163,6 +163,9 @@ void ETSFunctionType::AssignmentTarget(TypeRelation *relation, Type *source) bool sourceIsFunctional = source->IsETSObjectType(); auto *sourceFuncType = sourceIsFunctional ? source->AsETSObjectType()->GetFunctionalInterfaceInvokeType() : source->AsETSFunctionType(); + + SavedTypeRelationFlagsContext savedFlagsCtx(relation, relation->GetTypeRelationFlags() | + TypeRelationFlag::ONLY_CHECK_BOXING_UNBOXING); Signature *match = ProcessSignatures(relation, target, sourceFuncType); if (match == nullptr) { diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index 729dc1f138..264512afd4 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -218,6 +218,11 @@ public: return (flags_ & TypeRelationFlag::OVERRIDING_CONTEXT) != 0; } + [[nodiscard]] TypeRelationFlag GetTypeRelationFlags() const noexcept + { + return flags_; + } + const Checker *GetChecker() const { return checker_; diff --git a/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type-expected.txt b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type-expected.txt new file mode 100644 index 0000000000..a9666c47c4 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type-expected.txt @@ -0,0 +1,563 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./generic_typealias_func_type_lib", + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 54 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "imported": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 54 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 8 + } + } + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": true, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "num", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 21 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 29 + }, + "end": { + "line": 19, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 29 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 29 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 19, + "column": 33 + }, + "end": { + "line": 19, + "column": 34 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 25 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 36 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type.ets b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type.ets new file mode 100644 index 0000000000..dbd311c1e7 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 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. + */ + +import {foo} from "./generic_typealias_func_type_lib" + +function main() { + foo((num:number) => new Int(1)); +} diff --git a/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib-expected.txt b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib-expected.txt new file mode 100644 index 0000000000..a7a1a9c596 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib-expected.txt @@ -0,0 +1,781 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "Exec", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 17 + } + } + }, + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "pointer", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 36 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 36 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 36 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 38 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 16, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 26 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "exec", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Exec", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 30 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 41 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 43 + }, + "end": { + "line": 18, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 43 + }, + "end": { + "line": 18, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 43 + }, + "end": { + "line": 18, + "column": 45 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 34 + }, + "end": { + "line": 18, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 30 + }, + "end": { + "line": 18, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 30 + }, + "end": { + "line": 18, + "column": 46 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 46 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 48 + }, + "end": { + "line": 18, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 48 + }, + "end": { + "line": 18, + "column": 51 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 48 + }, + "end": { + "line": 18, + "column": 51 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "exec", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 16 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 19, + "column": 17 + }, + "end": { + "line": 19, + "column": 18 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 20 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 50 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib.ets b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib.ets new file mode 100644 index 0000000000..a806c89a74 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 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. + */ + +export type Exec = (pointer: A) => B + +export function foo(exec: Exec): C { + return exec(1); +} -- Gitee From d0cd26bec665f08d10d7983baa0e697433c0abaa Mon Sep 17 00:00:00 2001 From: Molokanov Yaroslav Date: Wed, 6 Mar 2024 09:55:17 +0300 Subject: [PATCH 10/13] Fixed typo in CompileCastUnboxable Signed-off-by: Molokanov Yaroslav Accept-Changeset: 12880:fe:1956:rt:0 --- ets2panda/compiler/core/ETSCompiler.cpp | 4 ++-- ets2panda/test/runtime/ets/castSequence.ets | 8 ++++---- .../test/test-lists/ets-runtime/ets-runtime-ignored.txt | 3 --- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 23b067caa1..5004810c11 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -1989,11 +1989,11 @@ void ETSCompiler::CompileCastUnboxable(const ir::TSAsExpression *expr) const break; } case checker::ETSObjectFlags::BUILTIN_BYTE: { - etsg->CastToChar(expr); + etsg->CastToByte(expr); break; } case checker::ETSObjectFlags::BUILTIN_CHAR: { - etsg->CastToByte(expr); + etsg->CastToChar(expr); break; } case checker::ETSObjectFlags::BUILTIN_SHORT: { diff --git a/ets2panda/test/runtime/ets/castSequence.ets b/ets2panda/test/runtime/ets/castSequence.ets index c3e86ca68a..f490ee4f52 100644 --- a/ets2panda/test/runtime/ets/castSequence.ets +++ b/ets2panda/test/runtime/ets/castSequence.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 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 @@ -25,10 +25,10 @@ function main(): void { assert a_Short instanceof Short assert b_double == 215.0 - let a_Int : Int = 2142; - let b_Double : Double = a_Int as Double; + let a_char : char = 128 as char; + let b_Char = a_char as Char; - assert b_Double instanceof Double && b_Double.unboxed() == 2142.0 + assert b_Char.unboxed() == 128 as char; return; } \ No newline at end of file diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index 7b6b2e0d97..21ef806ea2 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -54,9 +54,6 @@ OptionalCall.ets # Functional type with rest parameter lambdaExpressionWithRestParameter.ets -# Non-trivial cast sequence -castSequence.ets - # ignored due to interface implementation modification local-class-standard-example1.ets local-class-standard-example2.ets -- Gitee From 07e586eff0cb5ac2aa54044300e4f419a4477709 Mon Sep 17 00:00:00 2001 From: churkinaleksey Date: Thu, 29 Feb 2024 16:58:54 +0300 Subject: [PATCH 11/13] remove incorrect extra identifier check Signed-off-by: churkinaleksey Accept-Changeset: 12810:fe:1933:rt:0 --- ets2panda/checker/ets/helpers.cpp | 19 ++----------------- .../checker/types/ets/etsDynamicType.cpp | 1 + ...l_variable_to_functional_type-expected.txt | 2 +- ...variable_to_functional_type_1-expected.txt | 2 +- .../ets/wrong_context_function_2-expected.txt | 2 +- 5 files changed, 6 insertions(+), 20 deletions(-) diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index f69cae8f86..3ec818dcc7 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -612,23 +612,8 @@ void ETSChecker::ValidateAssignmentIdentifier(ir::Identifier *const ident, varbi WrongContextErrorClassifyByType(ident, resolved); } - if (assignmentExpr->Right() == ident) { - const auto *const targetType = assignmentExpr->Left()->TsType(); - ASSERT(targetType != nullptr); - - if (targetType->IsETSObjectType() && targetType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { - if (!type->IsETSFunctionType() && - !(type->IsETSObjectType() && type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::FUNCTIONAL))) { - ThrowTypeError({"Assigning a non-functional variable \"", ident->Name(), "\" to a functional type"}, - ident->Start()); - } - - return; - } - - if (!resolved->Declaration()->PossibleTDZ()) { - WrongContextErrorClassifyByType(ident, resolved); - } + if (assignmentExpr->Right() == ident && (!resolved->Declaration()->PossibleTDZ() && !type->IsETSFunctionType())) { + WrongContextErrorClassifyByType(ident, resolved); } } diff --git a/ets2panda/checker/types/ets/etsDynamicType.cpp b/ets2panda/checker/types/ets/etsDynamicType.cpp index 07a2b9fe42..94a5f55e49 100644 --- a/ets2panda/checker/types/ets/etsDynamicType.cpp +++ b/ets2panda/checker/types/ets/etsDynamicType.cpp @@ -101,6 +101,7 @@ void ETSDynamicType::CastTarget(TypeRelation *relation, Type *source) bool ETSDynamicType::IsConvertible(Type const *target) { return target->IsETSDynamicType() || target->IsETSObjectType() || target->IsETSArrayType() || + target->IsETSFunctionType() || target->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC | checker::TypeFlag::ETS_BOOLEAN); } diff --git a/ets2panda/test/parser/ets/assignment_non-functional_variable_to_functional_type-expected.txt b/ets2panda/test/parser/ets/assignment_non-functional_variable_to_functional_type-expected.txt index 9bdd661396..846964a90f 100644 --- a/ets2panda/test/parser/ets/assignment_non-functional_variable_to_functional_type-expected.txt +++ b/ets2panda/test/parser/ets/assignment_non-functional_variable_to_functional_type-expected.txt @@ -947,4 +947,4 @@ } } } -TypeError: Assigning a non-functional variable "observable" to a functional type [assignment_non-functional_variable_to_functional_type.ets:23:71] +TypeError: Type 'Observable|undefined' cannot be assigned to type '() => Observable|undefined' [assignment_non-functional_variable_to_functional_type.ets:23:71] diff --git a/ets2panda/test/parser/ets/assignment_non-functional_variable_to_functional_type_1-expected.txt b/ets2panda/test/parser/ets/assignment_non-functional_variable_to_functional_type_1-expected.txt index 366185c853..1534a2aea3 100644 --- a/ets2panda/test/parser/ets/assignment_non-functional_variable_to_functional_type_1-expected.txt +++ b/ets2panda/test/parser/ets/assignment_non-functional_variable_to_functional_type_1-expected.txt @@ -446,4 +446,4 @@ } } } -TypeError: Assigning a non-functional variable "b" to a functional type [assignment_non-functional_variable_to_functional_type_1.ets:20:9] +TypeError: Type 'int' cannot be assigned to type '() => Int' [assignment_non-functional_variable_to_functional_type_1.ets:20:9] diff --git a/ets2panda/test/parser/ets/wrong_context_function_2-expected.txt b/ets2panda/test/parser/ets/wrong_context_function_2-expected.txt index 2589987bff..b86107b447 100644 --- a/ets2panda/test/parser/ets/wrong_context_function_2-expected.txt +++ b/ets2panda/test/parser/ets/wrong_context_function_2-expected.txt @@ -455,4 +455,4 @@ } } } -TypeError: Function name "a" used in the wrong context [wrong_context_function_2.ets:23:9] +TypeError: Type '() => void' cannot be assigned to type 'int' [wrong_context_function_2.ets:23:9] -- Gitee From 31af0bc8aa5b7e91d66b9cad508c952bf61941c5 Mon Sep 17 00:00:00 2001 From: Ede Monus Date: Thu, 25 Jan 2024 11:49:27 +0100 Subject: [PATCH 12/13] [ETS] Fix instanceof for arrays in the parser and checker and emitter Fixes and extends the existing implementation of instanceof operator used with arrays as an operand. Modifies the handling of the instanceof operator in the parser, the checker and also the emitter. Fixes #12528 internal issue. Change-Id: I771f3ec572dbee9e7b6ed35c0a7051a6bb4604a8 Signed-off-by: Ede Monus Accept-Changeset: 11413:fe:1452:rt:772 --- ets2panda/checker/ETSAnalyzer.cpp | 7 +- ets2panda/checker/checkerContext.h | 3 +- ets2panda/checker/ets/arithmetic.cpp | 37 +- ets2panda/checker/ets/typeCreation.cpp | 7 +- ets2panda/checker/ets/typeRelationContext.cpp | 10 + ets2panda/checker/types/ets/etsArrayType.h | 12 + ets2panda/compiler/core/ETSCompiler.cpp | 12 +- ets2panda/parser/ETSparser.cpp | 24 ++ ets2panda/parser/ETSparser.h | 2 + ets2panda/parser/expressionParser.cpp | 8 +- ets2panda/parser/parserImpl.h | 2 + .../ets/dynamic_instanceof-expected.txt | 76 +++- .../test/compiler/ets/dynamic_instanceof.ets | 3 +- .../compiler/ets/union_types_1-expected.txt | 146 ++++++-- ets2panda/test/compiler/ets/union_types_1.ets | 3 +- .../compiler/ets/union_types_3-expected.txt | 38 +- ets2panda/test/compiler/ets/union_types_3.ets | 1 + .../compiler/ets/union_types_5-expected.txt | 146 ++++++-- ets2panda/test/compiler/ets/union_types_5.ets | 3 +- .../test/parser/ets/binary_op-expected.txt | 78 ++++- .../test/parser/ets/instanceof-expected.txt | 326 ++++++++++++++++-- ets2panda/test/parser/ets/instanceof.ets | 11 +- ...stanceof_with_not_object_type-expected.txt | 98 ++++-- .../ets/instanceof_with_not_object_type.ets | 1 + .../test/runtime/ets/NullishInstanceof.ets | 10 +- ets2panda/test/runtime/ets/instanceof.ets | 46 ++- 26 files changed, 935 insertions(+), 175 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 31c307af92..8884209dee 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -504,7 +504,8 @@ checker::Type *ETSAnalyzer::Check(ir::ETSParameterExpression *expr) const checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSPrimitiveType *node) const { - return nullptr; + ETSChecker *checker = GetETSChecker(); + return node->GetType(checker); } checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const @@ -2043,6 +2044,10 @@ checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const { ETSChecker *checker = GetETSChecker(); node->elementType_->Check(checker); + node->SetTsType(node->GetType(checker)); + + const auto arrayType = node->TsType()->AsETSArrayType(); + checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); return nullptr; } diff --git a/ets2panda/checker/checkerContext.h b/ets2panda/checker/checkerContext.h index 11ff0c4f3c..f5e753ab7c 100644 --- a/ets2panda/checker/checkerContext.h +++ b/ets2panda/checker/checkerContext.h @@ -45,7 +45,8 @@ enum class CheckerStatus : uint32_t { IN_LAMBDA = 1U << 13U, IGNORE_VISIBILITY = 1U << 14U, IN_INSTANCE_EXTENSION_METHOD = 1U << 15U, - IN_LOCAL_CLASS = 1U << 16U + IN_LOCAL_CLASS = 1U << 16U, + IN_INSTANCEOF_CONTEXT = 1U << 17U }; DEFINE_BITOPS(CheckerStatus) diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 18a6cd4f88..3ccb73b7a2 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -519,6 +519,8 @@ std::tuple ETSChecker::CheckBinaryOperatorInstanceOf(lexer::Sour tsType = GlobalETSBooleanType(); checker::Type *opType = rightType->IsETSDynamicType() ? GlobalBuiltinJSValueType() : GlobalETSObjectType(); ComputeApparentType(rightType); + RemoveStatus(checker::CheckerStatus::IN_INSTANCEOF_CONTEXT); + return {tsType, opType}; } @@ -643,28 +645,39 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, } std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, ir::Expression *right, - ir::Expression *expr, lexer::TokenType op, + ir::Expression *expr, lexer::TokenType operationType, lexer::SourcePosition pos, bool forcePromotion) { checker::Type *const leftType = left->Check(this); - checker::Type *const rightType = right->Check(this); + + if (operationType == lexer::TokenType::KEYW_INSTANCEOF) { + AddStatus(checker::CheckerStatus::IN_INSTANCEOF_CONTEXT); + } + + checker::Type *rightType = right->Check(this); + + if (right->IsTypeNode()) { + rightType = right->AsTypeNode()->GetType(this); + } + if ((leftType == nullptr) || (rightType == nullptr)) { ThrowTypeError("Unexpected type error in binary expression", pos); } - const bool isLogicalExtendedOperator = - (op == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) || (op == lexer::TokenType::PUNCTUATOR_LOGICAL_OR); + const bool isLogicalExtendedOperator = (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) || + (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR); Type *unboxedL = isLogicalExtendedOperator ? ETSBuiltinTypeAsConditionalType(leftType) : ETSBuiltinTypeAsPrimitiveType(leftType); Type *unboxedR = isLogicalExtendedOperator ? ETSBuiltinTypeAsConditionalType(rightType) : ETSBuiltinTypeAsPrimitiveType(rightType); checker::Type *tsType {}; - bool isEqualOp = - (op > lexer::TokenType::PUNCTUATOR_SUBSTITUTION && op < lexer::TokenType::PUNCTUATOR_ARROW) && !forcePromotion; + bool isEqualOp = (operationType > lexer::TokenType::PUNCTUATOR_SUBSTITUTION && + operationType < lexer::TokenType::PUNCTUATOR_ARROW) && + !forcePromotion; - if (CheckBinaryOperatorForBigInt(leftType, rightType, expr, op)) { - switch (op) { + if (CheckBinaryOperatorForBigInt(leftType, rightType, expr, operationType)) { + switch (operationType) { case lexer::TokenType::PUNCTUATOR_GREATER_THAN: case lexer::TokenType::PUNCTUATOR_LESS_THAN: case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: @@ -676,13 +689,13 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, }; auto checkMap = GetCheckMap(); - if (checkMap.find(op) != checkMap.end()) { - auto check = checkMap[op]; - tsType = check(this, left, right, op, pos, isEqualOp, leftType, rightType, unboxedL, unboxedR); + if (checkMap.find(operationType) != checkMap.end()) { + auto check = checkMap[operationType]; + tsType = check(this, left, right, operationType, pos, isEqualOp, leftType, rightType, unboxedL, unboxedR); return {tsType, tsType}; } - BinaryOperatorParams binaryParams {left, right, expr, op, pos, isEqualOp}; + BinaryOperatorParams binaryParams {left, right, expr, operationType, pos, isEqualOp}; TypeParams typeParams {leftType, rightType, unboxedL, unboxedR}; return CheckBinaryOperatorHelper(this, binaryParams, typeParams); } diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index ece4b88625..4fd5609511 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -124,8 +124,13 @@ ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType) } auto *arrayType = Allocator()->New(elementType); + + std::stringstream ss; + arrayType->ToAssemblerTypeWithRank(ss); + arrayType->SetAssemblerName(util::UString(ss.str(), Allocator()).View()); + auto it = arrayTypes_.insert({elementType, arrayType}); - if (it.second && !elementType->IsETSTypeParameter()) { + if (it.second && (!elementType->IsTypeParameter() || !elementType->IsETSTypeParameter())) { CreateBuiltinArraySignature(arrayType, arrayType->Rank()); } diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index d958481084..bf40ac8c89 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -44,6 +44,16 @@ void AssignmentContext::ValidateArrayTypeInitializerByElement(TypeRelation *rela bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *typeArgs, const lexer::SourcePosition &pos) { + if (checker_->HasStatus(CheckerStatus::IN_INSTANCEOF_CONTEXT)) { + if (typeArgs != nullptr) { + checker_->ReportWarning( + {"Type parameter is erased from type '", type->Name(), "' when used in instanceof expression."}, pos); + } + + result_ = type; + return true; + } + checker_->CheckNumberOfTypeArguments(type, typeArgs, pos); if (type->TypeArguments().empty()) { result_ = type; diff --git a/ets2panda/checker/types/ets/etsArrayType.h b/ets2panda/checker/types/ets/etsArrayType.h index 1448f9a194..c1989155ad 100644 --- a/ets2panda/checker/types/ets/etsArrayType.h +++ b/ets2panda/checker/types/ets/etsArrayType.h @@ -39,6 +39,17 @@ public: } void ToString(std::stringstream &ss, bool precise) const override; + + const util::StringView &AssemblerName() const + { + return assemblerName_; + } + + void SetAssemblerName(const util::StringView &newName) + { + assemblerName_ = newName; + } + void ToAssemblerType(std::stringstream &ss) const override; void ToAssemblerTypeWithRank(std::stringstream &ss) const override; void ToDebugInfoType(std::stringstream &ss) const override; @@ -53,6 +64,7 @@ public: private: Type *element_; + util::StringView assemblerName_; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 5004810c11..770c332690 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -161,9 +161,11 @@ void ETSCompiler::Compile(const ir::ETSClassLiteral *expr) const } } -void ETSCompiler::Compile([[maybe_unused]] const ir::ETSFunctionType *node) const +void ETSCompiler::Compile(const ir::ETSFunctionType *node) const { - UNREACHABLE(); + ETSGen *etsg = GetETSGen(); + + etsg->LoadAccumulatorNull(node, node->TsType()); } void ETSCompiler::Compile(const ir::ETSTuple *node) const @@ -1972,9 +1974,11 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::TSAnyKeyword *node) const UNREACHABLE(); } -void ETSCompiler::Compile([[maybe_unused]] const ir::TSArrayType *node) const +void ETSCompiler::Compile(const ir::TSArrayType *node) const { - UNREACHABLE(); + ETSGen *etsg = GetETSGen(); + + etsg->LoadAccumulatorNull(node, node->TsType()); } void ETSCompiler::CompileCastUnboxable(const ir::TSAsExpression *expr) const diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 2521168da7..b2a5cf63c1 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -3041,6 +3041,10 @@ ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags fl ir::TypeNode *potentialType = ParseTypeAnnotation(&options); if (potentialType != nullptr) { + if (potentialType->IsTSArrayType()) { + return potentialType; + } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { Lexer()->NextToken(); // eat '.' } @@ -3159,6 +3163,26 @@ bool IsPunctuartorSpecialCharacter(lexer::TokenType tokenType) } } +ir::Expression *ETSParser::ParseExpressionOrTypeAnnotation(lexer::TokenType type, + [[maybe_unused]] ExpressionParseFlags flags) +{ + if (type == lexer::TokenType::KEYW_INSTANCEOF) { + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; + + if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_NULL) { + auto *typeAnnotation = AllocNode(); + typeAnnotation->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + + return typeAnnotation; + } + + return ParseTypeAnnotation(&options); + } + + return ParseExpression(ExpressionParseFlags::DISALLOW_YIELD); +} + bool ETSParser::IsArrowFunctionExpressionStart() { const auto savedPos = Lexer()->Save(); diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 9dc53f0199..d4f1151550 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -319,6 +319,8 @@ private: // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParseExpression(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; + ir::Expression *ParseExpressionOrTypeAnnotation(lexer::TokenType type, ExpressionParseFlags flags) override; + ir::Expression *ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags) override; ir::ModifierFlags ParseTypeVarianceModifier(TypeAnnotationParsingOptions *const options); diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 3915d74e21..275f6ca5b8 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -1246,6 +1246,12 @@ void ParserImpl::CreateAmendedBinaryExpression(ir::Expression *const left, ir::E SetAmendedChildExpression(right, binaryExpr); } +ir::Expression *ParserImpl::ParseExpressionOrTypeAnnotation([[maybe_unused]] lexer::TokenType type, + [[maybe_unused]] ExpressionParseFlags flags) +{ + return ParseExpression(ExpressionParseFlags::DISALLOW_YIELD); +} + ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, ExpressionParseFlags flags) { lexer::TokenType operatorType = lexer_->GetToken().Type(); @@ -1266,7 +1272,7 @@ ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, Expressi newFlags |= ExpressionParseFlags::INSTANCEOF; } - ir::Expression *rightExpr = ParseExpression(newFlags); + ir::Expression *rightExpr = ParseExpressionOrTypeAnnotation(operatorType, ExpressionParseFlags::DISALLOW_YIELD); ir::ConditionalExpression *conditionalExpr = nullptr; if (rightExpr->IsConditionalExpression() && !rightExpr->IsGrouped()) { diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index 9bcae1e84b..adf31834c6 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -417,6 +417,8 @@ protected: // NOLINTNEXTLINE(google-default-arguments) virtual ir::Expression *ParseExpression(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); // NOLINTNEXTLINE(google-default-arguments) + virtual ir::Expression *ParseExpressionOrTypeAnnotation(lexer::TokenType type, ExpressionParseFlags flags); + // NOLINTNEXTLINE(google-default-arguments) virtual ir::Expression *ParsePatternElement(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS, bool allowDefault = true); virtual bool ParsePotentialNonNullExpression(ir::Expression **returnExpression, lexer::SourcePosition startLoc); diff --git a/ets2panda/test/compiler/ets/dynamic_instanceof-expected.txt b/ets2panda/test/compiler/ets/dynamic_instanceof-expected.txt index dd0097eb28..e7006b43b9 100644 --- a/ets2panda/test/compiler/ets/dynamic_instanceof-expected.txt +++ b/ets2panda/test/compiler/ets/dynamic_instanceof-expected.txt @@ -455,9 +455,35 @@ } }, "right": { - "type": "Identifier", - "name": "A", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 22 + } + } + }, "loc": { "start": { "line": 24, @@ -465,7 +491,7 @@ }, "end": { "line": 24, - "column": 21 + "column": 22 } } }, @@ -476,7 +502,7 @@ }, "end": { "line": 24, - "column": 21 + "column": 22 } } }, @@ -638,9 +664,35 @@ } }, "right": { - "type": "Identifier", - "name": "B", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 26 + }, + "end": { + "line": 28, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 26 + }, + "end": { + "line": 28, + "column": 28 + } + } + }, "loc": { "start": { "line": 28, @@ -648,7 +700,7 @@ }, "end": { "line": 28, - "column": 27 + "column": 28 } } }, @@ -659,7 +711,7 @@ }, "end": { "line": 28, - "column": 27 + "column": 28 } } }, @@ -670,7 +722,7 @@ }, "end": { "line": 28, - "column": 27 + "column": 28 } } } @@ -1977,7 +2029,7 @@ "column": 1 }, "end": { - "line": 36, + "line": 37, "column": 1 } } diff --git a/ets2panda/test/compiler/ets/dynamic_instanceof.ets b/ets2panda/test/compiler/ets/dynamic_instanceof.ets index 67dd69427a..01b06b980a 100644 --- a/ets2panda/test/compiler/ets/dynamic_instanceof.ets +++ b/ets2panda/test/compiler/ets/dynamic_instanceof.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Copyright (c) 2021-2024 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 @@ -33,3 +33,4 @@ function foo(): int { } } } + diff --git a/ets2panda/test/compiler/ets/union_types_1-expected.txt b/ets2panda/test/compiler/ets/union_types_1-expected.txt index c6343a07d2..36e39123ab 100644 --- a/ets2panda/test/compiler/ets/union_types_1-expected.txt +++ b/ets2panda/test/compiler/ets/union_types_1-expected.txt @@ -1245,9 +1245,35 @@ } }, "right": { - "type": "Identifier", - "name": "C", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 22 + }, + "end": { + "line": 35, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 22 + }, + "end": { + "line": 35, + "column": 24 + } + } + }, "loc": { "start": { "line": 35, @@ -1255,7 +1281,7 @@ }, "end": { "line": 35, - "column": 23 + "column": 24 } } }, @@ -1266,7 +1292,7 @@ }, "end": { "line": 35, - "column": 23 + "column": 24 } } }, @@ -1546,9 +1572,35 @@ } }, "right": { - "type": "Identifier", - "name": "A", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 22 + }, + "end": { + "line": 39, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 22 + }, + "end": { + "line": 39, + "column": 24 + } + } + }, "loc": { "start": { "line": 39, @@ -1556,7 +1608,7 @@ }, "end": { "line": 39, - "column": 23 + "column": 24 } } }, @@ -1567,7 +1619,7 @@ }, "end": { "line": 39, - "column": 23 + "column": 24 } } }, @@ -2695,9 +2747,35 @@ } }, "right": { - "type": "Identifier", - "name": "C", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 54, + "column": 22 + }, + "end": { + "line": 54, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 54, + "column": 22 + }, + "end": { + "line": 54, + "column": 24 + } + } + }, "loc": { "start": { "line": 54, @@ -2705,7 +2783,7 @@ }, "end": { "line": 54, - "column": 23 + "column": 24 } } }, @@ -2716,7 +2794,7 @@ }, "end": { "line": 54, - "column": 23 + "column": 24 } } }, @@ -2996,9 +3074,35 @@ } }, "right": { - "type": "Identifier", - "name": "B", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 58, + "column": 22 + }, + "end": { + "line": 58, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 58, + "column": 22 + }, + "end": { + "line": 58, + "column": 24 + } + } + }, "loc": { "start": { "line": 58, @@ -3006,7 +3110,7 @@ }, "end": { "line": 58, - "column": 23 + "column": 24 } } }, @@ -3017,7 +3121,7 @@ }, "end": { "line": 58, - "column": 23 + "column": 24 } } }, @@ -3560,7 +3664,7 @@ "column": 1 }, "end": { - "line": 66, + "line": 67, "column": 1 } } diff --git a/ets2panda/test/compiler/ets/union_types_1.ets b/ets2panda/test/compiler/ets/union_types_1.ets index 2f162f1ab6..204d1fe74e 100644 --- a/ets2panda/test/compiler/ets/union_types_1.ets +++ b/ets2panda/test/compiler/ets/union_types_1.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Copyright (c) 2021-2024 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 @@ -63,3 +63,4 @@ function main() { x = new B(); assert x.num == 42: "Error! The num field of union must be 42"; } + diff --git a/ets2panda/test/compiler/ets/union_types_3-expected.txt b/ets2panda/test/compiler/ets/union_types_3-expected.txt index a7c1cbf3c9..7bd8537740 100644 --- a/ets2panda/test/compiler/ets/union_types_3-expected.txt +++ b/ets2panda/test/compiler/ets/union_types_3-expected.txt @@ -1178,9 +1178,35 @@ } }, "right": { - "type": "Identifier", - "name": "String", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 23 + }, + "end": { + "line": 26, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 23 + }, + "end": { + "line": 26, + "column": 30 + } + } + }, "loc": { "start": { "line": 26, @@ -1188,7 +1214,7 @@ }, "end": { "line": 26, - "column": 29 + "column": 30 } } }, @@ -1199,7 +1225,7 @@ }, "end": { "line": 26, - "column": 29 + "column": 30 } } }, @@ -1989,7 +2015,7 @@ "column": 1 }, "end": { - "line": 35, + "line": 36, "column": 1 } } diff --git a/ets2panda/test/compiler/ets/union_types_3.ets b/ets2panda/test/compiler/ets/union_types_3.ets index 7d39b29505..6bab46b68c 100644 --- a/ets2panda/test/compiler/ets/union_types_3.ets +++ b/ets2panda/test/compiler/ets/union_types_3.ets @@ -32,3 +32,4 @@ function main() { // assert (x3 as double) == 3.14: "Error! Must be `3.14`"; // #15576 assert (x3 as Double) == 3.14: "Error! Must be `3.14`"; } + diff --git a/ets2panda/test/compiler/ets/union_types_5-expected.txt b/ets2panda/test/compiler/ets/union_types_5-expected.txt index 718a439e68..f503ba0d24 100644 --- a/ets2panda/test/compiler/ets/union_types_5-expected.txt +++ b/ets2panda/test/compiler/ets/union_types_5-expected.txt @@ -1009,9 +1009,35 @@ } }, "right": { - "type": "Identifier", - "name": "B", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 22 + }, + "end": { + "line": 27, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 22 + }, + "end": { + "line": 27, + "column": 24 + } + } + }, "loc": { "start": { "line": 27, @@ -1019,7 +1045,7 @@ }, "end": { "line": 27, - "column": 23 + "column": 24 } } }, @@ -1030,7 +1056,7 @@ }, "end": { "line": 27, - "column": 23 + "column": 24 } } }, @@ -1170,9 +1196,35 @@ } }, "right": { - "type": "Identifier", - "name": "C", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 29 + }, + "end": { + "line": 29, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 29 + }, + "end": { + "line": 29, + "column": 31 + } + } + }, "loc": { "start": { "line": 29, @@ -1180,7 +1232,7 @@ }, "end": { "line": 29, - "column": 30 + "column": 31 } } }, @@ -1191,7 +1243,7 @@ }, "end": { "line": 29, - "column": 30 + "column": 31 } } }, @@ -1716,9 +1768,35 @@ } }, "right": { - "type": "Identifier", - "name": "B", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 37, + "column": 29 + }, + "end": { + "line": 37, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 37, + "column": 29 + }, + "end": { + "line": 37, + "column": 31 + } + } + }, "loc": { "start": { "line": 37, @@ -1726,7 +1804,7 @@ }, "end": { "line": 37, - "column": 30 + "column": 31 } } }, @@ -1737,7 +1815,7 @@ }, "end": { "line": 37, - "column": 30 + "column": 31 } } }, @@ -1937,9 +2015,35 @@ } }, "right": { - "type": "Identifier", - "name": "C", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 36 + }, + "end": { + "line": 39, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 36 + }, + "end": { + "line": 39, + "column": 38 + } + } + }, "loc": { "start": { "line": 39, @@ -1947,7 +2051,7 @@ }, "end": { "line": 39, - "column": 37 + "column": 38 } } }, @@ -1958,7 +2062,7 @@ }, "end": { "line": 39, - "column": 37 + "column": 38 } } }, @@ -3284,7 +3388,7 @@ "column": 1 }, "end": { - "line": 55, + "line": 56, "column": 1 } } diff --git a/ets2panda/test/compiler/ets/union_types_5.ets b/ets2panda/test/compiler/ets/union_types_5.ets index c99a77d48b..f7f8975f0c 100644 --- a/ets2panda/test/compiler/ets/union_types_5.ets +++ b/ets2panda/test/compiler/ets/union_types_5.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Copyright (c) 2021-2024 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 @@ -52,3 +52,4 @@ function main(): void { bar(a); foo(a.union0); } + diff --git a/ets2panda/test/parser/ets/binary_op-expected.txt b/ets2panda/test/parser/ets/binary_op-expected.txt index 131c35f763..1545494a35 100644 --- a/ets2panda/test/parser/ets/binary_op-expected.txt +++ b/ets2panda/test/parser/ets/binary_op-expected.txt @@ -2583,9 +2583,35 @@ } }, "right": { - "type": "Identifier", - "name": "Object", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 32 + } + } + }, "loc": { "start": { "line": 53, @@ -2593,7 +2619,7 @@ }, "end": { "line": 53, - "column": 31 + "column": 32 } } }, @@ -2604,7 +2630,7 @@ }, "end": { "line": 53, - "column": 31 + "column": 32 } } }, @@ -2615,7 +2641,7 @@ }, "end": { "line": 53, - "column": 31 + "column": 32 } } }, @@ -2626,7 +2652,7 @@ }, "end": { "line": 53, - "column": 31 + "column": 32 } } }, @@ -7419,9 +7445,35 @@ } }, "right": { - "type": "Identifier", - "name": "Object", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 32 + } + } + }, "loc": { "start": { "line": 53, @@ -7429,7 +7481,7 @@ }, "end": { "line": 53, - "column": 31 + "column": 32 } } }, @@ -7440,7 +7492,7 @@ }, "end": { "line": 53, - "column": 31 + "column": 32 } } }, @@ -7459,7 +7511,7 @@ }, "end": { "line": 53, - "column": 31 + "column": 32 } } }, diff --git a/ets2panda/test/parser/ets/instanceof-expected.txt b/ets2panda/test/parser/ets/instanceof-expected.txt index cb207635cf..9c79f62b0f 100644 --- a/ets2panda/test/parser/ets/instanceof-expected.txt +++ b/ets2panda/test/parser/ets/instanceof-expected.txt @@ -268,9 +268,35 @@ } }, "right": { - "type": "Identifier", - "name": "String", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, "loc": { "start": { "line": 17, @@ -278,7 +304,7 @@ }, "end": { "line": 17, - "column": 26 + "column": 27 } } }, @@ -289,7 +315,7 @@ }, "end": { "line": 17, - "column": 26 + "column": 27 } } }, @@ -336,43 +362,291 @@ } }, "alternate": { - "type": "BlockStatement", - "statements": [ - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 2, + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "operator": "instanceof", + "left": { + "type": "Identifier", + "name": "v", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "right": { + "type": "TSArrayType", + "elementType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 19, + "column": 27 + }, + "end": { + "line": 19, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 32 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, "loc": { "start": { "line": 20, - "column": 12 + "column": 5 }, "end": { "line": 20, - "column": 13 + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 34 + }, + "end": { + "line": 21, + "column": 4 + } + } + }, + "alternate": { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "operator": "instanceof", + "left": { + "type": "Identifier", + "name": "v", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 15 + } + } + }, + "right": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 27 + }, + "end": { + "line": 21, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 27 + }, + "end": { + "line": 21, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 27 + }, + "end": { + "line": 21, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 35 + }, + "end": { + "line": 21, + "column": 36 } } }, "loc": { "start": { - "line": 20, - "column": 5 + "line": 21, + "column": 14 }, "end": { - "line": 20, - "column": 14 + "line": 21, + "column": 36 } } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 22, + "column": 12 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 37 + }, + "end": { + "line": 23, + "column": 4 + } + } + }, + "alternate": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 4, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 10 + }, + "end": { + "line": 25, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10 + }, + "end": { + "line": 25, + "column": 4 + } } - ], + }, "loc": { "start": { "line": 19, "column": 10 }, "end": { - "line": 21, + "line": 25, "column": 4 } } @@ -383,7 +657,7 @@ "column": 3 }, "end": { - "line": 21, + "line": 25, "column": 4 } } @@ -395,7 +669,7 @@ "column": 28 }, "end": { - "line": 22, + "line": 26, "column": 2 } } @@ -406,7 +680,7 @@ "column": 11 }, "end": { - "line": 22, + "line": 26, "column": 2 } } @@ -417,7 +691,7 @@ "column": 11 }, "end": { - "line": 22, + "line": 26, "column": 2 } } @@ -430,7 +704,7 @@ "column": 1 }, "end": { - "line": 22, + "line": 26, "column": 2 } } @@ -465,7 +739,7 @@ "column": 1 }, "end": { - "line": 23, + "line": 28, "column": 1 } } diff --git a/ets2panda/test/parser/ets/instanceof.ets b/ets2panda/test/parser/ets/instanceof.ets index 76da8d3629..34a3ea4361 100644 --- a/ets2panda/test/parser/ets/instanceof.ets +++ b/ets2panda/test/parser/ets/instanceof.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2024 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 @@ -14,9 +14,14 @@ */ function t(v: Object): int { - if (v instanceof String) { + if (v instanceof string) { return 1; - } else { + } else if (v instanceof int[]) { return 2; + } else if (v instanceof Double[]) { + return 3; + } else { + return 4; } } + diff --git a/ets2panda/test/parser/ets/instanceof_with_not_object_type-expected.txt b/ets2panda/test/parser/ets/instanceof_with_not_object_type-expected.txt index bc8beb2d14..423949cdb8 100644 --- a/ets2panda/test/parser/ets/instanceof_with_not_object_type-expected.txt +++ b/ets2panda/test/parser/ets/instanceof_with_not_object_type-expected.txt @@ -218,11 +218,11 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 21, "column": 10 }, "end": { - "line": 20, + "line": 21, "column": 14 } } @@ -242,11 +242,11 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 21, "column": 10 }, "end": { - "line": 20, + "line": 21, "column": 14 } } @@ -269,11 +269,11 @@ "decorators": [], "loc": { "start": { - "line": 22, + "line": 23, "column": 9 }, "end": { - "line": 22, + "line": 23, "column": 10 } } @@ -283,22 +283,22 @@ "value": 0, "loc": { "start": { - "line": 22, + "line": 23, "column": 13 }, "end": { - "line": 22, + "line": 23, "column": 14 } } }, "loc": { "start": { - "line": 22, + "line": 23, "column": 9 }, "end": { - "line": 22, + "line": 23, "column": 14 } } @@ -307,11 +307,11 @@ "kind": "let", "loc": { "start": { - "line": 22, + "line": 23, "column": 5 }, "end": { - "line": 22, + "line": 23, "column": 14 } } @@ -327,82 +327,108 @@ "decorators": [], "loc": { "start": { - "line": 23, + "line": 24, "column": 5 }, "end": { - "line": 23, + "line": 24, "column": 6 } } }, "right": { - "type": "Identifier", - "name": "a", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 18 + }, + "end": { + "line": 24, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 18 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, "loc": { "start": { - "line": 23, + "line": 24, "column": 18 }, "end": { - "line": 23, - "column": 19 + "line": 25, + "column": 2 } } }, "loc": { "start": { - "line": 23, + "line": 24, "column": 5 }, "end": { - "line": 23, - "column": 19 + "line": 25, + "column": 2 } } }, "loc": { "start": { - "line": 23, + "line": 24, "column": 5 }, "end": { - "line": 23, - "column": 19 + "line": 25, + "column": 2 } } } ], "loc": { "start": { - "line": 21, + "line": 22, "column": 1 }, "end": { - "line": 24, + "line": 25, "column": 2 } } }, "loc": { "start": { - "line": 20, + "line": 21, "column": 14 }, "end": { - "line": 24, + "line": 25, "column": 2 } } }, "loc": { "start": { - "line": 20, + "line": 21, "column": 14 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -411,11 +437,11 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 21, "column": 1 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -450,9 +476,9 @@ "column": 1 }, "end": { - "line": 25, + "line": 26, "column": 1 } } } -TypeError: Using the "instance of" operator with non-object type "a" [instanceof_with_not_object_type.ets:23:18] +SyntaxError: Cannot find type 'a'. [instanceof_with_not_object_type.ets:24:18] diff --git a/ets2panda/test/parser/ets/instanceof_with_not_object_type.ets b/ets2panda/test/parser/ets/instanceof_with_not_object_type.ets index 610a8b32e0..2b48d38df1 100644 --- a/ets2panda/test/parser/ets/instanceof_with_not_object_type.ets +++ b/ets2panda/test/parser/ets/instanceof_with_not_object_type.ets @@ -17,6 +17,7 @@ function a() { } + function main() { let b = 0 diff --git a/ets2panda/test/runtime/ets/NullishInstanceof.ets b/ets2panda/test/runtime/ets/NullishInstanceof.ets index 076c3a182e..f905ff7751 100644 --- a/ets2panda/test/runtime/ets/NullishInstanceof.ets +++ b/ets2panda/test/runtime/ets/NullishInstanceof.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2024 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 @@ -17,10 +17,6 @@ function is_null(v: Object | null | undefined) { return v instanceof null; } -function is_undef(v: Object | null | undefined) { - return v instanceof undefined; -} - function is_obj(v: Object | null | undefined) { return v instanceof Object; } @@ -56,10 +52,6 @@ function main() { assert(is_null(undefined) == false); assert(is_null(obj) == false); - assert(is_undef(null) == false); - assert(is_undef(undefined) == true); - assert(is_undef(obj) == false); - assert(is_obj(null) == false); assert(is_obj(undefined) == false); assert(is_obj(obj) == true); diff --git a/ets2panda/test/runtime/ets/instanceof.ets b/ets2panda/test/runtime/ets/instanceof.ets index d138be6db3..bf8c536eac 100644 --- a/ets2panda/test/runtime/ets/instanceof.ets +++ b/ets2panda/test/runtime/ets/instanceof.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2024 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 @@ -13,20 +13,56 @@ * limitations under the License. */ +function bar() {} + +function foo(): () => void { + return bar; +} + function main(): void { let obj = new Boolean(); - assert (obj instanceof Object) - assert (obj instanceof Boolean) - assert (!(obj instanceof Long)) - let nobj: Object|null = null; + assert (null instanceof null) assert (nobj instanceof null) assert (!(obj instanceof null)) let arr: int[] = [1, 2, 3]; + assert (arr instanceof Object) assert (!(arr instanceof Long)) + assert (obj instanceof Object); + assert (obj instanceof Boolean); + assert (!(obj instanceof Long)); + + let intArr: int[] = [1, 2, 3]; + + assert (intArr instanceof int[]); + assert (intArr instanceof Object); + assert (!(intArr instanceof Long)); + assert (!(intArr instanceof Int[])); + assert (!(intArr instanceof Int)); + + let integerArr: Int[] = new Int[10]; + + assert (integerArr instanceof Int[]); + assert (integerArr instanceof Object); + assert (!(intArr instanceof Double[])); + assert (!(integerArr instanceof int[])); + assert (!(integerArr instanceof Int)); + + let integerArrArr: Int[][] = [[10], [20]]; + + assert (integerArrArr instanceof Int[][]); + assert (integerArrArr instanceof Object); + assert (!(integerArrArr instanceof Int[])); + assert (!(integerArrArr instanceof Int)); + assert (!(integerArrArr instanceof Long[][])); + + let f: () => void = foo(); + + assert (f instanceof (() => void)); return; } + -- Gitee From dc5f0e7cb36c51036432225428235fe67192a666 Mon Sep 17 00:00:00 2001 From: Ede Monus Date: Thu, 25 Jan 2024 11:49:27 +0100 Subject: [PATCH 13/13] [ETS] Fix instanceof for arrays in the parser and checker and emitter Fixes and extends the existing implementation of instanceof operator used with arrays as an operand. Modifies the handling of the instanceof operator in the parser, the checker and also the emitter. Fixes #12528 internal issue. Change-Id: I771f3ec572dbee9e7b6ed35c0a7051a6bb4604a8 Signed-off-by: Ede Monus --- ets2panda/ir/ets/etsTypeReferencePart.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index d1ccc84180..fd6e75f9d6 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -90,6 +90,8 @@ checker::Type *ETSTypeReferencePart::Check(checker::ETSChecker *checker) checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) { if (prev_ == nullptr) { + // name_->Check(checker); + if (name_->IsIdentifier()) { if ((name_->AsIdentifier()->Variable() != nullptr) && (name_->AsIdentifier()->Variable()->Declaration()->IsTypeAliasDecl())) { -- Gitee