From 6037d1906d88e5f9b44e52212d65ae79c285bf59 Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Fri, 8 Dec 2023 13:38:08 +0300 Subject: [PATCH 1/8] Issue: #I8MX10 Reason: es2panda-plugin-test fails in cross-compilation (qemu) setting Description: use ${PANDA_RUN_PREFIX} to start the test under qemu Tests: (Change after actual run) All required pre-merge tests passed. Results are available in ggwatcher. Signed-off-by: Georgy Bronnikov Change-Id: I697b72786994ea1597f7858c608fa2d02132f50a --- ets2panda/test/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ets2panda/test/CMakeLists.txt b/ets2panda/test/CMakeLists.txt index 906befaf5e..d589a4cd15 100644 --- a/ets2panda/test/CMakeLists.txt +++ b/ets2panda/test/CMakeLists.txt @@ -93,7 +93,8 @@ if(PANDA_WITH_ETS) add_custom_target(es2panda-plugin-test COMMENT "Test es2panda plugin functionality" - COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} $ --plugins=e2p_test_plugin + COMMAND ${CMAKE_COMMAND} -E env + LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${PANDA_RUN_PREFIX} $ --plugins=e2p_test_plugin "${CMAKE_CURRENT_SOURCE_DIR}/unit/public/t.ets" > "${CMAKE_CURRENT_BINARY_DIR}/plugin_test.out" COMMAND ${CMAKE_COMMAND} -E compare_files "${CMAKE_CURRENT_BINARY_DIR}/plugin_test.out" "${CMAKE_CURRENT_SOURCE_DIR}/unit/public/plugin_test.expected.txt" -- Gitee From bb5c4032f5d791637ce3b23b182b777008bfae10 Mon Sep 17 00:00:00 2001 From: Maxim Bolshov Date: Mon, 20 Nov 2023 20:48:46 +0300 Subject: [PATCH 2/8] Support array creation with numeric as index Allow pass double/float values as index to array creation expression. Compile-time error will be raised if fractional part is not zero for literal values, runtime error will be raised for such values not known at compile-time. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8NJ7Z Signed-off-by: Maxim Bolshov --- ets2panda/BUILD.gn | 1 + ets2panda/CMakeLists.txt | 1 + ets2panda/checker/ETSAnalyzer.cpp | 2 +- ets2panda/checker/ETSchecker.h | 2 +- ets2panda/checker/ets/object.cpp | 17 +- .../compiler/lowering/ets/expandBrackets.cpp | 83 ++++ .../compiler/lowering/ets/expandBrackets.h | 34 ++ ets2panda/compiler/lowering/phase.cpp | 3 + .../ir/ets/etsNewArrayInstanceExpression.h | 5 + .../test/parser/ets/array_new-expected.txt | 373 +++++++++++++++++ ets2panda/test/parser/ets/array_new.ets | 18 + .../parser/ets/array_new_failed-expected.txt | 374 ++++++++++++++++++ .../test/parser/ets/array_new_failed.ets | 18 + .../test/runtime/ets/array-new-catched.ets | 27 ++ ets2panda/test/runtime/ets/array-new.ets | 20 + 15 files changed, 975 insertions(+), 3 deletions(-) create mode 100644 ets2panda/compiler/lowering/ets/expandBrackets.cpp create mode 100644 ets2panda/compiler/lowering/ets/expandBrackets.h create mode 100644 ets2panda/test/parser/ets/array_new-expected.txt create mode 100644 ets2panda/test/parser/ets/array_new.ets create mode 100644 ets2panda/test/parser/ets/array_new_failed-expected.txt create mode 100644 ets2panda/test/parser/ets/array_new_failed.ets create mode 100644 ets2panda/test/runtime/ets/array-new-catched.ets create mode 100644 ets2panda/test/runtime/ets/array-new.ets diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 29be24a258..7ca9df82df 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -155,6 +155,7 @@ libes2panda_sources = [ "compiler/function/functionBuilder.cpp", "compiler/function/generatorFunctionBuilder.cpp", "compiler/lowering/checkerPhase.cpp", + "compiler/lowering/ets/expandBrackets.cpp", "compiler/lowering/ets/generateDeclarations.cpp", "compiler/lowering/ets/lambdaLowering.cpp", "compiler/lowering/ets/objectIndexAccess.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 33d347dbfa..22c9c38df8 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -146,6 +146,7 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/opAssignment.cpp compiler/lowering/ets/tupleLowering.cpp compiler/lowering/ets/unionLowering.cpp + compiler/lowering/ets/expandBrackets.cpp ir/astDump.cpp ir/astNode.cpp ir/irnode.cpp diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 2ddbdb26f1..7d83ab5c6f 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -504,7 +504,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const ETSChecker *checker = GetETSChecker(); auto *element_type = expr->type_reference_->GetType(checker); - checker->ValidateArrayIndex(expr->dimension_); + checker->ValidateArrayIndex(expr->dimension_, true); expr->SetTsType(checker->CreateETSArrayType(element_type)); checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index b2e30b4fe1..d8034074e2 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -141,7 +141,7 @@ public: const lexer::SourcePosition &pos); void ResolveDeclaredMembersOfObject(ETSObjectType *type); int32_t GetTupleElementAccessValue(const Type *type) const; - void ValidateArrayIndex(ir::Expression *expr); + void ValidateArrayIndex(ir::Expression *expr, bool relaxed = false); void ValidateTupleIndex(const ETSTupleType *tuple, const ir::MemberExpression *expr); ETSObjectType *CheckThisOrSuperAccess(ir::Expression *node, ETSObjectType *class_type, std::string_view msg); void CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index fc8c0d4b9f..9c9cd7bd4e 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -921,7 +921,7 @@ void ETSChecker::CheckInnerClassMembers(const ETSObjectType *class_type) } } -void ETSChecker::ValidateArrayIndex(ir::Expression *const expr) +void ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) { auto *const expression_type = expr->Check(this); auto const *const unboxed_expression_type = ETSBuiltinTypeAsPrimitiveType(expression_type); @@ -932,6 +932,21 @@ void ETSChecker::ValidateArrayIndex(ir::Expression *const expr) expr->AddBoxingUnboxingFlag(GetUnboxingFlag(unboxed_expression_type)); } + if (relaxed && index_type != nullptr && index_type->HasTypeFlag(TypeFlag::ETS_FLOATING_POINT)) { + if (!expr->IsNumberLiteral()) { + return; + } + + auto num = expr->AsNumberLiteral()->Number(); + ASSERT(num.IsReal()); + double value = num.GetDouble(); + double intpart; + if (std::modf(value, &intpart) != 0.0) { + ThrowTypeError("Index fracional part should not be different from 0.0", expr->Start()); + } + return; + } + if (index_type == nullptr || !index_type->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX)) { std::stringstream message(""); if (expression_type->IsNonPrimitiveType()) { diff --git a/ets2panda/compiler/lowering/ets/expandBrackets.cpp b/ets2panda/compiler/lowering/ets/expandBrackets.cpp new file mode 100644 index 0000000000..9a8c5388d3 --- /dev/null +++ b/ets2panda/compiler/lowering/ets/expandBrackets.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023 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. + */ + +#include "expandBrackets.h" + +#include "checker/ETSchecker.h" +#include "compiler/lowering/util.h" +#include "ir/statements/blockStatement.h" +#include "ir/expressions/memberExpression.h" +#include "parser/ETSparser.h" +#include "varbinder/ETSBinder.h" + +namespace panda::es2panda::compiler { + +static ir::Identifier *GenTmpIdentifier(checker::Type *type, ArenaAllocator *allocator, varbinder::Scope *scope) +{ + ir::Identifier *ident = Gensym(allocator); + auto *const tmp_var = scope->AddDecl(allocator, ident->Name(), + varbinder::VariableFlags::LOCAL); + tmp_var->SetTsType(type); + ident->SetVariable(tmp_var); + ident->SetTsType(tmp_var->TsType()); + return ident; +} + +bool ExpandBracketsPhase::Perform(public_lib::Context *ctx, parser::Program *program) +{ + auto *const checker = ctx->checker->AsETSChecker(); + auto *const allocator = checker->Allocator(); + auto *const parser = ctx->parser->AsETSParser(); + + program->Ast()->TransformChildrenRecursively([parser, checker, allocator](ir::AstNode *ast) -> ir::AstNode * { + if (!ast->IsETSNewArrayInstanceExpression()) { + return ast; + } + auto *new_expression = ast->AsETSNewArrayInstanceExpression(); + auto *dimension = new_expression->Dimension(); + auto *dim_type = dimension->TsType(); + if (auto *unboxed = checker->ETSBuiltinTypeAsPrimitiveType(dim_type); unboxed != nullptr) { + dim_type = unboxed; + } + if (!dim_type->HasTypeFlag(checker::TypeFlag::ETS_FLOATING_POINT)) { + return ast; + } + + auto *casted_dimension = + parser->CreateFormattedExpression("@@E1 as int", parser::DEFAULT_SOURCE_FILE, dimension); + casted_dimension->Check(checker); + casted_dimension->SetParent(dimension->Parent()); + new_expression->SetDimension(casted_dimension); + + auto *const scope = NearestScope(new_expression); + auto *ident = GenTmpIdentifier(dim_type, allocator, scope); + auto *expr_type = checker->AllocNode(dim_type); + auto *sequence_expr = parser->CreateFormattedExpression( + "let @@I1 = (@@E2) as @@T3;" + "if (!isSafeInteger(@@I4)) {" + " throw new TypeError(\"Index fractional part should not be different from 0.0\");" + "};" + "(@@E5);", + parser::DEFAULT_SOURCE_FILE, ident, dimension, expr_type, ident->Clone(allocator), new_expression); + sequence_expr->SetParent(new_expression->Parent()); + checker->VarBinder()->AsETSBinder()->ResolveReferencesForScope(sequence_expr, scope); + sequence_expr->Check(checker); + + return sequence_expr; + }); + return true; +} + +} // namespace panda::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/expandBrackets.h b/ets2panda/compiler/lowering/ets/expandBrackets.h new file mode 100644 index 0000000000..7a771f0789 --- /dev/null +++ b/ets2panda/compiler/lowering/ets/expandBrackets.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 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_COMPILER_LOWERING_EXPAND_BRACKETS_H +#define ES2PANDA_COMPILER_LOWERING_EXPAND_BRACKETS_H + +#include "compiler/lowering/phase.h" + +namespace panda::es2panda::compiler { + +class ExpandBracketsPhase : public Phase { +public: + std::string_view Name() override + { + return "expand-brackets"; + } + bool Perform(public_lib::Context *ctx, parser::Program *program) override; +}; + +} // namespace panda::es2panda::compiler + +#endif diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 7b285fed83..4dd62e0dee 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -21,6 +21,7 @@ #include "lexer/token/sourceLocation.h" #include "compiler/lowering/checkerPhase.h" #include "compiler/lowering/plugin_phase.h" +#include "compiler/lowering/ets/expandBrackets.h" #include "compiler/lowering/ets/generateDeclarations.h" #include "compiler/lowering/ets/lambdaLowering.h" #include "compiler/lowering/ets/opAssignment.h" @@ -45,6 +46,7 @@ static OpAssignmentLowering OP_ASSIGNMENT_LOWERING; static ObjectIndexLowering OBJECT_INDEX_LOWERING; static TupleLowering TUPLE_LOWERING; // Can be only applied after checking phase, and OP_ASSIGNMENT_LOWERING phase static UnionLowering UNION_LOWERING; +static ExpandBracketsPhase EXPAND_BRACKETS_PHASE; static PluginPhase PLUGINS_AFTER_PARSE {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse}; static PluginPhase PLUGINS_AFTER_CHECK {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck}; static PluginPhase PLUGINS_AFTER_LOWERINGS {"plugins-after-lowering", ES2PANDA_STATE_LOWERED, @@ -62,6 +64,7 @@ std::vector GetETSPhaseList() &OBJECT_INDEX_LOWERING, &TUPLE_LOWERING, &UNION_LOWERING, + &EXPAND_BRACKETS_PHASE, &PLUGINS_AFTER_LOWERINGS, }; } diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.h b/ets2panda/ir/ets/etsNewArrayInstanceExpression.h index c27416e5fa..9b8e1376df 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.h +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.h @@ -66,6 +66,11 @@ public: return dimension_; } + void SetDimension(ir::Expression *dimension) + { + dimension_ = dimension; + } + // NOLINTNEXTLINE(google-default-arguments) [[nodiscard]] ETSNewArrayInstanceExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; diff --git a/ets2panda/test/parser/ets/array_new-expected.txt b/ets2panda/test/parser/ets/array_new-expected.txt new file mode 100644 index 0000000000..f67a81d376 --- /dev/null +++ b/ets2panda/test/parser/ets/array_new-expected.txt @@ -0,0 +1,373 @@ +{ + "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": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "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": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "init": { + "type": "ETSNewArrayInstanceExpression", + "typeReference": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "dimension": { + "type": "NumberLiteral", + "value": 5, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 23 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 3 + }, + "end": { + "line": 17, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 18, + "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": 19, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/array_new.ets b/ets2panda/test/parser/ets/array_new.ets new file mode 100644 index 0000000000..3d6aca46c6 --- /dev/null +++ b/ets2panda/test/parser/ets/array_new.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 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 foo(): void { + let a = new int[5.0] +} diff --git a/ets2panda/test/parser/ets/array_new_failed-expected.txt b/ets2panda/test/parser/ets/array_new_failed-expected.txt new file mode 100644 index 0000000000..7a1d50898a --- /dev/null +++ b/ets2panda/test/parser/ets/array_new_failed-expected.txt @@ -0,0 +1,374 @@ +{ + "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": "foo", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "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": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "init": { + "type": "ETSNewArrayInstanceExpression", + "typeReference": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "dimension": { + "type": "NumberLiteral", + "value": 5.1, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 23 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 3 + }, + "end": { + "line": 17, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 18, + "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": 19, + "column": 1 + } + } +} +TypeError: Index fracional part should not be different from 0.0 [array_new_failed.ets:17:19] diff --git a/ets2panda/test/parser/ets/array_new_failed.ets b/ets2panda/test/parser/ets/array_new_failed.ets new file mode 100644 index 0000000000..226b20a4d5 --- /dev/null +++ b/ets2panda/test/parser/ets/array_new_failed.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 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 foo(): void { + let a = new int[5.1] +} diff --git a/ets2panda/test/runtime/ets/array-new-catched.ets b/ets2panda/test/runtime/ets/array-new-catched.ets new file mode 100644 index 0000000000..9fd9a7201f --- /dev/null +++ b/ets2panda/test/runtime/ets/array-new-catched.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 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 baz(): number { + return 5.1 +} +function main(): void { + let catched = false; + try { + let a = new int[baz()] + } catch (e: TypeError) { + catched = true + } + assert catched +} diff --git a/ets2panda/test/runtime/ets/array-new.ets b/ets2panda/test/runtime/ets/array-new.ets new file mode 100644 index 0000000000..16037be12b --- /dev/null +++ b/ets2panda/test/runtime/ets/array-new.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 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(): void { + let A: Array = new Array(); + let a: Number[] = new Number[A.length + 2] + assert a.length == 2 +} -- Gitee From a0c357b81a8947af6a12675eb4884f2bf31f3080 Mon Sep 17 00:00:00 2001 From: ozerovnikita Date: Thu, 9 Nov 2023 20:14:04 +0300 Subject: [PATCH 3/8] fix hardcoded arktsconfig path Description: Move arktsconfig.json generation path to es2panda bin directory and change es2panda option.cpp to open it by default Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8J02Y Signed-off-by: ozerovnikita --- ets2panda/BUILD.gn | 4 --- ets2panda/CMakeLists.txt | 27 ++++++++++++++++--- ets2panda/test/unit/ast_dumper_test.cpp | 10 ++++--- .../test/unit/public/es2panda_public_test.cpp | 2 +- ets2panda/util/arktsconfig.cpp | 4 +-- ets2panda/util/arktsconfig.h | 4 +++ ets2panda/util/options.cpp | 9 ++++++- 7 files changed, 44 insertions(+), 16 deletions(-) diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 7ca9df82df..cb59a25c18 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -372,14 +372,10 @@ libes2panda_public_sources = [ "util/options.cpp", ] -build_gen_root = rebase_path(root_gen_dir) - config("libes2panda_config") { cflags_cc = [ "-fexceptions", "-Werror=shadow", - - "-DDEFAULT_ARKTSCONFIG=\"$build_gen_root/tools/es2panda/generated/arktsconfig.json\"", ] } diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 22c9c38df8..33b9d5959d 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -24,8 +24,31 @@ set(ES2PANDA_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}) set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(GENERATED_DIR ${OUTPUT_DIR}/generated) set(GENERATED_STAMP ${OUTPUT_DIR}/gen_dir.stamp) +if(CMAKE_CROSSCOMPILING) + ExternalProject_Get_Property(panda_host_tools binary_dir) + set(DEFAULT_ARKTSCONFIG "${binary_dir}/tools/es2panda/aot") +else() + set(DEFAULT_ARKTSCONFIG "${CMAKE_BINARY_DIR}/bin") +endif() file(MAKE_DIRECTORY "${GENERATED_DIR}") if(PANDA_WITH_ETS) + file(WRITE "${DEFAULT_ARKTSCONFIG}/arktsconfig.json" + "{\n" + " \"compilerOptions\": {\n" + " \"baseUrl\": \"${PANDA_ROOT}\",\n" + " \"paths\": {\n" + " \"std\": [\"${PANDA_ROOT}/plugins/ets/stdlib/std\"],\n" + " \"escompat\": [\"${PANDA_ROOT}/plugins/ets/stdlib/escompat\"],\n" + " \"import_tests\": [\"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/import_tests\"],\n" + " \"dynamic_import_tests\": [\"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests\"]\n" + " },\n" + " \"dynamicPaths\": {\n" + " \"dynamic_js_import_tests\": {\"language\": \"js\", \"hasDecl\": false},\n" + " \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests\": {\"language\": \"js\", \"hasDecl\": true}\n" + " }\n" + " }\n" + "}\n" + ) file(WRITE "${GENERATED_DIR}/arktsconfig.json" "{\n" " \"compilerOptions\": {\n" @@ -483,10 +506,6 @@ panda_target_include_directories(es2panda-public PRIVATE ${OUTPUT_DIR} ) -panda_target_compile_definitions(es2panda-public - PRIVATE "DEFAULT_ARKTSCONFIG=\"${GENERATED_DIR}/arktsconfig.json\"" -) - panda_target_compile_options(es2panda-public PRIVATE -fexceptions -Werror=shadow ) diff --git a/ets2panda/test/unit/ast_dumper_test.cpp b/ets2panda/test/unit/ast_dumper_test.cpp index 6d38b78fe1..e57b5adfea 100644 --- a/ets2panda/test/unit/ast_dumper_test.cpp +++ b/ets2panda/test/unit/ast_dumper_test.cpp @@ -83,8 +83,9 @@ TEST_F(ASTDumperTest, DumpJsonSimple) return a + b;\ }"; - int argc = 0; - const char *argv = ""; + int argc = 1; + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + const char *argv = "../../../bin/es2panda"; auto program = std::unique_ptr {GetProgram(argc, &argv, FILE_NAME, SRC)}; @@ -108,8 +109,9 @@ TEST_F(ASTDumperTest, DumpJsonUTF16Char) return 0;\ }"; - int argc = 0; - const char *argv = ""; + int argc = 1; + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + const char *argv = "../../../bin/es2panda"; auto program = std::unique_ptr {GetProgram(argc, &argv, FILE_NAME, SRC)}; diff --git a/ets2panda/test/unit/public/es2panda_public_test.cpp b/ets2panda/test/unit/public/es2panda_public_test.cpp index 723fd07de0..fcdef1dd36 100644 --- a/ets2panda/test/unit/public/es2panda_public_test.cpp +++ b/ets2panda/test/unit/public/es2panda_public_test.cpp @@ -23,7 +23,7 @@ public: { impl_ = es2panda_GetImpl(ES2PANDA_LIB_VERSION); // NOLINTNEXTLINE(modernize-avoid-c-arrays) - char const *argv[] = {"test"}; + char const *argv[] = {"../../../bin/es2panda"}; cfg_ = impl_->CreateConfig(1, argv); } diff --git a/ets2panda/util/arktsconfig.cpp b/ets2panda/util/arktsconfig.cpp index 3b12b56143..71feee3c18 100644 --- a/ets2panda/util/arktsconfig.cpp +++ b/ets2panda/util/arktsconfig.cpp @@ -57,7 +57,7 @@ static bool IsAbsolute(const std::string &path) #endif // ARKTSCONFIG_USE_FILESYSTEM } -static std::string JoinPaths(const std::string &a, const std::string &b) +std::string JoinPaths(const std::string &a, const std::string &b) { #ifndef ARKTSCONFIG_USE_FILESYSTEM return a + '/' + b; @@ -66,7 +66,7 @@ static std::string JoinPaths(const std::string &a, const std::string &b) #endif // ARKTSCONFIG_USE_FILESYSTEM } -static std::string ParentPath(const std::string &path) +std::string ParentPath(const std::string &path) { #ifndef ARKTSCONFIG_USE_FILESYSTEM auto pos = path.find('/'); diff --git a/ets2panda/util/arktsconfig.h b/ets2panda/util/arktsconfig.h index 87fa056006..4ba6b88548 100644 --- a/ets2panda/util/arktsconfig.h +++ b/ets2panda/util/arktsconfig.h @@ -143,6 +143,10 @@ private: // Find source files and compute destination locations // Return: vector of path pairs std::vector> FindProjectSources(const std::shared_ptr &arkts_config); + +std::string JoinPaths(const std::string &a, const std::string &b); +std::string ParentPath(const std::string &path); + } // namespace panda::es2panda #endif // ES2PANDA_AOT_TSCONFIG_H diff --git a/ets2panda/util/options.cpp b/ets2panda/util/options.cpp index f05099ad67..7df1a65674 100644 --- a/ets2panda/util/options.cpp +++ b/ets2panda/util/options.cpp @@ -17,6 +17,8 @@ #include "utils/pandargs.h" +#include "arktsconfig.h" + #include #ifdef PANDA_WITH_BYTECODE_OPTIMIZER @@ -183,7 +185,12 @@ bool Options::Parse(int argc, const char **argv) "Generate program dump before running phases in the list"); panda::PandArg dump_after_phases("dump-after-phases", "", "Generate program dump after running phases in the list"); - panda::PandArg arkts_config("arktsconfig", DEFAULT_ARKTSCONFIG, "Path to arkts configuration file"); + panda::PandArg arkts_config( + "arktsconfig", + panda::es2panda::JoinPaths( + panda::es2panda::ParentPath(argv[0]), // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + "arktsconfig.json"), + "Path to arkts configuration file"); // tail arguments panda::PandArg input_file("input", "", "input file"); -- Gitee From c86189cdcac7c891e559948bf9d9d7edcfbf93f5 Mon Sep 17 00:00:00 2001 From: gergocs Date: Thu, 30 Nov 2023 10:25:30 +0100 Subject: [PATCH 4/8] Fix assertion fail with null-coalescing with generics Description: This patch should fix the issue with null-coalescing operator usage with generics Issue: #14609 internal Testing: null-coalescing with generics Change-Id: Iddcc95411f1aab832e8d1020ae9c1dc444fb3502 Signed-off-by: Gergo Csizi --- ets2panda/checker/ets/object.cpp | 4 + .../parser/ets/NullCoalescingWithGenerics | 21 + .../NullCoalescingWithGenerics-expected.txt | 741 ++++++++++++++++++ 3 files changed, 766 insertions(+) create mode 100644 ets2panda/test/parser/ets/NullCoalescingWithGenerics create mode 100644 ets2panda/test/parser/ets/NullCoalescingWithGenerics-expected.txt diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 9c9cd7bd4e..d4af0bb605 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1536,6 +1536,10 @@ ETSObjectType *ETSChecker::GetTypeargumentedLUB(ETSObjectType *const source, ETS const util::StringView hash = GetHashFromTypeArguments(params); + if (!source->GetDeclNode()->IsClassDefinition()) { + return source; + } + ETSObjectType *template_type = source->GetDeclNode()->AsClassDefinition()->TsType()->AsETSObjectType(); auto *lub_type = template_type->GetInstantiatedType(hash); diff --git a/ets2panda/test/parser/ets/NullCoalescingWithGenerics b/ets2panda/test/parser/ets/NullCoalescingWithGenerics new file mode 100644 index 0000000000..2cfc5d722f --- /dev/null +++ b/ets2panda/test/parser/ets/NullCoalescingWithGenerics @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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 A { + public parent: A + alma() : A { + return this.parent ?? this + } +} diff --git a/ets2panda/test/parser/ets/NullCoalescingWithGenerics-expected.txt b/ets2panda/test/parser/ets/NullCoalescingWithGenerics-expected.txt new file mode 100644 index 0000000000..755a902cd8 --- /dev/null +++ b/ets2panda/test/parser/ets/NullCoalescingWithGenerics-expected.txt @@ -0,0 +1,741 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 29, + "column": 1 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 29, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 29, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 29, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "parent", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 1 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 1 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "alma", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "alma", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "LogicalExpression", + "operator": "??", + "left": { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 1 + } + } + }, + "property": { + "type": "Identifier", + "name": "parent", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 1 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 1 + } + } + }, + "right": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 33, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 33, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 33, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 33, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "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": 34, + "column": 1 + }, + "end": { + "line": 34, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 34, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 34, + "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": 35, + "column": 1 + } + } +} -- Gitee From 39de6911076aec1cec64050aaa6aa635aad47372 Mon Sep 17 00:00:00 2001 From: Martin Sajti Date: Fri, 8 Dec 2023 13:41:29 +0100 Subject: [PATCH 5/8] Fix lambda throw false 'undefined reference' errors for some variables Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8MXUD Internal issue: #12451, #12961, #13184 Test: build, new checker tests Signed-off-by: Martin Sajti --- ets2panda/checker/ets/function.cpp | 20 +- .../ets/lambda_unresolved_ref_1-expected.txt | 3979 +++++++++++++++++ .../compiler/ets/lambda_unresolved_ref_1.ets | 56 + 3 files changed, 4050 insertions(+), 5 deletions(-) create mode 100644 ets2panda/test/compiler/ets/lambda_unresolved_ref_1-expected.txt create mode 100644 ets2panda/test/compiler/ets/lambda_unresolved_ref_1.ets diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 6db0ba9c72..1d6467d3c8 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1143,16 +1143,26 @@ void ETSChecker::ValidateSignatureAccessibility(ETSObjectType *callee, Signature } } -void ETSChecker::CheckCapturedVariable(ir::AstNode *node, varbinder::Variable *var) +void ETSChecker::CheckCapturedVariable(ir::AstNode *const node, varbinder::Variable *const var) { if (node->IsIdentifier()) { - auto *parent = node->Parent(); + const auto *const parent = node->Parent(); + if (parent->IsUpdateExpression() || (parent->IsAssignmentExpression() && parent->AsAssignmentExpression()->Left() == node)) { - auto *ident_node = node->AsIdentifier(); - ResolveIdentifier(ident_node); + const auto *const ident_node = node->AsIdentifier(); + + const auto *resolved = ident_node->Variable(); + + if (resolved == nullptr) { + resolved = FindVariableInFunctionScope(ident_node->Name()); + } + + if (resolved == nullptr) { + resolved = FindVariableInGlobal(ident_node); + } - if (ident_node->Variable() == var) { + if (resolved == var) { var->AddFlag(varbinder::VariableFlags::BOXED); } } diff --git a/ets2panda/test/compiler/ets/lambda_unresolved_ref_1-expected.txt b/ets2panda/test/compiler/ets/lambda_unresolved_ref_1-expected.txt new file mode 100644 index 0000000000..8588d0e5bb --- /dev/null +++ b/ets2panda/test/compiler/ets/lambda_unresolved_ref_1-expected.txt @@ -0,0 +1,3979 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "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": 12 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 17, + "column": 31 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 33 + }, + "end": { + "line": 17, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 33 + }, + "end": { + "line": 17, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 33 + }, + "end": { + "line": 17, + "column": 39 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 17 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 36 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 36 + }, + "end": { + "line": 18, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 36 + }, + "end": { + "line": 18, + "column": 43 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "fn", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 46 + }, + "end": { + "line": 18, + "column": 48 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 46 + }, + "end": { + "line": 18, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 46 + }, + "end": { + "line": 18, + "column": 50 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 44 + }, + "end": { + "line": 18, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 32 + }, + "end": { + "line": 18, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 32 + }, + "end": { + "line": 18, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 53 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 53 + } + } + }, + { + "type": "ForUpdateStatement", + "init": { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "j", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 20 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 24 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "j", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 26 + }, + "end": { + "line": 19, + "column": 27 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 26 + }, + "end": { + "line": 19, + "column": 31 + } + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "j", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 35 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 33 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 19, + "column": 38 + }, + "end": { + "line": 19, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "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": 21, + "column": 2 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + { + "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": 23, + "column": 10 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "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": 23, + "column": 10 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "arr", + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 27 + }, + "end": { + "line": 23, + "column": 28 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 14 + }, + "end": { + "line": 23, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 14 + }, + "end": { + "line": 23, + "column": 28 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 30 + }, + "end": { + "line": 23, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 30 + }, + "end": { + "line": 23, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 30 + }, + "end": { + "line": 23, + "column": 36 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "copy", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 14 + }, + "end": { + "line": 24, + "column": 26 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 8 + }, + "end": { + "line": 24, + "column": 12 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 31 + }, + "end": { + "line": 24, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 31 + }, + "end": { + "line": 24, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 31 + }, + "end": { + "line": 24, + "column": 38 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 8 + } + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "arr", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 11 + }, + "end": { + "line": 25, + "column": 14 + } + } + }, + "property": { + "type": "Identifier", + "name": "length", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 15 + }, + "end": { + "line": 25, + "column": 21 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 25, + "column": 11 + }, + "end": { + "line": 25, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 21 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 25, + "column": 3 + }, + "end": { + "line": 25, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 39 + }, + "end": { + "line": 26, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 27 + }, + "end": { + "line": 26, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 27 + }, + "end": { + "line": 26, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 8 + }, + "end": { + "line": 26, + "column": 3 + } + } + } + ], + "kind": "const", + "loc": { + "start": { + "line": 24, + "column": 2 + }, + "end": { + "line": 26, + "column": 3 + } + } + }, + { + "type": "ForUpdateStatement", + "init": { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 11 + }, + "end": { + "line": 27, + "column": 12 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 27, + "column": 15 + }, + "end": { + "line": 27, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 11 + }, + "end": { + "line": 27, + "column": 16 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 27, + "column": 7 + }, + "end": { + "line": 27, + "column": 16 + } + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 18 + }, + "end": { + "line": 27, + "column": 19 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 10, + "loc": { + "start": { + "line": 27, + "column": 22 + }, + "end": { + "line": 27, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 18 + }, + "end": { + "line": 27, + "column": 24 + } + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 26 + }, + "end": { + "line": 27, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 26 + }, + "end": { + "line": 27, + "column": 29 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 27, + "column": 31 + }, + "end": { + "line": 27, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 2 + }, + "end": { + "line": 27, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo2", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 10 + }, + "end": { + "line": 30, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo2", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 10 + }, + "end": { + "line": 30, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "arr", + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 20 + }, + "end": { + "line": 30, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 20 + }, + "end": { + "line": 30, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 20 + }, + "end": { + "line": 30, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 28 + }, + "end": { + "line": 30, + "column": 29 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 15 + }, + "end": { + "line": 30, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 15 + }, + "end": { + "line": 30, + "column": 29 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 31 + }, + "end": { + "line": 30, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 31 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 31 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "copy", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 20 + }, + "end": { + "line": 31, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 20 + }, + "end": { + "line": 31, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 20 + }, + "end": { + "line": 31, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 31, + "column": 26 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 8 + }, + "end": { + "line": 31, + "column": 12 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 31 + }, + "end": { + "line": 31, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 31 + }, + "end": { + "line": 31, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 31 + }, + "end": { + "line": 31, + "column": 38 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 7 + }, + "end": { + "line": 32, + "column": 8 + } + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "arr", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 11 + }, + "end": { + "line": 32, + "column": 14 + } + } + }, + "property": { + "type": "Identifier", + "name": "length", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 15 + }, + "end": { + "line": 32, + "column": 21 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 32, + "column": 11 + }, + "end": { + "line": 32, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 7 + }, + "end": { + "line": 32, + "column": 21 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 32, + "column": 3 + }, + "end": { + "line": 32, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 39 + }, + "end": { + "line": 33, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 27 + }, + "end": { + "line": 33, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 27 + }, + "end": { + "line": 33, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 8 + }, + "end": { + "line": 33, + "column": 3 + } + } + } + ], + "kind": "const", + "loc": { + "start": { + "line": 31, + "column": 2 + }, + "end": { + "line": 33, + "column": 3 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "s", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 34, + "column": 9 + }, + "end": { + "line": 34, + "column": 12 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 6 + }, + "end": { + "line": 34, + "column": 7 + } + } + }, + "init": null, + "loc": { + "start": { + "line": 34, + "column": 6 + }, + "end": { + "line": 34, + "column": 7 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 34, + "column": 2 + }, + "end": { + "line": 34, + "column": 7 + } + } + }, + { + "type": "ForUpdateStatement", + "init": { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 11 + }, + "end": { + "line": 35, + "column": 12 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 35, + "column": 15 + }, + "end": { + "line": 35, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 11 + }, + "end": { + "line": 35, + "column": 16 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 35, + "column": 7 + }, + "end": { + "line": 35, + "column": 16 + } + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 18 + }, + "end": { + "line": 35, + "column": 19 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 10, + "loc": { + "start": { + "line": 35, + "column": 22 + }, + "end": { + "line": 35, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 18 + }, + "end": { + "line": 35, + "column": 24 + } + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 26 + }, + "end": { + "line": 35, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 26 + }, + "end": { + "line": 35, + "column": 29 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 35, + "column": 31 + }, + "end": { + "line": 35, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 2 + }, + "end": { + "line": 35, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 36 + }, + "end": { + "line": 36, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 14 + }, + "end": { + "line": 36, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 14 + }, + "end": { + "line": 36, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 36, + "column": 2 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 10 + }, + "end": { + "line": 39, + "column": 13 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 10 + }, + "end": { + "line": 39, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 17 + }, + "end": { + "line": 39, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 17 + }, + "end": { + "line": 39, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 17 + }, + "end": { + "line": 39, + "column": 23 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "arr", + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 40, + "column": 11 + }, + "end": { + "line": 40, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 19 + }, + "end": { + "line": 40, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 6 + }, + "end": { + "line": 40, + "column": 9 + } + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 40, + "column": 22 + }, + "end": { + "line": 40, + "column": 23 + } + } + }, + { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 40, + "column": 24 + }, + "end": { + "line": 40, + "column": 25 + } + } + }, + { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 40, + "column": 26 + }, + "end": { + "line": 40, + "column": 27 + } + } + }, + { + "type": "NumberLiteral", + "value": 4, + "loc": { + "start": { + "line": 40, + "column": 28 + }, + "end": { + "line": 40, + "column": 29 + } + } + } + ], + "loc": { + "start": { + "line": 40, + "column": 21 + }, + "end": { + "line": 40, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 6 + }, + "end": { + "line": 40, + "column": 30 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 40, + "column": 2 + }, + "end": { + "line": 40, + "column": 30 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "v", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 41, + "column": 17 + }, + "end": { + "line": 41, + "column": 22 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 14 + }, + "end": { + "line": 41, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 14 + }, + "end": { + "line": 41, + "column": 22 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 27 + }, + "end": { + "line": 41, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 27 + }, + "end": { + "line": 41, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 27 + }, + "end": { + "line": 41, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 13 + }, + "end": { + "line": 41, + "column": 33 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 9 + }, + "end": { + "line": 41, + "column": 11 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "v", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 41, + "column": 38 + }, + "end": { + "line": 41, + "column": 43 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 35 + }, + "end": { + "line": 41, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 35 + }, + "end": { + "line": 41, + "column": 43 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 46 + }, + "end": { + "line": 41, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 46 + }, + "end": { + "line": 41, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 46 + }, + "end": { + "line": 41, + "column": 53 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "arr", + "decorators": [], + "loc": { + "start": { + "line": 42, + "column": 9 + }, + "end": { + "line": 42, + "column": 12 + } + } + }, + "property": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 42, + "column": 13 + }, + "end": { + "line": 42, + "column": 14 + } + } + }, + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 42, + "column": 9 + }, + "end": { + "line": 42, + "column": 15 + } + } + }, + "right": { + "type": "TSAsExpression", + "expression": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Identifier", + "name": "v", + "decorators": [], + "loc": { + "start": { + "line": 42, + "column": 19 + }, + "end": { + "line": 42, + "column": 20 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 42, + "column": 23 + }, + "end": { + "line": 42, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 42, + "column": 18 + }, + "end": { + "line": 42, + "column": 25 + } + } + }, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 42, + "column": 29 + }, + "end": { + "line": 42, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 42, + "column": 18 + }, + "end": { + "line": 42, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 42, + "column": 9 + }, + "end": { + "line": 42, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 42, + "column": 9 + }, + "end": { + "line": 42, + "column": 35 + } + } + } + ], + "loc": { + "start": { + "line": 41, + "column": 54 + }, + "end": { + "line": 43, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 34 + }, + "end": { + "line": 43, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 34 + }, + "end": { + "line": 43, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 9 + }, + "end": { + "line": 43, + "column": 6 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 41, + "column": 5 + }, + "end": { + "line": 43, + "column": 6 + } + } + }, + { + "type": "ForUpdateStatement", + "init": { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "arr", + "decorators": [], + "loc": { + "start": { + "line": 44, + "column": 14 + }, + "end": { + "line": 44, + "column": 17 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 44, + "column": 20 + }, + "end": { + "line": 44, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 44, + "column": 14 + }, + "end": { + "line": 44, + "column": 21 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 44, + "column": 10 + }, + "end": { + "line": 44, + "column": 21 + } + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "arr", + "decorators": [], + "loc": { + "start": { + "line": 44, + "column": 23 + }, + "end": { + "line": 44, + "column": 26 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 4, + "loc": { + "start": { + "line": 44, + "column": 29 + }, + "end": { + "line": 44, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 44, + "column": 23 + }, + "end": { + "line": 44, + "column": 30 + } + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "arr", + "decorators": [], + "loc": { + "start": { + "line": 44, + "column": 34 + }, + "end": { + "line": 44, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 44, + "column": 32 + }, + "end": { + "line": 44, + "column": 37 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 44, + "column": 39 + }, + "end": { + "line": 44, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 44, + "column": 5 + }, + "end": { + "line": 44, + "column": 42 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "arr", + "decorators": [], + "loc": { + "start": { + "line": 45, + "column": 5 + }, + "end": { + "line": 45, + "column": 8 + } + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 45, + "column": 12 + }, + "end": { + "line": 45, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 45, + "column": 11 + }, + "end": { + "line": 45, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 45, + "column": 5 + }, + "end": { + "line": 45, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 45, + "column": 5 + }, + "end": { + "line": 45, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 39, + "column": 22 + }, + "end": { + "line": 46, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 13 + }, + "end": { + "line": 46, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 13 + }, + "end": { + "line": 46, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 1 + }, + "end": { + "line": 46, + "column": 2 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 50, + "column": 10 + }, + "end": { + "line": 50, + "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": 50, + "column": 10 + }, + "end": { + "line": 50, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "arr", + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 51, + "column": 14 + }, + "end": { + "line": 51, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 51, + "column": 22 + }, + "end": { + "line": 51, + "column": 23 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 51, + "column": 9 + }, + "end": { + "line": 51, + "column": 12 + } + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 51, + "column": 25 + }, + "end": { + "line": 51, + "column": 26 + } + } + }, + { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 51, + "column": 27 + }, + "end": { + "line": 51, + "column": 28 + } + } + }, + { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 51, + "column": 29 + }, + "end": { + "line": 51, + "column": 30 + } + } + }, + { + "type": "NumberLiteral", + "value": 4, + "loc": { + "start": { + "line": 51, + "column": 31 + }, + "end": { + "line": 51, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 51, + "column": 24 + }, + "end": { + "line": 51, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 51, + "column": 9 + }, + "end": { + "line": 51, + "column": 33 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 51, + "column": 5 + }, + "end": { + "line": 51, + "column": 33 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "v", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 52, + "column": 17 + }, + "end": { + "line": 52, + "column": 22 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 52, + "column": 14 + }, + "end": { + "line": 52, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 14 + }, + "end": { + "line": 52, + "column": 22 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 52, + "column": 27 + }, + "end": { + "line": 52, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 27 + }, + "end": { + "line": 52, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 27 + }, + "end": { + "line": 52, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 13 + }, + "end": { + "line": 52, + "column": 33 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 52, + "column": 9 + }, + "end": { + "line": 52, + "column": 11 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "v", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 52, + "column": 38 + }, + "end": { + "line": 52, + "column": 43 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 52, + "column": 35 + }, + "end": { + "line": 52, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 35 + }, + "end": { + "line": 52, + "column": 43 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 52, + "column": 46 + }, + "end": { + "line": 52, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 46 + }, + "end": { + "line": 52, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 46 + }, + "end": { + "line": 52, + "column": 53 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "arr", + "decorators": [], + "loc": { + "start": { + "line": 53, + "column": 9 + }, + "end": { + "line": 53, + "column": 12 + } + } + }, + "property": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 53, + "column": 13 + }, + "end": { + "line": 53, + "column": 14 + } + } + }, + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 53, + "column": 9 + }, + "end": { + "line": 53, + "column": 15 + } + } + }, + "right": { + "type": "TSAsExpression", + "expression": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Identifier", + "name": "v", + "decorators": [], + "loc": { + "start": { + "line": 53, + "column": 19 + }, + "end": { + "line": 53, + "column": 20 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 53, + "column": 23 + }, + "end": { + "line": 53, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 53, + "column": 18 + }, + "end": { + "line": 53, + "column": 25 + } + } + }, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 53, + "column": 29 + }, + "end": { + "line": 53, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 53, + "column": 18 + }, + "end": { + "line": 53, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 53, + "column": 9 + }, + "end": { + "line": 53, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 53, + "column": 9 + }, + "end": { + "line": 53, + "column": 35 + } + } + } + ], + "loc": { + "start": { + "line": 52, + "column": 54 + }, + "end": { + "line": 54, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 34 + }, + "end": { + "line": 54, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 34 + }, + "end": { + "line": 54, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 52, + "column": 9 + }, + "end": { + "line": 54, + "column": 6 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 52, + "column": 5 + }, + "end": { + "line": 54, + "column": 6 + } + } + }, + { + "type": "ForUpdateStatement", + "init": { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 55, + "column": 14 + }, + "end": { + "line": 55, + "column": 15 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 55, + "column": 18 + }, + "end": { + "line": 55, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 55, + "column": 14 + }, + "end": { + "line": 55, + "column": 19 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 55, + "column": 10 + }, + "end": { + "line": 55, + "column": 19 + } + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 55, + "column": 21 + }, + "end": { + "line": 55, + "column": 22 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 4, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 55, + "column": 21 + }, + "end": { + "line": 55, + "column": 26 + } + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 55, + "column": 30 + }, + "end": { + "line": 55, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 55, + "column": 28 + }, + "end": { + "line": 55, + "column": 31 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 55, + "column": 33 + }, + "end": { + "line": 55, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 55, + "column": 5 + }, + "end": { + "line": 55, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 50, + "column": 17 + }, + "end": { + "line": 56, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 50, + "column": 14 + }, + "end": { + "line": 56, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 50, + "column": 14 + }, + "end": { + "line": 56, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 50, + "column": 1 + }, + "end": { + "line": 56, + "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": 57, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/lambda_unresolved_ref_1.ets b/ets2panda/test/compiler/ets/lambda_unresolved_ref_1.ets new file mode 100644 index 0000000000..4c6a0275a2 --- /dev/null +++ b/ets2panda/test/compiler/ets/lambda_unresolved_ref_1.ets @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 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 C { + public foo(fn: () => void): void { + let bar: () => void = (): void => { fn() } + for (let j = 0; j < 1; ++j) {} + } +} + +function foo(arr: Object[]): void { + const copy: () => void = (): void => { + let c = arr.length + } + for (let s = 1; s < 10; s++) {} +} + +function foo2(arr: Object[]): void { + const copy: () => void = (): void => { + let c = arr.length + } + let s: int + for (let s = 1; s < 10; s++) {} +} + + +function bar(): void { + let arr: short[] = [1,2,3,4] + let fn: (v: short) => void = (v: short): void => { + arr[0] = (v + 1) as short; + } + for (let arr = 0; arr < 4; ++arr) { } + arr = [3]; +} + + + +function main() { + let arr: short[] = [1,2,3,4] + let fn: (v: short) => void = (v: short): void => { + arr[0] = (v + 1) as short; + } + for (let i = 0; i < 4; ++i) { } +} -- Gitee From eae01448ae69a11400d13cb33248b1f1723ce7a7 Mon Sep 17 00:00:00 2001 From: Peter Siket Date: Tue, 5 Dec 2023 16:46:06 +0100 Subject: [PATCH 6/8] Fixes invalid call generation. Issue: #I8M2l5 Fixes internal issue: #14750 Change-Id: I201d8088e64f57bf427ee1cef468b0162fd472d8 Signed-off-by: Peter Siket --- ets2panda/compiler/core/ETSGen.cpp | 18 +- .../ets/invalidCallInstruction-expected.txt | 1458 +++++++++++++++++ .../compiler/ets/invalidCallInstruction.ets | 41 + 3 files changed, 1508 insertions(+), 9 deletions(-) create mode 100644 ets2panda/test/compiler/ets/invalidCallInstruction-expected.txt create mode 100644 ets2panda/test/compiler/ets/invalidCallInstruction.ets diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index f529a204cc..3de10364a4 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -1183,31 +1183,31 @@ void ETSGen::EmitLocalBoxSet(ir::AstNode const *node, varbinder::LocalVariable * auto vreg = lhs_var->Vreg(); switch (checker::ETSChecker::TypeKind(content_type)) { case checker::TypeFlag::ETS_BOOLEAN: - Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_BOX_SET, vreg, 1); break; case checker::TypeFlag::BYTE: - Ra().Emit(node, Signatures::BUILTIN_BYTE_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_BYTE_BOX_SET, vreg, 1); break; case checker::TypeFlag::CHAR: - Ra().Emit(node, Signatures::BUILTIN_CHAR_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_CHAR_BOX_SET, vreg, 1); break; case checker::TypeFlag::SHORT: - Ra().Emit(node, Signatures::BUILTIN_SHORT_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_SHORT_BOX_SET, vreg, 1); break; case checker::TypeFlag::INT: - Ra().Emit(node, Signatures::BUILTIN_INT_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_INT_BOX_SET, vreg, 1); break; case checker::TypeFlag::LONG: - Ra().Emit(node, Signatures::BUILTIN_LONG_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_LONG_BOX_SET, vreg, 1); break; case checker::TypeFlag::FLOAT: - Ra().Emit(node, Signatures::BUILTIN_FLOAT_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_FLOAT_BOX_SET, vreg, 1); break; case checker::TypeFlag::DOUBLE: - Ra().Emit(node, Signatures::BUILTIN_DOUBLE_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_DOUBLE_BOX_SET, vreg, 1); break; default: - Ra().Emit(node, Signatures::BUILTIN_BOX_SET, vreg, 1); + Ra().Emit(node, Signatures::BUILTIN_BOX_SET, vreg, 1); break; } SetAccumulatorType(Checker()->GetGlobalTypesHolder()->GlobalVoidType()); diff --git a/ets2panda/test/compiler/ets/invalidCallInstruction-expected.txt b/ets2panda/test/compiler/ets/invalidCallInstruction-expected.txt new file mode 100644 index 0000000000..5a6ea0bffa --- /dev/null +++ b/ets2panda/test/compiler/ets/invalidCallInstruction-expected.txt @@ -0,0 +1,1458 @@ +{ + "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": 19 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i1", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 18, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 18, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 3 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i2", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i3", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i4", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i5", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 7 + }, + "end": { + "line": 22, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 22, + "column": 12 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 7 + }, + "end": { + "line": 22, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 22, + "column": 3 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i6", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 7 + }, + "end": { + "line": 23, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 23, + "column": 12 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 7 + }, + "end": { + "line": 23, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 3 + }, + "end": { + "line": 23, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i7", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 7 + }, + "end": { + "line": 24, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 7 + }, + "end": { + "line": 24, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 24, + "column": 3 + }, + "end": { + "line": 24, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i8", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 25, + "column": 12 + }, + "end": { + "line": 25, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 25, + "column": 3 + }, + "end": { + "line": 25, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i9", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 26, + "column": 9 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 26, + "column": 12 + }, + "end": { + "line": 26, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 26, + "column": 13 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 26, + "column": 3 + }, + "end": { + "line": 26, + "column": 14 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i10", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 7 + }, + "end": { + "line": 27, + "column": 10 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 7 + }, + "end": { + "line": 27, + "column": 14 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 27, + "column": 3 + }, + "end": { + "line": 27, + "column": 15 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i11", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 7 + }, + "end": { + "line": 28, + "column": 10 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 28, + "column": 13 + }, + "end": { + "line": 28, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 7 + }, + "end": { + "line": 28, + "column": 14 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 28, + "column": 3 + }, + "end": { + "line": 28, + "column": 15 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i12", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 7 + }, + "end": { + "line": 29, + "column": 10 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 29, + "column": 13 + }, + "end": { + "line": 29, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 7 + }, + "end": { + "line": 29, + "column": 14 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 29, + "column": 3 + }, + "end": { + "line": 29, + "column": 15 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i13", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 7 + }, + "end": { + "line": 30, + "column": 10 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 30, + "column": 13 + }, + "end": { + "line": 30, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 7 + }, + "end": { + "line": 30, + "column": 14 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 30, + "column": 3 + }, + "end": { + "line": 30, + "column": 15 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i14", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 7 + }, + "end": { + "line": 31, + "column": 10 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 31, + "column": 13 + }, + "end": { + "line": 31, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 7 + }, + "end": { + "line": 31, + "column": 14 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 31, + "column": 3 + }, + "end": { + "line": 31, + "column": 15 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i15", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 7 + }, + "end": { + "line": 32, + "column": 10 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 32, + "column": 13 + }, + "end": { + "line": 32, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 7 + }, + "end": { + "line": 32, + "column": 14 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 32, + "column": 3 + }, + "end": { + "line": 32, + "column": 15 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i16", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 7 + }, + "end": { + "line": 33, + "column": 10 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 33, + "column": 13 + }, + "end": { + "line": 33, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 7 + }, + "end": { + "line": 33, + "column": 14 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 33, + "column": 3 + }, + "end": { + "line": 33, + "column": 15 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "l", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 17 + }, + "end": { + "line": 35, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 17 + }, + "end": { + "line": 35, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 17 + }, + "end": { + "line": 35, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 11 + }, + "end": { + "line": 35, + "column": 23 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 7 + }, + "end": { + "line": 35, + "column": 8 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 29 + }, + "end": { + "line": 35, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 29 + }, + "end": { + "line": 35, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 29 + }, + "end": { + "line": 35, + "column": 36 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "i13", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 5 + }, + "end": { + "line": 36, + "column": 8 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 36, + "column": 11 + }, + "end": { + "line": 36, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 5 + }, + "end": { + "line": 36, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 5 + }, + "end": { + "line": 36, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 35, + "column": 37 + }, + "end": { + "line": 37, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 24 + }, + "end": { + "line": 37, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 24 + }, + "end": { + "line": 37, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 7 + }, + "end": { + "line": 37, + "column": 4 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 35, + "column": 3 + }, + "end": { + "line": 37, + "column": 4 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 39, + "column": 9 + }, + "end": { + "line": 39, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 2 + }, + "end": { + "line": 39, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 40, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 40, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 40, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 40, + "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": 42, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/invalidCallInstruction.ets b/ets2panda/test/compiler/ets/invalidCallInstruction.ets new file mode 100644 index 0000000000..3f57b01b8c --- /dev/null +++ b/ets2panda/test/compiler/ets/invalidCallInstruction.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021-2023 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 i1 = 1; + let i2 = 1; + let i3 = 1; + let i4 = 1; + let i5 = 1; + let i6 = 1; + let i7 = 1; + let i8 = 1; + let i9 = 1; + let i10 = 1; + let i11 = 1; + let i12 = 1; + let i13 = 1; + let i14 = 1; + let i15 = 1; + let i16 = 1; + + let l : () => void = () : void => { + i13 = 2; + } + + return 0; +} + -- Gitee From 9cc26f67b5430e2b538d2e229040a6fba8bd4840 Mon Sep 17 00:00:00 2001 From: Vsevolod Pukhov Date: Fri, 24 Nov 2023 21:03:14 +0300 Subject: [PATCH 7/8] interop_js: Adjust casting rules of ETSDynamicType Signed-off-by: Vsevolod Pukhov --- ets2panda/checker/ets/arithmetic.cpp | 2 +- ets2panda/checker/ets/conversion.cpp | 9 ++++ ets2panda/checker/types/ets/byteType.cpp | 5 --- ets2panda/checker/types/ets/charType.cpp | 5 --- ets2panda/checker/types/ets/doubleType.cpp | 5 --- .../checker/types/ets/etsBooleanType.cpp | 5 --- .../checker/types/ets/etsDynamicType.cpp | 39 +++++++++++++--- ets2panda/checker/types/ets/etsDynamicType.h | 3 +- ets2panda/checker/types/ets/etsObjectType.cpp | 5 --- ets2panda/checker/types/ets/etsUnionType.cpp | 2 +- ets2panda/checker/types/ets/etsUnionType.h | 2 +- ets2panda/checker/types/ets/floatType.cpp | 5 --- ets2panda/checker/types/ets/intType.cpp | 5 --- ets2panda/checker/types/ets/longType.cpp | 5 --- ets2panda/checker/types/ets/shortType.cpp | 5 --- ets2panda/checker/types/type.cpp | 5 +++ ets2panda/checker/types/type.h | 1 + ets2panda/checker/types/typeRelation.cpp | 4 ++ ets2panda/compiler/base/lreference.cpp | 15 +++---- ets2panda/compiler/core/ASTVerifier.cpp | 6 +++ ets2panda/compiler/core/ETSCompiler.cpp | 21 +++++---- ets2panda/compiler/core/ETSGen.cpp | 44 ++++++++----------- ets2panda/compiler/core/ETSGen.h | 8 ++-- ets2panda/compiler/scripts/signatures.yaml | 2 +- .../ets/dynamic-equality-error-expected.txt | 1 - .../compiler/ets/dynamic-equality-error.ets | 33 -------------- .../ets/dynamicLambda_error-expected.txt | 1 - .../test/compiler/ets/dynamicLambda_error.ets | 27 ------------ 28 files changed, 103 insertions(+), 167 deletions(-) delete mode 100644 ets2panda/test/compiler/ets/dynamic-equality-error-expected.txt delete mode 100644 ets2panda/test/compiler/ets/dynamic-equality-error.ets delete mode 100644 ets2panda/test/compiler/ets/dynamicLambda_error-expected.txt delete mode 100644 ets2panda/test/compiler/ets/dynamicLambda_error.ets diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index de5372293c..113250d258 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -377,7 +377,7 @@ std::tuple ETSChecker::CheckBinaryOperatorEqualDynamic(ir::Expre if (other_exp->TsType()->IsETSDynamicType()) { return {GlobalETSBooleanType(), GlobalBuiltinJSValueType()}; } - if (dyn_exp->TsType()->AsETSDynamicType()->IsConvertibleTo(other_exp->TsType())) { + if (dyn_exp->TsType()->AsETSDynamicType()->IsConvertible(other_exp->TsType())) { // NOTE: vpukhov. boxing flags are not set in dynamic values return {GlobalETSBooleanType(), other_exp->TsType()}; } diff --git a/ets2panda/checker/ets/conversion.cpp b/ets2panda/checker/ets/conversion.cpp index 83d5c7ec9e..b1dd99217b 100644 --- a/ets2panda/checker/ets/conversion.cpp +++ b/ets2panda/checker/ets/conversion.cpp @@ -240,6 +240,13 @@ void NarrowingReference(TypeRelation *const relation, ETSObjectType *const sourc NarrowingReferenceImpl(relation, source, target); } +static inline void RollbackBoxingIfFailed(TypeRelation *const relation) +{ + if (!relation->IsTrue()) { + relation->GetNode()->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); + } +} + ETSObjectType *Boxing(TypeRelation *const relation, Type *const source) { auto *const ets_checker = relation->GetChecker()->AsETSChecker(); @@ -272,6 +279,7 @@ void UnboxingWideningPrimitive(TypeRelation *const relation, ETSObjectType *cons } ASSERT(unboxed_source != nullptr); WideningPrimitive(relation, target, unboxed_source); + RollbackBoxingIfFailed(relation); } void NarrowingReferenceUnboxing(TypeRelation *const relation, ETSObjectType *const source, Type *const target) @@ -296,6 +304,7 @@ void BoxingWideningReference(TypeRelation *const relation, Type *const source, E } ASSERT(boxed_source != nullptr); WideningReference(relation, boxed_source, target); + RollbackBoxingIfFailed(relation); } void String(TypeRelation *const relation, Type *const source) diff --git a/ets2panda/checker/types/ets/byteType.cpp b/ets2panda/checker/types/ets/byteType.cpp index 05f77b0b62..f3468bbbac 100644 --- a/ets2panda/checker/types/ets/byteType.cpp +++ b/ets2panda/checker/types/ets/byteType.cpp @@ -82,11 +82,6 @@ void ByteType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/ets/charType.cpp b/ets2panda/checker/types/ets/charType.cpp index be7d27609f..2c4f3995e7 100644 --- a/ets2panda/checker/types/ets/charType.cpp +++ b/ets2panda/checker/types/ets/charType.cpp @@ -82,11 +82,6 @@ void CharType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/ets/doubleType.cpp b/ets2panda/checker/types/ets/doubleType.cpp index 4f92ba9218..4b3055837c 100644 --- a/ets2panda/checker/types/ets/doubleType.cpp +++ b/ets2panda/checker/types/ets/doubleType.cpp @@ -77,11 +77,6 @@ void DoubleType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/ets/etsBooleanType.cpp b/ets2panda/checker/types/ets/etsBooleanType.cpp index aaf1dac4e6..4d6f2f531c 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.cpp +++ b/ets2panda/checker/types/ets/etsBooleanType.cpp @@ -64,11 +64,6 @@ void ETSBooleanType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/ets/etsDynamicType.cpp b/ets2panda/checker/types/ets/etsDynamicType.cpp index f279b0a4ab..908f69830b 100644 --- a/ets2panda/checker/types/ets/etsDynamicType.cpp +++ b/ets2panda/checker/types/ets/etsDynamicType.cpp @@ -15,6 +15,7 @@ #include "etsDynamicType.h" #include "checker/ETSchecker.h" +#include "checker/ets/conversion.h" #include "checker/types/ets/etsDynamicFunctionType.h" namespace panda::es2panda::checker { @@ -41,7 +42,14 @@ void ETSDynamicType::AssignmentTarget(TypeRelation *relation, Type *source) return ETSObjectType::AssignmentTarget(relation, source); } - relation->Result(true); + if (relation->ApplyBoxing() && !relation->IsTrue() && IsConvertible(source)) { + relation->Result(true); + return; + } + + if (source->IsETSDynamicType()) { + relation->Result(true); + } } bool ETSDynamicType::AssignmentSource(TypeRelation *relation, Type *target) @@ -50,7 +58,12 @@ bool ETSDynamicType::AssignmentSource(TypeRelation *relation, Type *target) return ETSObjectType::AssignmentSource(relation, target); } - if (target->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC) || target->IsETSStringType()) { + if (relation->ApplyUnboxing() && IsConvertible(target)) { + relation->Result(true); + return true; + } + + if (target->IsETSDynamicType()) { relation->Result(true); } return relation->IsTrue(); @@ -62,19 +75,33 @@ void ETSDynamicType::Cast(TypeRelation *relation, Type *target) return ETSObjectType::Cast(relation, target); } - if (relation->InCastingContext()) { + if (relation->InCastingContext() || IsConvertible(target)) { relation->Result(true); return; } - if (IsConvertibleTo(target)) { + conversion::Forbidden(relation); +} + +void ETSDynamicType::CastTarget(TypeRelation *relation, Type *source) +{ + if (has_decl_) { + ETSObjectType::CastTarget(relation, source); + return; + } + + if (relation->InCastingContext() || IsConvertible(source)) { relation->Result(true); + return; } + + conversion::Forbidden(relation); } -bool ETSDynamicType::IsConvertibleTo(Type *target) +bool ETSDynamicType::IsConvertible(Type const *target) { - return target->IsETSStringType() || target->IsLambdaObject() || target->IsETSDynamicType() || + return target->IsETSDynamicType() || (target->IsETSObjectType() && !target->IsETSNullLike()) || + target->IsETSArrayType() || target->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC | checker::TypeFlag::ETS_BOOLEAN); } diff --git a/ets2panda/checker/types/ets/etsDynamicType.h b/ets2panda/checker/types/ets/etsDynamicType.h index 62b96ee6f9..b30f1dc7b5 100644 --- a/ets2panda/checker/types/ets/etsDynamicType.h +++ b/ets2panda/checker/types/ets/etsDynamicType.h @@ -35,6 +35,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; void Cast(TypeRelation *relation, Type *target) override; + void CastTarget(TypeRelation *relation, Type *source) override; es2panda::Language Language() const { @@ -50,7 +51,7 @@ public: void ToAssemblerType(std::stringstream &ss) const override; - static bool IsConvertibleTo(Type *target); + static bool IsConvertible(Type const *target); private: mutable PropertyMap properties_cache_; diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 6c6435e7ec..be89ec759c 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -611,11 +611,6 @@ void ETSObjectType::Cast(TypeRelation *const relation, Type *const target) } } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index b3335689a1..49e66f31a8 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -198,7 +198,7 @@ void ETSUnionType::Cast(TypeRelation *relation, Type *target) conversion::Forbidden(relation); } -void ETSUnionType::CastToThis(TypeRelation *relation, Type *source) +void ETSUnionType::CastTarget(TypeRelation *relation, Type *source) { Type *target_type = FindTypeIsCastableToThis(relation->GetNode(), relation, source); if (target_type != nullptr) { diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index ce032fcef4..a31e85f423 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -67,7 +67,7 @@ public: bool AssignmentSource(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *global_types) override; void Cast(TypeRelation *relation, Type *target) override; - void CastToThis(TypeRelation *relation, Type *source); + void CastTarget(TypeRelation *relation, Type *source) override; Type *FindTypeIsCastableToThis(ir::Expression *node, TypeRelation *relation, Type *source) const; Type *FindTypeIsCastableToSomeType(ir::Expression *node, TypeRelation *relation, Type *target) const; Type *FindUnboxableType() const; diff --git a/ets2panda/checker/types/ets/floatType.cpp b/ets2panda/checker/types/ets/floatType.cpp index 56070a4330..474118265a 100644 --- a/ets2panda/checker/types/ets/floatType.cpp +++ b/ets2panda/checker/types/ets/floatType.cpp @@ -82,11 +82,6 @@ void FloatType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/ets/intType.cpp b/ets2panda/checker/types/ets/intType.cpp index a0e4670bdf..b9dc7c2e2f 100644 --- a/ets2panda/checker/types/ets/intType.cpp +++ b/ets2panda/checker/types/ets/intType.cpp @@ -87,11 +87,6 @@ void IntType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/ets/longType.cpp b/ets2panda/checker/types/ets/longType.cpp index 6b0fdba23e..abb5df301e 100644 --- a/ets2panda/checker/types/ets/longType.cpp +++ b/ets2panda/checker/types/ets/longType.cpp @@ -82,11 +82,6 @@ void LongType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/ets/shortType.cpp b/ets2panda/checker/types/ets/shortType.cpp index 1812690e6c..a43783d20f 100644 --- a/ets2panda/checker/types/ets/shortType.cpp +++ b/ets2panda/checker/types/ets/shortType.cpp @@ -82,11 +82,6 @@ void ShortType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSUnionType()) { - target->AsETSUnionType()->CastToThis(relation, this); - return; - } - conversion::Forbidden(relation); } diff --git a/ets2panda/checker/types/type.cpp b/ets2panda/checker/types/type.cpp index f50b36c8de..c28e55dcf5 100644 --- a/ets2panda/checker/types/type.cpp +++ b/ets2panda/checker/types/type.cpp @@ -105,6 +105,11 @@ void Type::Cast(TypeRelation *const relation, [[maybe_unused]] Type *target) relation->Result(false); } +void Type::CastTarget(TypeRelation *const relation, [[maybe_unused]] Type *source) +{ + relation->Result(false); +} + void Type::IsSupertypeOf(TypeRelation *const relation, [[maybe_unused]] Type *source) { relation->Result(false); diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index 470524b486..5f1b44af2e 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -240,6 +240,7 @@ public: virtual bool AssignmentSource(TypeRelation *relation, Type *target); virtual void Compare(TypeRelation *relation, Type *other); virtual void Cast(TypeRelation *relation, Type *target); + virtual void CastTarget(TypeRelation *relation, Type *source); virtual void IsSupertypeOf(TypeRelation *relation, Type *source); virtual Type *AsSuper(Checker *checker, varbinder::Variable *source_var); diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index 9c25f672ca..a3453c5190 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -122,6 +122,7 @@ bool TypeRelation::IsComparableTo(Type *source, Type *target) { result_ = CacheLookup(source, target, checker_->ComparableResults(), RelationType::COMPARABLE); + // NOTE: vpukhov. reimplement dynamic comparison and remove this check if (source->IsETSDynamicType() || target->IsETSDynamicType()) { if (!(source->IsETSDynamicType() && target->IsETSDynamicType())) { return false; @@ -151,6 +152,9 @@ bool TypeRelation::IsCastableTo(Type *const source, Type *const target) flags_ |= TypeRelationFlag::UNCHECKED_CAST; source->Cast(this, target); + if (!IsTrue()) { + target->CastTarget(this, source); + } if (!IsTrue()) { return false; diff --git a/ets2panda/compiler/base/lreference.cpp b/ets2panda/compiler/base/lreference.cpp index 2087869948..86deaaf53d 100644 --- a/ets2panda/compiler/base/lreference.cpp +++ b/ets2panda/compiler/base/lreference.cpp @@ -276,8 +276,7 @@ void ETSLReference::SetValueComputed(const ir::MemberExpression *member_expr) co const auto *const object_type = member_expr->Object()->TsType(); if (object_type->IsETSDynamicType()) { - const auto lang = object_type->AsETSDynamicType()->Language(); - etsg_->StoreElementDynamic(Node(), base_reg_, prop_reg_, lang); + etsg_->StoreElementDynamic(Node(), base_reg_, prop_reg_); return; } @@ -341,8 +340,7 @@ void ETSLReference::SetValue() const const util::StringView full_name = etsg_->FormClassPropReference(static_obj_ref_->AsETSObjectType(), prop_name); if (static_obj_ref_->IsETSDynamicType()) { - const auto lang = static_obj_ref_->AsETSDynamicType()->Language(); - etsg_->StorePropertyDynamic(Node(), member_expr_ts_type, base_reg_, prop_name, lang); + etsg_->StorePropertyDynamic(Node(), member_expr_ts_type, base_reg_, prop_name); } else { etsg_->StoreStaticProperty(Node(), member_expr_ts_type, full_name); } @@ -350,13 +348,14 @@ void ETSLReference::SetValue() const return; } - if (static_obj_ref_->IsETSDynamicType()) { - const auto lang = static_obj_ref_->AsETSDynamicType()->Language(); - etsg_->StorePropertyDynamic(Node(), member_expr_ts_type, base_reg_, prop_name, lang); + auto const *object_type = member_expr->Object()->TsType(); + + if (object_type->IsETSDynamicType()) { + etsg_->StorePropertyDynamic(Node(), member_expr_ts_type, base_reg_, prop_name); return; } - if (static_obj_ref_->IsETSUnionType()) { + if (object_type->IsETSUnionType()) { etsg_->StoreUnionProperty(Node(), base_reg_, prop_name); return; } diff --git a/ets2panda/compiler/core/ASTVerifier.cpp b/ets2panda/compiler/core/ASTVerifier.cpp index 60cca9a8de..f4b2c6cf22 100644 --- a/ets2panda/compiler/core/ASTVerifier.cpp +++ b/ets2panda/compiler/core/ASTVerifier.cpp @@ -751,6 +751,12 @@ bool ASTVerifier::CheckImportExportMethod(const varbinder::Variable *var_callee, util::StringView name) { auto *signature = call_expr->AsCallExpression()->Signature(); + if (signature->Owner() == nullptr) { + // NOTE(vpukhov): Add a synthetic owner for dynamic signatures + ASSERT(call_expr->AsCallExpression()->Callee()->TsType()->HasTypeFlag(checker::TypeFlag::ETS_DYNAMIC_FLAG)); + return true; + } + if (signature != nullptr && var_callee->Declaration() != nullptr && var_callee->Declaration()->Node() != nullptr && !IsContainedIn(var_callee->Declaration()->Node(), signature->Owner()->GetDeclNode()) && var_callee->Declaration()->Node() != signature->Owner()->GetDeclNode()) { diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index f4209e0e1e..de21cbc011 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -660,9 +660,8 @@ void ETSCompiler::CompileDynamic(const ir::CallExpression *expr, compiler::VReg } etsg->StoreAccumulator(expr, dyn_param2); etsg->CallDynamic(expr, callee_reg, dyn_param2, expr->Signature(), expr->Arguments()); - etsg->SetAccumulatorType(expr->TsType()); - - if (expr->Signature()->ReturnType() != expr->TsType()) { + etsg->SetAccumulatorType(expr->Signature()->ReturnType()); + if (etsg->GetAccumulatorType() != expr->TsType()) { etsg->ApplyConversion(expr, expr->TsType()); } } @@ -817,8 +816,7 @@ static bool CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression * auto ttctx = compiler::TargetTypeContext(etsg, expr->OptionalType()); if (object_type->IsETSDynamicType()) { - auto lang = object_type->AsETSDynamicType()->Language(); - etsg->LoadElementDynamic(expr, obj_reg, lang); + etsg->LoadElementDynamic(expr, obj_reg); } else { etsg->LoadArrayElement(expr, obj_reg); } @@ -917,8 +915,7 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const etsg->CallThisVirtual0(expr, obj_reg, sig->InternalName()); etsg->SetAccumulatorType(expr->TsType()); } else if (object_type->IsETSDynamicType()) { - auto lang = object_type->AsETSDynamicType()->Language(); - etsg->LoadPropertyDynamic(expr, expr->OptionalType(), obj_reg, prop_name, lang); + etsg->LoadPropertyDynamic(expr, expr->OptionalType(), obj_reg, prop_name); } else if (object_type->IsETSUnionType()) { etsg->LoadUnionProperty(expr, expr->OptionalType(), expr->IsGenericField(), obj_reg, prop_name); } else { @@ -982,8 +979,7 @@ void ETSCompiler::Compile(const ir::ObjectExpression *expr) const value->Compile(etsg); etsg->ApplyConversion(value, key->TsType()); if (expr->TsType()->IsETSDynamicType()) { - etsg->StorePropertyDynamic(expr, value->TsType(), obj_reg, pname, - expr->TsType()->AsETSDynamicType()->Language()); + etsg->StorePropertyDynamic(expr, value->TsType(), obj_reg, pname); } else { etsg->StoreProperty(expr, key->TsType(), obj_reg, pname); } @@ -1723,11 +1719,14 @@ void ETSCompiler::Compile(const ir::TSAsExpression *expr) const break; } case checker::TypeFlag::ETS_ARRAY: - case checker::TypeFlag::ETS_OBJECT: - case checker::TypeFlag::ETS_DYNAMIC_TYPE: { + case checker::TypeFlag::ETS_OBJECT: { etsg->CastToArrayOrObject(expr, target_type, expr->is_unchecked_cast_); break; } + case checker::TypeFlag::ETS_DYNAMIC_TYPE: { + etsg->CastToDynamic(expr, target_type->AsETSDynamicType()); + break; + } case checker::TypeFlag::ETS_STRING_ENUM: [[fallthrough]]; case checker::TypeFlag::ETS_ENUM: { diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 3de10364a4..1b1c37178a 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -268,7 +268,7 @@ void ETSGen::LoadDynamicModuleVariable(const ir::AstNode *node, varbinder::Varia auto *id = data->specifier->AsImportSpecifier()->Imported(); auto lang = import->Language(); - LoadPropertyDynamic(node, Checker()->GlobalBuiltinDynamicType(lang), obj_reg, id->Name(), lang); + LoadPropertyDynamic(node, Checker()->GlobalBuiltinDynamicType(lang), obj_reg, id->Name()); ApplyConversion(node); } @@ -478,9 +478,9 @@ void ETSGen::LoadUnionProperty([[maybe_unused]] const ir::AstNode *const node, } void ETSGen::StorePropertyDynamic(const ir::AstNode *node, const checker::Type *prop_type, VReg obj_reg, - const util::StringView &prop_name, Language lang) + const util::StringView &prop_name) { - auto *type = prop_type; + auto const lang = GetVRegType(obj_reg)->AsETSDynamicType()->Language(); std::string_view method_name {}; if (prop_type->IsETSBooleanType()) { method_name = Signatures::Dynamic::SetPropertyBooleanBuiltin(lang); @@ -502,35 +502,33 @@ void ETSGen::StorePropertyDynamic(const ir::AstNode *node, const checker::Type * method_name = Signatures::Dynamic::SetPropertyStringBuiltin(lang); } else if (prop_type->IsETSObjectType()) { method_name = Signatures::Dynamic::SetPropertyDynamicBuiltin(lang); - type = Checker()->GlobalBuiltinDynamicType(lang); + // NOTE: vpukhov. add non-dynamic builtin + if (!prop_type->IsETSDynamicType()) { + CastToDynamic(node, Checker()->GlobalBuiltinDynamicType(lang)->AsETSDynamicType()); + } } else { ASSERT_PRINT(false, "Unsupported property type"); } RegScope rs(this); - - // Load property value VReg prop_value_reg = AllocReg(); - - if (prop_type != type && !prop_type->IsETSDynamicType()) { - CastToDynamic(node, type->AsETSDynamicType()); - } + VReg prop_name_reg = AllocReg(); StoreAccumulator(node, prop_value_reg); // Load property name LoadAccumulatorString(node, prop_name); - VReg prop_name_reg = AllocReg(); StoreAccumulator(node, prop_name_reg); // Set property by name Ra().Emit(node, method_name, obj_reg, prop_name_reg, prop_value_reg, dummy_reg_); - SetAccumulatorType(Checker()->GlobalVoidType()); + SetAccumulatorType(nullptr); } void ETSGen::LoadPropertyDynamic(const ir::AstNode *node, const checker::Type *prop_type, VReg obj_reg, - const util::StringView &prop_name, Language lang) + const util::StringView &prop_name) { + auto const lang = GetVRegType(obj_reg)->AsETSDynamicType()->Language(); auto *type = prop_type; std::string_view method_name {}; if (prop_type->IsETSBooleanType()) { @@ -574,8 +572,9 @@ void ETSGen::LoadPropertyDynamic(const ir::AstNode *node, const checker::Type *p } } -void ETSGen::StoreElementDynamic(const ir::AstNode *node, VReg object_reg, VReg index, Language lang) +void ETSGen::StoreElementDynamic(const ir::AstNode *node, VReg object_reg, VReg index) { + auto const lang = GetVRegType(object_reg)->AsETSDynamicType()->Language(); std::string_view method_name = Signatures::Dynamic::SetElementDynamicBuiltin(lang); RegScope rs(this); @@ -588,8 +587,9 @@ void ETSGen::StoreElementDynamic(const ir::AstNode *node, VReg object_reg, VReg SetAccumulatorType(Checker()->GlobalVoidType()); } -void ETSGen::LoadElementDynamic(const ir::AstNode *node, VReg object_reg, Language lang) +void ETSGen::LoadElementDynamic(const ir::AstNode *node, VReg object_reg) { + auto const lang = GetVRegType(object_reg)->AsETSDynamicType()->Language(); std::string_view method_name = Signatures::Dynamic::GetElementDynamicBuiltin(lang); RegScope rs(this); @@ -1245,7 +1245,7 @@ void ETSGen::CastToBoolean([[maybe_unused]] const ir::AstNode *node) break; } case checker::TypeFlag::ETS_DYNAMIC_TYPE: { - CastDynamicTo(node, checker::TypeFlag::BOOLEAN); + CastDynamicTo(node, checker::TypeFlag::ETS_BOOLEAN); ASSERT(GetAccumulatorType() == Checker()->GlobalETSBooleanType()); break; } @@ -1556,10 +1556,6 @@ void ETSGen::CastToArrayOrObject(const ir::AstNode *const node, const checker::T ASSERT(GetAccumulatorType()->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)); const auto *const source_type = GetAccumulatorType(); - if (source_type->IsETSDynamicType() && target_type->IsETSDynamicType()) { - SetAccumulatorType(target_type); - return; - } if (source_type->IsETSDynamicType()) { CastDynamicToObject(node, target_type); @@ -1622,6 +1618,7 @@ void ETSGen::CastDynamicToObject(const ir::AstNode *node, const checker::Type *t StoreAccumulator(node, type_reg); Ra().Emit(node, method_name, dyn_obj_reg, type_reg); + Sa().Emit(node, util::UString(ss.str(), Allocator()).View()); // trick verifier SetAccumulatorType(target_type); return; } @@ -1694,6 +1691,7 @@ void ETSGen::CastToDynamic(const ir::AstNode *node, const checker::ETSDynamicTyp break; } case checker::TypeFlag::ETS_DYNAMIC_TYPE: { + SetAccumulatorType(type); return; } default: { @@ -1719,8 +1717,6 @@ void ETSGen::CastDynamicTo(const ir::AstNode *node, enum checker::TypeFlag type_ checker::Type *object_type {}; auto type = GetAccumulatorType()->AsETSDynamicType(); switch (type_flag) { - case checker::TypeFlag::BOOLEAN: - [[fallthrough]]; case checker::TypeFlag::ETS_BOOLEAN: { method_name = compiler::Signatures::Dynamic::GetBooleanBuiltin(type->Language()); object_type = Checker()->GlobalETSBooleanType(); @@ -1766,10 +1762,6 @@ void ETSGen::CastDynamicTo(const ir::AstNode *node, enum checker::TypeFlag type_ object_type = Checker()->GlobalBuiltinETSStringType(); break; } - case checker::TypeFlag::OBJECT: { - SetAccumulatorType(Checker()->GlobalETSObjectType()); - return; - } default: { UNREACHABLE(); } diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 95aaa9528a..516e82d3a0 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -72,12 +72,12 @@ public: void LoadProperty(const ir::AstNode *node, const checker::Type *prop_type, bool is_generic, VReg obj_reg, const util::StringView &full_name); void StorePropertyDynamic(const ir::AstNode *node, const checker::Type *prop_type, VReg obj_reg, - const util::StringView &name, Language lang); + const util::StringView &name); void LoadPropertyDynamic(const ir::AstNode *node, const checker::Type *prop_type, VReg obj_reg, - const util::StringView &prop_name, Language lang); + const util::StringView &prop_name); - void StoreElementDynamic(const ir::AstNode *node, VReg object_reg, VReg index, Language lang); - void LoadElementDynamic(const ir::AstNode *node, VReg object_reg, Language lang); + void StoreElementDynamic(const ir::AstNode *node, VReg object_reg, VReg index); + void LoadElementDynamic(const ir::AstNode *node, VReg object_reg); void StoreUnionProperty(const ir::AstNode *node, VReg obj_reg, const util::StringView &name); void LoadUnionProperty(const ir::AstNode *node, const checker::Type *prop_type, bool is_generic, VReg obj_reg, diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 9a6c75de79..48b890f3f4 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -633,7 +633,7 @@ signatures: - callee: BUILTIN_JSRUNTIME method_name: getValueObject - params: [BUILTIN_JSVALUE, BUILTIN_TYPE] + params: [BUILTIN_JSVALUE, BUILTIN_OBJECT] # 2nd argument is ClassClass return_type: BUILTIN_OBJECT ref: BUILTIN_JSRUNTIME_GET_VALUE_OBJECT diff --git a/ets2panda/test/compiler/ets/dynamic-equality-error-expected.txt b/ets2panda/test/compiler/ets/dynamic-equality-error-expected.txt deleted file mode 100644 index e573b947a5..0000000000 --- a/ets2panda/test/compiler/ets/dynamic-equality-error-expected.txt +++ /dev/null @@ -1 +0,0 @@ -TypeError: The operands of strict equality are not compatible with each other [dynamic-equality-error.ets:29:9] diff --git a/ets2panda/test/compiler/ets/dynamic-equality-error.ets b/ets2panda/test/compiler/ets/dynamic-equality-error.ets deleted file mode 100644 index 22746cf891..0000000000 --- a/ets2panda/test/compiler/ets/dynamic-equality-error.ets +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2021-2023 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. - */ - -/*--- -flags: [dynamic-ast] ----*/ - -import { A } from "dynamic_js_import_tests" - -class B { - -} - -function main(): int { - let a = new A(); - let b = new B(); - if (a === b) { - return 0; - } - return 1; -} diff --git a/ets2panda/test/compiler/ets/dynamicLambda_error-expected.txt b/ets2panda/test/compiler/ets/dynamicLambda_error-expected.txt deleted file mode 100644 index f52f74f5da..0000000000 --- a/ets2panda/test/compiler/ets/dynamicLambda_error-expected.txt +++ /dev/null @@ -1 +0,0 @@ -TypeError: Initializers type is not assignable to the target type [dynamicLambda_error.ets:25:39] diff --git a/ets2panda/test/compiler/ets/dynamicLambda_error.ets b/ets2panda/test/compiler/ets/dynamicLambda_error.ets deleted file mode 100644 index 0daba36398..0000000000 --- a/ets2panda/test/compiler/ets/dynamicLambda_error.ets +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2021-2023 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. - */ - -/*--- -flags: [dynamic-ast] ----*/ - -import { A } from "dynamic_js_import_tests" - -function foo(): int { - let a = new A(); - let f: JSValue = (x: int, y: int): int => { return x * x + y * y } - let f1: (x: int, y: int) => int = f; - return 0; -} -- Gitee From 3c75ab08ba94960a11dfb0dd5ef9d1573fc39a06 Mon Sep 17 00:00:00 2001 From: Anton Soldatov Date: Fri, 1 Dec 2023 16:48:52 +0800 Subject: [PATCH 8/8] Title: Added inference of async type function with no return type to Promise Issue: https://gitee.com/open_harmony/dashboard?issue_id=I8G594&from=project-issue Testing: Internal phase check, ets test case Change-Id: I6b9d9bf0fbe9608899590090a98e60c49b9032d3 Signed-off-by: Orlovsky Maxim --- ets2panda/BUILD.gn | 1 + ets2panda/CMakeLists.txt | 1 + ets2panda/checker/ETSchecker.h | 5 + ets2panda/checker/ets/aliveAnalyzer.cpp | 15 +- ets2panda/checker/ets/function.cpp | 216 +- .../types/ets/etsAsyncFuncReturnType.h | 2 +- ets2panda/compiler/core/JSCompiler.cpp | 1 + .../compiler/lowering/ets/promiseVoid.cpp | 225 ++ ets2panda/compiler/lowering/ets/promiseVoid.h | 34 + ets2panda/compiler/lowering/phase.cpp | 18 +- ets2panda/compiler/scripts/signatures.yaml | 2 + ets2panda/ir/statements/returnStatement.cpp | 6 + ets2panda/ir/statements/returnStatement.h | 1 + .../compiler/ets/promiseVoid-expected.txt | 3069 +++++++++++++++++ ets2panda/test/compiler/ets/promiseVoid.ets | 56 + .../test-lists/parser/parser-js-ignored.txt | 3 + 16 files changed, 3553 insertions(+), 102 deletions(-) create mode 100644 ets2panda/compiler/lowering/ets/promiseVoid.cpp create mode 100644 ets2panda/compiler/lowering/ets/promiseVoid.h create mode 100644 ets2panda/test/compiler/ets/promiseVoid-expected.txt create mode 100644 ets2panda/test/compiler/ets/promiseVoid.ets diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index cb59a25c18..ccdedd350b 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -160,6 +160,7 @@ libes2panda_sources = [ "compiler/lowering/ets/lambdaLowering.cpp", "compiler/lowering/ets/objectIndexAccess.cpp", "compiler/lowering/ets/opAssignment.cpp", + "compiler/lowering/ets/promiseVoid.cpp", "compiler/lowering/ets/tupleLowering.cpp", "compiler/lowering/ets/unionLowering.cpp", "compiler/lowering/phase.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 33b9d5959d..0132316be1 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -170,6 +170,7 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/tupleLowering.cpp compiler/lowering/ets/unionLowering.cpp compiler/lowering/ets/expandBrackets.cpp + compiler/lowering/ets/promiseVoid.cpp ir/astDump.cpp ir/astNode.cpp ir/irnode.cpp diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index d8034074e2..c531649ef5 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -305,6 +305,11 @@ public: Signature *ResolveConstructExpression(ETSObjectType *type, const ArenaVector &arguments, const lexer::SourcePosition &pos); void CheckObjectLiteralArguments(Signature *sig, ArenaVector const &arguments); + Signature *ComposeSignature(ir::ScriptFunction *func, SignatureInfo *signature_info, Type *return_type, + varbinder::Variable *name_var); + Type *ComposeReturnType(ir::ScriptFunction *func, util::StringView func_name, bool is_construct_sig); + SignatureInfo *ComposeSignatureInfo(ir::ScriptFunction *func); + void ValidateMainSignature(ir::ScriptFunction *func); checker::ETSFunctionType *BuildFunctionSignature(ir::ScriptFunction *func, bool is_construct_sig = false); checker::ETSFunctionType *BuildMethodSignature(ir::MethodDefinition *method); Signature *CheckEveryAbstractSignatureIsOverridden(ETSFunctionType *target, ETSFunctionType *source); diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index 3c6ef37295..869388f539 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -16,6 +16,7 @@ #include "aliveAnalyzer.h" #include +#include "checker/types/ets/etsAsyncFuncReturnType.h" #include "ir/base/classDefinition.h" #include "ir/base/classProperty.h" #include "ir/base/methodDefinition.h" @@ -272,11 +273,17 @@ void AliveAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *method_def) status_ = LivenessStatus::ALIVE; AnalyzeStat(func->Body()); ASSERT(method_def->TsType() && method_def->TsType()->IsETSFunctionType()); + const auto *return_type = method_def->TsType()->AsETSFunctionType()->FindSignature(func)->ReturnType(); + const auto is_void = return_type->IsETSVoidType() || return_type == checker_->GlobalBuiltinVoidType(); - if (status_ == LivenessStatus::ALIVE && - (!method_def->TsType()->AsETSFunctionType()->FindSignature(func)->ReturnType()->IsETSVoidType() && - method_def->TsType()->AsETSFunctionType()->FindSignature(func)->ReturnType() != - checker_->GlobalBuiltinVoidType())) { + auto is_promise_void = false; + + if (return_type->IsETSAsyncFuncReturnType()) { + const auto *as_async = return_type->AsETSAsyncFuncReturnType(); + is_promise_void = as_async->GetPromiseTypeArg() == checker_->GlobalBuiltinVoidType(); + } + + if (status_ == LivenessStatus::ALIVE && !is_void && !is_promise_void) { checker_->ThrowTypeError("Function with a non void return type must return a value.", func->Id()->Start()); } diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 1d6467d3c8..ff521c782e 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -692,12 +692,100 @@ void ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType } } -checker::ETSFunctionType *ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool is_construct_sig) +Signature *ETSChecker::ComposeSignature(ir::ScriptFunction *func, SignatureInfo *signature_info, Type *return_type, + varbinder::Variable *name_var) { - bool is_arrow = func->IsArrow(); - auto *name_var = is_arrow ? nullptr : func->Id()->Variable(); - auto func_name = name_var == nullptr ? util::StringView() : name_var->Name(); + auto *signature = CreateSignature(signature_info, return_type, func); + signature->SetOwner(Context().ContainingClass()); + signature->SetOwnerVar(name_var); + + const auto *return_type_annotation = func->ReturnTypeAnnotation(); + if (return_type_annotation == nullptr && ((func->Flags() & ir::ScriptFunctionFlags::HAS_RETURN) != 0)) { + signature->AddSignatureFlag(SignatureFlags::NEED_RETURN_TYPE); + } + + if (func->IsAbstract()) { + signature->AddSignatureFlag(SignatureFlags::ABSTRACT); + signature->AddSignatureFlag(SignatureFlags::VIRTUAL); + } + + if (func->IsStatic()) { + signature->AddSignatureFlag(SignatureFlags::STATIC); + } + + if (func->IsConstructor()) { + signature->AddSignatureFlag(SignatureFlags::CONSTRUCTOR); + } + + if (signature->Owner()->GetDeclNode()->IsFinal() || func->IsFinal()) { + signature->AddSignatureFlag(SignatureFlags::FINAL); + } + if (func->IsPublic()) { + signature->AddSignatureFlag(SignatureFlags::PUBLIC); + } else if (func->IsInternal()) { + if (func->IsProtected()) { + signature->AddSignatureFlag(SignatureFlags::INTERNAL_PROTECTED); + } else { + signature->AddSignatureFlag(SignatureFlags::INTERNAL); + } + } else if (func->IsProtected()) { + signature->AddSignatureFlag(SignatureFlags::PROTECTED); + } else if (func->IsPrivate()) { + signature->AddSignatureFlag(SignatureFlags::PRIVATE); + } + + return signature; +} + +Type *ETSChecker::ComposeReturnType(ir::ScriptFunction *func, util::StringView func_name, bool is_construct_sig) +{ + auto *const return_type_annotation = func->ReturnTypeAnnotation(); + checker::Type *return_type {}; + + if (return_type_annotation == nullptr) { + // implicit void return type + return_type = is_construct_sig || func->IsEntryPoint() || func_name.Is(compiler::Signatures::CCTOR) + ? GlobalVoidType() + : GlobalBuiltinVoidType(); + + if (return_type == nullptr) { + const auto var_map = VarBinder()->TopScope()->Bindings(); + + const auto builtin_void = var_map.find(compiler::Signatures::BUILTIN_VOID_CLASS); + ASSERT(builtin_void != var_map.end()); + + BuildClassProperties(builtin_void->second->Declaration()->Node()->AsClassDefinition()); + + ASSERT(GlobalBuiltinVoidType() != nullptr); + return_type = GlobalBuiltinVoidType(); + } + + if (func->IsAsyncFunc()) { + auto implicit_promise_void = [this]() { + const auto &promise_global = GlobalBuiltinPromiseType()->AsETSObjectType(); + auto promise_type = + promise_global->Instantiate(Allocator(), Relation(), GetGlobalTypesHolder())->AsETSObjectType(); + promise_type->AddTypeFlag(checker::TypeFlag::GENERIC); + promise_type->TypeArguments().clear(); + promise_type->TypeArguments().emplace_back(GlobalBuiltinVoidType()); + return promise_type; + }; + + return_type = implicit_promise_void(); + } + } else if (func->IsEntryPoint() && return_type_annotation->GetType(this) == GlobalBuiltinVoidType()) { + return_type = GlobalVoidType(); + } else { + return_type = GetTypeFromTypeAnnotation(return_type_annotation); + return_type_annotation->SetTsType(return_type); + } + + return return_type; +} + +SignatureInfo *ETSChecker::ComposeSignatureInfo(ir::ScriptFunction *func) +{ auto *signature_info = CreateSignatureInfo(); signature_info->rest_var = nullptr; signature_info->min_arg_count = 0; @@ -741,107 +829,58 @@ checker::ETSFunctionType *ETSChecker::BuildFunctionSignature(ir::ScriptFunction } } - if (func_name.Is(compiler::Signatures::MAIN) && - func->Scope()->Name().Utf8().find(compiler::Signatures::ETS_GLOBAL) != std::string::npos) { - func->AddFlag(ir::ScriptFunctionFlags::ENTRY_POINT); - } + return signature_info; +} - if (func->IsEntryPoint()) { - if (func->Params().size() >= 2U) { - ThrowTypeError("0 or 1 argument are allowed", func->Start()); - } +void ETSChecker::ValidateMainSignature(ir::ScriptFunction *func) +{ + if (func->Params().size() >= 2U) { + ThrowTypeError("0 or 1 argument are allowed", func->Start()); + } - if (func->Params().size() == 1) { - auto const *const param = func->Params()[0]->AsETSParameterExpression(); + if (func->Params().size() == 1) { + auto const *const param = func->Params()[0]->AsETSParameterExpression(); - if (param->IsRestParameter()) { - ThrowTypeError("Rest parameter is not allowed in the 'main' function.", param->Start()); - } + if (param->IsRestParameter()) { + ThrowTypeError("Rest parameter is not allowed in the 'main' function.", param->Start()); + } - const auto param_type = param->Variable()->TsType(); - if (!param_type->IsETSArrayType() || !param_type->AsETSArrayType()->ElementType()->IsETSStringType()) { - ThrowTypeError("Only 'string[]' type argument is allowed.", param->Start()); - } + const auto param_type = param->Variable()->TsType(); + if (!param_type->IsETSArrayType() || !param_type->AsETSArrayType()->ElementType()->IsETSStringType()) { + ThrowTypeError("Only 'string[]' type argument is allowed.", param->Start()); } } +} - auto *const return_type_annotation = func->ReturnTypeAnnotation(); - checker::Type *return_type {}; - - if (return_type_annotation == nullptr) { - // implicit void return type - return_type = is_construct_sig || func->IsEntryPoint() || func_name.Is(compiler::Signatures::CCTOR) - ? GlobalVoidType() - : GlobalBuiltinVoidType(); - - if (return_type == nullptr) { - const auto var_map = VarBinder()->TopScope()->Bindings(); - - const auto builtin_void = var_map.find(compiler::Signatures::BUILTIN_VOID_CLASS); - ASSERT(builtin_void != var_map.end()); +checker::ETSFunctionType *ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool is_construct_sig) +{ + bool is_arrow = func->IsArrow(); + auto *name_var = is_arrow ? nullptr : func->Id()->Variable(); + auto func_name = name_var == nullptr ? util::StringView() : name_var->Name(); - BuildClassProperties(builtin_void->second->Declaration()->Node()->AsClassDefinition()); + auto *signature_info = ComposeSignatureInfo(func); - ASSERT(GlobalBuiltinVoidType() != nullptr); - return_type = GlobalBuiltinVoidType(); - } - } else if (func->IsEntryPoint() && return_type_annotation->GetType(this) == GlobalBuiltinVoidType()) { - return_type = GlobalVoidType(); - } else { - return_type = GetTypeFromTypeAnnotation(return_type_annotation); - return_type_annotation->SetTsType(return_type); + if (func_name.Is(compiler::Signatures::MAIN) && + func->Scope()->Name().Utf8().find(compiler::Signatures::ETS_GLOBAL) != std::string::npos) { + func->AddFlag(ir::ScriptFunctionFlags::ENTRY_POINT); + } + if (func->IsEntryPoint()) { + ValidateMainSignature(func); } - auto *signature = CreateSignature(signature_info, return_type, func); - signature->SetOwner(Context().ContainingClass()); - signature->SetOwnerVar(name_var); - + auto *return_type = ComposeReturnType(func, func_name, is_construct_sig); + auto *signature = ComposeSignature(func, signature_info, return_type, name_var); if (is_construct_sig) { signature->AddSignatureFlag(SignatureFlags::CONSTRUCT); } else { signature->AddSignatureFlag(SignatureFlags::CALL); } - if (return_type_annotation == nullptr && ((func->Flags() & ir::ScriptFunctionFlags::HAS_RETURN) != 0)) { - signature->AddSignatureFlag(SignatureFlags::NEED_RETURN_TYPE); - } - auto *func_type = CreateETSFunctionType(func, signature, func_name); func->SetSignature(signature); func_type->SetVariable(name_var); VarBinder()->AsETSBinder()->BuildFunctionName(func); - if (func->IsAbstract()) { - signature->AddSignatureFlag(SignatureFlags::ABSTRACT); - signature->AddSignatureFlag(SignatureFlags::VIRTUAL); - } - - if (func->IsStatic()) { - signature->AddSignatureFlag(SignatureFlags::STATIC); - } - - if (func->IsConstructor()) { - signature->AddSignatureFlag(SignatureFlags::CONSTRUCTOR); - } - - if (func->Signature()->Owner()->GetDeclNode()->IsFinal() || func->IsFinal()) { - signature->AddSignatureFlag(SignatureFlags::FINAL); - } - - if (func->IsPublic()) { - signature->AddSignatureFlag(SignatureFlags::PUBLIC); - } else if (func->IsInternal()) { - if (func->IsProtected()) { - signature->AddSignatureFlag(SignatureFlags::INTERNAL_PROTECTED); - } else { - signature->AddSignatureFlag(SignatureFlags::INTERNAL); - } - } else if (func->IsProtected()) { - signature->AddSignatureFlag(SignatureFlags::PROTECTED); - } else if (func->IsPrivate()) { - signature->AddSignatureFlag(SignatureFlags::PRIVATE); - } - if (!is_arrow) { name_var->SetTsType(func_type); } @@ -2458,8 +2497,15 @@ ir::MethodDefinition *ETSChecker::CreateAsyncImplMethod(ir::MethodDefinition *as Allocator()->New(Allocator()->New(object_id, nullptr, nullptr)); object_id->SetParent(return_type_ann->Part()); return_type_ann->Part()->SetParent(return_type_ann); - ETSObjectType *const promise_type = - GetTypeFromTypeAnnotation(async_func->ReturnTypeAnnotation())->AsETSObjectType(); + auto *async_func_ret_type_ann = async_func->ReturnTypeAnnotation(); + auto *promise_type = [this](ir::TypeNode *type) { + if (type != nullptr) { + return GetTypeFromTypeAnnotation(type)->AsETSObjectType(); + } + + return GlobalBuiltinPromiseType()->AsETSObjectType(); + }(async_func_ret_type_ann); + auto *ret_type = Allocator()->New(Allocator(), promise_type); return_type_ann->SetTsType(ret_type); diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h index fc3fb0df7f..c4b5eb41f9 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h @@ -35,7 +35,6 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; -private: const Type *GetPromiseTypeArg() const { return promise_type_->TypeArguments()[0]; @@ -46,6 +45,7 @@ private: return promise_type_->TypeArguments()[0]; } +private: ETSObjectType *promise_type_; }; } // namespace panda::es2panda::checker diff --git a/ets2panda/compiler/core/JSCompiler.cpp b/ets2panda/compiler/core/JSCompiler.cpp index 6f11b26be7..a2a935c292 100644 --- a/ets2panda/compiler/core/JSCompiler.cpp +++ b/ets2panda/compiler/core/JSCompiler.cpp @@ -2158,4 +2158,5 @@ void JSCompiler::Compile([[maybe_unused]] const ir::TSVoidKeyword *node) const { UNREACHABLE(); } + } // namespace panda::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/promiseVoid.cpp b/ets2panda/compiler/lowering/ets/promiseVoid.cpp new file mode 100644 index 0000000000..06d0bacff8 --- /dev/null +++ b/ets2panda/compiler/lowering/ets/promiseVoid.cpp @@ -0,0 +1,225 @@ +/** + * Copyright (c) 2023 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. + */ + +#include "promiseVoid.h" +#include "checker/ETSchecker.h" +#include "checker/checker.h" +#include "compiler/core/compilerContext.h" +#include "generated/signatures.h" +#include "ir/base/scriptFunction.h" +#include "ir/ets/etsTypeReference.h" +#include "ir/ets/etsTypeReferencePart.h" +#include "ir/expressions/functionExpression.h" +#include "ir/expressions/identifier.h" +#include "ir/statements/returnStatement.h" +#include "ir/typeNode.h" +#include "lexer/token/sourceLocation.h" +#include "ir/astNode.h" +#include "ir/statements/blockStatement.h" +#include "util/ustring.h" + +namespace panda::es2panda::compiler { + +std::string_view PromiseVoidLowering::Name() +{ + static std::string const NAME = "promise-void"; + return NAME; +} + +static ir::BlockStatement *HandleAsyncScriptFunctionBody(checker::ETSChecker *checker, ir::BlockStatement *body) +{ + (void)checker; + body->TransformChildrenRecursively([checker](ir::AstNode *ast) -> ir::AstNode * { + if (ast->IsReturnStatement()) { + auto *return_stmt = ast->AsReturnStatement(); + const auto *arg = return_stmt->Argument(); + if (arg == nullptr) { + auto *void_id = + checker->AllocNode(compiler::Signatures::VOID_OBJECT, checker->Allocator()); + const auto &return_loc = return_stmt->Range(); + void_id->SetRange({return_loc.end, return_loc.end}); + return_stmt->SetArgument(void_id); + } + } + return ast; + }); + return body; +} + +static void SetRangeRecursively(ir::TypeNode *node, const lexer::SourceRange &loc) +{ + node->SetRange(loc); + node->TransformChildrenRecursively([loc](ir::AstNode *ast) -> ir::AstNode * { + ast->SetRange(loc); + return ast; + }); +} + +static ir::TypeNode *CreatePromiseVoidType(checker::ETSChecker *checker, const lexer::SourceRange &loc) +{ + auto *void_param = [checker]() { + auto params_vector = ArenaVector(checker->Allocator()->Adapter()); + auto *void_id = + checker->AllocNode(compiler::Signatures::BUILTIN_VOID_CLASS, checker->Allocator()); + void_id->SetReference(); + auto *part = checker->AllocNode(void_id); + params_vector.push_back(checker->AllocNode(part)); + auto *params = checker->AllocNode(std::move(params_vector)); + return params; + }(); + + auto *promise_void_type = [checker, void_param]() { + auto *promise_id = + checker->AllocNode(compiler::Signatures::BUILTIN_PROMISE_CLASS, checker->Allocator()); + promise_id->SetReference(); + auto *part = checker->AllocNode(promise_id, void_param, nullptr); + auto *type = checker->AllocNode(part); + return type; + }(); + + SetRangeRecursively(promise_void_type, loc); + + return promise_void_type; +} + +static bool CheckForPromiseVoid(const ir::TypeNode *type) +{ + if (type == nullptr || !type->IsETSTypeReference()) { + return false; + } + + auto *type_ref = type->AsETSTypeReference(); + auto *type_part = type_ref->Part(); + if (type_part->Previous() != nullptr) { + return false; + } + + const auto ¶ms = type_part->TypeParams()->Params(); + if (params.size() != 1) { + return false; + } + + const auto ¶m = params.at(0); + if (!param->IsETSTypeReference()) { + return false; + } + + const auto *param_ref = param->AsETSTypeReference(); + const auto *param_part = param_ref->Part(); + if (param_part->Previous() != nullptr) { + return false; + } + + const auto is_type_promise = + type_part->Name()->AsIdentifier()->Name() == compiler::Signatures::BUILTIN_PROMISE_CLASS; + const auto is_param_void = param_part->Name()->AsIdentifier()->Name() == compiler::Signatures::BUILTIN_VOID_CLASS; + + return is_type_promise && is_param_void; +} + +bool PromiseVoidLowering::Perform(public_lib::Context *ctx, parser::Program *program) +{ + auto *checker = ctx->checker->AsETSChecker(); + + auto gen_type_location = [](ir::ScriptFunction *function) -> lexer::SourceRange { + const auto ¶ms = function->Params(); + const auto &id = function->Id(); + const auto &body = function->Body(); + if (!params.empty()) { + const auto &last = params.back(); + const auto &loc = last->Range(); + return {loc.end, loc.end}; + } + + if (id != nullptr) { + const auto &loc = id->Range(); + return {loc.end, loc.end}; + } + + if (function->HasBody()) { + const auto &loc = body->Range(); + return {loc.start, loc.start}; + } + + const auto &loc = function->Range(); + return {loc.end, loc.end}; + }; + + program->Ast()->TransformChildrenRecursively([checker, gen_type_location](ir::AstNode *ast) -> ir::AstNode * { + if (ast->IsScriptFunction() && ast->AsScriptFunction()->IsAsyncFunc()) { + auto *function = ast->AsScriptFunction(); + auto *return_ann = function->ReturnTypeAnnotation(); + const auto has_return_ann = return_ann != nullptr; + const auto has_promise_void = CheckForPromiseVoid(return_ann); + + if (!has_return_ann) { + const auto &loc = gen_type_location(function); + function->SetReturnTypeAnnotation(CreatePromiseVoidType(checker, loc)); + + if (function->HasBody()) { + HandleAsyncScriptFunctionBody(checker, function->Body()->AsBlockStatement()); + } + } else if (has_promise_void && function->HasBody()) { + HandleAsyncScriptFunctionBody(checker, function->Body()->AsBlockStatement()); + } + } + + return ast; + }); + + return true; +} + +bool PromiseVoidLowering::Postcondition(public_lib::Context *ctx, const parser::Program *program) +{ + (void)ctx; + + auto check_function_body = [](const ir::BlockStatement *body) -> bool { + if (body->IsReturnStatement()) { + auto *return_stmt = body->AsReturnStatement(); + const auto *arg = return_stmt->Argument(); + + if (!arg->IsIdentifier()) { + return false; + } + + const auto *id = arg->AsIdentifier(); + return id->Name() == compiler::Signatures::VOID_OBJECT; + } + + return true; + }; + + auto is_ok = true; + program->Ast()->IterateRecursively([check_function_body, &is_ok](ir::AstNode *ast) { + if (ast->IsScriptFunction() && ast->AsScriptFunction()->IsAsyncFunc()) { + auto *function = ast->AsScriptFunction(); + auto *return_ann = function->ReturnTypeAnnotation(); + if (!CheckForPromiseVoid(return_ann)) { + return; + } + if (function->HasBody()) { + if (!check_function_body(function->Body()->AsBlockStatement())) { + is_ok = false; + return; + } + } + } + return; + }); + + return is_ok; +} +} // namespace panda::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/promiseVoid.h b/ets2panda/compiler/lowering/ets/promiseVoid.h new file mode 100644 index 0000000000..b09200838d --- /dev/null +++ b/ets2panda/compiler/lowering/ets/promiseVoid.h @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2023 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_COMPILER_LOWERING_PROMISE_VOID_H +#define ES2PANDA_COMPILER_LOWERING_PROMISE_VOID_H + +#include "compiler/lowering/phase.h" + +namespace panda::es2panda::compiler { + +class PromiseVoidLowering : public Phase { +public: + std::string_view Name() override; + bool Perform(public_lib::Context *ctx, parser::Program *program) override; + bool Postcondition(public_lib::Context *ctx, const parser::Program *program) override; + +private: +}; + +} // namespace panda::es2panda::compiler + +#endif diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 4dd62e0dee..e8cb715dbe 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -28,6 +28,7 @@ #include "compiler/lowering/ets/tupleLowering.h" #include "compiler/lowering/ets/unionLowering.h" #include "public/es2panda_lib.h" +#include "compiler/lowering/ets/promiseVoid.h" namespace panda::es2panda::compiler { @@ -47,25 +48,18 @@ static ObjectIndexLowering OBJECT_INDEX_LOWERING; static TupleLowering TUPLE_LOWERING; // Can be only applied after checking phase, and OP_ASSIGNMENT_LOWERING phase static UnionLowering UNION_LOWERING; static ExpandBracketsPhase EXPAND_BRACKETS_PHASE; +static PromiseVoidLowering PROMISE_VOID_LOWERING; static PluginPhase PLUGINS_AFTER_PARSE {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse}; static PluginPhase PLUGINS_AFTER_CHECK {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck}; static PluginPhase PLUGINS_AFTER_LOWERINGS {"plugins-after-lowering", ES2PANDA_STATE_LOWERED, &util::Plugin::AfterLowerings}; - std::vector GetETSPhaseList() { return std::vector { - &PLUGINS_AFTER_PARSE, - &LAMBDA_LOWERING, - &CHECKER_PHASE, - &PLUGINS_AFTER_CHECK, - &GENERATE_TS_DECLARATIONS_PHASE, - &OP_ASSIGNMENT_LOWERING, - &OBJECT_INDEX_LOWERING, - &TUPLE_LOWERING, - &UNION_LOWERING, - &EXPAND_BRACKETS_PHASE, - &PLUGINS_AFTER_LOWERINGS, + &PLUGINS_AFTER_PARSE, &PROMISE_VOID_LOWERING, &LAMBDA_LOWERING, + &CHECKER_PHASE, &PLUGINS_AFTER_CHECK, &GENERATE_TS_DECLARATIONS_PHASE, + &OP_ASSIGNMENT_LOWERING, &OBJECT_INDEX_LOWERING, &TUPLE_LOWERING, + &UNION_LOWERING, &EXPAND_BRACKETS_PHASE, &PLUGINS_AFTER_LOWERINGS, }; } diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 48b890f3f4..be3639d81f 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -118,6 +118,8 @@ defines: ref: STATIC_INVOKE_METHOD - name: instantiate ref: STATIC_INSTANTIATE_METHOD + - name: Void + ref: VOID_OBJECT packages: - name: 'std.core' diff --git a/ets2panda/ir/statements/returnStatement.cpp b/ets2panda/ir/statements/returnStatement.cpp index fed52f836b..4c1cf00120 100644 --- a/ets2panda/ir/statements/returnStatement.cpp +++ b/ets2panda/ir/statements/returnStatement.cpp @@ -81,4 +81,10 @@ void ReturnStatement::SetReturnType(checker::ETSChecker *checker, checker::Type } } } + +void ReturnStatement::SetArgument(Expression *arg) +{ + argument_ = arg; + arg->SetParent(this); +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/statements/returnStatement.h b/ets2panda/ir/statements/returnStatement.h index 3bbe888c02..2c43a7e89a 100644 --- a/ets2panda/ir/statements/returnStatement.h +++ b/ets2panda/ir/statements/returnStatement.h @@ -63,6 +63,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void SetReturnType(checker::ETSChecker *checker, checker::Type *type) override; + void SetArgument(Expression *arg); void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/ets2panda/test/compiler/ets/promiseVoid-expected.txt b/ets2panda/test/compiler/ets/promiseVoid-expected.txt new file mode 100644 index 0000000000..73c1460b96 --- /dev/null +++ b/ets2panda/test/compiler/ets/promiseVoid-expected.txt @@ -0,0 +1,3069 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "testAsyncVoidMethodImplicit", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidMethodImplicit", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 17, + "column": 41 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "testAsyncVoidMethodExplicit", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 11 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidMethodExplicit", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 11 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 42 + }, + "end": { + "line": 18, + "column": 49 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 50 + }, + "end": { + "line": 18, + "column": 54 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 50 + }, + "end": { + "line": 18, + "column": 55 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 50 + }, + "end": { + "line": 18, + "column": 55 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 49 + }, + "end": { + "line": 18, + "column": 55 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 42 + }, + "end": { + "line": 18, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 42 + }, + "end": { + "line": 18, + "column": 57 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 64 + }, + "end": { + "line": 18, + "column": 64 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 58 + }, + "end": { + "line": 18, + "column": 64 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 56 + }, + "end": { + "line": 18, + "column": 66 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 38 + }, + "end": { + "line": 18, + "column": 66 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 38 + }, + "end": { + "line": 18, + "column": 66 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 66 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "testAsyncVoidMethodExplicitObject", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 11 + }, + "end": { + "line": 19, + "column": 44 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidMethodExplicitObject", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 11 + }, + "end": { + "line": 19, + "column": 44 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 48 + }, + "end": { + "line": 19, + "column": 55 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 56 + }, + "end": { + "line": 19, + "column": 60 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 56 + }, + "end": { + "line": 19, + "column": 61 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 56 + }, + "end": { + "line": 19, + "column": 61 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 55 + }, + "end": { + "line": 19, + "column": 61 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 48 + }, + "end": { + "line": 19, + "column": 63 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 48 + }, + "end": { + "line": 19, + "column": 63 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 71 + }, + "end": { + "line": 19, + "column": 75 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 64 + }, + "end": { + "line": 19, + "column": 75 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 62 + }, + "end": { + "line": 19, + "column": 77 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 44 + }, + "end": { + "line": 19, + "column": 77 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 44 + }, + "end": { + "line": 19, + "column": 77 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 77 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "testAsyncVoidMethodReturns", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 11 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidMethodReturns", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 11 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 20, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 13 + }, + "end": { + "line": 21, + "column": 17 + } + } + }, + "init": { + "type": "BooleanLiteral", + "value": false, + "loc": { + "start": { + "line": 21, + "column": 20 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 13 + }, + "end": { + "line": 21, + "column": 25 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 13 + }, + "end": { + "line": 22, + "column": 17 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 19 + }, + "end": { + "line": 24, + "column": 10 + } + } + }, + "alternate": { + "type": "BlockStatement", + "statements": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 17 + }, + "end": { + "line": 25, + "column": 21 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 31 + }, + "end": { + "line": 25, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 25 + }, + "end": { + "line": 25, + "column": 31 + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 23 + }, + "end": { + "line": 25, + "column": 33 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 16 + }, + "end": { + "line": 26, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 26, + "column": 10 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 40 + }, + "end": { + "line": 27, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 27, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 37 + }, + "end": { + "line": 27, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 27, + "column": 6 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "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": 28, + "column": 2 + }, + "end": { + "line": 28, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + { + "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": "testAsyncVoidImplicit", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 16 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidImplicit", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 16 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 37 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 30, + "column": 40 + }, + "end": { + "line": 30, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 42 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 42 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "testAsyncVoidExplicit", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 16 + }, + "end": { + "line": 31, + "column": 37 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidExplicit", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 16 + }, + "end": { + "line": 31, + "column": 37 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 41 + }, + "end": { + "line": 31, + "column": 48 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 49 + }, + "end": { + "line": 31, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 49 + }, + "end": { + "line": 31, + "column": 54 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 49 + }, + "end": { + "line": 31, + "column": 54 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 48 + }, + "end": { + "line": 31, + "column": 54 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 41 + }, + "end": { + "line": 31, + "column": 56 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 41 + }, + "end": { + "line": 31, + "column": 56 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 63 + }, + "end": { + "line": 31, + "column": 63 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 57 + }, + "end": { + "line": 31, + "column": 63 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 55 + }, + "end": { + "line": 31, + "column": 65 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 37 + }, + "end": { + "line": 31, + "column": 65 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 37 + }, + "end": { + "line": 31, + "column": 65 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 65 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "testAsyncVoidExplicitObject", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 32, + "column": 43 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidExplicitObject", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 32, + "column": 43 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 47 + }, + "end": { + "line": 32, + "column": 54 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 55 + }, + "end": { + "line": 32, + "column": 59 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 55 + }, + "end": { + "line": 32, + "column": 60 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 55 + }, + "end": { + "line": 32, + "column": 60 + } + } + } + ], + "loc": { + "start": { + "line": 32, + "column": 54 + }, + "end": { + "line": 32, + "column": 60 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 47 + }, + "end": { + "line": 32, + "column": 62 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 47 + }, + "end": { + "line": 32, + "column": 62 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 70 + }, + "end": { + "line": 32, + "column": 74 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 63 + }, + "end": { + "line": 32, + "column": 74 + } + } + } + ], + "loc": { + "start": { + "line": 32, + "column": 61 + }, + "end": { + "line": 32, + "column": 76 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 43 + }, + "end": { + "line": 32, + "column": 76 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 43 + }, + "end": { + "line": 32, + "column": 76 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 76 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "testAsyncVoidEarlyReturn", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 16 + }, + "end": { + "line": 33, + "column": 40 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidEarlyReturn", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 16 + }, + "end": { + "line": 33, + "column": 40 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 44 + }, + "end": { + "line": 33, + "column": 51 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 52 + }, + "end": { + "line": 33, + "column": 56 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 52 + }, + "end": { + "line": 33, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 52 + }, + "end": { + "line": 33, + "column": 57 + } + } + } + ], + "loc": { + "start": { + "line": 33, + "column": 51 + }, + "end": { + "line": 33, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 44 + }, + "end": { + "line": 33, + "column": 59 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 44 + }, + "end": { + "line": 33, + "column": 59 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "flag", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 34, + "column": 15 + }, + "end": { + "line": 34, + "column": 22 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 9 + }, + "end": { + "line": 34, + "column": 13 + } + } + }, + "init": { + "type": "BooleanLiteral", + "value": true, + "loc": { + "start": { + "line": 34, + "column": 25 + }, + "end": { + "line": 34, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 9 + }, + "end": { + "line": 34, + "column": 29 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 34, + "column": 5 + }, + "end": { + "line": 34, + "column": 29 + } + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 9 + }, + "end": { + "line": 35, + "column": 13 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 15 + }, + "end": { + "line": 36, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 9 + }, + "end": { + "line": 36, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 35, + "column": 15 + }, + "end": { + "line": 37, + "column": 6 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 35, + "column": 5 + }, + "end": { + "line": 37, + "column": 6 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 38, + "column": 5 + }, + "end": { + "line": 38, + "column": 12 + } + } + }, + "property": { + "type": "Identifier", + "name": "println", + "decorators": [], + "loc": { + "start": { + "line": 38, + "column": 13 + }, + "end": { + "line": 38, + "column": 20 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 38, + "column": 5 + }, + "end": { + "line": 38, + "column": 20 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "something", + "loc": { + "start": { + "line": 38, + "column": 21 + }, + "end": { + "line": 38, + "column": 32 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 38, + "column": 5 + }, + "end": { + "line": 38, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 38, + "column": 5 + }, + "end": { + "line": 38, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 33, + "column": 58 + }, + "end": { + "line": 39, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 40 + }, + "end": { + "line": 39, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 40 + }, + "end": { + "line": 39, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 1 + }, + "end": { + "line": 39, + "column": 2 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "testAsyncVoidMultipleReturns", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 16 + }, + "end": { + "line": 40, + "column": 44 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "testAsyncVoidMultipleReturns", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 16 + }, + "end": { + "line": 40, + "column": 44 + } + } + }, + "generator": false, + "async": true, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Promise", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 40, + "column": 44 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 40, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 40, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 40, + "column": 44 + } + } + } + ], + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 40, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 40, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 40, + "column": 44 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "flag", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 41, + "column": 15 + }, + "end": { + "line": 41, + "column": 22 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 9 + }, + "end": { + "line": 41, + "column": 13 + } + } + }, + "init": { + "type": "BooleanLiteral", + "value": true, + "loc": { + "start": { + "line": 41, + "column": 25 + }, + "end": { + "line": 41, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 9 + }, + "end": { + "line": 41, + "column": 29 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 41, + "column": 5 + }, + "end": { + "line": 41, + "column": 29 + } + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 42, + "column": 9 + }, + "end": { + "line": 42, + "column": 13 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 43, + "column": 15 + }, + "end": { + "line": 43, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 9 + }, + "end": { + "line": 43, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 42, + "column": 15 + }, + "end": { + "line": 44, + "column": 6 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 42, + "column": 5 + }, + "end": { + "line": 44, + "column": 6 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 45, + "column": 5 + }, + "end": { + "line": 45, + "column": 12 + } + } + }, + "property": { + "type": "Identifier", + "name": "println", + "decorators": [], + "loc": { + "start": { + "line": 45, + "column": 13 + }, + "end": { + "line": 45, + "column": 20 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 45, + "column": 5 + }, + "end": { + "line": 45, + "column": 20 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "something x1", + "loc": { + "start": { + "line": 45, + "column": 21 + }, + "end": { + "line": 45, + "column": 35 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 45, + "column": 5 + }, + "end": { + "line": 45, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 45, + "column": 5 + }, + "end": { + "line": 45, + "column": 36 + } + } + }, + { + "type": "IfStatement", + "test": { + "type": "UnaryExpression", + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "flag", + "decorators": [], + "loc": { + "start": { + "line": 46, + "column": 10 + }, + "end": { + "line": 46, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 46, + "column": 9 + }, + "end": { + "line": 46, + "column": 14 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "Void", + "decorators": [], + "loc": { + "start": { + "line": 47, + "column": 15 + }, + "end": { + "line": 47, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 47, + "column": 9 + }, + "end": { + "line": 47, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 46, + "column": 16 + }, + "end": { + "line": 48, + "column": 6 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 46, + "column": 5 + }, + "end": { + "line": 48, + "column": 6 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 49, + "column": 5 + }, + "end": { + "line": 49, + "column": 12 + } + } + }, + "property": { + "type": "Identifier", + "name": "println", + "decorators": [], + "loc": { + "start": { + "line": 49, + "column": 13 + }, + "end": { + "line": 49, + "column": 20 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 49, + "column": 5 + }, + "end": { + "line": 49, + "column": 20 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "something x2", + "loc": { + "start": { + "line": 49, + "column": 21 + }, + "end": { + "line": 49, + "column": 35 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 49, + "column": 5 + }, + "end": { + "line": 49, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 49, + "column": 5 + }, + "end": { + "line": 49, + "column": 36 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 50, + "column": 12 + }, + "end": { + "line": 50, + "column": 19 + } + } + }, + "property": { + "type": "Identifier", + "name": "println", + "decorators": [], + "loc": { + "start": { + "line": 50, + "column": 20 + }, + "end": { + "line": 50, + "column": 27 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 50, + "column": 12 + }, + "end": { + "line": 50, + "column": 27 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "something x3", + "loc": { + "start": { + "line": 50, + "column": 28 + }, + "end": { + "line": 50, + "column": 42 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 50, + "column": 12 + }, + "end": { + "line": 50, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 50, + "column": 5 + }, + "end": { + "line": 50, + "column": 43 + } + } + } + ], + "loc": { + "start": { + "line": 40, + "column": 47 + }, + "end": { + "line": 51, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 51, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 44 + }, + "end": { + "line": 51, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 1 + }, + "end": { + "line": 51, + "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": 57, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/promiseVoid.ets b/ets2panda/test/compiler/ets/promiseVoid.ets new file mode 100644 index 0000000000..0d62020dfb --- /dev/null +++ b/ets2panda/test/compiler/ets/promiseVoid.ets @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021-2023 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 A { + async testAsyncVoidMethodImplicit() {} + async testAsyncVoidMethodExplicit(): Promise { return } + async testAsyncVoidMethodExplicitObject(): Promise { return Void } + async testAsyncVoidMethodReturns() { + let flag = false + if (flag) { + return + } else { + if (flag) { return } + } + } +} + +async function testAsyncVoidImplicit() {} +async function testAsyncVoidExplicit(): Promise { return } +async function testAsyncVoidExplicitObject(): Promise { return Void } +async function testAsyncVoidEarlyReturn(): Promise { + let flag: boolean = true + if (flag) { + return + } + console.println("something") +} +async function testAsyncVoidMultipleReturns() { + let flag: boolean = true + if (flag) { + return + } + console.println("something x1") + if (!flag) { + return // we return here + } + console.println("something x2") + return console.println("something x3") +} + +// NOTE(orlovskiymaxim): add support for lambdas +// let testAsyncVoidLambdaImplicit = async () => {} +// let testAsyncVoidLambdaExplicit = async (): Promise => { return } +// let testAsyncVoidLambdaExplicitObject = async (): Promise => { return } diff --git a/ets2panda/test/test-lists/parser/parser-js-ignored.txt b/ets2panda/test/test-lists/parser/parser-js-ignored.txt index f44c772da3..0c171f3c34 100644 --- a/ets2panda/test/test-lists/parser/parser-js-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-js-ignored.txt @@ -1,3 +1,6 @@ +# FIXME(igelhaus): Temporarily skipped for dev branch stabilization +parser/ets/literals.ets + parser/ets/import_tests/modules/module.ets parser/ets/import_tests/import_class_members_1.ets parser/ets/import_tests/import_class_members_2.ets -- Gitee