From f1610bddc76634e5e2d9f6c1a8eaae309dc73412 Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Sun, 26 Nov 2023 11:35:19 +0800 Subject: [PATCH 01/35] [ArkTS] support 13.7.1 Selective Export Directive Test: ets-cts, parser, ets-runtime pass Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8KC39 Signed-off-by: liwentao --- ets2panda/parser/ETSparser.cpp | 42 +- ets2panda/parser/ETSparser.h | 7 +- .../selective_export/import_1-expected.txt | 389 ++++++++++++++ .../parser/ets/selective_export/import_1.ets | 21 + .../selective_export/import_2-expected.txt | 389 ++++++++++++++ .../parser/ets/selective_export/import_2.ets | 21 + .../selective_export/import_3-expected.txt | 389 ++++++++++++++ .../parser/ets/selective_export/import_3.ets | 21 + .../selective_export/import_4-expected.txt | 477 ++++++++++++++++++ .../parser/ets/selective_export/import_4.ets | 21 + .../selective_export_1-expected.txt | 288 +++++++++++ .../selective_export/selective_export_1.ets | 20 + .../selective_export_2-expected.txt | 288 +++++++++++ .../selective_export/selective_export_2.ets | 20 + .../selective_export_3-expected.txt | 439 ++++++++++++++++ .../selective_export/selective_export_3.ets | 24 + .../selective_export_4-expected.txt | 423 ++++++++++++++++ .../selective_export/selective_export_4.ets | 24 + .../selective_export_bad-expected.txt | 1 + .../selective_export/selective_export_bad.ets | 20 + 20 files changed, 3314 insertions(+), 10 deletions(-) create mode 100644 ets2panda/test/parser/ets/selective_export/import_1-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/import_1.ets create mode 100644 ets2panda/test/parser/ets/selective_export/import_2-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/import_2.ets create mode 100644 ets2panda/test/parser/ets/selective_export/import_3-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/import_3.ets create mode 100644 ets2panda/test/parser/ets/selective_export/import_4-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/import_4.ets create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_1-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_1.ets create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_2-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_2.ets create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_3-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_3.ets create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_4-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_4.ets create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_bad-expected.txt create mode 100644 ets2panda/test/parser/ets/selective_export/selective_export_bad.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index ddee2a5b0..da82788af 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -646,6 +646,8 @@ void ETSParser::MarkNodeAsExported(ir::AstNode *node, lexer::SourcePosition star ArenaVector ETSParser::ParseTopLevelStatements(ArenaVector &statements) { ArenaVector global_properties(Allocator()->Adapter()); + field_map_.clear(); + export_name_map_.clear(); bool default_export = false; using ParserFunctionPtr = std::function; @@ -685,7 +687,7 @@ ArenaVector ETSParser::ParseTopLevelStatements(ArenaVectorGetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { - ParseReExport(Lexer()->GetToken().Start()); + ParseExport(Lexer()->GetToken().Start()); continue; } @@ -797,7 +799,17 @@ ArenaVector ETSParser::ParseTopLevelStatements(ArenaVectorSetRange({start_loc, end_loc}); + field_map_.insert({field_name->Name(), field}); declarations->push_back(field); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { @@ -1328,6 +1341,8 @@ ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *meth } auto *method = AllocNode(method_kind, method_name, func_expr, modifiers, Allocator(), false); method->SetRange(func_expr->Range()); + + field_map_.insert({method_name->Name(), method}); AddProxyOverloadToMethodWithDefaultParams(method, ident_node); return method; @@ -2843,7 +2858,7 @@ ir::DebuggerStatement *ETSParser::ParseDebuggerStatement() ThrowUnexpectedToken(lexer::TokenType::KEYW_DEBUGGER); } -void ETSParser::ParseReExport(lexer::SourcePosition start_loc) +void ETSParser::ParseExport(lexer::SourcePosition start_loc) { ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE); @@ -2855,10 +2870,12 @@ void ETSParser::ParseReExport(lexer::SourcePosition start_loc) ParseNamedSpecifiers(&specifiers, true); if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_FROM) { - ThrowSyntaxError("Selective export directive is not implemented yet"); + // selective export directive + return; } } + // re-export directive ir::ImportSource *re_export_source = nullptr; std::vector user_paths; @@ -3032,8 +3049,9 @@ std::vector ETSParser::ParseImportDeclarations(ArenaVector *specifiers, bool is_re_export) +void ETSParser::ParseNamedSpecifiers(ArenaVector *specifiers, bool is_export) { + lexer::SourcePosition start_loc = Lexer()->GetToken().Start(); // NOTE(user): handle qualifiedName in file bindings: qualifiedName '.' '*' if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { ThrowExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE); @@ -3041,6 +3059,7 @@ void ETSParser::ParseNamedSpecifiers(ArenaVector *specifiers, boo Lexer()->NextToken(); // eat '{' auto file_name = GetProgram()->SourceFilePath().Mutf8(); + std::vector exported_idents; while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { @@ -3056,7 +3075,7 @@ void ETSParser::ParseNamedSpecifiers(ArenaVector *specifiers, boo ir::Identifier *local = nullptr; imported->SetRange(Lexer()->GetToken().Loc()); - Lexer()->NextToken(); // eat import name + Lexer()->NextToken(); // eat import/export name if (CheckModuleAsModifier() && Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS) { Lexer()->NextToken(); // eat `as` literal @@ -3071,6 +3090,10 @@ void ETSParser::ParseNamedSpecifiers(ArenaVector *specifiers, boo util::Helpers::CheckImportedName(specifiers, specifier, file_name); + if (is_export) { + util::StringView member_name = local->Name(); + exported_idents.push_back(member_name); + } specifiers->push_back(specifier); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { @@ -3080,8 +3103,11 @@ void ETSParser::ParseNamedSpecifiers(ArenaVector *specifiers, boo Lexer()->NextToken(); // eat '}' - if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_FROM && !is_re_export) { - ThrowSyntaxError("Unexpected token, expected 'from'"); + if (is_export && Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_FROM) { + // update exported idents to export name map when it is not the case of re-export + for (auto member_name : exported_idents) { + export_name_map_.insert({member_name, start_loc}); + } } } diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 84d7503c2..d918a6953 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -99,6 +99,8 @@ private: bool has_decl; }; + std::map field_map_; + std::map export_name_map_; void ParseProgram(ScriptKind kind) override; [[nodiscard]] std::unique_ptr InitLexer(const SourceFile &source_file) override; void ParsePackageDeclaration(ArenaVector &statements); @@ -115,7 +117,8 @@ private: std::tuple GetSourceRegularPath(const std::string &path, const std::string &resolved_path); void ParseSources(const std::vector &paths, bool is_external = true); std::tuple> ParseFromClause(bool require_from); - void ParseNamedSpecifiers(ArenaVector *specifiers, bool is_re_export = false); + void ParseNamedSpecifiers(ArenaVector *specifiers, bool is_export = false); + void ParseNamedExportSpecifiers(ArenaVector *specifiers, bool default_export); void ParseUserSources(std::vector user_parths); std::vector ParseImportDeclarations(ArenaVector &statements); void ParseDefaultSources(); @@ -189,7 +192,7 @@ private: ir::Expression *ParseCoverParenthesizedExpressionAndArrowParameterList() override; ir::Statement *ParseTryStatement() override; ir::DebuggerStatement *ParseDebuggerStatement() override; - void ParseReExport(lexer::SourcePosition start_loc); + void ParseExport(lexer::SourcePosition start_loc); ir::Statement *ParseImportDeclaration(StatementParsingFlags flags) override; ir::Statement *ParseExportDeclaration(StatementParsingFlags flags) override; ir::AnnotatedExpression *ParseVariableDeclaratorKey(VariableParsingFlags flags) override; diff --git a/ets2panda/test/parser/ets/selective_export/import_1-expected.txt b/ets2panda/test/parser/ets/selective_export/import_1-expected.txt new file mode 100644 index 000000000..4d08cca3d --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/import_1-expected.txt @@ -0,0 +1,389 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./", + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 8 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/selective_export/import_1.ets b/ets2panda/test/parser/ets/selective_export/import_1.ets new file mode 100644 index 000000000..cf5db051c --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/import_1.ets @@ -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. + */ + +import * from "./selective_export_1" + +function main() : void +{ + foo(); +} diff --git a/ets2panda/test/parser/ets/selective_export/import_2-expected.txt b/ets2panda/test/parser/ets/selective_export/import_2-expected.txt new file mode 100644 index 000000000..4d08cca3d --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/import_2-expected.txt @@ -0,0 +1,389 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./", + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 8 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/selective_export/import_2.ets b/ets2panda/test/parser/ets/selective_export/import_2.ets new file mode 100644 index 000000000..a99c8f6a4 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/import_2.ets @@ -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. + */ + +import * from "./selective_export_2" + +function main() : void +{ + foo(); +} diff --git a/ets2panda/test/parser/ets/selective_export/import_3-expected.txt b/ets2panda/test/parser/ets/selective_export/import_3-expected.txt new file mode 100644 index 000000000..4d08cca3d --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/import_3-expected.txt @@ -0,0 +1,389 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./", + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 8 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/selective_export/import_3.ets b/ets2panda/test/parser/ets/selective_export/import_3.ets new file mode 100644 index 000000000..30f03e957 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/import_3.ets @@ -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. + */ + +import * from "./selective_export_3" + +function main() : void +{ + foo(); +} diff --git a/ets2panda/test/parser/ets/selective_export/import_4-expected.txt b/ets2panda/test/parser/ets/selective_export/import_4-expected.txt new file mode 100644 index 000000000..271570dc9 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/import_4-expected.txt @@ -0,0 +1,477 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./", + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "sum", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 12 + } + } + }, + "init": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 23 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 25 + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 28 + }, + "end": { + "line": 20, + "column": 31 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 28 + }, + "end": { + "line": 20, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 33 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 34 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/selective_export/import_4.ets b/ets2panda/test/parser/ets/selective_export/import_4.ets new file mode 100644 index 000000000..0d2aee422 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/import_4.ets @@ -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. + */ + +import * from "./selective_export_4" + +function main() : void +{ + let sum: int = foo() + bar(); +} diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_1-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_1-expected.txt new file mode 100644 index 000000000..26044f2d6 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_1-expected.txt @@ -0,0 +1,288 @@ +{ + "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": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "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": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_1.ets b/ets2panda/test/parser/ets/selective_export/selective_export_1.ets new file mode 100644 index 000000000..37c93c395 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_1.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 foo(): int { + return 1; +} + +export { foo }; diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_2-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_2-expected.txt new file mode 100644 index 000000000..44ce8e929 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_2-expected.txt @@ -0,0 +1,288 @@ +{ + "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": 18, + "column": 10 + }, + "end": { + "line": 18, + "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": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_2.ets b/ets2panda/test/parser/ets/selective_export/selective_export_2.ets new file mode 100644 index 000000000..3a0c5b898 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_2.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. + */ + +export { foo }; + +function foo(): int { + return 1; +} diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_3-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_3-expected.txt new file mode 100644 index 000000000..fd12d7c7d --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_3-expected.txt @@ -0,0 +1,439 @@ +{ + "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": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "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 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "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": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 20 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 21 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 22, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 25, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_3.ets b/ets2panda/test/parser/ets/selective_export/selective_export_3.ets new file mode 100644 index 000000000..1a64e5b86 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_3.ets @@ -0,0 +1,24 @@ +/* + * 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(): int { + return bar(); +} + +function bar(): int { + return 1; +} + +export { foo }; diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_4-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_4-expected.txt new file mode 100644 index 000000000..3687ae1c0 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_4-expected.txt @@ -0,0 +1,423 @@ +{ + "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": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "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 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "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": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 20 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 21 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 22, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 25, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_4.ets b/ets2panda/test/parser/ets/selective_export/selective_export_4.ets new file mode 100644 index 000000000..75cc498e0 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_4.ets @@ -0,0 +1,24 @@ +/* + * 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(): int { + return 1; +} + +function bar(): int { + return 2; +} + +export { foo, bar }; diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_bad-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_bad-expected.txt new file mode 100644 index 000000000..dc09c9ecd --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_bad-expected.txt @@ -0,0 +1 @@ +SyntaxError: Cannot find name 'foo' to export. [selective_export_bad.ets:16:8] diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_bad.ets b/ets2panda/test/parser/ets/selective_export/selective_export_bad.ets new file mode 100644 index 000000000..0e6c6f7c8 --- /dev/null +++ b/ets2panda/test/parser/ets/selective_export/selective_export_bad.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. + */ + +export { foo }; + +function bar(): int { + return 1; +} -- Gitee From 76fd3d0432baed52cafce0f3a032b6928b8f419c Mon Sep 17 00:00:00 2001 From: ElevenDuan Date: Mon, 11 Dec 2023 14:59:07 +0800 Subject: [PATCH 02/35] Parser fails on params funciton with union and optional Signed-off-by: ElevenDuan --- ets2panda/parser/ETSparser.cpp | 37 +- ets2panda/parser/ETSparser.h | 3 +- .../ets/optional_union_paramter-expected.txt | 1497 +++++++++++++++++ .../parser/ets/optional_union_paramter.ets | 23 + 4 files changed, 1552 insertions(+), 8 deletions(-) create mode 100644 ets2panda/test/parser/ets/optional_union_paramter-expected.txt create mode 100644 ets2panda/test/parser/ets/optional_union_paramter.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index da82788af..0c1d9a780 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -16,6 +16,7 @@ #include "ETSparser.h" #include +#include "macros.h" #include "parser/parserFlags.h" #include "util/arktsconfig.h" #include "util/helpers.h" @@ -2241,20 +2242,42 @@ std::string ETSParser::PrimitiveTypeToName(ir::PrimitiveType type) UNREACHABLE(); } } +std::string ETSParser::GetNameForETSUnionType(const ir::TypeNode *type_annotation) const +{ + ASSERT(type_annotation->IsETSUnionType()); + std::string newstr; + for (size_t i = 0; i < type_annotation->AsETSUnionType()->Types().size(); i++) { + auto type = type_annotation->AsETSUnionType()->Types()[i]; + if (type->IsNullAssignable() || type->IsUndefinedAssignable()) { + continue; + } + std::string str = GetNameForTypeNode(type, false); + newstr += str; + if (i != type_annotation->AsETSUnionType()->Types().size() - 1) { + newstr += "|"; + } + } + if (type_annotation->IsNullAssignable()) { + newstr += "|null"; + } + if (type_annotation->IsUndefinedAssignable()) { + newstr += "|undefined"; + } + return newstr; +} -std::string ETSParser::GetNameForTypeNode(const ir::TypeNode *type_annotation) const +std::string ETSParser::GetNameForTypeNode(const ir::TypeNode *type_annotation, bool adjust) const { - if ((type_annotation->IsNullAssignable() || type_annotation->IsUndefinedAssignable()) && - type_annotation->IsETSUnionType()) { - type_annotation = type_annotation->AsETSUnionType()->Types().front(); + if (type_annotation->IsETSUnionType()) { + return GetNameForETSUnionType(type_annotation); } - const auto adjust_nullish = [type_annotation](std::string const &s) { + const auto adjust_nullish = [type_annotation, adjust](std::string const &s) { std::string newstr = s; - if (type_annotation->IsNullAssignable()) { + if (type_annotation->IsNullAssignable() && adjust) { newstr += "|null"; } - if (type_annotation->IsUndefinedAssignable()) { + if (type_annotation->IsUndefinedAssignable() && adjust) { newstr += "|undefined"; } return newstr; diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index d918a6953..5d18d6a3e 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -177,7 +177,8 @@ private: ir::MethodDefinition *CreateProxyConstructorDefinition(ir::MethodDefinition const *method); void AddProxyOverloadToMethodWithDefaultParams(ir::MethodDefinition *method, ir::Identifier *ident_node = nullptr); static std::string PrimitiveTypeToName(ir::PrimitiveType type); - std::string GetNameForTypeNode(const ir::TypeNode *type_annotation) const; + std::string GetNameForTypeNode(const ir::TypeNode *type_annotation, bool adjust = true) const; + std::string GetNameForETSUnionType(const ir::TypeNode *type_annotation) const; ir::TSInterfaceDeclaration *ParseInterfaceBody(ir::Identifier *name, bool is_static); bool IsArrowFunctionExpressionStart(); ir::ArrowFunctionExpression *ParseArrowFunctionExpression(); diff --git a/ets2panda/test/parser/ets/optional_union_paramter-expected.txt b/ets2panda/test/parser/ets/optional_union_paramter-expected.txt new file mode 100644 index 000000000..a48d7291b --- /dev/null +++ b/ets2panda/test/parser/ets/optional_union_paramter-expected.txt @@ -0,0 +1,1497 @@ +{ + "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": "split", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "split", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "separator", + "typeAnnotation": { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 17, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 39 + }, + "end": { + "line": 17, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 39 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 39 + }, + "end": { + "line": 17, + "column": 43 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 43 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "limit", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 52 + }, + "end": { + "line": 17, + "column": 58 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 52 + }, + "end": { + "line": 17, + "column": 59 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 52 + }, + "end": { + "line": 17, + "column": 59 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 44 + }, + "end": { + "line": 17, + "column": 59 + } + } + }, + "initializer": { + "type": "UndefinedLiteral", + "value": undefined, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 44 + }, + "end": { + "line": 17, + "column": 59 + } + } + } + ], + "returnType": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 61 + }, + "end": { + "line": 17, + "column": 67 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 61 + }, + "end": { + "line": 17, + "column": 68 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 61 + }, + "end": { + "line": 17, + "column": 68 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 70 + }, + "end": { + "line": 17, + "column": 71 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ArrayExpression", + "elements": [ + { + "type": "StringLiteral", + "value": "", + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 20 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 70 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "overloads": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "split_proxy", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "split_proxy", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "separator", + "typeAnnotation": { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "limit", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "$proxy_mask$", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + } + ], + "returnType": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "operator": "==", + "left": { + "type": "BinaryExpression", + "operator": "&", + "left": { + "type": "BinaryExpression", + "operator": ">>", + "left": { + "type": "Identifier", + "name": "$proxy_mask$", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "consequent": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "limit", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "right": { + "type": "UndefinedLiteral", + "value": undefined, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "property": { + "type": "Identifier", + "name": "split", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "separator", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + { + "type": "Identifier", + "name": "limit", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 3 + } + } + } + ], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 19, + "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": 20, + "column": 2 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 20, + "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": "main", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10 + }, + "end": { + "line": 21, + "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": 21, + "column": 10 + }, + "end": { + "line": 21, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 20 + }, + "end": { + "line": 21, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 20 + }, + "end": { + "line": 21, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 20 + }, + "end": { + "line": 21, + "column": 26 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 21, + "column": 25 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 23, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/optional_union_paramter.ets b/ets2panda/test/parser/ets/optional_union_paramter.ets new file mode 100644 index 000000000..4ee62946d --- /dev/null +++ b/ets2panda/test/parser/ets/optional_union_paramter.ets @@ -0,0 +1,23 @@ +/* + * 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 split (separator: String | Int, limit?: Number) :String[] { + return [""] + } +} +function main () : void { + +} -- Gitee From b40dc2eaf8664e84be4875add129ef341085c3b2 Mon Sep 17 00:00:00 2001 From: Amosov Alexey Date: Sun, 10 Dec 2023 12:47:19 +0300 Subject: [PATCH 03/35] fix IsContainedIn in AstVerifier, added internal check Signed-off-by: Amosov Alexey --- ets2panda/compiler/core/ASTVerifier.cpp | 104 ++- ets2panda/test/CMakeLists.txt | 2 +- .../test/unit/public/ast_verifier_test.cpp | 773 +++++++++++++++++- 3 files changed, 814 insertions(+), 65 deletions(-) diff --git a/ets2panda/compiler/core/ASTVerifier.cpp b/ets2panda/compiler/core/ASTVerifier.cpp index 3b7f52d49..11f6ba9f7 100644 --- a/ets2panda/compiler/core/ASTVerifier.cpp +++ b/ets2panda/compiler/core/ASTVerifier.cpp @@ -18,6 +18,8 @@ #include "checker/types/typeFlag.h" #include "ir/astNode.h" #include "ir/base/classDefinition.h" +#include "ir/base/classElement.h" +#include "ir/statement.h" #include "ir/base/classStaticBlock.h" #include "ir/base/methodDefinition.h" #include "ir/base/scriptFunction.h" @@ -27,6 +29,7 @@ #include "ir/ets/etsTypeReference.h" #include "ir/ets/etsTypeReferencePart.h" #include "ir/ets/etsImportDeclaration.h" +#include "ir/ets/etsScript.h" #include "ir/module/importSpecifier.h" #include "ir/module/importNamespaceSpecifier.h" #include "ir/module/importDefaultSpecifier.h" @@ -120,23 +123,39 @@ bool IsContainedIn(const T *child, const T *parent) std::unordered_set saved_nodes; while (child != nullptr && child != parent) { + saved_nodes.emplace(child); + child = child->Parent(); if (saved_nodes.find(child) != saved_nodes.end()) { return false; } - child = child->Parent(); - saved_nodes.emplace(child); } return child == parent; } - +bool IsVisibleInternalNode(const ir::AstNode *ast, const ir::AstNode *obj_type_decl_node) +{ + auto *current_top_statement = (static_cast(ast->GetTopStatement())); + auto *current_program = current_top_statement->Program(); + if (current_program == nullptr) { + return false; + } + util::StringView package_name_current = current_program->GetPackageName(); + auto *object_top_statement = (static_cast(obj_type_decl_node->GetTopStatement())); + auto *object_program = object_top_statement->Program(); + if (object_program == nullptr) { + return false; + } + util::StringView package_name_object = object_program->GetPackageName(); + return current_top_statement == object_top_statement || + (package_name_current == package_name_object && !package_name_current.Empty()); +} bool ValidateVariableAccess(const varbinder::LocalVariable *prop_var, const ir::MemberExpression *ast) { - const auto *decl = prop_var->Declaration(); - if (decl == nullptr) { + const auto *prop_var_decl = prop_var->Declaration(); + if (prop_var_decl == nullptr) { return false; } - const auto *node = decl->Node(); - if (node == nullptr) { + const auto *prop_var_decl_node = prop_var_decl->Node(); + if (prop_var_decl_node == nullptr) { return false; } auto *obj_type = ast->ObjType(); @@ -147,36 +166,43 @@ bool ValidateVariableAccess(const varbinder::LocalVariable *prop_var, const ir:: if (obj_type_decl_node == nullptr) { return false; } - const auto *parent_node = node->Parent(); - if (parent_node != nullptr && parent_node->IsClassDefinition() && obj_type_decl_node->IsClassDefinition()) { - if (IsContainedIn(ast, obj_type_decl_node->AsClassDefinition())) { + const auto *prop_var_decl_node_parent = prop_var_decl_node->Parent(); + if (prop_var_decl_node_parent != nullptr && prop_var_decl_node_parent->IsClassDefinition() && + obj_type_decl_node->IsClassDefinition()) { + // Check if the variable is used where it is declared + if (IsContainedIn(ast, prop_var_decl_node_parent->AsClassDefinition())) { return true; } - if (node->IsPrivate() && parent_node == obj_type_decl_node) { - return true; + if (prop_var_decl_node->IsPrivate()) { + return false; } - if (node->IsProtected()) { + if (prop_var_decl_node->IsProtected()) { + // Check if the variable is inherited and is used in class in which it is inherited auto ret = obj_type->IsPropertyInherited(prop_var); - return ret; + return ret && IsContainedIn(ast, obj_type_decl_node->AsClassDefinition()); + } + if (prop_var_decl_node->IsInternal()) { + return IsVisibleInternalNode(ast, obj_type_decl_node); } + return true; } return false; } bool ValidateMethodAccess(const ir::MemberExpression *member_expression, const ir::CallExpression *ast) { - auto *obj_type = member_expression->ObjType(); - if (obj_type == nullptr) { + auto *member_obj_type = member_expression->ObjType(); + if (member_obj_type == nullptr) { return false; } - - if (obj_type->HasObjectFlag(checker::ETSObjectFlags::RESOLVED_SUPER) && obj_type->SuperType() != nullptr && - obj_type->SuperType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE | - checker::ETSObjectFlags::GLOBAL_CLASS)) { + if (member_obj_type->HasObjectFlag(checker::ETSObjectFlags::RESOLVED_SUPER) && + member_obj_type->SuperType() != nullptr && + member_obj_type->SuperType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE | + checker::ETSObjectFlags::GLOBAL)) { return true; } - const auto *decl_node = obj_type->GetDeclNode(); - if (decl_node == nullptr) { + const auto *member_obj_type_decl_node = member_obj_type->GetDeclNode(); + if (member_obj_type_decl_node == nullptr) { return false; } auto *signature = ast->Signature(); @@ -187,18 +213,25 @@ bool ValidateMethodAccess(const ir::MemberExpression *member_expression, const i if (owner_sign == nullptr) { return false; } - auto *decl_node_sign = owner_sign->GetDeclNode(); - if (decl_node_sign != nullptr && decl_node_sign->IsClassDefinition() && decl_node->IsClassDefinition()) { - if (IsContainedIn(ast, decl_node->AsClassDefinition())) { + auto *owner_sign_decl_node = owner_sign->GetDeclNode(); + if (owner_sign_decl_node != nullptr && owner_sign_decl_node->IsClassDefinition() && + member_obj_type_decl_node->IsClassDefinition()) { + // Check if the method is used where it is declared + if (IsContainedIn(ast, owner_sign_decl_node->AsClassDefinition())) { return true; } - if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE) && decl_node_sign == decl_node) { - return true; + if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE)) { + return false; } if (signature->HasSignatureFlag(checker::SignatureFlags::PROTECTED)) { - auto ret = obj_type->IsSignatureInherited(signature); - return ret; + // Check if the method is inherited and is used in class in which it is inherited + auto ret = member_obj_type->IsSignatureInherited(signature); + return ret && IsContainedIn(ast, member_obj_type_decl_node->AsClassDefinition()); + } + if (signature->HasSignatureFlag(checker::SignatureFlags::INTERNAL)) { + return IsVisibleInternalNode(ast, member_obj_type_decl_node); } + return true; } return false; } @@ -689,8 +722,8 @@ bool ASTVerifier::VerifyModifierAccess(const ir::AstNode *ast) } if (ast->IsMemberExpression()) { const auto *prop_var = ast->AsMemberExpression()->PropVar(); - if (prop_var != nullptr && prop_var->HasFlag(varbinder::VariableFlags::PROPERTY) && - !ValidateVariableAccess(prop_var, ast->AsMemberExpression())) { + if (prop_var == nullptr || (prop_var->HasFlag(varbinder::VariableFlags::PROPERTY) && + !ValidateVariableAccess(prop_var, ast->AsMemberExpression()))) { AddError("PROPERTY_NOT_VISIBLE_HERE: " + ToStringHelper(ast), ast->Start()); return false; } @@ -698,11 +731,14 @@ bool ASTVerifier::VerifyModifierAccess(const ir::AstNode *ast) if (ast->IsCallExpression()) { const auto *call_expr = ast->AsCallExpression(); const auto *callee = call_expr->Callee(); - if (callee != nullptr && callee->IsMemberExpression()) { + if (callee == nullptr) { + return false; + } + if (callee->IsMemberExpression()) { const auto *callee_member = callee->AsMemberExpression(); const auto *prop_var_callee = callee_member->PropVar(); - if (prop_var_callee != nullptr && prop_var_callee->HasFlag(varbinder::VariableFlags::METHOD) && - !ValidateMethodAccess(callee_member, ast->AsCallExpression())) { + if (prop_var_callee == nullptr || (prop_var_callee->HasFlag(varbinder::VariableFlags::METHOD) && + !ValidateMethodAccess(callee_member, ast->AsCallExpression()))) { AddError("PROPERTY_NOT_VISIBLE_HERE: " + ToStringHelper(callee), callee->Start()); return false; } diff --git a/ets2panda/test/CMakeLists.txt b/ets2panda/test/CMakeLists.txt index 334456fb3..470de382d 100644 --- a/ets2panda/test/CMakeLists.txt +++ b/ets2panda/test/CMakeLists.txt @@ -112,7 +112,7 @@ if(PANDA_WITH_ETS) SOURCES unit/public/ast_verifier_test.cpp LIBRARIES - es2panda-lib + es2panda-public es2panda-lib INCLUDE_DIRS ${ES2PANDA_PATH} ${ES2PANDA_BINARY_ROOT} diff --git a/ets2panda/test/unit/public/ast_verifier_test.cpp b/ets2panda/test/unit/public/ast_verifier_test.cpp index 77acdc512..83d414bb0 100644 --- a/ets2panda/test/unit/public/ast_verifier_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_test.cpp @@ -22,6 +22,7 @@ #include "macros.h" #include "parser/ETSparser.h" #include "varbinder/ETSBinder.h" +#include "public/es2panda_lib.h" #include #include @@ -42,41 +43,44 @@ }()) // NOLINTEND(cppcoreguidelines-macro-usage) -namespace panda::es2panda { - class ASTVerifierTest : public testing::Test { public: ASTVerifierTest() { - allocator_ = std::make_unique(SpaceType::SPACE_TYPE_COMPILER); + impl_ = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + char const *argv[] = {"test"}; + cfg_ = impl_->CreateConfig(1, argv); + allocator_ = new panda::ArenaAllocator(panda::SpaceType::SPACE_TYPE_COMPILER); } - ~ASTVerifierTest() override = default; - - static void SetUpTestCase() + ~ASTVerifierTest() override { - constexpr auto COMPILER_SIZE = operator""_MB(256ULL); - mem::MemConfig::Initialize(0, 0, COMPILER_SIZE, 0, 0, 0); - PoolManager::Initialize(); + delete allocator_; + impl_->DestroyConfig(cfg_); } - ArenaAllocator *Allocator() + panda::ArenaAllocator *Allocator() { - return allocator_.get(); + return allocator_; } NO_COPY_SEMANTIC(ASTVerifierTest); NO_MOVE_SEMANTIC(ASTVerifierTest); -private: - std::unique_ptr allocator_; +protected: + // NOLINTBEGIN(misc-non-private-member-variables-in-classes) + es2panda_Impl const *impl_; + es2panda_Config *cfg_; + panda::ArenaAllocator *allocator_; + // NOLINTEND(misc-non-private-member-variables-in-classes) }; TEST_F(ASTVerifierTest, NullParent) { - compiler::ASTVerifier verifier {Allocator()}; - ir::StringLiteral empty_node; + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + panda::es2panda::ir::StringLiteral empty_node; - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("HasParent"); bool has_parent = verifier.Verify(&empty_node, checks); const auto &errors = verifier.GetErrors(); @@ -90,10 +94,10 @@ TEST_F(ASTVerifierTest, NullParent) TEST_F(ASTVerifierTest, NullType) { - compiler::ASTVerifier verifier {Allocator()}; - ir::StringLiteral empty_node; + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + panda::es2panda::ir::StringLiteral empty_node; - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("HasType"); bool has_type = verifier.Verify(&empty_node, checks); const auto &errors = verifier.GetErrors(); @@ -107,10 +111,10 @@ TEST_F(ASTVerifierTest, NullType) TEST_F(ASTVerifierTest, WithoutScope) { - compiler::ASTVerifier verifier {Allocator()}; - ir::StringLiteral empty_node; + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + panda::es2panda::ir::StringLiteral empty_node; - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("HasScope"); bool has_scope = verifier.Verify(&empty_node, checks); const auto &errors = verifier.GetErrors(); @@ -135,7 +139,7 @@ TEST_F(ASTVerifierTest, ScopeTest) local.SetScope(&scope); - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("HasScope"); bool is_ok = verifier.Verify(&ident, checks); @@ -159,7 +163,7 @@ TEST_F(ASTVerifierTest, ScopeNodeTest) local.SetScope(&scope); - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("VerifyScopeNode"); bool is_ok = verifier.Verify(&ident, checks); @@ -181,7 +185,7 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionCorrect1) left.SetTsType(etschecker.GlobalIntType()); right.SetTsType(etschecker.GlobalIntType()); - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("CheckArithmeticExpression"); bool is_correct = verifier.Verify(arithmetic_expression.AsBinaryExpression(), checks); ASSERT_EQ(is_correct, true); @@ -210,7 +214,7 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionCorrect2) left2.SetTsType(etschecker.GlobalIntType()); right2.SetTsType(etschecker.GlobalIntType()); - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("CheckArithmeticExpression"); bool is_correct = verifier.Verify(arithmetic_expression.AsBinaryExpression(), checks); ASSERT_EQ(is_correct, true); @@ -223,7 +227,7 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionNegative1) auto program = panda::es2panda::parser::Program::NewProgram(Allocator()); auto parser = panda::es2panda::parser::ETSParser(&program, panda::es2panda::CompilerOptions {}); - const util::StringView left_param("1"); + const panda::es2panda::util::StringView left_param("1"); constexpr uint32_t RIGHT_PARAM = 1; auto left = panda::es2panda::ir::StringLiteral(left_param); auto right = panda::es2panda::ir::NumberLiteral(panda::es2panda::lexer::Number {RIGHT_PARAM}); @@ -233,7 +237,7 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionNegative1) left.SetTsType(etschecker.GlobalETSStringLiteralType()); right.SetTsType(etschecker.GlobalIntType()); - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("CheckArithmeticExpression"); bool is_correct = verifier.Verify(arithmetic_expression.AsBinaryExpression(), checks); @@ -254,11 +258,720 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionNegative2) left.SetTsType(etschecker.GlobalETSStringLiteralType()); right.SetTsType(etschecker.GlobalIntType()); - auto checks = compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; checks.insert("CheckArithmeticExpression"); bool is_correct = verifier.Verify(arithmetic_expression.AsBinaryExpression(), checks); ASSERT_EQ(is_correct, false); } -} // namespace panda::es2panda +constexpr char const *PRIVATE_PROTECTED_PUBLIC_TEST = + R"XXX( + class Base { + public a: int = 1; + protected b: int = 2; + private c: int = 3; + public publicMethod() { + this.a = 4; + this.protectedMethod(); + this.privateMethod(); + } + protected protectedMethod() { + this.b = 5; + this.publicMethod(); + this.privateMethod(); + } + private privateMethod() { + this.c = 6; + this.publicMethod(); + this.protectedMethod(); + } + } + class Derived extends Base { + foo () { + this.a = 7; + this.b = 8; + this.publicMethod(); + this.protectedMethod(); + } + } + function main(): void { + let base: Base = new Base(); + let a = base.a; + base.publicMethod(); + let derived1: Derived = new Derived(); + let b = derived1.a; + derived1.publicMethod(); + derived1.foo(); + let derived2: Base = new Derived(); + let c = derived2.a; + derived2.publicMethod(); + } + )XXX"; + +TEST_F(ASTVerifierTest, PrivateProtectedPublicAccessTestCorrect) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, PRIVATE_PROTECTED_PUBLIC_TEST, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + + ASSERT_EQ(is_correct, true); + ASSERT_EQ(errors.size(), 0); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, PrivateAccessTestNegative1) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + } + class Derived extends Base { + public b: int = this.a; + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[1] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[0] + ->AsClassProperty() + ->AddModifier(panda::es2panda::ir::ModifierFlags::PRIVATE); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR MUST BE UNREACHABLE.ID a"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, PrivateAccessTestNegative2) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + } + function main(): void { + let base: Base = new Base(); + let a = base.a; + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[1] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[0] + ->AsClassProperty() + ->AddModifier(panda::es2panda::ir::ModifierFlags::PRIVATE); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID base.ID a"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, PrivateAccessTestNegative3) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + } + class Derived extends Base {} + function main(): void { + let derived: Derived = new Derived(); + let a = derived.a; + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[1] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[0] + ->AsClassProperty() + ->AddModifier(panda::es2panda::ir::ModifierFlags::PRIVATE); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID derived.ID a"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, PrivateAccessTestNegative4) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + } + class Derived extends Base {} + function main(): void { + let derived: Base = new Derived(); + let a = derived.a; + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[1] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[0] + ->AsClassProperty() + ->AddModifier(panda::es2panda::ir::ModifierFlags::PRIVATE); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID derived.ID a"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, PrivateAccessTestNegative5) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + public privateMethod() { + this.a = 2; + } + } + function main(): void { + let base: Base = new Base(); + base.privateMethod(); + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[0] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[1] + ->AsClassElement() + ->Value() + ->AsFunctionExpression() + ->Function() + ->AsScriptFunction() + ->Body() + ->AsBlockStatement() + ->Statements()[1] + ->AsExpressionStatement() + ->GetExpression() + ->AsCallExpression() + ->Signature() + ->AddSignatureFlag(panda::es2panda::checker::SignatureFlags::PRIVATE); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID base.ID privateMethod"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, PrivateAccessTestNegative6) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + public privateMethod() { + this.a = 2; + } + } + class Derived extends Base {} + function main(): void { + let derived: Derived = new Derived(); + derived.privateMethod(); + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[0] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[1] + ->AsClassElement() + ->Value() + ->AsFunctionExpression() + ->Function() + ->AsScriptFunction() + ->Body() + ->AsBlockStatement() + ->Statements()[1] + ->AsExpressionStatement() + ->GetExpression() + ->AsCallExpression() + ->Signature() + ->AddSignatureFlag(panda::es2panda::checker::SignatureFlags::PRIVATE); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID derived.ID privateMethod"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, PrivateAccessTestNegative7) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + public privateMethod() { + this.a = 2; + } + } + class Derived extends Base {} + function main(): void { + let derived: Base = new Derived(); + derived.privateMethod(); + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[0] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[1] + ->AsClassElement() + ->Value() + ->AsFunctionExpression() + ->Function() + ->AsScriptFunction() + ->Body() + ->AsBlockStatement() + ->Statements()[1] + ->AsExpressionStatement() + ->GetExpression() + ->AsCallExpression() + ->Signature() + ->AddSignatureFlag(panda::es2panda::checker::SignatureFlags::PRIVATE); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID derived.ID privateMethod"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, ProtectedAccessTestCorrect) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class A { + public a: int = 1; + } + class B extends A { + public b: int = this.a; + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[1] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[0] + ->AsClassProperty() + ->AddModifier(panda::es2panda::ir::ModifierFlags::PROTECTED); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + + ASSERT_EQ(is_correct, true); + ASSERT_EQ(errors.size(), 0); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, ProtectedAccessTestNegative1) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + } + function main(): void { + let base: Base = new Base(); + let a = base.a; + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[1] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[0] + ->AsClassProperty() + ->AddModifier(panda::es2panda::ir::ModifierFlags::PROTECTED); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID base.ID a"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, ProtectedAccessTestNegative2) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + } + class Derived extends Base {} + function main(): void { + let derived: Derived = new Derived(); + let a = derived.a; + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[1] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[0] + ->AsClassProperty() + ->AddModifier(panda::es2panda::ir::ModifierFlags::PROTECTED); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID derived.ID a"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, ProtectedAccessTestNegative3) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + } + class Derived extends Base {} + function main(): void { + let derived: Base = new Derived(); + let a = derived.a; + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[1] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[0] + ->AsClassProperty() + ->AddModifier(panda::es2panda::ir::ModifierFlags::PROTECTED); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID derived.ID a"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, ProtectedAccessTestNegative4) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + public protectedMethod() { + this.a = 2; + } + } + function main(): void { + let base: Base = new Base(); + base.protectedMethod(); + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[0] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[1] + ->AsClassElement() + ->Value() + ->AsFunctionExpression() + ->Function() + ->AsScriptFunction() + ->Body() + ->AsBlockStatement() + ->Statements()[1] + ->AsExpressionStatement() + ->GetExpression() + ->AsCallExpression() + ->Signature() + ->AddSignatureFlag(panda::es2panda::checker::SignatureFlags::PROTECTED); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID base.ID protectedMethod"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, ProtectedAccessTestNegative5) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + public protectedMethod() { + this.a = 2; + } + } + class Derived extends Base {} + function main(): void { + let derived: Derived = new Derived(); + derived.protectedMethod(); + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[0] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[1] + ->AsClassElement() + ->Value() + ->AsFunctionExpression() + ->Function() + ->AsScriptFunction() + ->Body() + ->AsBlockStatement() + ->Statements()[1] + ->AsExpressionStatement() + ->GetExpression() + ->AsCallExpression() + ->Signature() + ->AddSignatureFlag(panda::es2panda::checker::SignatureFlags::PROTECTED); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID derived.ID protectedMethod"); + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, ProtectedAccessTestNegative6) +{ + panda::es2panda::compiler::ASTVerifier verifier {Allocator()}; + + char const *text = R"XXX( + class Base { + public a: int = 1; + public protectedMethod() { + this.a = 2; + } + } + class Derived extends Base {} + function main(): void { + let derived: Base = new Derived(); + derived.protectedMethod(); + } + )XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto *ast = reinterpret_cast(impl_->ProgramAst(impl_->ContextProgram(ctx))); + + ast->AsBlockStatement() + ->Statements()[0] + ->AsClassDeclaration() + ->Definition() + ->AsClassDefinition() + ->Body()[1] + ->AsClassElement() + ->Value() + ->AsFunctionExpression() + ->Function() + ->AsScriptFunction() + ->Body() + ->AsBlockStatement() + ->Statements()[1] + ->AsExpressionStatement() + ->GetExpression() + ->AsCallExpression() + ->Signature() + ->AddSignatureFlag(panda::es2panda::checker::SignatureFlags::PROTECTED); + + auto checks = panda::es2panda::compiler::ASTVerifier::CheckSet {Allocator()->Adapter()}; + checks.insert("VerifyModifierAccessRecursive"); + bool is_correct = verifier.Verify(ast, checks); + const auto &errors = verifier.GetErrors(); + const auto [name, error] = errors[0]; + + ASSERT_EQ(is_correct, false); + ASSERT_EQ(errors.size(), 1); + ASSERT_EQ(error.message, "PROPERTY_NOT_VISIBLE_HERE: MEMBER_EXPR ID derived.ID protectedMethod"); + impl_->DestroyContext(ctx); +} -- Gitee From 839f65824b4d0240447a6c6c0dc5d8f6d1057093 Mon Sep 17 00:00:00 2001 From: ElevenDuan Date: Sat, 9 Dec 2023 10:37:25 +0800 Subject: [PATCH 04/35] type inference test case change Signed-off-by: ElevenDuan --- ets2panda/checker/ETSAnalyzer.cpp | 26 +- .../expressions/arrowFunctionExpression.cpp | 5 +- ...bda_cast_infer_type_narrowing-expected.txt | 208 +++++- .../lambda_cast_infer_type_narrowing.ets | 1 + .../lambda_cast_infer_type_void-expected.txt | 519 +++++++++++++++ .../lambda_cast_infer_type_void.ets | 1 + ...mbda_cast_infer_type_widening-expected.txt | 208 +++++- .../lambda_cast_infer_type_widening.ets | 1 + .../lambda_cast_type_has_pramas-expected.txt | 200 +++++- .../lambda_cast_type_has_pramas.ets | 1 + .../lambda_infer_type-expected.txt} | 158 +++-- .../lambda_infer_type/lambda_infer_type.ets | 1 + ...a_infer_type_arrow_expression-expected.txt | 142 +++- .../lambda_infer_type_arrow_expression.ets | 1 + ...type_arrow_expression_literal-expected.txt | 132 +++- ...da_infer_type_arrow_expression_literal.ets | 1 + .../lambda_infer_type_has_return-expected.txt | 146 +++- .../lambda_infer_type_has_return.ets | 3 +- .../lambda_infer_type_param1-expected.txt | 0 .../lambda_infer_type_param1.ets | 0 .../lambda_infer_type_param2-expected.txt | 0 .../lambda_infer_type_param2.ets | 0 ...lambda_infer_type_retrun_enum-expected.txt | 124 +++- .../lambda_infer_type_retrun_enum.ets | 1 + ...ambda_infer_type_return_array-expected.txt | 137 +++- .../lambda_infer_type_return_array.ets | 1 + ...mbda_infer_type_return_lambda-expected.txt | 146 +++- .../lambda_infer_type_return_lambda.ets | 3 +- ...bda_infer_type_return_lambda1-expected.txt | 138 +++- .../lambda_infer_type_return_lambda1.ets | 1 + ...type_return_lambda_expression-expected.txt | 226 ++++++- ...da_infer_type_return_lambda_expression.ets | 3 +- ...bda_infer_type_return_literal-expected.txt | 124 +++- .../lambda_infer_type_return_literal.ets | 1 + ...ambda_infer_type_return_union-expected.txt | 180 ++++- .../lambda_infer_type_return_union.ets | 1 + .../lambda_infer_type_scope-expected.txt | 623 ++++++++++++++++++ .../lambda_infer_type_scope.ets | 20 + .../lambda_infer_type-expected.txt | 337 ---------- 39 files changed, 3282 insertions(+), 538 deletions(-) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt (77%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets (94%) create mode 100644 ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_cast_infer_type_void.ets (95%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt (77%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets (94%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt (71%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_cast_type_has_pramas.ets (94%) rename ets2panda/test/{parser/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt => compiler/ets/lambda_infer_type/lambda_infer_type-expected.txt} (74%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type.ets (95%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt (75%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_arrow_expression.ets (95%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt (74%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal.ets (94%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt (80%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_has_return.ets (92%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_param1-expected.txt (100%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_param1.ets (100%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt (100%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_param2.ets (100%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_retrun_enum-expected.txt (80%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_retrun_enum.ets (95%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt (76%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_array.ets (94%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt (76%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_lambda.ets (93%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt (69%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_lambda1.ets (94%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt (61%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression.ets (91%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt (69%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_literal.ets (95%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt (72%) rename ets2panda/test/{parser => compiler}/ets/lambda_infer_type/lambda_infer_type_return_union.ets (94%) create mode 100644 ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope-expected.txt create mode 100644 ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope.ets delete mode 100644 ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type-expected.txt diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index bf673fc5f..c7a578595 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -779,31 +779,7 @@ checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const checker->AddStatus(checker::CheckerStatus::IN_LAMBDA); checker->Context().SetContainingSignature(func_type->CallSignatures()[0]); - auto *body_type = expr->Function()->Body()->Check(checker); - if (expr->Function()->Body()->IsExpression()) { - /* - when function body is ArrowFunctionExpression, need infer type for this function body - example code: - ``` - let x = () => () => {} - ``` - */ - if (expr->Function()->ReturnTypeAnnotation() == nullptr) { - if (expr->Function()->Body()->IsArrowFunctionExpression()) { - auto *arrow_func = expr->Function()->Body()->AsArrowFunctionExpression(); - auto *type_annotation = arrow_func->CreateTypeAnnotation(checker); - func_type->CallSignatures()[0]->SetReturnType(type_annotation->GetType(checker)); - } else { - func_type->CallSignatures()[0]->SetReturnType(body_type); - } - } - - checker::AssignmentContext( - checker->Relation(), expr->Function()->Body()->AsExpression(), body_type, - func_type->CallSignatures()[0]->ReturnType(), expr->Function()->Start(), - {"Return statements return type is not compatible with the containing functions return type"}, - checker::TypeRelationFlag::DIRECT_RETURN); - } + expr->Function()->Body()->Check(checker); checker->Context().SetContainingSignature(nullptr); checker->CheckCapturedVariables(); diff --git a/ets2panda/ir/expressions/arrowFunctionExpression.cpp b/ets2panda/ir/expressions/arrowFunctionExpression.cpp index 249aa8377..83a1873db 100644 --- a/ets2panda/ir/expressions/arrowFunctionExpression.cpp +++ b/ets2panda/ir/expressions/arrowFunctionExpression.cpp @@ -133,11 +133,10 @@ ir::TypeNode *ArrowFunctionExpression::CreateTypeAnnotation(checker::ETSChecker return_node = Function()->ReturnTypeAnnotation(); } - auto *param_scope = checker->Scope()->AsFunctionScope()->ParamScope(); - auto signature = ir::FunctionSignature(nullptr, std::move(Function()->Params()), return_node); + auto orig_params = Function()->Params(); + auto signature = ir::FunctionSignature(nullptr, std::move(orig_params), return_node); auto *func_type = checker->Allocator()->New(std::move(signature), ir::ScriptFunctionFlags::NONE); - func_type->SetScope(param_scope); return_node->SetParent(func_type); return func_type; } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt similarity index 77% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt index 5c23000dd..4006b73d2 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt @@ -512,7 +512,7 @@ }, "end": { "line": 23, - "column": 6 + "column": 12 } } }, @@ -523,7 +523,7 @@ }, "end": { "line": 23, - "column": 6 + "column": 12 } } }, @@ -534,7 +534,7 @@ }, "end": { "line": 23, - "column": 6 + "column": 12 } } }, @@ -572,6 +572,190 @@ "column": 39 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 29 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 29 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 29 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 24 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 21 + } + } + }, + "init": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 39 + }, + "end": { + "line": 23, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 40 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 40 + } + } } ], "loc": { @@ -580,7 +764,7 @@ "column": 13 }, "end": { - "line": 23, + "line": 24, "column": 6 } } @@ -591,7 +775,7 @@ "column": 10 }, "end": { - "line": 23, + "line": 24, "column": 6 } } @@ -602,7 +786,7 @@ "column": 10 }, "end": { - "line": 23, + "line": 24, "column": 6 } } @@ -615,7 +799,7 @@ "column": 5 }, "end": { - "line": 23, + "line": 24, "column": 6 } } @@ -704,11 +888,11 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 25, "column": 2 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -720,7 +904,7 @@ "column": 19 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -731,7 +915,7 @@ "column": 1 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -881,7 +1065,7 @@ "column": 1 }, "end": { - "line": 25, + "line": 26, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets similarity index 94% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets index 3deadfbc3..d30c88298 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets @@ -20,5 +20,6 @@ class A { class B extends A { main () { let a = (a : A) => { return a} as (a : B) => B + let expected : (a : B) => B = a } } diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt new file mode 100644 index 000000000..66623064b --- /dev/null +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt @@ -0,0 +1,519 @@ +{ + "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": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 10 + } + } + }, + "init": { + "type": "TSAsExpression", + "expression": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 25 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 21 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 32 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 17 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 33 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 34 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 34 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 19, + "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": 20, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_void.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void.ets similarity index 95% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_void.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void.ets index cfdec9acf..40ba385a3 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_void.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void.ets @@ -15,4 +15,5 @@ function main () { let x = () => {} as ()=> void + let expected : () => void = x } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt similarity index 77% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt index 46895a799..545b1715c 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt @@ -512,7 +512,7 @@ }, "end": { "line": 23, - "column": 6 + "column": 12 } } }, @@ -523,7 +523,7 @@ }, "end": { "line": 23, - "column": 6 + "column": 12 } } }, @@ -534,7 +534,7 @@ }, "end": { "line": 23, - "column": 6 + "column": 12 } } }, @@ -572,6 +572,190 @@ "column": 39 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 29 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 29 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 29 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 31 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 24 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 21 + } + } + }, + "init": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 39 + }, + "end": { + "line": 23, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 23, + "column": 40 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 40 + } + } } ], "loc": { @@ -580,7 +764,7 @@ "column": 13 }, "end": { - "line": 23, + "line": 24, "column": 6 } } @@ -591,7 +775,7 @@ "column": 10 }, "end": { - "line": 23, + "line": 24, "column": 6 } } @@ -602,7 +786,7 @@ "column": 10 }, "end": { - "line": 23, + "line": 24, "column": 6 } } @@ -615,7 +799,7 @@ "column": 5 }, "end": { - "line": 23, + "line": 24, "column": 6 } } @@ -704,11 +888,11 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 25, "column": 2 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -720,7 +904,7 @@ "column": 19 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -731,7 +915,7 @@ "column": 1 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -881,7 +1065,7 @@ "column": 1 }, "end": { - "line": 25, + "line": 26, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets similarity index 94% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets index 3c904151b..cb90f223b 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening.ets @@ -20,5 +20,6 @@ class A { class B extends A { main () { let a = (a : B) => { return a} as (a : A) => A + let expected : (a : A) => A = a } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt similarity index 71% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt index f5d882086..0d17b84dd 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt @@ -428,7 +428,7 @@ }, "end": { "line": 18, - "column": 2 + "column": 8 } } }, @@ -439,7 +439,7 @@ }, "end": { "line": 18, - "column": 2 + "column": 8 } } }, @@ -450,7 +450,7 @@ }, "end": { "line": 18, - "column": 2 + "column": 8 } } }, @@ -488,6 +488,190 @@ "column": 38 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 29 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 29 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 33 + }, + "end": { + "line": 18, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 33 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 33 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 17 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 40 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 40 + } + } } ], "loc": { @@ -496,7 +680,7 @@ "column": 18 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -507,7 +691,7 @@ "column": 15 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -518,7 +702,7 @@ "column": 15 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -531,7 +715,7 @@ "column": 1 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -566,7 +750,7 @@ "column": 1 }, "end": { - "line": 19, + "line": 20, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_type_has_pramas.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas.ets similarity index 94% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_type_has_pramas.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas.ets index 54b4f3e7e..565472361 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_type_has_pramas.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas.ets @@ -15,4 +15,5 @@ function main () { let x = (a : Int) => { return 1 } as (a : Int) => Int + let expected : (a : Int) => Int = x } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type-expected.txt similarity index 74% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type-expected.txt index 1ca55a254..1fa2395cb 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type-expected.txt @@ -185,34 +185,21 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "ArrowFunctionExpression", - "function": { - "type": "ScriptFunction", - "id": null, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 17, - "column": 19 - }, - "end": { - "line": 17, - "column": 21 - } - } - }, + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], "loc": { "start": { "line": 17, - "column": 13 + "column": 19 }, "end": { "line": 17, @@ -231,6 +218,49 @@ } } }, + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 21 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", "typeAnnotation": { "type": "ETSFunctionType", "params": [], @@ -244,67 +274,83 @@ "decorators": [], "loc": { "start": { - "line": 17, - "column": 30 + "line": 18, + "column": 26 }, "end": { - "line": 17, - "column": 34 + "line": 18, + "column": 30 } } }, "loc": { "start": { - "line": 17, - "column": 30 + "line": 18, + "column": 26 }, "end": { "line": 18, - "column": 2 + "column": 32 } } }, "loc": { "start": { - "line": 17, - "column": 30 + "line": 18, + "column": 26 }, "end": { "line": 18, - "column": 2 + "column": 32 } } }, "loc": { "start": { - "line": 17, - "column": 25 + "line": 18, + "column": 20 }, "end": { "line": 18, - "column": 2 + "column": 32 } } }, + "decorators": [], "loc": { "start": { - "line": 17, - "column": 13 + "line": 18, + "column": 9 }, "end": { - "line": 17, - "column": 21 + "line": 18, + "column": 17 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 33 + }, + "end": { + "line": 18, + "column": 34 } } }, "loc": { "start": { - "line": 17, + "line": 18, "column": 9 }, "end": { - "line": 17, - "column": 21 + "line": 18, + "column": 34 } } } @@ -312,12 +358,12 @@ "kind": "let", "loc": { "start": { - "line": 17, + "line": 18, "column": 5 }, "end": { - "line": 17, - "column": 21 + "line": 18, + "column": 34 } } } @@ -325,10 +371,10 @@ "loc": { "start": { "line": 16, - "column": 18 + "column": 17 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -336,10 +382,10 @@ "loc": { "start": { "line": 16, - "column": 15 + "column": 14 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -347,10 +393,10 @@ "loc": { "start": { "line": 16, - "column": 15 + "column": 14 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -363,7 +409,7 @@ "column": 1 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -398,7 +444,7 @@ "column": 1 }, "end": { - "line": 19, + "line": 20, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type.ets similarity index 95% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type.ets index 2b174aac2..c3e1e2354 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type.ets @@ -15,4 +15,5 @@ function main() { let x = () => {} + let expected : () => void = x } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt similarity index 75% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt index 5805f98ba..1037cfbeb 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt @@ -155,7 +155,7 @@ }, "end": { "line": 19, - "column": 6 + "column": 12 } } }, @@ -189,7 +189,7 @@ }, "end": { "line": 19, - "column": 6 + "column": 12 } } }, @@ -200,7 +200,7 @@ }, "end": { "line": 19, - "column": 6 + "column": 12 } } }, @@ -211,7 +211,7 @@ }, "end": { "line": 19, - "column": 6 + "column": 12 } } } @@ -224,7 +224,121 @@ }, "end": { "line": 19, - "column": 6 + "column": 12 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 24 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 34 + }, + "end": { + "line": 19, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 35 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 35 } } } @@ -235,7 +349,7 @@ "column": 14 }, "end": { - "line": 19, + "line": 20, "column": 6 } } @@ -246,7 +360,7 @@ "column": 11 }, "end": { - "line": 19, + "line": 20, "column": 6 } } @@ -257,7 +371,7 @@ "column": 11 }, "end": { - "line": 19, + "line": 20, "column": 6 } } @@ -270,7 +384,7 @@ "column": 5 }, "end": { - "line": 19, + "line": 20, "column": 6 } } @@ -359,11 +473,11 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 21, "column": 2 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -375,7 +489,7 @@ "column": 9 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -386,7 +500,7 @@ "column": 1 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -536,7 +650,7 @@ "column": 1 }, "end": { - "line": 21, + "line": 22, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression.ets similarity index 95% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression.ets index f7f3f8866..8b0adf283 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression.ets @@ -16,5 +16,6 @@ class A { main1 () { let x = () => new A() + let expected : () => A = x } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt similarity index 74% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt index 707d202c3..654f361bb 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt @@ -186,6 +186,120 @@ "column": 24 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 24 + }, + "end": { + "line": 19, + "column": 35 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 36 + }, + "end": { + "line": 19, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 37 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 37 + } + } } ], "loc": { @@ -194,7 +308,7 @@ "column": 14 }, "end": { - "line": 19, + "line": 20, "column": 6 } } @@ -205,7 +319,7 @@ "column": 11 }, "end": { - "line": 19, + "line": 20, "column": 6 } } @@ -216,7 +330,7 @@ "column": 11 }, "end": { - "line": 19, + "line": 20, "column": 6 } } @@ -229,7 +343,7 @@ "column": 5 }, "end": { - "line": 19, + "line": 20, "column": 6 } } @@ -318,11 +432,11 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 21, "column": 2 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -334,7 +448,7 @@ "column": 9 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -345,7 +459,7 @@ "column": 1 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -495,7 +609,7 @@ "column": 1 }, "end": { - "line": 21, + "line": 22, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal.ets similarity index 94% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal.ets index f25216490..d63502690 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal.ets @@ -16,5 +16,6 @@ class A { main1 () { let x = () => 1 + let expected : () => Int = x } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt similarity index 80% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt index b307e9a56..13636ecff 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt @@ -82,11 +82,11 @@ "loc": { "start": { "line": 18, - "column": 9 + "column": 13 }, "end": { "line": 18, - "column": 10 + "column": 14 } } }, @@ -274,7 +274,7 @@ "loc": { "start": { "line": 18, - "column": 17 + "column": 21 }, "end": { "line": 21, @@ -285,7 +285,7 @@ "loc": { "start": { "line": 18, - "column": 13 + "column": 17 }, "end": { "line": 21, @@ -296,7 +296,7 @@ "loc": { "start": { "line": 18, - "column": 13 + "column": 17 }, "end": { "line": 21, @@ -307,7 +307,7 @@ "loc": { "start": { "line": 18, - "column": 9 + "column": 13 }, "end": { "line": 21, @@ -320,13 +320,127 @@ "loc": { "start": { "line": 18, - "column": 5 + "column": 9 }, "end": { "line": 21, "column": 10 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 30 + }, + "end": { + "line": 22, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 30 + }, + "end": { + "line": 22, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 30 + }, + "end": { + "line": 22, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 24 + }, + "end": { + "line": 22, + "column": 33 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 13 + }, + "end": { + "line": 22, + "column": 21 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 34 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 13 + }, + "end": { + "line": 22, + "column": 35 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 35 + } + } } ], "loc": { @@ -335,7 +449,7 @@ "column": 13 }, "end": { - "line": 22, + "line": 23, "column": 6 } } @@ -346,7 +460,7 @@ "column": 10 }, "end": { - "line": 22, + "line": 23, "column": 6 } } @@ -357,7 +471,7 @@ "column": 10 }, "end": { - "line": 22, + "line": 23, "column": 6 } } @@ -370,7 +484,7 @@ "column": 5 }, "end": { - "line": 22, + "line": 23, "column": 6 } } @@ -459,11 +573,11 @@ "decorators": [], "loc": { "start": { - "line": 23, + "line": 24, "column": 2 }, "end": { - "line": 23, + "line": 24, "column": 2 } } @@ -475,7 +589,7 @@ "column": 9 }, "end": { - "line": 23, + "line": 24, "column": 2 } } @@ -486,7 +600,7 @@ "column": 1 }, "end": { - "line": 23, + "line": 24, "column": 2 } } @@ -636,7 +750,7 @@ "column": 1 }, "end": { - "line": 24, + "line": 25, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_has_return.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return.ets similarity index 92% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_has_return.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return.ets index 357e2c31b..4cb018cc8 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_has_return.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return.ets @@ -15,9 +15,10 @@ class A { main () { - let x = ()=>{ + let x = ()=>{ let a : A = new A() return a } + let expected : () => A = x } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_param1-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param1-expected.txt similarity index 100% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_param1-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param1-expected.txt diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_param1.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param1.ets similarity index 100% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_param1.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param1.ets diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt similarity index 100% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_param2.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2.ets similarity index 100% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_param2.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2.ets diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_retrun_enum-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_retrun_enum-expected.txt similarity index 80% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_retrun_enum-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_retrun_enum-expected.txt index 001c89166..ae8e7882a 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_retrun_enum-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_retrun_enum-expected.txt @@ -526,6 +526,120 @@ "column": 6 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Color", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 26 + }, + "end": { + "line": 22, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 26 + }, + "end": { + "line": 22, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 26 + }, + "end": { + "line": 22, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 33 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 17 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 34 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 35 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 35 + } + } } ], "loc": { @@ -534,7 +648,7 @@ "column": 18 }, "end": { - "line": 22, + "line": 23, "column": 2 } } @@ -545,7 +659,7 @@ "column": 15 }, "end": { - "line": 22, + "line": 23, "column": 2 } } @@ -556,7 +670,7 @@ "column": 15 }, "end": { - "line": 22, + "line": 23, "column": 2 } } @@ -569,7 +683,7 @@ "column": 1 }, "end": { - "line": 22, + "line": 23, "column": 2 } } @@ -604,7 +718,7 @@ "column": 1 }, "end": { - "line": 23, + "line": 24, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_retrun_enum.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_retrun_enum.ets similarity index 95% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_retrun_enum.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_retrun_enum.ets index b2b1bf9c5..8ed8c6e8c 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_retrun_enum.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_retrun_enum.ets @@ -19,4 +19,5 @@ function main () { let y : Color = Color.Red return y } + let expected : () => Color = x } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt similarity index 76% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt index b4aa958ea..a333dff5f 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt @@ -436,6 +436,133 @@ "column": 19 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 24 + }, + "end": { + "line": 19, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 24 + }, + "end": { + "line": 19, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 24 + }, + "end": { + "line": 19, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 33 + }, + "end": { + "line": 19, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 34 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 35 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 36 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 36 + } + } } ], "loc": { @@ -444,7 +571,7 @@ "column": 18 }, "end": { - "line": 19, + "line": 20, "column": 2 } } @@ -455,7 +582,7 @@ "column": 15 }, "end": { - "line": 19, + "line": 20, "column": 2 } } @@ -466,7 +593,7 @@ "column": 15 }, "end": { - "line": 19, + "line": 20, "column": 2 } } @@ -479,7 +606,7 @@ "column": 1 }, "end": { - "line": 19, + "line": 20, "column": 2 } } @@ -514,7 +641,7 @@ "column": 1 }, "end": { - "line": 20, + "line": 21, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_array.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array.ets similarity index 94% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_array.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array.ets index 4c471e8e9..c2a299ba2 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_array.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array.ets @@ -16,4 +16,5 @@ function main () { let y : number[] = [ 1 ,2 ,3 ] let x = () => y + let expected : () => number[] = x } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt similarity index 76% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt index f5e21f45a..4db8770ef 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt @@ -399,6 +399,134 @@ } } }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 32 + }, + "end": { + "line": 23, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 32 + }, + "end": { + "line": 23, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 32 + }, + "end": { + "line": 23, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 26 + }, + "end": { + "line": 23, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 20 + }, + "end": { + "line": 23, + "column": 37 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 38 + }, + "end": { + "line": 23, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 39 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 39 + } + } + }, { "type": "ReturnStatement", "argument": { @@ -407,22 +535,22 @@ "decorators": [], "loc": { "start": { - "line": 23, + "line": 24, "column": 12 }, "end": { - "line": 23, + "line": 24, "column": 13 } } }, "loc": { "start": { - "line": 23, + "line": 24, "column": 5 }, "end": { - "line": 23, + "line": 24, "column": 13 } } @@ -434,7 +562,7 @@ "column": 17 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -445,7 +573,7 @@ "column": 14 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -456,7 +584,7 @@ "column": 14 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -469,7 +597,7 @@ "column": 1 }, "end": { - "line": 24, + "line": 25, "column": 2 } } @@ -504,7 +632,7 @@ "column": 1 }, "end": { - "line": 25, + "line": 26, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda.ets similarity index 93% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda.ets index 52a1a7cb1..159e56374 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda.ets @@ -20,5 +20,6 @@ function main() { } return y } - return x + let expected : () => () => Int = x + return x } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt similarity index 69% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt index 487934f8a..9aef2f59f 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt @@ -311,6 +311,134 @@ "column": 27 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 32 + }, + "end": { + "line": 18, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 32 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 32 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 17 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 40 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 40 + } + } } ], "loc": { @@ -319,7 +447,7 @@ "column": 17 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -330,7 +458,7 @@ "column": 14 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -341,7 +469,7 @@ "column": 14 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -354,7 +482,7 @@ "column": 1 }, "end": { - "line": 18, + "line": 19, "column": 2 } } @@ -389,7 +517,7 @@ "column": 1 }, "end": { - "line": 19, + "line": 20, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda1.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1.ets similarity index 94% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda1.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1.ets index 0d36b599b..f0cb1b26b 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda1.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1.ets @@ -15,4 +15,5 @@ function main() { let x = () => () => {} + let expected : () => () => void = x } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt similarity index 61% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt index 47d0a0294..2237eae3a 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt @@ -69,7 +69,80 @@ "params": [], "body": { "type": "BlockStatement", - "statements": [], + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "expected", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "main1", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 40 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 23, + "column": 43 + } + } + } + ], "loc": { "start": { "line": 1, @@ -120,7 +193,7 @@ "type": "MethodDefinition", "key": { "type": "Identifier", - "name": "main", + "name": "main1", "decorators": [], "loc": { "start": { @@ -129,7 +202,7 @@ }, "end": { "line": 16, - "column": 14 + "column": 15 } } }, @@ -144,7 +217,7 @@ "type": "ScriptFunction", "id": { "type": "Identifier", - "name": "main", + "name": "main1", "decorators": [], "loc": { "start": { @@ -153,7 +226,7 @@ }, "end": { "line": 16, - "column": 14 + "column": 15 } } }, @@ -285,7 +358,7 @@ "loc": { "start": { "line": 16, - "column": 18 + "column": 19 }, "end": { "line": 22, @@ -296,7 +369,7 @@ "loc": { "start": { "line": 16, - "column": 15 + "column": 16 }, "end": { "line": 22, @@ -307,7 +380,7 @@ "loc": { "start": { "line": 16, - "column": 15 + "column": 16 }, "end": { "line": 22, @@ -327,6 +400,141 @@ "column": 2 } } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "expected", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "value": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "main1", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 40 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 43 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 22 + }, + "end": { + "line": 23, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 34 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 43 + } + } } ], "loc": { @@ -358,7 +566,7 @@ "column": 1 }, "end": { - "line": 23, + "line": 24, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression.ets similarity index 91% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression.ets index 4c20b1a83..8bcea1baa 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression.ets @@ -13,10 +13,11 @@ * limitations under the License. */ -function main () { +function main1 () { return () => { return () => { } } } +let expected : () => () => void = main1 () diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt similarity index 69% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt index 0b1093dd0..84d4b4848 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt @@ -280,6 +280,120 @@ "column": 6 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 31 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 32 + }, + "end": { + "line": 20, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 33 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 33 + } + } } ], "loc": { @@ -288,7 +402,7 @@ "column": 18 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -299,7 +413,7 @@ "column": 15 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -310,7 +424,7 @@ "column": 15 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -323,7 +437,7 @@ "column": 1 }, "end": { - "line": 20, + "line": 21, "column": 2 } } @@ -358,7 +472,7 @@ "column": 1 }, "end": { - "line": 21, + "line": 22, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_literal.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal.ets similarity index 95% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_literal.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal.ets index 368e82afb..05e3bf890 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_literal.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal.ets @@ -17,4 +17,5 @@ function main () { let x = () => { return 1 } + let expected : () => Int = x } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt similarity index 72% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt index bdbe6148f..191ba526c 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt @@ -436,6 +436,176 @@ "column": 4 } } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "expected", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 24 + }, + "end": { + "line": 21, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 24 + }, + "end": { + "line": 21, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 24 + }, + "end": { + "line": 21, + "column": 29 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 30 + }, + "end": { + "line": 21, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 30 + }, + "end": { + "line": 21, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 30 + }, + "end": { + "line": 21, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 24 + }, + "end": { + "line": 21, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 18 + }, + "end": { + "line": 21, + "column": 38 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 15 + } + } + }, + "init": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 39 + }, + "end": { + "line": 21, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 40 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 40 + } + } } ], "loc": { @@ -444,7 +614,7 @@ "column": 18 }, "end": { - "line": 21, + "line": 22, "column": 2 } } @@ -455,7 +625,7 @@ "column": 15 }, "end": { - "line": 21, + "line": 22, "column": 2 } } @@ -466,7 +636,7 @@ "column": 15 }, "end": { - "line": 21, + "line": 22, "column": 2 } } @@ -479,7 +649,7 @@ "column": 1 }, "end": { - "line": 21, + "line": 22, "column": 2 } } @@ -514,7 +684,7 @@ "column": 1 }, "end": { - "line": 22, + "line": 23, "column": 1 } } diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_union.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union.ets similarity index 94% rename from ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_union.ets rename to ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union.ets index 3cd66a19d..6196e74e3 100644 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type_return_union.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union.ets @@ -18,4 +18,5 @@ function main () { let y : Int | Double = 2.0 return y } + let expected : () => Int | Double = x } diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope-expected.txt new file mode 100644 index 000000000..1034ff0fd --- /dev/null +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope-expected.txt @@ -0,0 +1,623 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "value": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": true, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 19 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "right": { + "type": "Identifier", + "name": "p", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "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": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "AssertStatement", + "test": { + "type": "BinaryExpression", + "operator": "==", + "left": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "f", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 42, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 16 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 43, + "loc": { + "start": { + "line": 19, + "column": 21 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "second": null, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope.ets new file mode 100644 index 000000000..dcc3b3870 --- /dev/null +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope.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. + */ + +let b = 1; +let f = (p: double) => b + p; +function main () { + assert f(42) == 43 +} diff --git a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type-expected.txt b/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type-expected.txt deleted file mode 100644 index 18135a31d..000000000 --- a/ets2panda/test/parser/ets/lambda_infer_type/lambda_infer_type-expected.txt +++ /dev/null @@ -1,337 +0,0 @@ -{ - "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": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "x", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9 - }, - "end": { - "line": 17, - "column": 10 - } - } - }, - "init": { - "type": "ArrowFunctionExpression", - "function": { - "type": "ScriptFunction", - "id": null, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 17, - "column": 19 - }, - "end": { - "line": 17, - "column": 21 - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 13 - }, - "end": { - "line": 17, - "column": 21 - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 13 - }, - "end": { - "line": 17, - "column": 21 - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 9 - }, - "end": { - "line": 17, - "column": 21 - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 17, - "column": 5 - }, - "end": { - "line": 17, - "column": 21 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 17 - }, - "end": { - "line": 18, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 14 - }, - "end": { - "line": 18, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 14 - }, - "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 - } - } -} -- Gitee From 8dadfd56bcb04ecae6b5c19933b6e41af5fee061 Mon Sep 17 00:00:00 2001 From: Orlovsky Maxim Date: Thu, 14 Dec 2023 10:51:11 +0300 Subject: [PATCH 05/35] =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84Issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8OETO 原因(目的、解决的问题等) Fixed UB in ASTVerifier class 描述(做了什么,变更了什么) Updated ASTVerifier variable initialization 测试用例(新增、改动、可能影响的功能) No added tests Signed-off-by: Orlovsky Maxim --- ets2panda/compiler/core/ASTVerifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ets2panda/compiler/core/ASTVerifier.cpp b/ets2panda/compiler/core/ASTVerifier.cpp index 11f6ba9f7..524bb6345 100644 --- a/ets2panda/compiler/core/ASTVerifier.cpp +++ b/ets2panda/compiler/core/ASTVerifier.cpp @@ -549,7 +549,7 @@ std::optional ASTVerifier::GetLocalScopeVariable(con bool ASTVerifier::VerifyChildNode(const ir::AstNode *ast) { ASSERT(ast); - bool is_ok; + bool is_ok = true; ast->Iterate([&](const auto node) { if (ast != node->Parent()) { AddError("INCORRECT_PARENT_REF: " + ToStringHelper(node), node->Start()); -- Gitee From 112291f80b5264bd158b44e510dd24e0d8833371 Mon Sep 17 00:00:00 2001 From: Sizov Nikita Date: Mon, 13 Nov 2023 14:57:46 +0300 Subject: [PATCH 06/35] Implement Source Ast Dumper in es2panda Signed-off-by: Sizov Nikita --- ets2panda/BUILD.gn | 1 + ets2panda/CMakeLists.txt | 1 + ets2panda/compiler/lowering/phase.cpp | 40 ++++++++-- ets2panda/compiler/lowering/phase.h | 6 ++ ets2panda/es2panda.h | 2 + ets2panda/ir/as/namedType.cpp | 6 ++ ets2panda/ir/as/namedType.h | 1 + ets2panda/ir/as/prefixAssertionExpression.cpp | 6 ++ ets2panda/ir/as/prefixAssertionExpression.h | 1 + ets2panda/ir/astNode.cpp | 7 ++ ets2panda/ir/astNode.h | 3 + ets2panda/ir/base/catchClause.cpp | 17 ++++ ets2panda/ir/base/catchClause.h | 1 + ets2panda/ir/base/classDefinition.cpp | 57 ++++++++++++++ ets2panda/ir/base/classDefinition.h | 2 +- ets2panda/ir/base/classProperty.cpp | 38 +++++++++ ets2panda/ir/base/classProperty.h | 2 +- ets2panda/ir/base/classStaticBlock.cpp | 6 ++ ets2panda/ir/base/classStaticBlock.h | 1 + ets2panda/ir/base/decorator.cpp | 6 ++ ets2panda/ir/base/decorator.h | 1 + ets2panda/ir/base/metaProperty.cpp | 7 ++ ets2panda/ir/base/metaProperty.h | 1 + ets2panda/ir/base/methodDefinition.cpp | 52 +++++++++++++ ets2panda/ir/base/methodDefinition.h | 1 + ets2panda/ir/base/property.cpp | 7 ++ ets2panda/ir/base/property.h | 1 + ets2panda/ir/base/scriptFunction.cpp | 45 +++++++++++ ets2panda/ir/base/scriptFunction.h | 1 + ets2panda/ir/base/spreadElement.cpp | 12 +++ ets2panda/ir/base/spreadElement.h | 1 + ets2panda/ir/base/templateElement.cpp | 7 ++ ets2panda/ir/base/templateElement.h | 1 + ets2panda/ir/base/tsIndexSignature.cpp | 8 +- ets2panda/ir/base/tsIndexSignature.h | 1 + ets2panda/ir/base/tsMethodSignature.cpp | 8 +- ets2panda/ir/base/tsMethodSignature.h | 1 + ets2panda/ir/base/tsPropertySignature.cpp | 8 +- ets2panda/ir/base/tsPropertySignature.h | 1 + ets2panda/ir/base/tsSignatureDeclaration.cpp | 7 ++ ets2panda/ir/base/tsSignatureDeclaration.h | 2 +- ets2panda/ir/ets/etsClassLiteral.cpp | 6 ++ ets2panda/ir/ets/etsClassLiteral.h | 1 + ets2panda/ir/ets/etsFunctionType.cpp | 23 ++++++ ets2panda/ir/ets/etsFunctionType.h | 1 + ets2panda/ir/ets/etsLaunchExpression.cpp | 7 ++ ets2panda/ir/ets/etsLaunchExpression.h | 1 + .../ir/ets/etsNewArrayInstanceExpression.cpp | 12 +++ .../ir/ets/etsNewArrayInstanceExpression.h | 1 + .../ir/ets/etsNewClassInstanceExpression.cpp | 17 ++++ .../ir/ets/etsNewClassInstanceExpression.h | 2 +- .../etsNewMultiDimArrayInstanceExpression.cpp | 14 ++++ .../etsNewMultiDimArrayInstanceExpression.h | 2 +- ets2panda/ir/ets/etsPackageDeclaration.cpp | 9 +++ ets2panda/ir/ets/etsPackageDeclaration.h | 2 +- ets2panda/ir/ets/etsParameterExpression.cpp | 25 ++++++ ets2panda/ir/ets/etsParameterExpression.h | 1 + ets2panda/ir/ets/etsPrimitiveType.cpp | 36 +++++++++ ets2panda/ir/ets/etsPrimitiveType.h | 1 + ets2panda/ir/ets/etsStructDeclaration.cpp | 6 ++ ets2panda/ir/ets/etsStructDeclaration.h | 2 +- ets2panda/ir/ets/etsTuple.cpp | 16 ++++ ets2panda/ir/ets/etsTuple.h | 1 + ets2panda/ir/ets/etsTypeReference.cpp | 9 ++- ets2panda/ir/ets/etsTypeReference.h | 3 +- ets2panda/ir/ets/etsTypeReferencePart.cpp | 11 +++ ets2panda/ir/ets/etsTypeReferencePart.h | 1 + ets2panda/ir/ets/etsUnionType.cpp | 11 +++ ets2panda/ir/ets/etsUnionType.h | 1 + ets2panda/ir/ets/etsWildcardType.cpp | 6 ++ ets2panda/ir/ets/etsWildcardType.h | 1 + ets2panda/ir/expressions/arrayExpression.cpp | 15 +++- ets2panda/ir/expressions/arrayExpression.h | 1 + .../expressions/arrowFunctionExpression.cpp | 6 ++ .../ir/expressions/arrowFunctionExpression.h | 1 + .../ir/expressions/assignmentExpression.cpp | 12 +++ .../ir/expressions/assignmentExpression.h | 1 + ets2panda/ir/expressions/awaitExpression.cpp | 6 ++ ets2panda/ir/expressions/awaitExpression.h | 1 + ets2panda/ir/expressions/binaryExpression.cpp | 15 ++++ ets2panda/ir/expressions/binaryExpression.h | 1 + ets2panda/ir/expressions/blockExpression.cpp | 11 +++ ets2panda/ir/expressions/blockExpression.h | 1 + ets2panda/ir/expressions/callExpression.cpp | 16 ++++ ets2panda/ir/expressions/callExpression.h | 1 + ets2panda/ir/expressions/chainExpression.cpp | 6 ++ ets2panda/ir/expressions/chainExpression.h | 1 + ets2panda/ir/expressions/classExpression.cpp | 6 ++ ets2panda/ir/expressions/classExpression.h | 1 + .../ir/expressions/conditionalExpression.cpp | 22 ++++++ .../ir/expressions/conditionalExpression.h | 1 + .../ir/expressions/functionExpression.cpp | 6 ++ ets2panda/ir/expressions/functionExpression.h | 1 + ets2panda/ir/expressions/identifier.cpp | 13 ++++ ets2panda/ir/expressions/identifier.h | 1 + ets2panda/ir/expressions/importExpression.cpp | 7 ++ ets2panda/ir/expressions/importExpression.h | 1 + .../ir/expressions/literals/bigIntLiteral.cpp | 6 ++ .../ir/expressions/literals/bigIntLiteral.h | 1 + .../expressions/literals/booleanLiteral.cpp | 6 ++ .../ir/expressions/literals/booleanLiteral.h | 1 + .../ir/expressions/literals/charLiteral.cpp | 7 ++ .../ir/expressions/literals/charLiteral.h | 1 + .../ir/expressions/literals/nullLiteral.cpp | 7 ++ .../ir/expressions/literals/nullLiteral.h | 1 + .../ir/expressions/literals/numberLiteral.cpp | 26 +++++++ .../ir/expressions/literals/numberLiteral.h | 1 + .../ir/expressions/literals/regExpLiteral.cpp | 7 ++ .../ir/expressions/literals/regExpLiteral.h | 1 + .../ir/expressions/literals/stringLiteral.cpp | 39 ++++++++++ .../ir/expressions/literals/stringLiteral.h | 1 + .../expressions/literals/undefinedLiteral.cpp | 6 ++ .../expressions/literals/undefinedLiteral.h | 1 + ets2panda/ir/expressions/memberExpression.cpp | 25 ++++++ ets2panda/ir/expressions/memberExpression.h | 1 + ets2panda/ir/expressions/newExpression.cpp | 7 ++ ets2panda/ir/expressions/newExpression.h | 1 + ets2panda/ir/expressions/objectExpression.cpp | 6 ++ ets2panda/ir/expressions/objectExpression.h | 1 + .../ir/expressions/omittedExpression.cpp | 7 ++ ets2panda/ir/expressions/omittedExpression.h | 1 + .../ir/expressions/sequenceExpression.cpp | 12 +++ ets2panda/ir/expressions/sequenceExpression.h | 1 + ets2panda/ir/expressions/superExpression.cpp | 7 ++ ets2panda/ir/expressions/superExpression.h | 1 + .../expressions/taggedTemplateExpression.cpp | 6 ++ .../ir/expressions/taggedTemplateExpression.h | 1 + ets2panda/ir/expressions/templateLiteral.cpp | 6 ++ ets2panda/ir/expressions/templateLiteral.h | 1 + ets2panda/ir/expressions/thisExpression.cpp | 6 ++ ets2panda/ir/expressions/thisExpression.h | 1 + ets2panda/ir/expressions/unaryExpression.cpp | 7 ++ ets2panda/ir/expressions/unaryExpression.h | 1 + ets2panda/ir/expressions/updateExpression.cpp | 14 ++++ ets2panda/ir/expressions/updateExpression.h | 1 + ets2panda/ir/expressions/yieldExpression.cpp | 7 ++ ets2panda/ir/expressions/yieldExpression.h | 1 + ets2panda/ir/module/exportAllDeclaration.cpp | 7 ++ ets2panda/ir/module/exportAllDeclaration.h | 1 + .../ir/module/exportDefaultDeclaration.cpp | 7 ++ .../ir/module/exportDefaultDeclaration.h | 1 + .../ir/module/exportNamedDeclaration.cpp | 7 ++ ets2panda/ir/module/exportNamedDeclaration.h | 1 + ets2panda/ir/module/exportSpecifier.cpp | 7 ++ ets2panda/ir/module/exportSpecifier.h | 1 + ets2panda/ir/module/importDeclaration.cpp | 19 +++++ ets2panda/ir/module/importDeclaration.h | 1 + .../ir/module/importDefaultSpecifier.cpp | 7 ++ ets2panda/ir/module/importDefaultSpecifier.h | 1 + .../ir/module/importNamespaceSpecifier.cpp | 7 ++ .../ir/module/importNamespaceSpecifier.h | 1 + ets2panda/ir/module/importSpecifier.cpp | 7 ++ ets2panda/ir/module/importSpecifier.h | 1 + ets2panda/ir/opaqueTypeNode.cpp | 7 ++ ets2panda/ir/opaqueTypeNode.h | 1 + ets2panda/ir/srcDump.cpp | 77 +++++++++++++++++++ ets2panda/ir/srcDump.h | 54 +++++++++++++ ets2panda/ir/statements/assertStatement.cpp | 12 +++ ets2panda/ir/statements/assertStatement.h | 1 + ets2panda/ir/statements/blockStatement.cpp | 12 +++ ets2panda/ir/statements/blockStatement.h | 1 + ets2panda/ir/statements/breakStatement.cpp | 11 +++ ets2panda/ir/statements/breakStatement.h | 1 + ets2panda/ir/statements/classDeclaration.cpp | 11 +++ ets2panda/ir/statements/classDeclaration.h | 1 + ets2panda/ir/statements/continueStatement.cpp | 7 ++ ets2panda/ir/statements/continueStatement.h | 1 + ets2panda/ir/statements/debuggerStatement.cpp | 7 ++ ets2panda/ir/statements/debuggerStatement.h | 1 + ets2panda/ir/statements/doWhileStatement.cpp | 21 +++++ ets2panda/ir/statements/doWhileStatement.h | 1 + ets2panda/ir/statements/emptyStatement.cpp | 7 ++ ets2panda/ir/statements/emptyStatement.h | 1 + .../ir/statements/expressionStatement.cpp | 14 ++++ ets2panda/ir/statements/expressionStatement.h | 1 + ets2panda/ir/statements/forInStatement.cpp | 7 ++ ets2panda/ir/statements/forInStatement.h | 1 + ets2panda/ir/statements/forOfStatement.cpp | 26 +++++++ ets2panda/ir/statements/forOfStatement.h | 1 + .../ir/statements/forUpdateStatement.cpp | 30 ++++++++ ets2panda/ir/statements/forUpdateStatement.h | 1 + .../ir/statements/functionDeclaration.cpp | 7 ++ ets2panda/ir/statements/functionDeclaration.h | 1 + ets2panda/ir/statements/ifStatement.cpp | 33 ++++++++ ets2panda/ir/statements/ifStatement.h | 1 + ets2panda/ir/statements/labelledStatement.cpp | 11 +++ ets2panda/ir/statements/labelledStatement.h | 1 + ets2panda/ir/statements/returnStatement.cpp | 11 +++ ets2panda/ir/statements/returnStatement.h | 1 + .../ir/statements/switchCaseStatement.cpp | 21 +++++ ets2panda/ir/statements/switchCaseStatement.h | 1 + ets2panda/ir/statements/switchStatement.cpp | 22 ++++++ ets2panda/ir/statements/switchStatement.h | 1 + ets2panda/ir/statements/throwStatement.cpp | 9 +++ ets2panda/ir/statements/throwStatement.h | 1 + ets2panda/ir/statements/tryStatement.cpp | 26 +++++++ ets2panda/ir/statements/tryStatement.h | 1 + .../ir/statements/variableDeclaration.cpp | 30 ++++++++ ets2panda/ir/statements/variableDeclaration.h | 1 + .../ir/statements/variableDeclarator.cpp | 19 +++++ ets2panda/ir/statements/variableDeclarator.h | 1 + ets2panda/ir/statements/whileStatement.cpp | 18 +++++ ets2panda/ir/statements/whileStatement.h | 1 + ets2panda/ir/ts/tsAnyKeyword.cpp | 7 ++ ets2panda/ir/ts/tsAnyKeyword.h | 1 + ets2panda/ir/ts/tsArrayType.cpp | 9 +++ ets2panda/ir/ts/tsArrayType.h | 1 + ets2panda/ir/ts/tsAsExpression.cpp | 5 ++ ets2panda/ir/ts/tsAsExpression.h | 2 + ets2panda/ir/ts/tsBigintKeyword.cpp | 6 ++ ets2panda/ir/ts/tsBigintKeyword.h | 1 + ets2panda/ir/ts/tsBooleanKeyword.cpp | 7 ++ ets2panda/ir/ts/tsBooleanKeyword.h | 1 + ets2panda/ir/ts/tsClassImplements.cpp | 7 ++ ets2panda/ir/ts/tsClassImplements.h | 1 + ets2panda/ir/ts/tsConditionalType.cpp | 6 ++ ets2panda/ir/ts/tsConditionalType.h | 1 + ets2panda/ir/ts/tsConstructorType.cpp | 6 ++ ets2panda/ir/ts/tsConstructorType.h | 1 + ets2panda/ir/ts/tsEnumDeclaration.cpp | 26 +++++++ ets2panda/ir/ts/tsEnumDeclaration.h | 1 + ets2panda/ir/ts/tsEnumMember.cpp | 12 +++ ets2panda/ir/ts/tsEnumMember.h | 1 + ets2panda/ir/ts/tsExternalModuleReference.cpp | 7 ++ ets2panda/ir/ts/tsExternalModuleReference.h | 1 + ets2panda/ir/ts/tsFunctionType.cpp | 6 ++ ets2panda/ir/ts/tsFunctionType.h | 1 + ets2panda/ir/ts/tsImportEqualsDeclaration.cpp | 6 ++ ets2panda/ir/ts/tsImportEqualsDeclaration.h | 1 + ets2panda/ir/ts/tsImportType.cpp | 6 ++ ets2panda/ir/ts/tsImportType.h | 1 + ets2panda/ir/ts/tsIndexedAccessType.cpp | 6 ++ ets2panda/ir/ts/tsIndexedAccessType.h | 1 + ets2panda/ir/ts/tsInferType.cpp | 6 ++ ets2panda/ir/ts/tsInferType.h | 1 + ets2panda/ir/ts/tsInterfaceBody.cpp | 8 ++ ets2panda/ir/ts/tsInterfaceBody.h | 1 + ets2panda/ir/ts/tsInterfaceDeclaration.cpp | 37 +++++++++ ets2panda/ir/ts/tsInterfaceDeclaration.h | 1 + ets2panda/ir/ts/tsInterfaceHeritage.cpp | 8 ++ ets2panda/ir/ts/tsInterfaceHeritage.h | 1 + ets2panda/ir/ts/tsIntersectionType.cpp | 6 ++ ets2panda/ir/ts/tsIntersectionType.h | 1 + ets2panda/ir/ts/tsLiteralType.cpp | 6 ++ ets2panda/ir/ts/tsLiteralType.h | 1 + ets2panda/ir/ts/tsMappedType.cpp | 6 ++ ets2panda/ir/ts/tsMappedType.h | 1 + ets2panda/ir/ts/tsModuleBlock.cpp | 6 ++ ets2panda/ir/ts/tsModuleBlock.h | 1 + ets2panda/ir/ts/tsModuleDeclaration.cpp | 6 ++ ets2panda/ir/ts/tsModuleDeclaration.h | 1 + ets2panda/ir/ts/tsNamedTupleMember.cpp | 6 ++ ets2panda/ir/ts/tsNamedTupleMember.h | 1 + ets2panda/ir/ts/tsNeverKeyword.cpp | 6 ++ ets2panda/ir/ts/tsNeverKeyword.h | 1 + ets2panda/ir/ts/tsNonNullExpression.cpp | 8 ++ ets2panda/ir/ts/tsNonNullExpression.h | 1 + ets2panda/ir/ts/tsNullKeyword.cpp | 6 ++ ets2panda/ir/ts/tsNullKeyword.h | 1 + ets2panda/ir/ts/tsNumberKeyword.cpp | 7 ++ ets2panda/ir/ts/tsNumberKeyword.h | 1 + ets2panda/ir/ts/tsObjectKeyword.cpp | 7 ++ ets2panda/ir/ts/tsObjectKeyword.h | 1 + ets2panda/ir/ts/tsParameterProperty.cpp | 6 ++ ets2panda/ir/ts/tsParameterProperty.h | 1 + ets2panda/ir/ts/tsParenthesizedType.cpp | 6 ++ ets2panda/ir/ts/tsParenthesizedType.h | 1 + ets2panda/ir/ts/tsQualifiedName.cpp | 6 ++ ets2panda/ir/ts/tsQualifiedName.h | 1 + ets2panda/ir/ts/tsStringKeyword.cpp | 7 ++ ets2panda/ir/ts/tsStringKeyword.h | 1 + ets2panda/ir/ts/tsThisType.cpp | 6 ++ ets2panda/ir/ts/tsThisType.h | 1 + ets2panda/ir/ts/tsTupleType.cpp | 6 ++ ets2panda/ir/ts/tsTupleType.h | 1 + ets2panda/ir/ts/tsTypeAliasDeclaration.cpp | 23 ++++++ ets2panda/ir/ts/tsTypeAliasDeclaration.h | 1 + ets2panda/ir/ts/tsTypeAssertion.cpp | 6 ++ ets2panda/ir/ts/tsTypeAssertion.h | 1 + ets2panda/ir/ts/tsTypeLiteral.cpp | 6 ++ ets2panda/ir/ts/tsTypeLiteral.h | 1 + ets2panda/ir/ts/tsTypeOperator.cpp | 6 ++ ets2panda/ir/ts/tsTypeOperator.h | 1 + ets2panda/ir/ts/tsTypeParameter.cpp | 6 ++ ets2panda/ir/ts/tsTypeParameter.h | 1 + .../ir/ts/tsTypeParameterDeclaration.cpp | 11 +++ ets2panda/ir/ts/tsTypeParameterDeclaration.h | 1 + .../ir/ts/tsTypeParameterInstantiation.cpp | 15 ++++ .../ir/ts/tsTypeParameterInstantiation.h | 1 + ets2panda/ir/ts/tsTypePredicate.cpp | 5 ++ ets2panda/ir/ts/tsTypePredicate.h | 1 + ets2panda/ir/ts/tsTypeQuery.cpp | 6 ++ ets2panda/ir/ts/tsTypeQuery.h | 1 + ets2panda/ir/ts/tsTypeReference.cpp | 6 ++ ets2panda/ir/ts/tsTypeReference.h | 1 + ets2panda/ir/ts/tsUndefinedKeyword.cpp | 7 ++ ets2panda/ir/ts/tsUndefinedKeyword.h | 1 + ets2panda/ir/ts/tsUnionType.cpp | 6 ++ ets2panda/ir/ts/tsUnionType.h | 1 + ets2panda/ir/ts/tsUnknownKeyword.cpp | 7 ++ ets2panda/ir/ts/tsUnknownKeyword.h | 1 + ets2panda/ir/ts/tsVoidKeyword.cpp | 7 ++ ets2panda/ir/ts/tsVoidKeyword.h | 1 + ets2panda/test/unit/ast_dumper_test.cpp | 26 +++++++ ets2panda/util/options.cpp | 14 ++++ 305 files changed, 2079 insertions(+), 21 deletions(-) create mode 100644 ets2panda/ir/srcDump.cpp create mode 100644 ets2panda/ir/srcDump.h diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index e498a933f..30bba267c 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -254,6 +254,7 @@ libes2panda_sources = [ "ir/module/importNamespaceSpecifier.cpp", "ir/module/importSpecifier.cpp", "ir/opaqueTypeNode.cpp", + "ir/srcDump.cpp", "ir/statement.cpp", "ir/statements/assertStatement.cpp", "ir/statements/blockStatement.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index f5bf5b757..2cc33b548 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -175,6 +175,7 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/expandBrackets.cpp compiler/lowering/ets/promiseVoid.cpp ir/astDump.cpp + ir/srcDump.cpp ir/astNode.cpp ir/irnode.cpp ir/typeNode.cpp diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 21867db6a..b64e813bc 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -130,10 +130,7 @@ bool Phase::Apply(public_lib::Context *ctx, parser::Program *program) return true; } - if (options->dump_before_phases.count(name) > 0) { - std::cout << "Before phase " << Name() << ":" << std::endl; - std::cout << program->Dump() << std::endl; - } + CheckOptionsBeforePhase(options, program, name); #ifndef NDEBUG if (!Precondition(ctx, program)) { @@ -146,10 +143,7 @@ bool Phase::Apply(public_lib::Context *ctx, parser::Program *program) return false; } - if (options->dump_after_phases.count(name) > 0) { - std::cout << "After phase " << Name() << ":" << std::endl; - std::cout << program->Dump() << std::endl; - } + CheckOptionsAfterPhase(options, program, name); #ifndef NDEBUG check_program(program); @@ -163,4 +157,34 @@ bool Phase::Apply(public_lib::Context *ctx, parser::Program *program) return true; } +void Phase::CheckOptionsBeforePhase(const CompilerOptions *options, const parser::Program *program, + const std::string &name) const +{ + if (options->dump_after_phases.count(name) > 0) { + std::cout << "After phase " << name << ":" << std::endl; + std::cout << program->Dump() << std::endl; + } + + if (options->dump_ets_src_after_phases.count(name) > 0) { + std::cout << "After phase " << name << " ets source" + << ":" << std::endl; + std::cout << program->Ast()->DumpEtsSrc() << std::endl; + } +} + +void Phase::CheckOptionsAfterPhase(const CompilerOptions *options, const parser::Program *program, + const std::string &name) const +{ + if (options->dump_after_phases.count(name) > 0) { + std::cout << "After phase " << name << ":" << std::endl; + std::cout << program->Dump() << std::endl; + } + + if (options->dump_ets_src_after_phases.count(name) > 0) { + std::cout << "After phase " << name << " ets source" + << ":" << std::endl; + std::cout << program->Ast()->DumpEtsSrc() << std::endl; + } +} + } // namespace panda::es2panda::compiler diff --git a/ets2panda/compiler/lowering/phase.h b/ets2panda/compiler/lowering/phase.h index 8052a9ab2..9e2a381c1 100644 --- a/ets2panda/compiler/lowering/phase.h +++ b/ets2panda/compiler/lowering/phase.h @@ -39,6 +39,12 @@ public: { return true; } + +private: + void CheckOptionsBeforePhase(const CompilerOptions *options, const parser::Program *program, + const std::string &name) const; + void CheckOptionsAfterPhase(const CompilerOptions *options, const parser::Program *program, + const std::string &name) const; }; std::vector GetPhaseList(ScriptExtension ext); diff --git a/ets2panda/es2panda.h b/ets2panda/es2panda.h index 4c0d3725c..6cca648fb 100644 --- a/ets2panda/es2panda.h +++ b/ets2panda/es2panda.h @@ -104,7 +104,9 @@ struct CompilerOptions { std::vector plugins {}; std::unordered_set skip_phases {}; std::unordered_set dump_before_phases {}; + std::unordered_set dump_ets_src_before_phases {}; std::unordered_set dump_after_phases {}; + std::unordered_set dump_ets_src_after_phases {}; std::shared_ptr arkts_config {}; CompilationMode compilation_mode {}; // NOLINTEND(misc-non-private-member-variables-in-classes) diff --git a/ets2panda/ir/as/namedType.cpp b/ets2panda/ir/as/namedType.cpp index 1957c7a14..8c1cd5350 100644 --- a/ets2panda/ir/as/namedType.cpp +++ b/ets2panda/ir/as/namedType.cpp @@ -21,6 +21,7 @@ #include "ir/expressions/identifier.h" #include "ir/ts/tsTypeParameterInstantiation.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void NamedType::TransformChildren(const NodeTransformer &cb) @@ -58,6 +59,11 @@ void NamedType::Dump(AstDumper *dumper) const {"isNullable", nullable_}}); } +void NamedType::Dump(SrcDumper *dumper) const +{ + dumper->Add("NamedType"); +} + void NamedType::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/as/namedType.h b/ets2panda/ir/as/namedType.h index 5c8259eb9..f0da80b2a 100644 --- a/ets2panda/ir/as/namedType.h +++ b/ets2panda/ir/as/namedType.h @@ -59,6 +59,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; diff --git a/ets2panda/ir/as/prefixAssertionExpression.cpp b/ets2panda/ir/as/prefixAssertionExpression.cpp index 9d1634253..e06f9058a 100644 --- a/ets2panda/ir/as/prefixAssertionExpression.cpp +++ b/ets2panda/ir/as/prefixAssertionExpression.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" namespace panda::es2panda::ir { @@ -39,6 +40,11 @@ void PrefixAssertionExpression::Dump(AstDumper *dumper) const dumper->Add({{"type", "PrefixAssertionExpression"}, {"expression", expr_}, {"type", type_}}); } +void PrefixAssertionExpression::Dump(SrcDumper *dumper) const +{ + dumper->Add("PrefixAssertionExpression"); +} + void PrefixAssertionExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/as/prefixAssertionExpression.h b/ets2panda/ir/as/prefixAssertionExpression.h index 758df8b69..63546010d 100644 --- a/ets2panda/ir/as/prefixAssertionExpression.h +++ b/ets2panda/ir/as/prefixAssertionExpression.h @@ -39,6 +39,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/astNode.cpp b/ets2panda/ir/astNode.cpp index 4687db690..19a80ab4c 100644 --- a/ets2panda/ir/astNode.cpp +++ b/ets2panda/ir/astNode.cpp @@ -15,6 +15,7 @@ #include "astNode.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "typeNode.h" namespace panda::es2panda::ir { @@ -115,4 +116,10 @@ std::string AstNode::DumpJSON() const ir::AstDumper dumper {this}; return dumper.Str(); } + +std::string AstNode::DumpEtsSrc() const +{ + ir::SrcDumper dumper {this}; + return dumper.Str(); +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index 9a30d7bb9..e6f7b47c0 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -75,6 +75,7 @@ DEFINE_BITOPS(BoxingUnboxingFlags) // Forward declarations class AstDumper; class Expression; +class SrcDumper; class Statement; class ClassElement; @@ -478,8 +479,10 @@ public: AstNode *FindChild(const NodePredicate &cb) const; std::string DumpJSON() const; + std::string DumpEtsSrc() const; virtual void Dump(ir::AstDumper *dumper) const = 0; + virtual void Dump(ir::SrcDumper *dumper) const = 0; virtual void Compile([[maybe_unused]] compiler::PandaGen *pg) const = 0; virtual void Compile([[maybe_unused]] compiler::ETSGen *etsg) const {}; virtual checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) = 0; diff --git a/ets2panda/ir/base/catchClause.cpp b/ets2panda/ir/base/catchClause.cpp index feee7e595..da8ceb1c5 100644 --- a/ets2panda/ir/base/catchClause.cpp +++ b/ets2panda/ir/base/catchClause.cpp @@ -19,6 +19,7 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/identifier.h" #include "ir/statements/blockStatement.h" @@ -46,6 +47,22 @@ void CatchClause::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "CatchClause"}, {"body", body_}, {"param", AstDumper::Nullish(param_)}}); } +void CatchClause::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(body_ != nullptr); + dumper->Add("("); + if (param_ != nullptr) { + param_->Dump(dumper); + } + dumper->Add(") {"); + dumper->IncrIndent(); + dumper->Endl(); + body_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + dumper->Add("}"); +} + bool CatchClause::IsDefaultCatchClause() const { return param_->AsIdentifier()->TypeAnnotation() == nullptr; diff --git a/ets2panda/ir/base/catchClause.h b/ets2panda/ir/base/catchClause.h index 22fff21e3..0a4032356 100644 --- a/ets2panda/ir/base/catchClause.h +++ b/ets2panda/ir/base/catchClause.h @@ -69,6 +69,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/classDefinition.cpp b/ets2panda/ir/base/classDefinition.cpp index 31520c1ff..86458df85 100644 --- a/ets2panda/ir/base/classDefinition.cpp +++ b/ets2panda/ir/base/classDefinition.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/classStaticBlock.h" #include "ir/base/methodDefinition.h" #include "ir/base/scriptFunction.h" @@ -130,6 +131,62 @@ void ClassDefinition::Dump(ir::AstDumper *dumper) const {"body", body_, prop_filter}}); } +void ClassDefinition::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(ident_ != nullptr); + + if (IsExtern()) { + dumper->Add("extern "); + } + + if (IsFinal()) { + dumper->Add("final "); + } + + if (IsAbstract()) { + dumper->Add("abstract "); + } + + dumper->Add("class "); + ident_->Dump(dumper); + + if (type_params_ != nullptr) { + dumper->Add("<"); + type_params_->Dump(dumper); + dumper->Add("> "); + } + + if (super_class_ != nullptr) { + dumper->Add(" extends "); + super_class_->Dump(dumper); + } + + if (!implements_.empty()) { + dumper->Add(" implements "); + for (auto interface : implements_) { + interface->Dump(dumper); + if (interface != implements_.back()) { + dumper->Add(", "); + } + } + } + + dumper->Add(" {"); + if (!body_.empty()) { + dumper->IncrIndent(); + dumper->Endl(); + for (auto elem : body_) { + elem->Dump(dumper); + if (elem == body_.back()) { + dumper->DecrIndent(); + } + dumper->Endl(); + } + } + dumper->Add("}"); + dumper->Endl(); +} + void ClassDefinition::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/classDefinition.h b/ets2panda/ir/base/classDefinition.h index f0fc0cebc..e992e96ba 100644 --- a/ets2panda/ir/base/classDefinition.h +++ b/ets2panda/ir/base/classDefinition.h @@ -275,7 +275,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/classProperty.cpp b/ets2panda/ir/base/classProperty.cpp index 26e1c96ed..86699fdb3 100644 --- a/ets2panda/ir/base/classProperty.cpp +++ b/ets2panda/ir/base/classProperty.cpp @@ -21,6 +21,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/decorator.h" #include "ir/typeNode.h" #include "ir/expression.h" @@ -78,6 +79,43 @@ void ClassProperty::Dump(ir::AstDumper *dumper) const {"decorators", decorators_}}); } +void ClassProperty::Dump(ir::SrcDumper *dumper) const +{ + if (IsPrivate()) { + dumper->Add("private "); + } else if (IsProtected()) { + dumper->Add("protected "); + } else if (IsInternal()) { + dumper->Add("internal "); + } else { + dumper->Add("public "); + } + + if (IsStatic()) { + dumper->Add("static "); + } + + if (IsReadonly()) { + dumper->Add("readonly "); + } + + if (key_ != nullptr) { + key_->Dump(dumper); + } + + if (type_annotation_ != nullptr) { + dumper->Add(": "); + type_annotation_->Dump(dumper); + } + + if (value_ != nullptr) { + dumper->Add(" = "); + value_->Dump(dumper); + } + + dumper->Add(";"); +} + void ClassProperty::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/classProperty.h b/ets2panda/ir/base/classProperty.h index c9e7ae4b9..474cd9694 100644 --- a/ets2panda/ir/base/classProperty.h +++ b/ets2panda/ir/base/classProperty.h @@ -58,7 +58,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/classStaticBlock.cpp b/ets2panda/ir/base/classStaticBlock.cpp index 4f0b307bb..db53d6666 100644 --- a/ets2panda/ir/base/classStaticBlock.cpp +++ b/ets2panda/ir/base/classStaticBlock.cpp @@ -21,6 +21,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/decorator.h" #include "ir/base/scriptFunction.h" #include "ir/expression.h" @@ -46,6 +47,11 @@ void ClassStaticBlock::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ClassStaticBlock"}, {"value", value_}}); } +void ClassStaticBlock::Dump([[maybe_unused]] ir::SrcDumper *dumper) const +{ + // NOTE(nsizov): we don't want to show this node +} + void ClassStaticBlock::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/classStaticBlock.h b/ets2panda/ir/base/classStaticBlock.h index 89edc771a..7debb7fab 100644 --- a/ets2panda/ir/base/classStaticBlock.h +++ b/ets2panda/ir/base/classStaticBlock.h @@ -40,6 +40,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/decorator.cpp b/ets2panda/ir/base/decorator.cpp index beb884f79..eed3b5f6d 100644 --- a/ets2panda/ir/base/decorator.cpp +++ b/ets2panda/ir/base/decorator.cpp @@ -18,6 +18,7 @@ #include "es2panda.h" #include "ir/expression.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/ETSchecker.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" @@ -39,6 +40,11 @@ void Decorator::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "Decorator"}, {"expression", expr_}}); } +void Decorator::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("Decorator"); +} + void Decorator::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/decorator.h b/ets2panda/ir/base/decorator.h index 303ee9f35..dfbcc9027 100644 --- a/ets2panda/ir/base/decorator.h +++ b/ets2panda/ir/base/decorator.h @@ -42,6 +42,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/metaProperty.cpp b/ets2panda/ir/base/metaProperty.cpp index ed43fa1e0..a5208db90 100644 --- a/ets2panda/ir/base/metaProperty.cpp +++ b/ets2panda/ir/base/metaProperty.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void MetaProperty::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -49,6 +51,11 @@ void MetaProperty::Compile(compiler::PandaGen *pg) const pg->GetAstCompiler()->Compile(this); } +void MetaProperty::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("MetaProperty"); +} + void MetaProperty::Compile(compiler::ETSGen *etsg) const { etsg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/metaProperty.h b/ets2panda/ir/base/metaProperty.h index 0fd279f99..c5eb1bb84 100644 --- a/ets2panda/ir/base/metaProperty.h +++ b/ets2panda/ir/base/metaProperty.h @@ -48,6 +48,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/methodDefinition.cpp b/ets2panda/ir/base/methodDefinition.cpp index 0f261bdc9..149db9d9b 100644 --- a/ets2panda/ir/base/methodDefinition.cpp +++ b/ets2panda/ir/base/methodDefinition.cpp @@ -19,6 +19,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { @@ -120,6 +122,56 @@ void MethodDefinition::Dump(ir::AstDumper *dumper) const {"decorators", decorators_}}); } +void MethodDefinition::Dump(ir::SrcDumper *dumper) const +{ + for (auto method : overloads_) { + method->Dump(dumper); + dumper->Endl(); + } + + if (IsPrivate()) { + dumper->Add("private "); + } else if (IsProtected()) { + dumper->Add("protected "); + } else if (IsInternal()) { + dumper->Add("internal "); + } else { + dumper->Add("public "); + } + + if (IsStatic()) { + dumper->Add("static "); + } + + if (IsAbstract()) { + dumper->Add("abstract "); + } + + if (IsFinal()) { + dumper->Add("final "); + } + + if (IsNative()) { + dumper->Add("native "); + } + + if (IsAsync()) { + dumper->Add("async "); + } + + if (IsOverride()) { + dumper->Add("override "); + } + + if (key_ != nullptr) { + key_->Dump(dumper); + } + + if (value_ != nullptr) { + value_->Dump(dumper); + } +} + void MethodDefinition::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/methodDefinition.h b/ets2panda/ir/base/methodDefinition.h index 8791bed9a..5221b451f 100644 --- a/ets2panda/ir/base/methodDefinition.h +++ b/ets2panda/ir/base/methodDefinition.h @@ -111,6 +111,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/property.cpp b/ets2panda/ir/base/property.cpp index 962be1644..113ae6224 100644 --- a/ets2panda/ir/base/property.cpp +++ b/ets2panda/ir/base/property.cpp @@ -19,6 +19,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { Property::Property([[maybe_unused]] Tag const tag, Property const &other, Expression *const key, @@ -177,6 +179,11 @@ void Property::Compile(compiler::ETSGen *etsg) const etsg->GetAstCompiler()->Compile(this); } +void Property::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("Property"); +} + checker::Type *Property::Check(checker::TSChecker *checker) { return checker->GetAnalyzer()->Check(this); diff --git a/ets2panda/ir/base/property.h b/ets2panda/ir/base/property.h index cb9f1636a..f69086b21 100644 --- a/ets2panda/ir/base/property.h +++ b/ets2panda/ir/base/property.h @@ -111,6 +111,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/scriptFunction.cpp b/ets2panda/ir/base/scriptFunction.cpp index b9224670f..2c6753db0 100644 --- a/ets2panda/ir/base/scriptFunction.cpp +++ b/ets2panda/ir/base/scriptFunction.cpp @@ -19,6 +19,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { @@ -79,6 +81,49 @@ void ScriptFunction::Dump(ir::AstDumper *dumper) const } } +void ScriptFunction::Dump(ir::SrcDumper *dumper) const +{ + if (TypeParams() != nullptr) { + TypeParams()->Dump(dumper); + } + dumper->Add("("); + for (auto param : Params()) { + param->Dump(dumper); + if (param != Params().back()) { + dumper->Add(", "); + } + } + dumper->Add(")"); + if (ReturnTypeAnnotation() != nullptr) { + dumper->Add(": "); + ReturnTypeAnnotation()->Dump(dumper); + } + + if (IsThrowing()) { + dumper->Add(" throws"); + } + + if (HasBody()) { + if (body_->IsBlockStatement()) { + dumper->Add(" {"); + if (!body_->AsBlockStatement()->Statements().empty()) { + dumper->IncrIndent(); + dumper->Endl(); + body_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + } + dumper->Add("}"); + } else { + dumper->Add(" "); + body_->Dump(dumper); + } + } + if (!IsArrow()) { + dumper->Endl(); + } +} + void ScriptFunction::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/scriptFunction.h b/ets2panda/ir/base/scriptFunction.h index a037ff3af..f93616a18 100644 --- a/ets2panda/ir/base/scriptFunction.h +++ b/ets2panda/ir/base/scriptFunction.h @@ -300,6 +300,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/spreadElement.cpp b/ets2panda/ir/base/spreadElement.cpp index aa6719ad4..6dc6d00c6 100644 --- a/ets2panda/ir/base/spreadElement.cpp +++ b/ets2panda/ir/base/spreadElement.cpp @@ -20,6 +20,7 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/decorator.h" #include "ir/typeNode.h" #include "ir/expressions/arrayExpression.h" @@ -140,6 +141,17 @@ void SpreadElement::Dump(ir::AstDumper *dumper) const {"typeAnnotation", AstDumper::Optional(TypeAnnotation())}}); } +void SpreadElement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("..."); + argument_->Dump(dumper); + auto type = TypeAnnotation(); + if (type != nullptr) { + dumper->Add(": "); + type->Dump(dumper); + } +} + void SpreadElement::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/spreadElement.h b/ets2panda/ir/base/spreadElement.h index 6e507264b..bd484b6a0 100644 --- a/ets2panda/ir/base/spreadElement.h +++ b/ets2panda/ir/base/spreadElement.h @@ -87,6 +87,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/templateElement.cpp b/ets2panda/ir/base/templateElement.cpp index f77f02370..8816ba413 100644 --- a/ets2panda/ir/base/templateElement.cpp +++ b/ets2panda/ir/base/templateElement.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TemplateElement::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -31,6 +33,11 @@ void TemplateElement::Dump(ir::AstDumper *dumper) const }); } +void TemplateElement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TemplateElement"); +} + void TemplateElement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/templateElement.h b/ets2panda/ir/base/templateElement.h index 320770290..85154cdd1 100644 --- a/ets2panda/ir/base/templateElement.h +++ b/ets2panda/ir/base/templateElement.h @@ -50,6 +50,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/tsIndexSignature.cpp b/ets2panda/ir/base/tsIndexSignature.cpp index 2bea99f71..f48774bd9 100644 --- a/ets2panda/ir/base/tsIndexSignature.cpp +++ b/ets2panda/ir/base/tsIndexSignature.cpp @@ -14,7 +14,8 @@ */ #include "tsIndexSignature.h" - +#include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" @@ -46,6 +47,11 @@ void TSIndexSignature::Dump(ir::AstDumper *dumper) const {"readonly", readonly_}}); } +void TSIndexSignature::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSIndexSignature"); +} + void TSIndexSignature::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/tsIndexSignature.h b/ets2panda/ir/base/tsIndexSignature.h index 4c9fd1ae2..d63443ec4 100644 --- a/ets2panda/ir/base/tsIndexSignature.h +++ b/ets2panda/ir/base/tsIndexSignature.h @@ -67,6 +67,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/tsMethodSignature.cpp b/ets2panda/ir/base/tsMethodSignature.cpp index ab3eda459..11d32a2b4 100644 --- a/ets2panda/ir/base/tsMethodSignature.cpp +++ b/ets2panda/ir/base/tsMethodSignature.cpp @@ -14,7 +14,8 @@ */ #include "tsMethodSignature.h" - +#include "ir/astDump.h" +#include "ir/srcDump.h" #include "varbinder/scope.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" @@ -44,6 +45,11 @@ void TSMethodSignature::Dump(ir::AstDumper *dumper) const {"typeAnnotation", AstDumper::Optional(ReturnTypeAnnotation())}}); } +void TSMethodSignature::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSMethodSignature"); +} + void TSMethodSignature::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/tsMethodSignature.h b/ets2panda/ir/base/tsMethodSignature.h index fdc102d8b..369e48260 100644 --- a/ets2panda/ir/base/tsMethodSignature.h +++ b/ets2panda/ir/base/tsMethodSignature.h @@ -111,6 +111,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/tsPropertySignature.cpp b/ets2panda/ir/base/tsPropertySignature.cpp index ee863b4b7..e055f5d94 100644 --- a/ets2panda/ir/base/tsPropertySignature.cpp +++ b/ets2panda/ir/base/tsPropertySignature.cpp @@ -14,7 +14,8 @@ */ #include "tsPropertySignature.h" - +#include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" @@ -48,6 +49,11 @@ void TSPropertySignature::Dump(ir::AstDumper *dumper) const {"typeAnnotation", AstDumper::Optional(TypeAnnotation())}}); } +void TSPropertySignature::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSPropertySignature"); +} + void TSPropertySignature::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/tsPropertySignature.h b/ets2panda/ir/base/tsPropertySignature.h index 02768c8d6..4a462391d 100644 --- a/ets2panda/ir/base/tsPropertySignature.h +++ b/ets2panda/ir/base/tsPropertySignature.h @@ -71,6 +71,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/base/tsSignatureDeclaration.cpp b/ets2panda/ir/base/tsSignatureDeclaration.cpp index 50825acdf..cafb5a243 100644 --- a/ets2panda/ir/base/tsSignatureDeclaration.cpp +++ b/ets2panda/ir/base/tsSignatureDeclaration.cpp @@ -20,6 +20,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSSignatureDeclaration::TransformChildren(const NodeTransformer &cb) @@ -42,6 +44,11 @@ void TSSignatureDeclaration::Dump(ir::AstDumper *dumper) const {"returnType", AstDumper::Optional(ReturnTypeAnnotation())}}); } +void TSSignatureDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSSignatureDeclaration"); +} + void TSSignatureDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/base/tsSignatureDeclaration.h b/ets2panda/ir/base/tsSignatureDeclaration.h index b24d0abbe..caeeac2d2 100644 --- a/ets2panda/ir/base/tsSignatureDeclaration.h +++ b/ets2panda/ir/base/tsSignatureDeclaration.h @@ -93,7 +93,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsClassLiteral.cpp b/ets2panda/ir/ets/etsClassLiteral.cpp index 0168b7dda..ad0eabe30 100644 --- a/ets2panda/ir/ets/etsClassLiteral.cpp +++ b/ets2panda/ir/ets/etsClassLiteral.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ETSClassLiteral::TransformChildren(const NodeTransformer &cb) @@ -36,6 +37,11 @@ void ETSClassLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSClassLiteral"}}); } +void ETSClassLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ETSClassLiteral"); +} + void ETSClassLiteral::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsClassLiteral.h b/ets2panda/ir/ets/etsClassLiteral.h index e9262b2a6..592f3536f 100644 --- a/ets2panda/ir/ets/etsClassLiteral.h +++ b/ets2panda/ir/ets/etsClassLiteral.h @@ -48,6 +48,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsFunctionType.cpp b/ets2panda/ir/ets/etsFunctionType.cpp index adeff5d2b..0c6844b0a 100644 --- a/ets2panda/ir/ets/etsFunctionType.cpp +++ b/ets2panda/ir/ets/etsFunctionType.cpp @@ -20,6 +20,8 @@ #include "checker/ETSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ETSFunctionType::TransformChildren(const NodeTransformer &cb) @@ -44,6 +46,27 @@ void ETSFunctionType::Dump(ir::AstDumper *dumper) const } } +void ETSFunctionType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("("); + for (auto *param : Params()) { + param->Dump(dumper); + if (param != Params().back()) { + dumper->Add(", "); + } + } + dumper->Add(")"); + + if (TypeParams() != nullptr) { + TypeParams()->Dump(dumper); + } + + if (ReturnType() != nullptr) { + dumper->Add("=> "); + ReturnType()->Dump(dumper); + } +} + void ETSFunctionType::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsFunctionType.h b/ets2panda/ir/ets/etsFunctionType.h index ca70d6707..f52f97b59 100644 --- a/ets2panda/ir/ets/etsFunctionType.h +++ b/ets2panda/ir/ets/etsFunctionType.h @@ -96,6 +96,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsLaunchExpression.cpp b/ets2panda/ir/ets/etsLaunchExpression.cpp index 8c006c458..a492c7c3f 100644 --- a/ets2panda/ir/ets/etsLaunchExpression.cpp +++ b/ets2panda/ir/ets/etsLaunchExpression.cpp @@ -19,6 +19,8 @@ #include "compiler/core/ETSGen.h" #include "checker/ETSchecker.h" #include "checker/TSchecker.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { ETSLaunchExpression::ETSLaunchExpression(CallExpression *expr) @@ -41,6 +43,11 @@ void ETSLaunchExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSLaunchExpression"}, {"expr", expr_}}); } +void ETSLaunchExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ETSLaunchExpression"); +} + void ETSLaunchExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsLaunchExpression.h b/ets2panda/ir/ets/etsLaunchExpression.h index b8558ef6e..5f41d342c 100644 --- a/ets2panda/ir/ets/etsLaunchExpression.h +++ b/ets2panda/ir/ets/etsLaunchExpression.h @@ -50,6 +50,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp index 7ac314d18..51c56de94 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" namespace panda::es2panda::ir { @@ -41,6 +42,17 @@ void ETSNewArrayInstanceExpression::Dump(ir::AstDumper *dumper) const {{"type", "ETSNewArrayInstanceExpression"}, {"typeReference", type_reference_}, {"dimension", dimension_}}); } +void ETSNewArrayInstanceExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("new "); + ASSERT(type_reference_); + type_reference_->Dump(dumper); + ASSERT(dimension_); + dumper->Add("["); + dimension_->Dump(dumper); + dumper->Add("]"); +} + void ETSNewArrayInstanceExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.h b/ets2panda/ir/ets/etsNewArrayInstanceExpression.h index 6a5b70f03..50e8cbea1 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.h +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.h @@ -77,6 +77,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp b/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp index 21e9c8c6d..6d361fb6c 100644 --- a/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp @@ -19,6 +19,7 @@ #include "compiler/core/pandagen.h" #include "checker/TSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ETSNewClassInstanceExpression::TransformChildren(const NodeTransformer &cb) @@ -55,6 +56,22 @@ void ETSNewClassInstanceExpression::Dump(ir::AstDumper *dumper) const {"classBody", AstDumper::Optional(class_def_)}}); } +void ETSNewClassInstanceExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("new "); + if (type_reference_ != nullptr) { + type_reference_->Dump(dumper); + } + dumper->Add("("); + for (auto argument : arguments_) { + argument->Dump(dumper); + if (argument != arguments_.back()) { + dumper->Add(", "); + } + } + dumper->Add(")"); +} + void ETSNewClassInstanceExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsNewClassInstanceExpression.h b/ets2panda/ir/ets/etsNewClassInstanceExpression.h index 69b2bdd25..031531ca7 100644 --- a/ets2panda/ir/ets/etsNewClassInstanceExpression.h +++ b/ets2panda/ir/ets/etsNewClassInstanceExpression.h @@ -87,7 +87,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp index f927e2d41..4455ff7bb 100644 --- a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp @@ -19,6 +19,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ETSNewMultiDimArrayInstanceExpression::TransformChildren(const NodeTransformer &cb) @@ -44,6 +46,18 @@ void ETSNewMultiDimArrayInstanceExpression::Dump(ir::AstDumper *dumper) const {"dimensions", dimensions_}}); } +void ETSNewMultiDimArrayInstanceExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("new "); + ASSERT(type_reference_); + type_reference_->Dump(dumper); + for (auto dim : dimensions_) { + dumper->Add("["); + dim->Dump(dumper); + dumper->Add("]"); + } +} + void ETSNewMultiDimArrayInstanceExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.h b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.h index 189453beb..e031d1f23 100644 --- a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.h +++ b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.h @@ -89,7 +89,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsPackageDeclaration.cpp b/ets2panda/ir/ets/etsPackageDeclaration.cpp index b9fe930d9..27a44e419 100644 --- a/ets2panda/ir/ets/etsPackageDeclaration.cpp +++ b/ets2panda/ir/ets/etsPackageDeclaration.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ETSPackageDeclaration::TransformChildren(const NodeTransformer &cb) @@ -36,6 +37,14 @@ void ETSPackageDeclaration::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSPackageDeclaration"}, {"name", name_}}); } +void ETSPackageDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("package "); + name_->Dump(dumper); + dumper->Add(";"); + dumper->Endl(); +} + void ETSPackageDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsPackageDeclaration.h b/ets2panda/ir/ets/etsPackageDeclaration.h index b16b4a1d3..88d51f0c0 100644 --- a/ets2panda/ir/ets/etsPackageDeclaration.h +++ b/ets2panda/ir/ets/etsPackageDeclaration.h @@ -40,7 +40,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsParameterExpression.cpp b/ets2panda/ir/ets/etsParameterExpression.cpp index 6065a8a5c..23ac4ebd1 100644 --- a/ets2panda/ir/ets/etsParameterExpression.cpp +++ b/ets2panda/ir/ets/etsParameterExpression.cpp @@ -21,6 +21,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" #include "ir/expressions/identifier.h" #include "ir/base/spreadElement.h" @@ -143,6 +144,30 @@ void ETSParameterExpression::Dump(ir::AstDumper *const dumper) const } } +void ETSParameterExpression::Dump(ir::SrcDumper *const dumper) const +{ + if (IsRestParameter()) { + spread_->Dump(dumper); + } else { + if (ident_ != nullptr) { + ASSERT(ident_->IsAnnotatedExpression()); + ident_->Dump(dumper); + auto type_annotation = ident_->AsAnnotatedExpression()->TypeAnnotation(); + if (type_annotation != nullptr) { + dumper->Add(": "); + type_annotation->Dump(dumper); + } + } + if (initializer_ != nullptr) { + ASSERT(initializer_->IsNumberLiteral()); + if (initializer_->AsNumberLiteral()->Str().Length() > 0) { + dumper->Add(" = "); + initializer_->Dump(dumper); + } + } + } +} + void ETSParameterExpression::Compile(compiler::PandaGen *const pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsParameterExpression.h b/ets2panda/ir/ets/etsParameterExpression.h index a58975af4..2bbe07083 100644 --- a/ets2panda/ir/ets/etsParameterExpression.h +++ b/ets2panda/ir/ets/etsParameterExpression.h @@ -84,6 +84,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void TransformChildren(const NodeTransformer &cb) override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsPrimitiveType.cpp b/ets2panda/ir/ets/etsPrimitiveType.cpp index f8debf898..cf436280e 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.cpp +++ b/ets2panda/ir/ets/etsPrimitiveType.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ETSPrimitiveType::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -30,6 +31,41 @@ void ETSPrimitiveType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSPrimitiveType"}}); } +void ETSPrimitiveType::Dump(ir::SrcDumper *dumper) const +{ + switch (GetPrimitiveType()) { + case PrimitiveType::BYTE: + dumper->Add("byte"); + break; + case PrimitiveType::INT: + dumper->Add("int"); + break; + case PrimitiveType::LONG: + dumper->Add("long"); + break; + case PrimitiveType::SHORT: + dumper->Add("short"); + break; + case PrimitiveType::FLOAT: + dumper->Add("float"); + break; + case PrimitiveType::DOUBLE: + dumper->Add("double"); + break; + case PrimitiveType::BOOLEAN: + dumper->Add("boolean"); + break; + case PrimitiveType::CHAR: + dumper->Add("char"); + break; + case PrimitiveType::VOID: + dumper->Add("void"); + break; + default: + UNREACHABLE(); + } +} + void ETSPrimitiveType::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsPrimitiveType.h b/ets2panda/ir/ets/etsPrimitiveType.h index 57cef567c..15afb7350 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.h +++ b/ets2panda/ir/ets/etsPrimitiveType.h @@ -33,6 +33,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsStructDeclaration.cpp b/ets2panda/ir/ets/etsStructDeclaration.cpp index 14f7101ad..37026f4a6 100644 --- a/ets2panda/ir/ets/etsStructDeclaration.cpp +++ b/ets2panda/ir/ets/etsStructDeclaration.cpp @@ -20,6 +20,7 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/classDefinition.h" #include "ir/base/decorator.h" #include "ir/expressions/identifier.h" @@ -49,6 +50,11 @@ void ETSStructDeclaration::Dump(ir::AstDumper *dumper) const {{"type", "ETSStructDeclaration"}, {"definition", def_}, {"decorators", AstDumper::Optional(decorators_)}}); } +void ETSStructDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ETSStructDeclaration"); +} + void ETSStructDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsStructDeclaration.h b/ets2panda/ir/ets/etsStructDeclaration.h index 663f295b4..43159c057 100644 --- a/ets2panda/ir/ets/etsStructDeclaration.h +++ b/ets2panda/ir/ets/etsStructDeclaration.h @@ -74,7 +74,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; - + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; diff --git a/ets2panda/ir/ets/etsTuple.cpp b/ets2panda/ir/ets/etsTuple.cpp index e289cfd47..13c879a2b 100644 --- a/ets2panda/ir/ets/etsTuple.cpp +++ b/ets2panda/ir/ets/etsTuple.cpp @@ -50,6 +50,22 @@ void ETSTuple::Dump(ir::AstDumper *const dumper) const {"spreadType", AstDumper::Nullish(spread_type_)}}); } +void ETSTuple::Dump(ir::SrcDumper *const dumper) const +{ + dumper->Add("["); + for (auto type_annot : type_annotation_list_) { + type_annot->Dump(dumper); + if (type_annot != type_annotation_list_.back() || spread_type_ != nullptr) { + dumper->Add(", "); + } + } + if (spread_type_ != nullptr) { + dumper->Add("..."); + spread_type_->Dump(dumper); + } + dumper->Add(("]")); +} + void ETSTuple::Compile([[maybe_unused]] compiler::PandaGen *const pg) const {} void ETSTuple::Compile([[maybe_unused]] compiler::ETSGen *const etsg) const {} diff --git a/ets2panda/ir/ets/etsTuple.h b/ets2panda/ir/ets/etsTuple.h index b0d6dc9fb..ce5af95a3 100644 --- a/ets2panda/ir/ets/etsTuple.h +++ b/ets2panda/ir/ets/etsTuple.h @@ -68,6 +68,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsTypeReference.cpp b/ets2panda/ir/ets/etsTypeReference.cpp index c763b3b38..59b72fc8c 100644 --- a/ets2panda/ir/ets/etsTypeReference.cpp +++ b/ets2panda/ir/ets/etsTypeReference.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/ts/tsQualifiedName.h" #include "ir/ets/etsTypeReferencePart.h" @@ -34,7 +35,7 @@ void ETSTypeReference::Iterate(const NodeTraverser &cb) const cb(part_); } -ir::Identifier *ETSTypeReference::BaseName() +ir::Identifier *ETSTypeReference::BaseName() const { ir::ETSTypeReferencePart *part_iter = part_; @@ -62,6 +63,12 @@ void ETSTypeReference::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSTypeReference"}, {"part", part_}}); } +void ETSTypeReference::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(part_ != nullptr); + part_->Dump(dumper); +} + void ETSTypeReference::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsTypeReference.h b/ets2panda/ir/ets/etsTypeReference.h index d37661e37..40b9e6c8d 100644 --- a/ets2panda/ir/ets/etsTypeReference.h +++ b/ets2panda/ir/ets/etsTypeReference.h @@ -36,11 +36,12 @@ public: return part_; } - ir::Identifier *BaseName(); + ir::Identifier *BaseName() const; void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index add1f5003..767585e47 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -21,6 +21,8 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" +#include "macros.h" namespace panda::es2panda::ir { void ETSTypeReferencePart::TransformChildren(const NodeTransformer &cb) @@ -57,6 +59,15 @@ void ETSTypeReferencePart::Dump(ir::AstDumper *dumper) const {"previous", AstDumper::Optional(prev_)}}); } +void ETSTypeReferencePart::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(name_ != nullptr); + name_->Dump(dumper); + if (type_params_ != nullptr) { + type_params_->Dump(dumper); + } +} + void ETSTypeReferencePart::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsTypeReferencePart.h b/ets2panda/ir/ets/etsTypeReferencePart.h index c5a502644..4facc1a6d 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.h +++ b/ets2panda/ir/ets/etsTypeReferencePart.h @@ -58,6 +58,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsUnionType.cpp b/ets2panda/ir/ets/etsUnionType.cpp index 3b07a4446..1e00c17a7 100644 --- a/ets2panda/ir/ets/etsUnionType.cpp +++ b/ets2panda/ir/ets/etsUnionType.cpp @@ -17,6 +17,7 @@ #include "checker/ETSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ETSUnionType::TransformChildren(const NodeTransformer &cb) @@ -38,6 +39,16 @@ void ETSUnionType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ETSUnionType"}, {"types", types_}}); } +void ETSUnionType::Dump(ir::SrcDumper *dumper) const +{ + for (auto type : types_) { + type->Dump(dumper); + if (type != types_.back()) { + dumper->Add(" | "); + } + } +} + void ETSUnionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} checker::Type *ETSUnionType::Check([[maybe_unused]] checker::TSChecker *checker) diff --git a/ets2panda/ir/ets/etsUnionType.h b/ets2panda/ir/ets/etsUnionType.h index 9b0e96ff4..48b942d2c 100644 --- a/ets2panda/ir/ets/etsUnionType.h +++ b/ets2panda/ir/ets/etsUnionType.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; diff --git a/ets2panda/ir/ets/etsWildcardType.cpp b/ets2panda/ir/ets/etsWildcardType.cpp index 1ca767524..f8c5a1880 100644 --- a/ets2panda/ir/ets/etsWildcardType.cpp +++ b/ets2panda/ir/ets/etsWildcardType.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/ets/etsTypeReference.h" namespace panda::es2panda::ir { @@ -45,6 +46,11 @@ void ETSWildcardType::Dump(ir::AstDumper *dumper) const {"out", AstDumper::Optional(IsOut())}}); } +void ETSWildcardType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ETSWildcardType"); +} + void ETSWildcardType::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ets/etsWildcardType.h b/ets2panda/ir/ets/etsWildcardType.h index b380fd348..d633409a4 100644 --- a/ets2panda/ir/ets/etsWildcardType.h +++ b/ets2panda/ir/ets/etsWildcardType.h @@ -37,6 +37,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/arrayExpression.cpp b/ets2panda/ir/expressions/arrayExpression.cpp index e620acd9e..b1b2ef87a 100644 --- a/ets2panda/ir/expressions/arrayExpression.cpp +++ b/ets2panda/ir/expressions/arrayExpression.cpp @@ -24,11 +24,12 @@ #include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "ir/base/decorator.h" +#include "ir/srcDump.h" +#include "ir/typeNode.h" #include "ir/base/spreadElement.h" #include "ir/expressions/assignmentExpression.h" #include "ir/expressions/identifier.h" #include "ir/expressions/objectExpression.h" -#include "ir/typeNode.h" #include "util/helpers.h" namespace panda::es2panda::ir { @@ -204,6 +205,18 @@ void ArrayExpression::Dump(ir::AstDumper *dumper) const {"optional", AstDumper::Optional(optional_)}}); } +void ArrayExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("["); + for (auto element : elements_) { + element->Dump(dumper); + if (element != elements_.back()) { + dumper->Add(", "); + } + } + dumper->Add("]"); +} + void ArrayExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/arrayExpression.h b/ets2panda/ir/expressions/arrayExpression.h index 50284260f..cd5f4132d 100644 --- a/ets2panda/ir/expressions/arrayExpression.h +++ b/ets2panda/ir/expressions/arrayExpression.h @@ -126,6 +126,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/arrowFunctionExpression.cpp b/ets2panda/ir/expressions/arrowFunctionExpression.cpp index 83a1873db..7d568360b 100644 --- a/ets2panda/ir/expressions/arrowFunctionExpression.cpp +++ b/ets2panda/ir/expressions/arrowFunctionExpression.cpp @@ -21,6 +21,7 @@ #include "checker/ets/typeRelationContext.h" #include "checker/TSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/scriptFunction.h" #include "ir/ets/etsTypeReference.h" #include "ir/ets/etsTypeReferencePart.h" @@ -44,6 +45,11 @@ void ArrowFunctionExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ArrowFunctionExpression"}, {"function", func_}}); } +void ArrowFunctionExpression::Dump(ir::SrcDumper *dumper) const +{ + func_->Dump(dumper); +} + void ArrowFunctionExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/arrowFunctionExpression.h b/ets2panda/ir/expressions/arrowFunctionExpression.h index e7cd2df79..bc4051939 100644 --- a/ets2panda/ir/expressions/arrowFunctionExpression.h +++ b/ets2panda/ir/expressions/arrowFunctionExpression.h @@ -89,6 +89,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/assignmentExpression.cpp b/ets2panda/ir/expressions/assignmentExpression.cpp index 175f28f0f..d916ecf58 100644 --- a/ets2panda/ir/expressions/assignmentExpression.cpp +++ b/ets2panda/ir/expressions/assignmentExpression.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/regScope.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/scriptFunction.h" #include "ir/base/spreadElement.h" #include "ir/expressions/identifier.h" @@ -119,6 +120,17 @@ void AssignmentExpression::Dump(ir::AstDumper *dumper) const } } +void AssignmentExpression::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(left_); + left_->Dump(dumper); + dumper->Add(" "); + dumper->Add(TokenToString(operator_)); + dumper->Add(" "); + ASSERT(right_); + right_->Dump(dumper); +} + void AssignmentExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/assignmentExpression.h b/ets2panda/ir/expressions/assignmentExpression.h index 86a514565..976f93ca5 100644 --- a/ets2panda/ir/expressions/assignmentExpression.h +++ b/ets2panda/ir/expressions/assignmentExpression.h @@ -120,6 +120,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; void CompilePattern(compiler::PandaGen *pg) const; diff --git a/ets2panda/ir/expressions/awaitExpression.cpp b/ets2panda/ir/expressions/awaitExpression.cpp index f0fac3d9b..5048bd86c 100644 --- a/ets2panda/ir/expressions/awaitExpression.cpp +++ b/ets2panda/ir/expressions/awaitExpression.cpp @@ -19,6 +19,7 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void AwaitExpression::TransformChildren(const NodeTransformer &cb) @@ -40,6 +41,11 @@ void AwaitExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "AwaitExpression"}, {"argument", AstDumper::Nullish(argument_)}}); } +void AwaitExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("AwaitExpression"); +} + void AwaitExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/awaitExpression.h b/ets2panda/ir/expressions/awaitExpression.h index 1a0a6c46c..ab1160ad3 100644 --- a/ets2panda/ir/expressions/awaitExpression.h +++ b/ets2panda/ir/expressions/awaitExpression.h @@ -47,6 +47,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/binaryExpression.cpp b/ets2panda/ir/expressions/binaryExpression.cpp index 4da4ae6df..8375458ce 100644 --- a/ets2panda/ir/expressions/binaryExpression.cpp +++ b/ets2panda/ir/expressions/binaryExpression.cpp @@ -18,6 +18,8 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "checker/TSchecker.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void BinaryExpression::TransformChildren(const NodeTransformer &cb) @@ -40,6 +42,19 @@ void BinaryExpression::Dump(ir::AstDumper *dumper) const {"right", right_}}); } +void BinaryExpression::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(left_ != nullptr); + ASSERT(right_ != nullptr); + dumper->Add("("); + left_->Dump(dumper); + dumper->Add(" "); + dumper->Add(TokenToString(operator_)); + dumper->Add(" "); + right_->Dump(dumper); + dumper->Add(")"); +} + void BinaryExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/binaryExpression.h b/ets2panda/ir/expressions/binaryExpression.h index 89849ee78..82a2f61ba 100644 --- a/ets2panda/ir/expressions/binaryExpression.h +++ b/ets2panda/ir/expressions/binaryExpression.h @@ -148,6 +148,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/blockExpression.cpp b/ets2panda/ir/expressions/blockExpression.cpp index 02e3ff477..f20c401f6 100644 --- a/ets2panda/ir/expressions/blockExpression.cpp +++ b/ets2panda/ir/expressions/blockExpression.cpp @@ -16,6 +16,7 @@ #include "blockExpression.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "compiler/core/ETSGen.h" #include "checker/ETSchecker.h" #include "ir/astNode.h" @@ -70,6 +71,16 @@ void BlockExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "BlockExpression"}, {"statements", statements_}}); } +void BlockExpression::Dump(ir::SrcDumper *dumper) const +{ + for (auto *statement : statements_) { + statement->Dump(dumper); + if (statement != statements_.back()) { + dumper->Endl(); + } + } +} + void BlockExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const { UNREACHABLE(); diff --git a/ets2panda/ir/expressions/blockExpression.h b/ets2panda/ir/expressions/blockExpression.h index 9e0a892b9..6c6329ccd 100644 --- a/ets2panda/ir/expressions/blockExpression.h +++ b/ets2panda/ir/expressions/blockExpression.h @@ -47,6 +47,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/callExpression.cpp b/ets2panda/ir/expressions/callExpression.cpp index ede576373..fc1be7c61 100644 --- a/ets2panda/ir/expressions/callExpression.cpp +++ b/ets2panda/ir/expressions/callExpression.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void CallExpression::TransformChildren(const NodeTransformer &cb) @@ -59,6 +61,20 @@ void CallExpression::Dump(ir::AstDumper *dumper) const {"typeParameters", AstDumper::Optional(type_params_)}}); } +void CallExpression::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(callee_); + callee_->Dump(dumper); + dumper->Add("("); + for (auto arg : arguments_) { + arg->Dump(dumper); + if (arg != arguments_.back()) { + dumper->Add(", "); + } + } + dumper->Add(")"); +} + void CallExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/callExpression.h b/ets2panda/ir/expressions/callExpression.h index fc2add288..067c7fda4 100644 --- a/ets2panda/ir/expressions/callExpression.h +++ b/ets2panda/ir/expressions/callExpression.h @@ -148,6 +148,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/chainExpression.cpp b/ets2panda/ir/expressions/chainExpression.cpp index c7bddde72..0c2ee1a5d 100644 --- a/ets2panda/ir/expressions/chainExpression.cpp +++ b/ets2panda/ir/expressions/chainExpression.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/memberExpression.h" namespace panda::es2panda::ir { @@ -37,6 +38,11 @@ void ChainExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ChainExpression"}, {"expression", expression_}}); } +void ChainExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ChainExpression"); +} + void ChainExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/chainExpression.h b/ets2panda/ir/expressions/chainExpression.h index 33e41e4cd..0bd2bdb17 100644 --- a/ets2panda/ir/expressions/chainExpression.h +++ b/ets2panda/ir/expressions/chainExpression.h @@ -51,6 +51,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; void CompileToReg(compiler::PandaGen *pg, compiler::VReg &obj_reg) const; diff --git a/ets2panda/ir/expressions/classExpression.cpp b/ets2panda/ir/expressions/classExpression.cpp index b2fb7234f..6caf00999 100644 --- a/ets2panda/ir/expressions/classExpression.cpp +++ b/ets2panda/ir/expressions/classExpression.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ClassExpression::TransformChildren(const NodeTransformer &cb) @@ -36,6 +37,11 @@ void ClassExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ClassExpression"}, {"definition", def_}}); } +void ClassExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ClassExpression"); +} + void ClassExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/classExpression.h b/ets2panda/ir/expressions/classExpression.h index 4970733dc..3277ec23a 100644 --- a/ets2panda/ir/expressions/classExpression.h +++ b/ets2panda/ir/expressions/classExpression.h @@ -43,6 +43,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/conditionalExpression.cpp b/ets2panda/ir/expressions/conditionalExpression.cpp index 7c6c572c9..c75255d97 100644 --- a/ets2panda/ir/expressions/conditionalExpression.cpp +++ b/ets2panda/ir/expressions/conditionalExpression.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ConditionalExpression::TransformChildren(const NodeTransformer &cb) @@ -40,6 +42,26 @@ void ConditionalExpression::Dump(ir::AstDumper *dumper) const {{"type", "ConditionalExpression"}, {"test", test_}, {"consequent", consequent_}, {"alternate", alternate_}}); } +void ConditionalExpression::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(test_ != nullptr); + dumper->Add("("); + test_->Dump(dumper); + dumper->Add(" ? "); + if (consequent_ != nullptr) { + consequent_->Dump(dumper); + } + dumper->Add(" : "); + if (alternate_ != nullptr) { + alternate_->Dump(dumper); + } + dumper->Add(")"); + if ((parent_ != nullptr) && (parent_->IsBlockStatement() || parent_->IsBlockExpression())) { + dumper->Add(";"); + dumper->Endl(); + } +} + void ConditionalExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/conditionalExpression.h b/ets2panda/ir/expressions/conditionalExpression.h index 19cab1b07..58d76d14d 100644 --- a/ets2panda/ir/expressions/conditionalExpression.h +++ b/ets2panda/ir/expressions/conditionalExpression.h @@ -72,6 +72,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; diff --git a/ets2panda/ir/expressions/functionExpression.cpp b/ets2panda/ir/expressions/functionExpression.cpp index f8add6e72..243a94df4 100644 --- a/ets2panda/ir/expressions/functionExpression.cpp +++ b/ets2panda/ir/expressions/functionExpression.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void FunctionExpression::TransformChildren(const NodeTransformer &cb) @@ -36,6 +37,11 @@ void FunctionExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "FunctionExpression"}, {"function", func_}}); } +void FunctionExpression::Dump(ir::SrcDumper *dumper) const +{ + func_->Dump(dumper); +} + void FunctionExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/functionExpression.h b/ets2panda/ir/expressions/functionExpression.h index 754e520e3..265bdc5fd 100644 --- a/ets2panda/ir/expressions/functionExpression.h +++ b/ets2panda/ir/expressions/functionExpression.h @@ -65,6 +65,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/identifier.cpp b/ets2panda/ir/expressions/identifier.cpp index 1913c2e1a..03d77fb78 100644 --- a/ets2panda/ir/expressions/identifier.cpp +++ b/ets2panda/ir/expressions/identifier.cpp @@ -20,6 +20,8 @@ #include "checker/TSchecker.h" #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { Identifier::Identifier([[maybe_unused]] Tag const tag, Identifier const &other, ArenaAllocator *const allocator) @@ -91,6 +93,17 @@ void Identifier::Dump(ir::AstDumper *dumper) const {"decorators", decorators_}}); } +void Identifier::Dump(ir::SrcDumper *dumper) const +{ + if (IsPrivateIdent()) { + dumper->Add("private "); + } + dumper->Add(std::string(name_)); + if (IsOptional()) { + dumper->Add("?"); + } +} + void Identifier::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/identifier.h b/ets2panda/ir/expressions/identifier.h index 7c4709964..acbb027f9 100644 --- a/ets2panda/ir/expressions/identifier.h +++ b/ets2panda/ir/expressions/identifier.h @@ -203,6 +203,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/importExpression.cpp b/ets2panda/ir/expressions/importExpression.cpp index c9d711027..21a048c90 100644 --- a/ets2panda/ir/expressions/importExpression.cpp +++ b/ets2panda/ir/expressions/importExpression.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ImportExpression::TransformChildren(const NodeTransformer &cb) @@ -35,6 +37,11 @@ void ImportExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ImportExpression"}, {"source", source_}}); } +void ImportExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ImportExpression"); +} + void ImportExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/importExpression.h b/ets2panda/ir/expressions/importExpression.h index c4a099ade..4ac17ab18 100644 --- a/ets2panda/ir/expressions/importExpression.h +++ b/ets2panda/ir/expressions/importExpression.h @@ -40,6 +40,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/literals/bigIntLiteral.cpp b/ets2panda/ir/expressions/literals/bigIntLiteral.cpp index b721e9db2..a12339916 100644 --- a/ets2panda/ir/expressions/literals/bigIntLiteral.cpp +++ b/ets2panda/ir/expressions/literals/bigIntLiteral.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void BigIntLiteral::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -29,6 +30,11 @@ void BigIntLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "BigIntLiteral"}, {"value", src_}}); } +void BigIntLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add(std::string(src_)); +} + void BigIntLiteral::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/literals/bigIntLiteral.h b/ets2panda/ir/expressions/literals/bigIntLiteral.h index 1180cc788..0ae06c264 100644 --- a/ets2panda/ir/expressions/literals/bigIntLiteral.h +++ b/ets2panda/ir/expressions/literals/bigIntLiteral.h @@ -41,6 +41,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/literals/booleanLiteral.cpp b/ets2panda/ir/expressions/literals/booleanLiteral.cpp index 1eb3eee72..40bfa7bc6 100644 --- a/ets2panda/ir/expressions/literals/booleanLiteral.cpp +++ b/ets2panda/ir/expressions/literals/booleanLiteral.cpp @@ -20,6 +20,7 @@ #include "checker/TSchecker.h" #include "checker/ETSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void BooleanLiteral::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -30,6 +31,11 @@ void BooleanLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "BooleanLiteral"}, {"value", boolean_}}); } +void BooleanLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add(boolean_ ? "true" : "false"); +} + void BooleanLiteral::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/literals/booleanLiteral.h b/ets2panda/ir/expressions/literals/booleanLiteral.h index 8974de165..88f62c6bf 100644 --- a/ets2panda/ir/expressions/literals/booleanLiteral.h +++ b/ets2panda/ir/expressions/literals/booleanLiteral.h @@ -40,6 +40,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/literals/charLiteral.cpp b/ets2panda/ir/expressions/literals/charLiteral.cpp index 0a6adcf98..ce4be05ff 100644 --- a/ets2panda/ir/expressions/literals/charLiteral.cpp +++ b/ets2panda/ir/expressions/literals/charLiteral.cpp @@ -20,7 +20,9 @@ #include "compiler/core/ETSGen.h" #include "checker/ETSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" +#include #include namespace panda::es2panda::ir { @@ -32,6 +34,11 @@ void CharLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "CharLiteral"}, {"value", char_}}); } +void CharLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add(std::to_string(char_)); +} + void CharLiteral::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/literals/charLiteral.h b/ets2panda/ir/expressions/literals/charLiteral.h index 619acec7b..629e1a0d0 100644 --- a/ets2panda/ir/expressions/literals/charLiteral.h +++ b/ets2panda/ir/expressions/literals/charLiteral.h @@ -46,6 +46,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/literals/nullLiteral.cpp b/ets2panda/ir/expressions/literals/nullLiteral.cpp index f04d88b76..74c0e5781 100644 --- a/ets2panda/ir/expressions/literals/nullLiteral.cpp +++ b/ets2panda/ir/expressions/literals/nullLiteral.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void NullLiteral::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void NullLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "NullLiteral"}, {"value", AstDumper::Property::Constant::PROP_NULL}}); } +void NullLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("null"); +} + void NullLiteral::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/literals/nullLiteral.h b/ets2panda/ir/expressions/literals/nullLiteral.h index 9089ec475..4fb46bb41 100644 --- a/ets2panda/ir/expressions/literals/nullLiteral.h +++ b/ets2panda/ir/expressions/literals/nullLiteral.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/literals/numberLiteral.cpp b/ets2panda/ir/expressions/literals/numberLiteral.cpp index af42b4f51..dc7e40501 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.cpp +++ b/ets2panda/ir/expressions/literals/numberLiteral.cpp @@ -14,10 +14,13 @@ */ #include "numberLiteral.h" +#include #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void NumberLiteral::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +31,29 @@ void NumberLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "NumberLiteral"}, {"value", number_}}); } +void NumberLiteral::Dump(ir::SrcDumper *dumper) const +{ + if (number_.IsInt()) { + dumper->Add(number_.GetInt()); + return; + } + + if (number_.IsLong()) { + dumper->Add(number_.GetLong()); + return; + } + + if (number_.IsFloat()) { + dumper->Add(number_.GetFloat()); + return; + } + + if (number_.IsDouble()) { + dumper->Add(number_.GetDouble()); + return; + } +} + void NumberLiteral::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/literals/numberLiteral.h b/ets2panda/ir/expressions/literals/numberLiteral.h index 6b05f8e34..0abcbbce6 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.h +++ b/ets2panda/ir/expressions/literals/numberLiteral.h @@ -55,6 +55,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/literals/regExpLiteral.cpp b/ets2panda/ir/expressions/literals/regExpLiteral.cpp index 353d8fabb..d735658aa 100644 --- a/ets2panda/ir/expressions/literals/regExpLiteral.cpp +++ b/ets2panda/ir/expressions/literals/regExpLiteral.cpp @@ -20,6 +20,8 @@ #include "compiler/core/regScope.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void RegExpLiteral::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -30,6 +32,11 @@ void RegExpLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "RegExpLiteral"}, {"source", pattern_}, {"flags", flags_str_}}); } +void RegExpLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add(std::string(pattern_)); +} + void RegExpLiteral::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/literals/regExpLiteral.h b/ets2panda/ir/expressions/literals/regExpLiteral.h index 57be86c6c..19b8582d1 100644 --- a/ets2panda/ir/expressions/literals/regExpLiteral.h +++ b/ets2panda/ir/expressions/literals/regExpLiteral.h @@ -50,6 +50,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/literals/stringLiteral.cpp b/ets2panda/ir/expressions/literals/stringLiteral.cpp index 1406de9d8..995b112d9 100644 --- a/ets2panda/ir/expressions/literals/stringLiteral.cpp +++ b/ets2panda/ir/expressions/literals/stringLiteral.cpp @@ -14,10 +14,14 @@ */ #include "stringLiteral.h" +#include #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" +#include "macros.h" namespace panda::es2panda::ir { void StringLiteral::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +32,41 @@ void StringLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "StringLiteral"}, {"value", str_}}); } +void StringLiteral::Dump(ir::SrcDumper *dumper) const +{ + std::string str(str_); + std::string escaped_str; + escaped_str.push_back('\"'); + for (size_t i = 0, j = str_.Length(); i < j; ++i) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + const char c = str_.Bytes()[i]; + // check if a given character is printable + // the cast is necessary to avoid undefined behaviour + if (std::isprint(static_cast(c)) != 0U) { + escaped_str.push_back(c); + } else { + escaped_str.push_back('\\'); + if (c == '\n') { + escaped_str.push_back('n'); + } else if (c == '\t') { + escaped_str.push_back('t'); + } else if (c == '\v') { + escaped_str.push_back('v'); + } else if (c == '\f') { + escaped_str.push_back('f'); + } else if (c == '\r') { + escaped_str.push_back('r'); + } else if (c == '\0') { + escaped_str.push_back('0'); + } else { + UNREACHABLE(); + } + } + } + escaped_str.push_back('\"'); + dumper->Add(escaped_str); +} + void StringLiteral::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/literals/stringLiteral.h b/ets2panda/ir/expressions/literals/stringLiteral.h index 09a19409d..081eed374 100644 --- a/ets2panda/ir/expressions/literals/stringLiteral.h +++ b/ets2panda/ir/expressions/literals/stringLiteral.h @@ -47,6 +47,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/literals/undefinedLiteral.cpp b/ets2panda/ir/expressions/literals/undefinedLiteral.cpp index 2b2bc2ccc..27bddb8b4 100644 --- a/ets2panda/ir/expressions/literals/undefinedLiteral.cpp +++ b/ets2panda/ir/expressions/literals/undefinedLiteral.cpp @@ -20,6 +20,7 @@ #include "checker/TSchecker.h" #include "checker/ETSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void UndefinedLiteral::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -30,6 +31,11 @@ void UndefinedLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "UndefinedLiteral"}, {"value", AstDumper::Property::Constant::PROP_UNDEFINED}}); } +void UndefinedLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("undefined"); +} + void UndefinedLiteral::Compile(compiler::PandaGen *pg) const { pg->LoadConst(this, compiler::Constant::JS_UNDEFINED); diff --git a/ets2panda/ir/expressions/literals/undefinedLiteral.h b/ets2panda/ir/expressions/literals/undefinedLiteral.h index 3393da272..818867cde 100644 --- a/ets2panda/ir/expressions/literals/undefinedLiteral.h +++ b/ets2panda/ir/expressions/literals/undefinedLiteral.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index f099705db..90a9fb501 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -19,6 +19,8 @@ #include "checker/ets/castingContext.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { MemberExpression::MemberExpression([[maybe_unused]] Tag const tag, MemberExpression const &other, @@ -62,6 +64,29 @@ void MemberExpression::Dump(ir::AstDumper *dumper) const {"optional", IsOptional()}}); } +void MemberExpression::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(object_ != nullptr); + ASSERT(property_ != nullptr); + + object_->Dump(dumper); + if (IsOptional()) { + dumper->Add("?"); + } + if ((MemberExpressionKind::ELEMENT_ACCESS & kind_) != 0U) { + dumper->Add("["); + property_->Dump(dumper); + dumper->Add("]"); + } else { + dumper->Add("."); + property_->Dump(dumper); + } + if ((parent_ != nullptr) && (parent_->IsBlockStatement() || parent_->IsBlockExpression())) { + dumper->Add(";"); + dumper->Endl(); + } +} + void MemberExpression::LoadRhs(compiler::PandaGen *pg) const { compiler::RegScope rs(pg); diff --git a/ets2panda/ir/expressions/memberExpression.h b/ets2panda/ir/expressions/memberExpression.h index b59de6358..57305e315 100644 --- a/ets2panda/ir/expressions/memberExpression.h +++ b/ets2panda/ir/expressions/memberExpression.h @@ -173,6 +173,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; bool CompileComputed(compiler::ETSGen *etsg) const; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; diff --git a/ets2panda/ir/expressions/newExpression.cpp b/ets2panda/ir/expressions/newExpression.cpp index 5959c7ffc..f56cdeb80 100644 --- a/ets2panda/ir/expressions/newExpression.cpp +++ b/ets2panda/ir/expressions/newExpression.cpp @@ -19,6 +19,8 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "util/helpers.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { NewExpression::NewExpression([[maybe_unused]] Tag const tag, NewExpression const &other, @@ -69,6 +71,11 @@ void NewExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "NewExpression"}, {"callee", callee_}, {"arguments", arguments_}}); } +void NewExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("NewExpression"); +} + void NewExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/newExpression.h b/ets2panda/ir/expressions/newExpression.h index 2fe51c8b6..a1d974cd3 100644 --- a/ets2panda/ir/expressions/newExpression.h +++ b/ets2panda/ir/expressions/newExpression.h @@ -59,6 +59,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/objectExpression.cpp b/ets2panda/ir/expressions/objectExpression.cpp index 18c4b4010..c9fc9d1ea 100644 --- a/ets2panda/ir/expressions/objectExpression.cpp +++ b/ets2panda/ir/expressions/objectExpression.cpp @@ -25,6 +25,7 @@ #include "checker/ets/typeRelationContext.h" #include "checker/ts/destructuringContext.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" #include "ir/base/property.h" #include "ir/base/scriptFunction.h" @@ -229,6 +230,11 @@ void ObjectExpression::Dump(ir::AstDumper *dumper) const {"optional", AstDumper::Optional(optional_)}}); } +void ObjectExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ObjectExpression"); +} + void ObjectExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/objectExpression.h b/ets2panda/ir/expressions/objectExpression.h index 0791b2262..9f8892ac5 100644 --- a/ets2panda/ir/expressions/objectExpression.h +++ b/ets2panda/ir/expressions/objectExpression.h @@ -106,6 +106,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/omittedExpression.cpp b/ets2panda/ir/expressions/omittedExpression.cpp index babc86133..0ab3d1f33 100644 --- a/ets2panda/ir/expressions/omittedExpression.cpp +++ b/ets2panda/ir/expressions/omittedExpression.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void OmittedExpression::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void OmittedExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "OmittedExpression"}}); } +void OmittedExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("OmittedExpression"); +} + void OmittedExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/omittedExpression.h b/ets2panda/ir/expressions/omittedExpression.h index 10e0a39e9..4f1f340b7 100644 --- a/ets2panda/ir/expressions/omittedExpression.h +++ b/ets2panda/ir/expressions/omittedExpression.h @@ -35,6 +35,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/sequenceExpression.cpp b/ets2panda/ir/expressions/sequenceExpression.cpp index 477f6ef9d..383020425 100644 --- a/ets2panda/ir/expressions/sequenceExpression.cpp +++ b/ets2panda/ir/expressions/sequenceExpression.cpp @@ -19,6 +19,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { SequenceExpression::SequenceExpression([[maybe_unused]] Tag const tag, SequenceExpression const &other, @@ -61,6 +63,16 @@ void SequenceExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "SequenceExpression"}, {"expressions", sequence_}}); } +void SequenceExpression::Dump(ir::SrcDumper *dumper) const +{ + for (auto *expr : sequence_) { + expr->Dump(dumper); + if (expr != sequence_.back()) { + dumper->Add(", "); + } + } +} + void SequenceExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/sequenceExpression.h b/ets2panda/ir/expressions/sequenceExpression.h index e34c0f7a1..98c53be09 100644 --- a/ets2panda/ir/expressions/sequenceExpression.h +++ b/ets2panda/ir/expressions/sequenceExpression.h @@ -53,6 +53,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/superExpression.cpp b/ets2panda/ir/expressions/superExpression.cpp index 1b5c777ab..02e824431 100644 --- a/ets2panda/ir/expressions/superExpression.cpp +++ b/ets2panda/ir/expressions/superExpression.cpp @@ -20,6 +20,8 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "util/helpers.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void SuperExpression::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -30,6 +32,11 @@ void SuperExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "Super"}}); } +void SuperExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("super"); +} + void SuperExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/superExpression.h b/ets2panda/ir/expressions/superExpression.h index a5582fdad..29d12a994 100644 --- a/ets2panda/ir/expressions/superExpression.h +++ b/ets2panda/ir/expressions/superExpression.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/taggedTemplateExpression.cpp b/ets2panda/ir/expressions/taggedTemplateExpression.cpp index f13baf1d4..1a4100fab 100644 --- a/ets2panda/ir/expressions/taggedTemplateExpression.cpp +++ b/ets2panda/ir/expressions/taggedTemplateExpression.cpp @@ -22,6 +22,7 @@ #include "compiler/core/regScope.h" #include "checker/TSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/memberExpression.h" #include "ir/expressions/templateLiteral.h" #include "ir/ts/tsTypeParameterInstantiation.h" @@ -55,6 +56,11 @@ void TaggedTemplateExpression::Dump(ir::AstDumper *dumper) const {"typeParameters", AstDumper::Optional(type_params_)}}); } +void TaggedTemplateExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TaggedTemplateExpression"); +} + void TaggedTemplateExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/taggedTemplateExpression.h b/ets2panda/ir/expressions/taggedTemplateExpression.h index 5db6b4774..3d69e696e 100644 --- a/ets2panda/ir/expressions/taggedTemplateExpression.h +++ b/ets2panda/ir/expressions/taggedTemplateExpression.h @@ -57,6 +57,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/templateLiteral.cpp b/ets2panda/ir/expressions/templateLiteral.cpp index e6bbee9f4..732c96706 100644 --- a/ets2panda/ir/expressions/templateLiteral.cpp +++ b/ets2panda/ir/expressions/templateLiteral.cpp @@ -20,6 +20,7 @@ #include "checker/TSchecker.h" #include "checker/ETSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/templateElement.h" namespace panda::es2panda::ir { @@ -77,6 +78,11 @@ void TemplateLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TemplateLiteral"}, {"expressions", expressions_}, {"quasis", quasis_}}); } +void TemplateLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TemplateLiteral"); +} + void TemplateLiteral::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/templateLiteral.h b/ets2panda/ir/expressions/templateLiteral.h index 7eb13149a..046ea69c4 100644 --- a/ets2panda/ir/expressions/templateLiteral.h +++ b/ets2panda/ir/expressions/templateLiteral.h @@ -54,6 +54,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/thisExpression.cpp b/ets2panda/ir/expressions/thisExpression.cpp index d8013b9d7..9598cea01 100644 --- a/ets2panda/ir/expressions/thisExpression.cpp +++ b/ets2panda/ir/expressions/thisExpression.cpp @@ -26,6 +26,7 @@ #include "ir/base/methodDefinition.h" #include "ir/statements/blockStatement.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/callExpression.h" namespace panda::es2panda::ir { @@ -37,6 +38,11 @@ void ThisExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ThisExpression"}}); } +void ThisExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("this"); +} + void ThisExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/thisExpression.h b/ets2panda/ir/expressions/thisExpression.h index 061866025..51ab04112 100644 --- a/ets2panda/ir/expressions/thisExpression.h +++ b/ets2panda/ir/expressions/thisExpression.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/unaryExpression.cpp b/ets2panda/ir/expressions/unaryExpression.cpp index b76d05d63..82601c41b 100644 --- a/ets2panda/ir/expressions/unaryExpression.cpp +++ b/ets2panda/ir/expressions/unaryExpression.cpp @@ -21,6 +21,7 @@ #include "checker/TSchecker.h" #include "checker/ETSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/identifier.h" #include "ir/expressions/literals/bigIntLiteral.h" #include "ir/expressions/literals/numberLiteral.h" @@ -43,6 +44,12 @@ void UnaryExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "UnaryExpression"}, {"operator", operator_}, {"prefix", true}, {"argument", argument_}}); } +void UnaryExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add(TokenToString(operator_)); + argument_->Dump(dumper); +} + void UnaryExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/unaryExpression.h b/ets2panda/ir/expressions/unaryExpression.h index b15dd94fd..b53c8c8de 100644 --- a/ets2panda/ir/expressions/unaryExpression.h +++ b/ets2panda/ir/expressions/unaryExpression.h @@ -64,6 +64,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/updateExpression.cpp b/ets2panda/ir/expressions/updateExpression.cpp index 4f1fffbb8..5453e7543 100644 --- a/ets2panda/ir/expressions/updateExpression.cpp +++ b/ets2panda/ir/expressions/updateExpression.cpp @@ -15,6 +15,7 @@ #include "updateExpression.h" +#include "macros.h" #include "varbinder/variable.h" #include "compiler/base/lreference.h" #include "compiler/core/pandagen.h" @@ -23,6 +24,7 @@ #include "checker/TSchecker.h" #include "checker/ETSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/unaryExpression.h" #include "ir/ts/tsAsExpression.h" #include "ir/expressions/identifier.h" @@ -44,6 +46,18 @@ void UpdateExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "UpdateExpression"}, {"operator", operator_}, {"prefix", prefix_}, {"argument", argument_}}); } +void UpdateExpression::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(argument_); + if (prefix_) { + dumper->Add(TokenToString(operator_)); + argument_->Dump(dumper); + } else { + argument_->Dump(dumper); + dumper->Add(TokenToString(operator_)); + } +} + void UpdateExpression::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/updateExpression.h b/ets2panda/ir/expressions/updateExpression.h index 75300e97f..553d77315 100644 --- a/ets2panda/ir/expressions/updateExpression.h +++ b/ets2panda/ir/expressions/updateExpression.h @@ -71,6 +71,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/expressions/yieldExpression.cpp b/ets2panda/ir/expressions/yieldExpression.cpp index 74b627b91..36ce163da 100644 --- a/ets2panda/ir/expressions/yieldExpression.cpp +++ b/ets2panda/ir/expressions/yieldExpression.cpp @@ -20,6 +20,8 @@ #include "compiler/function/generatorFunctionBuilder.h" #include "checker/TSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" + namespace panda::es2panda::ir { void YieldExpression::TransformChildren(const NodeTransformer &cb) { @@ -40,6 +42,11 @@ void YieldExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "YieldExpression"}, {"delegate", delegate_}, {"argument", AstDumper::Nullish(argument_)}}); } +void YieldExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("YieldExpression"); +} + void YieldExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/expressions/yieldExpression.h b/ets2panda/ir/expressions/yieldExpression.h index 25a10a6e0..1f78687a9 100644 --- a/ets2panda/ir/expressions/yieldExpression.h +++ b/ets2panda/ir/expressions/yieldExpression.h @@ -52,6 +52,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/module/exportAllDeclaration.cpp b/ets2panda/ir/module/exportAllDeclaration.cpp index c34cb356e..4ffeaef3a 100644 --- a/ets2panda/ir/module/exportAllDeclaration.cpp +++ b/ets2panda/ir/module/exportAllDeclaration.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ExportAllDeclaration::TransformChildren(const NodeTransformer &cb) @@ -43,6 +45,11 @@ void ExportAllDeclaration::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ExportAllDeclaration"}, {"source", source_}, {"exported", AstDumper::Nullish(exported_)}}); } +void ExportAllDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ExportAllDeclaration"); +} + void ExportAllDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/module/exportAllDeclaration.h b/ets2panda/ir/module/exportAllDeclaration.h index a472a1fd5..12e40b170 100644 --- a/ets2panda/ir/module/exportAllDeclaration.h +++ b/ets2panda/ir/module/exportAllDeclaration.h @@ -42,6 +42,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/module/exportDefaultDeclaration.cpp b/ets2panda/ir/module/exportDefaultDeclaration.cpp index 82e090025..5506246c5 100644 --- a/ets2panda/ir/module/exportDefaultDeclaration.cpp +++ b/ets2panda/ir/module/exportDefaultDeclaration.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ExportDefaultDeclaration::TransformChildren(const NodeTransformer &cb) @@ -36,6 +38,11 @@ void ExportDefaultDeclaration::Dump(ir::AstDumper *dumper) const {{"type", IsExportEquals() ? "TSExportAssignment" : "ExportDefaultDeclaration"}, {"declaration", decl_}}); } +void ExportDefaultDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ExportDefaultDeclaration"); +} + void ExportDefaultDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/module/exportDefaultDeclaration.h b/ets2panda/ir/module/exportDefaultDeclaration.h index 532098f02..b92eff136 100644 --- a/ets2panda/ir/module/exportDefaultDeclaration.h +++ b/ets2panda/ir/module/exportDefaultDeclaration.h @@ -44,6 +44,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/module/exportNamedDeclaration.cpp b/ets2panda/ir/module/exportNamedDeclaration.cpp index ff886326f..662a4de79 100644 --- a/ets2panda/ir/module/exportNamedDeclaration.cpp +++ b/ets2panda/ir/module/exportNamedDeclaration.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ExportNamedDeclaration::TransformChildren(const NodeTransformer &cb) @@ -67,6 +69,11 @@ void ExportNamedDeclaration::Dump(ir::AstDumper *dumper) const {"specifiers", specifiers_}}); } +void ExportNamedDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ExportNamedDeclaration"); +} + void ExportNamedDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/module/exportNamedDeclaration.h b/ets2panda/ir/module/exportNamedDeclaration.h index 78a515225..4a5a8c7d8 100644 --- a/ets2panda/ir/module/exportNamedDeclaration.h +++ b/ets2panda/ir/module/exportNamedDeclaration.h @@ -78,6 +78,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/module/exportSpecifier.cpp b/ets2panda/ir/module/exportSpecifier.cpp index 2aa19dee8..0f728c080 100644 --- a/ets2panda/ir/module/exportSpecifier.cpp +++ b/ets2panda/ir/module/exportSpecifier.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ExportSpecifier::TransformChildren(const NodeTransformer &cb) @@ -37,6 +39,11 @@ void ExportSpecifier::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ExportSpecifier"}, {"local", local_}, {"exported", exported_}}); } +void ExportSpecifier::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ExportSpecifier"); +} + void ExportSpecifier::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/module/exportSpecifier.h b/ets2panda/ir/module/exportSpecifier.h index 1770e7f06..ac0cf334d 100644 --- a/ets2panda/ir/module/exportSpecifier.h +++ b/ets2panda/ir/module/exportSpecifier.h @@ -41,6 +41,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/module/importDeclaration.cpp b/ets2panda/ir/module/importDeclaration.cpp index e1208b0d0..70b22948b 100644 --- a/ets2panda/ir/module/importDeclaration.cpp +++ b/ets2panda/ir/module/importDeclaration.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ImportDeclaration::TransformChildren(const NodeTransformer &cb) @@ -43,6 +45,23 @@ void ImportDeclaration::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ImportDeclaration"}, {"source", source_}, {"specifiers", specifiers_}}); } +void ImportDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("import "); + for (auto specifier : specifiers_) { + specifier->Dump(dumper); + if (specifier != specifiers_.back()) { + dumper->Add(", "); + } else { + dumper->Add(" "); + } + } + dumper->Add("from "); + source_->Dump(dumper); + dumper->Add(";"); + dumper->Endl(); +} + void ImportDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/module/importDeclaration.h b/ets2panda/ir/module/importDeclaration.h index fa7251ef8..fc9d2a1e8 100644 --- a/ets2panda/ir/module/importDeclaration.h +++ b/ets2panda/ir/module/importDeclaration.h @@ -47,6 +47,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/module/importDefaultSpecifier.cpp b/ets2panda/ir/module/importDefaultSpecifier.cpp index ea4a43b93..1999c374f 100644 --- a/ets2panda/ir/module/importDefaultSpecifier.cpp +++ b/ets2panda/ir/module/importDefaultSpecifier.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ImportDefaultSpecifier::TransformChildren(const NodeTransformer &cb) @@ -35,6 +37,11 @@ void ImportDefaultSpecifier::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ImportDefaultSpecifier"}, {"local", local_}}); } +void ImportDefaultSpecifier::Dump(ir::SrcDumper *dumper) const +{ + local_->Dump(dumper); +} + void ImportDefaultSpecifier::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/module/importDefaultSpecifier.h b/ets2panda/ir/module/importDefaultSpecifier.h index c698045b7..1df936b87 100644 --- a/ets2panda/ir/module/importDefaultSpecifier.h +++ b/ets2panda/ir/module/importDefaultSpecifier.h @@ -35,6 +35,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/module/importNamespaceSpecifier.cpp b/ets2panda/ir/module/importNamespaceSpecifier.cpp index 44660316c..406f735a8 100644 --- a/ets2panda/ir/module/importNamespaceSpecifier.cpp +++ b/ets2panda/ir/module/importNamespaceSpecifier.cpp @@ -19,6 +19,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ImportNamespaceSpecifier::TransformChildren(const NodeTransformer &cb) @@ -36,6 +38,11 @@ void ImportNamespaceSpecifier::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ImportNamespaceSpecifier"}, {"local", local_}}); } +void ImportNamespaceSpecifier::Dump(ir::SrcDumper *dumper) const +{ + local_->Dump(dumper); +} + void ImportNamespaceSpecifier::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/module/importNamespaceSpecifier.h b/ets2panda/ir/module/importNamespaceSpecifier.h index e4bbeaccb..3b79e7f1b 100644 --- a/ets2panda/ir/module/importNamespaceSpecifier.h +++ b/ets2panda/ir/module/importNamespaceSpecifier.h @@ -41,6 +41,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/module/importSpecifier.cpp b/ets2panda/ir/module/importSpecifier.cpp index 984e4137d..632e363f4 100644 --- a/ets2panda/ir/module/importSpecifier.cpp +++ b/ets2panda/ir/module/importSpecifier.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ImportSpecifier::TransformChildren(const NodeTransformer &cb) @@ -41,6 +43,11 @@ void ImportSpecifier::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ImportSpecifier"}, {"local", ir::AstDumper::Optional(local_)}, {"imported", imported_}}); } +void ImportSpecifier::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ImportSpecifier"); +} + void ImportSpecifier::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/module/importSpecifier.h b/ets2panda/ir/module/importSpecifier.h index 2aad8a29e..4f98dd150 100644 --- a/ets2panda/ir/module/importSpecifier.h +++ b/ets2panda/ir/module/importSpecifier.h @@ -51,6 +51,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/opaqueTypeNode.cpp b/ets2panda/ir/opaqueTypeNode.cpp index b09b065cb..ec0bc6194 100644 --- a/ets2panda/ir/opaqueTypeNode.cpp +++ b/ets2panda/ir/opaqueTypeNode.cpp @@ -18,6 +18,8 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" + namespace panda::es2panda::ir { void OpaqueTypeNode::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void OpaqueTypeNode::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "OpaqueType"}}); } +void OpaqueTypeNode::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("OpaqueTypeNode"); +} + void OpaqueTypeNode::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/opaqueTypeNode.h b/ets2panda/ir/opaqueTypeNode.h index c37708193..3f3194080 100644 --- a/ets2panda/ir/opaqueTypeNode.h +++ b/ets2panda/ir/opaqueTypeNode.h @@ -39,6 +39,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/srcDump.cpp b/ets2panda/ir/srcDump.cpp new file mode 100644 index 000000000..791371120 --- /dev/null +++ b/ets2panda/ir/srcDump.cpp @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2021 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 "srcDump.h" + +#include + +#include +#include + +namespace panda::es2panda::ir { + +SrcDumper::SrcDumper(const ir::AstNode *node) +{ + node->Dump(this); +} + +void SrcDumper::IncrIndent() +{ + indent_.push_back(' '); + indent_.push_back(' '); +} + +void SrcDumper::DecrIndent() +{ + if (indent_.size() >= 2U) { + indent_.pop_back(); + indent_.pop_back(); + } +} + +void SrcDumper::Endl(size_t num) +{ + while (num != 0U) { + ss_ << std::endl; + --num; + } + ss_ << indent_; +} + +void SrcDumper::Add(const std::string &str) +{ + ss_ << str; +} + +void SrcDumper::Add(const int32_t i) +{ + ss_ << i; +} + +void SrcDumper::Add(const int64_t l) +{ + ss_ << l; +} + +void SrcDumper::Add(const float f) +{ + ss_ << f; +} + +void SrcDumper::Add(const double d) +{ + ss_ << d; +} +} // namespace panda::es2panda::ir diff --git a/ets2panda/ir/srcDump.h b/ets2panda/ir/srcDump.h new file mode 100644 index 000000000..f80c81942 --- /dev/null +++ b/ets2panda/ir/srcDump.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2021 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_IR_SRCDUMP_H +#define ES2PANDA_IR_SRCDUMP_H + +#include +#include +#include +#include + +#include +#include + +namespace panda::es2panda::ir { + +class SrcDumper { +public: + explicit SrcDumper(const ir::AstNode *node); + + void Add(const std::string &str); + void Add(int32_t i); + void Add(int64_t l); + void Add(float f); + void Add(double d); + + std::string Str() const + { + return ss_.str(); + } + + void IncrIndent(); + void DecrIndent(); + void Endl(size_t num = 1); + +private: + std::stringstream ss_; + std::string indent_; +}; +} // namespace panda::es2panda::ir + +#endif // ES2PANDA_IR_SRCDUMP_H diff --git a/ets2panda/ir/statements/assertStatement.cpp b/ets2panda/ir/statements/assertStatement.cpp index 4b09acd23..393cdea5a 100644 --- a/ets2panda/ir/statements/assertStatement.cpp +++ b/ets2panda/ir/statements/assertStatement.cpp @@ -22,6 +22,7 @@ #include "checker/ETSchecker.h" #include "checker/TSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expression.h" namespace panda::es2panda::ir { @@ -48,6 +49,17 @@ void AssertStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "AssertStatement"}, {"test", test_}, {"second", AstDumper::Nullish(second_)}}); } +void AssertStatement::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(test_); + dumper->Add("assert("); + test_->Dump(dumper); + dumper->Add(")"); + if (parent_->IsStatement()) { + dumper->Add(";"); + } +} + void AssertStatement::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/assertStatement.h b/ets2panda/ir/statements/assertStatement.h index 504911064..88b468ad9 100644 --- a/ets2panda/ir/statements/assertStatement.h +++ b/ets2panda/ir/statements/assertStatement.h @@ -47,6 +47,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/blockStatement.cpp b/ets2panda/ir/statements/blockStatement.cpp index 4bb8908d3..76b50d2ad 100644 --- a/ets2panda/ir/statements/blockStatement.cpp +++ b/ets2panda/ir/statements/blockStatement.cpp @@ -22,6 +22,7 @@ #include "checker/TSchecker.h" #include "checker/ETSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void BlockStatement::TransformChildren(const NodeTransformer &cb) @@ -43,6 +44,17 @@ void BlockStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", IsProgram() ? "Program" : "BlockStatement"}, {"statements", statements_}}); } +void BlockStatement::Dump(ir::SrcDumper *dumper) const +{ + // NOTE(nsizov): trailing blocks + for (auto statement : statements_) { + statement->Dump(dumper); + if (statement != statements_.back()) { + dumper->Endl(); + } + } +} + void BlockStatement::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/blockStatement.h b/ets2panda/ir/statements/blockStatement.h index 6f75c047d..a3c1f9529 100644 --- a/ets2panda/ir/statements/blockStatement.h +++ b/ets2panda/ir/statements/blockStatement.h @@ -77,6 +77,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/breakStatement.cpp b/ets2panda/ir/statements/breakStatement.cpp index 674edc681..50cff0716 100644 --- a/ets2panda/ir/statements/breakStatement.cpp +++ b/ets2panda/ir/statements/breakStatement.cpp @@ -19,6 +19,7 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/identifier.h" #include "checker/ETSchecker.h" @@ -42,6 +43,16 @@ void BreakStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "BreakStatement"}, {"label", AstDumper::Nullish(ident_)}}); } +void BreakStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("break"); + if (ident_ != nullptr) { + dumper->Add(" "); + ident_->Dump(dumper); + } + dumper->Add(";"); +} + void BreakStatement::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/breakStatement.h b/ets2panda/ir/statements/breakStatement.h index 67f4b944f..35ffa3fa4 100644 --- a/ets2panda/ir/statements/breakStatement.h +++ b/ets2panda/ir/statements/breakStatement.h @@ -50,6 +50,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/classDeclaration.cpp b/ets2panda/ir/statements/classDeclaration.cpp index 627e9bece..5e2b38767 100644 --- a/ets2panda/ir/statements/classDeclaration.cpp +++ b/ets2panda/ir/statements/classDeclaration.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ClassDeclaration::TransformChildren(const NodeTransformer &cb) @@ -43,6 +45,15 @@ void ClassDeclaration::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ClassDeclaration"}, {"definition", def_}, {"decorators", AstDumper::Optional(decorators_)}}); } +void ClassDeclaration::Dump(ir::SrcDumper *dumper) const +{ + if (def_ != nullptr) { + def_->Dump(dumper); + } + // NOTE(nsizov): support decorators when supported in ArkTS + ASSERT(decorators_.empty()); +} + void ClassDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/classDeclaration.h b/ets2panda/ir/statements/classDeclaration.h index c6e5925b4..acc51c23e 100644 --- a/ets2panda/ir/statements/classDeclaration.h +++ b/ets2panda/ir/statements/classDeclaration.h @@ -59,6 +59,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; diff --git a/ets2panda/ir/statements/continueStatement.cpp b/ets2panda/ir/statements/continueStatement.cpp index da58f870a..6b9739ecc 100644 --- a/ets2panda/ir/statements/continueStatement.cpp +++ b/ets2panda/ir/statements/continueStatement.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ContinueStatement::TransformChildren(const NodeTransformer &cb) @@ -39,6 +41,11 @@ void ContinueStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ContinueStatement"}, {"label", AstDumper::Nullish(ident_)}}); } +void ContinueStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("continue;"); +} + void ContinueStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/continueStatement.h b/ets2panda/ir/statements/continueStatement.h index 857b43f7f..2ccb75102 100644 --- a/ets2panda/ir/statements/continueStatement.h +++ b/ets2panda/ir/statements/continueStatement.h @@ -50,6 +50,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/debuggerStatement.cpp b/ets2panda/ir/statements/debuggerStatement.cpp index b0bb23faa..9ae8e40d5 100644 --- a/ets2panda/ir/statements/debuggerStatement.cpp +++ b/ets2panda/ir/statements/debuggerStatement.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void DebuggerStatement::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void DebuggerStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "DebuggerStatement"}}); } +void DebuggerStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("DebuggerStatement"); +} + void DebuggerStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/debuggerStatement.h b/ets2panda/ir/statements/debuggerStatement.h index 70feeb469..de1e2f402 100644 --- a/ets2panda/ir/statements/debuggerStatement.h +++ b/ets2panda/ir/statements/debuggerStatement.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/doWhileStatement.cpp b/ets2panda/ir/statements/doWhileStatement.cpp index 93d2a413e..769d97bd5 100644 --- a/ets2panda/ir/statements/doWhileStatement.cpp +++ b/ets2panda/ir/statements/doWhileStatement.cpp @@ -14,6 +14,7 @@ */ #include "doWhileStatement.h" +#include #include "varbinder/scope.h" #include "compiler/base/condition.h" @@ -21,6 +22,8 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "checker/TSchecker.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void DoWhileStatement::TransformChildren(const NodeTransformer &cb) @@ -40,6 +43,24 @@ void DoWhileStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "DoWhileStatement"}, {"body", body_}, {"test", test_}}); } +void DoWhileStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("do {"); + if (body_ != nullptr) { + dumper->IncrIndent(); + dumper->Endl(); + body_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + } + dumper->Add("} while"); + dumper->Add("("); + if (test_ != nullptr) { + test_->Dump(dumper); + } + dumper->Add(")"); +} + void DoWhileStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/doWhileStatement.h b/ets2panda/ir/statements/doWhileStatement.h index dbae0763e..487dd589c 100644 --- a/ets2panda/ir/statements/doWhileStatement.h +++ b/ets2panda/ir/statements/doWhileStatement.h @@ -62,6 +62,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/emptyStatement.cpp b/ets2panda/ir/statements/emptyStatement.cpp index 4c00f2a89..a5a9bab6c 100644 --- a/ets2panda/ir/statements/emptyStatement.cpp +++ b/ets2panda/ir/statements/emptyStatement.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void EmptyStatement::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void EmptyStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "EmptyStatement"}}); } +void EmptyStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("EmptyStatement"); +} + void EmptyStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/emptyStatement.h b/ets2panda/ir/statements/emptyStatement.h index a8ac9416a..f6d86e6cf 100644 --- a/ets2panda/ir/statements/emptyStatement.h +++ b/ets2panda/ir/statements/emptyStatement.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/expressionStatement.cpp b/ets2panda/ir/statements/expressionStatement.cpp index d4750832b..2f10412f4 100644 --- a/ets2panda/ir/statements/expressionStatement.cpp +++ b/ets2panda/ir/statements/expressionStatement.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ExpressionStatement::TransformChildren(const NodeTransformer &cb) @@ -35,6 +37,18 @@ void ExpressionStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ExpressionStatement"}, {"expression", expression_}}); } +void ExpressionStatement::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(expression_ != nullptr); + expression_->Dump(dumper); + if ((parent_ != nullptr) && (parent_->IsBlockStatement() || parent_->IsSwitchCaseStatement())) { + dumper->Add(";"); + if (parent_->IsSwitchCaseStatement()) { + dumper->Endl(); + } + } +} + void ExpressionStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/expressionStatement.h b/ets2panda/ir/statements/expressionStatement.h index 57e061a22..85da0d287 100644 --- a/ets2panda/ir/statements/expressionStatement.h +++ b/ets2panda/ir/statements/expressionStatement.h @@ -38,6 +38,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/forInStatement.cpp b/ets2panda/ir/statements/forInStatement.cpp index 331be2f2f..a1344d736 100644 --- a/ets2panda/ir/statements/forInStatement.cpp +++ b/ets2panda/ir/statements/forInStatement.cpp @@ -21,6 +21,8 @@ #include "compiler/core/pandagen.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ForInStatement::TransformChildren(const NodeTransformer &cb) @@ -42,6 +44,11 @@ void ForInStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ForInStatement"}, {"left", left_}, {"right", right_}, {"body", body_}}); } +void ForInStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("ForInStatement"); +} + void ForInStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/forInStatement.h b/ets2panda/ir/statements/forInStatement.h index 13f428e3b..0702403ed 100644 --- a/ets2panda/ir/statements/forInStatement.h +++ b/ets2panda/ir/statements/forInStatement.h @@ -72,6 +72,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/forOfStatement.cpp b/ets2panda/ir/statements/forOfStatement.cpp index 50cb1e9d1..7ce6be2d4 100644 --- a/ets2panda/ir/statements/forOfStatement.cpp +++ b/ets2panda/ir/statements/forOfStatement.cpp @@ -15,6 +15,7 @@ #include "forOfStatement.h" +#include "macros.h" #include "varbinder/scope.h" #include "compiler/base/iterators.h" #include "compiler/base/lreference.h" @@ -22,6 +23,8 @@ #include "checker/TSchecker.h" #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ForOfStatement::TransformChildren(const NodeTransformer &cb) @@ -44,6 +47,29 @@ void ForOfStatement::Dump(ir::AstDumper *dumper) const {{"type", "ForOfStatement"}, {"await", is_await_}, {"left", left_}, {"right", right_}, {"body", body_}}); } +void ForOfStatement::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(left_ != nullptr); + ASSERT(right_ != nullptr); + dumper->Add("for "); + if (is_await_) { + dumper->Add("await "); + } + dumper->Add("("); + left_->Dump(dumper); + dumper->Add(" of "); + right_->Dump(dumper); + dumper->Add(") {"); + if (body_ != nullptr) { + dumper->IncrIndent(); + dumper->Endl(); + body_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + } + dumper->Add("}"); +} + void ForOfStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/forOfStatement.h b/ets2panda/ir/statements/forOfStatement.h index 9a2e9ba8a..2d5fbbb25 100644 --- a/ets2panda/ir/statements/forOfStatement.h +++ b/ets2panda/ir/statements/forOfStatement.h @@ -77,6 +77,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/forUpdateStatement.cpp b/ets2panda/ir/statements/forUpdateStatement.cpp index 09ccc2060..711632f31 100644 --- a/ets2panda/ir/statements/forUpdateStatement.cpp +++ b/ets2panda/ir/statements/forUpdateStatement.cpp @@ -14,6 +14,7 @@ */ #include "forUpdateStatement.h" +#include #include "varbinder/scope.h" #include "compiler/base/condition.h" @@ -23,6 +24,8 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/dynamicContext.h" #include "checker/TSchecker.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ForUpdateStatement::TransformChildren(const NodeTransformer &cb) @@ -66,6 +69,33 @@ void ForUpdateStatement::Dump(ir::AstDumper *dumper) const {"body", body_}}); } +void ForUpdateStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("for "); + dumper->Add("("); + if (init_ != nullptr) { + init_->Dump(dumper); + } + dumper->Add(";"); + if (test_ != nullptr) { + test_->Dump(dumper); + } + dumper->Add(";"); + if (update_ != nullptr) { + update_->Dump(dumper); + } + dumper->Add(") "); + dumper->Add("{"); + if (body_ != nullptr) { + dumper->IncrIndent(); + dumper->Endl(); + body_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + } + dumper->Add("}"); +} + void ForUpdateStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/forUpdateStatement.h b/ets2panda/ir/statements/forUpdateStatement.h index 03e828ba1..fc4dfcc84 100644 --- a/ets2panda/ir/statements/forUpdateStatement.h +++ b/ets2panda/ir/statements/forUpdateStatement.h @@ -82,6 +82,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/functionDeclaration.cpp b/ets2panda/ir/statements/functionDeclaration.cpp index a5c9e3a61..b3e229242 100644 --- a/ets2panda/ir/statements/functionDeclaration.cpp +++ b/ets2panda/ir/statements/functionDeclaration.cpp @@ -19,6 +19,8 @@ #include "varbinder/scope.h" #include "compiler/core/ETSGen.h" #include "checker/TSchecker.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" #include "compiler/core/pandagen.h" namespace panda::es2panda::ir { @@ -47,6 +49,11 @@ void FunctionDeclaration::Dump(ir::AstDumper *dumper) const {"function", func_}}); } +void FunctionDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("FunctionDeclaration"); +} + void FunctionDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/functionDeclaration.h b/ets2panda/ir/statements/functionDeclaration.h index 449be1311..5437f2c3a 100644 --- a/ets2panda/ir/statements/functionDeclaration.h +++ b/ets2panda/ir/statements/functionDeclaration.h @@ -59,6 +59,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/ifStatement.cpp b/ets2panda/ir/statements/ifStatement.cpp index 05b30ac41..44e8b5757 100644 --- a/ets2panda/ir/statements/ifStatement.cpp +++ b/ets2panda/ir/statements/ifStatement.cpp @@ -14,10 +14,13 @@ */ #include "ifStatement.h" +#include #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void IfStatement::TransformChildren(const NodeTransformer &cb) @@ -48,6 +51,36 @@ void IfStatement::Dump(ir::AstDumper *dumper) const {"alternate", AstDumper::Nullish(alternate_)}}); } +void IfStatement::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(test_); + dumper->Add("if ("); + test_->Dump(dumper); + dumper->Add(") {"); + if (consequent_ != nullptr) { + dumper->IncrIndent(); + dumper->Endl(); + dumper->DecrIndent(); + consequent_->Dump(dumper); + dumper->Endl(); + } + dumper->Add("}"); + if (alternate_ != nullptr) { + dumper->Add(" else "); + if (alternate_->IsBlockStatement()) { + dumper->Add("{"); + dumper->IncrIndent(); + dumper->Endl(); + dumper->DecrIndent(); + alternate_->Dump(dumper); + dumper->Endl(); + dumper->Add("}"); + } else { + alternate_->Dump(dumper); + } + } +} + void IfStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/ifStatement.h b/ets2panda/ir/statements/ifStatement.h index 70f0f2c9d..0671a827f 100644 --- a/ets2panda/ir/statements/ifStatement.h +++ b/ets2panda/ir/statements/ifStatement.h @@ -70,6 +70,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/labelledStatement.cpp b/ets2panda/ir/statements/labelledStatement.cpp index c43d30ebf..f74131e62 100644 --- a/ets2panda/ir/statements/labelledStatement.cpp +++ b/ets2panda/ir/statements/labelledStatement.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void LabelledStatement::TransformChildren(const NodeTransformer &cb) @@ -37,6 +39,15 @@ void LabelledStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "LabelledStatement"}, {"label", ident_}, {"body", body_}}); } +void LabelledStatement::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(ident_ != nullptr); + ident_->Dump(dumper); + dumper->Add(":"); + dumper->Endl(); + body_->Dump(dumper); +} + const ir::AstNode *LabelledStatement::GetReferencedStatement() const { const auto *iter = body_; diff --git a/ets2panda/ir/statements/labelledStatement.h b/ets2panda/ir/statements/labelledStatement.h index 28046f2fa..bb74240f4 100644 --- a/ets2panda/ir/statements/labelledStatement.h +++ b/ets2panda/ir/statements/labelledStatement.h @@ -58,6 +58,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/returnStatement.cpp b/ets2panda/ir/statements/returnStatement.cpp index 4c1cf0012..cb0e92dae 100644 --- a/ets2panda/ir/statements/returnStatement.cpp +++ b/ets2panda/ir/statements/returnStatement.cpp @@ -19,6 +19,7 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void ReturnStatement::TransformChildren(const NodeTransformer &cb) @@ -40,6 +41,16 @@ void ReturnStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ReturnStatement"}, {"argument", AstDumper::Nullish(argument_)}}); } +void ReturnStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("return"); + if (argument_ != nullptr) { + dumper->Add(" "); + argument_->Dump(dumper); + } + dumper->Add(";"); +} + void ReturnStatement::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/returnStatement.h b/ets2panda/ir/statements/returnStatement.h index 3b9db1fd9..c09f0531e 100644 --- a/ets2panda/ir/statements/returnStatement.h +++ b/ets2panda/ir/statements/returnStatement.h @@ -67,6 +67,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/switchCaseStatement.cpp b/ets2panda/ir/statements/switchCaseStatement.cpp index 3830c777c..b8fe7a025 100644 --- a/ets2panda/ir/statements/switchCaseStatement.cpp +++ b/ets2panda/ir/statements/switchCaseStatement.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void SwitchCaseStatement::TransformChildren(const NodeTransformer &cb) @@ -47,6 +49,25 @@ void SwitchCaseStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "SwitchCase"}, {"test", AstDumper::Nullish(test_)}, {"consequent", consequent_}}); } +void SwitchCaseStatement::Dump(ir::SrcDumper *dumper) const +{ + if (test_ != nullptr) { + dumper->Add("case "); + test_->Dump(dumper); + dumper->Add(":"); + } else { + dumper->Add("default:"); + } + if (!consequent_.empty()) { + dumper->IncrIndent(); + dumper->Endl(); + for (auto cs : consequent_) { + cs->Dump(dumper); + } + dumper->DecrIndent(); + } +} + void SwitchCaseStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/switchCaseStatement.h b/ets2panda/ir/statements/switchCaseStatement.h index 43022283d..3997c92d5 100644 --- a/ets2panda/ir/statements/switchCaseStatement.h +++ b/ets2panda/ir/statements/switchCaseStatement.h @@ -55,6 +55,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/switchStatement.cpp b/ets2panda/ir/statements/switchStatement.cpp index c7d908bd2..5c56c170d 100644 --- a/ets2panda/ir/statements/switchStatement.cpp +++ b/ets2panda/ir/statements/switchStatement.cpp @@ -21,6 +21,8 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "checker/TSchecker.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void SwitchStatement::TransformChildren(const NodeTransformer &cb) @@ -46,6 +48,26 @@ void SwitchStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "SwitchStatement"}, {"discriminant", discriminant_}, {"cases", cases_}}); } +void SwitchStatement::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(discriminant_); + dumper->Add("switch ("); + discriminant_->Dump(dumper); + dumper->Add(") {"); + if (!cases_.empty()) { + dumper->IncrIndent(); + dumper->Endl(); + for (auto cs : cases_) { + cs->Dump(dumper); + if (cs == cases_.back()) { + dumper->DecrIndent(); + } + dumper->Endl(); + } + } + dumper->Add("}"); +} + void SwitchStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/switchStatement.h b/ets2panda/ir/statements/switchStatement.h index 8a4b86b2b..6b14aab08 100644 --- a/ets2panda/ir/statements/switchStatement.h +++ b/ets2panda/ir/statements/switchStatement.h @@ -79,6 +79,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/throwStatement.cpp b/ets2panda/ir/statements/throwStatement.cpp index 28a3e2f54..5ac70ad69 100644 --- a/ets2panda/ir/statements/throwStatement.cpp +++ b/ets2panda/ir/statements/throwStatement.cpp @@ -19,6 +19,7 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expression.h" namespace panda::es2panda::ir { @@ -37,6 +38,14 @@ void ThrowStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ThrowStatement"}, {"argument", argument_}}); } +void ThrowStatement::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(Argument() != nullptr); + dumper->Add("throw "); + Argument()->Dump(dumper); + dumper->Add(";"); +} + void ThrowStatement::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/throwStatement.h b/ets2panda/ir/statements/throwStatement.h index 2a224ce2d..40e2b0770 100644 --- a/ets2panda/ir/statements/throwStatement.h +++ b/ets2panda/ir/statements/throwStatement.h @@ -39,6 +39,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/tryStatement.cpp b/ets2panda/ir/statements/tryStatement.cpp index f325b681e..5c632f3ed 100644 --- a/ets2panda/ir/statements/tryStatement.cpp +++ b/ets2panda/ir/statements/tryStatement.cpp @@ -21,6 +21,7 @@ #include "compiler/core/dynamicContext.h" #include "compiler/base/catchTable.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/catchClause.h" #include "ir/statements/blockStatement.h" @@ -59,6 +60,31 @@ void TryStatement::Dump(ir::AstDumper *dumper) const {"finalizer", AstDumper::Nullish(finalizer_)}}); } +void TryStatement::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(block_ != nullptr); + dumper->Add("try {"); + dumper->IncrIndent(); + dumper->Endl(); + block_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + dumper->Add("}"); + for (auto clause : catch_clauses_) { + dumper->Add(" catch "); + clause->Dump(dumper); + } + if (finalizer_ != nullptr) { + dumper->Add(" finally {"); + dumper->IncrIndent(); + dumper->Endl(); + finalizer_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + dumper->Add("}"); + } +} + bool TryStatement::HasDefaultCatchClause() const { return (!catch_clauses_.empty() && catch_clauses_.back()->IsDefaultCatchClause()); diff --git a/ets2panda/ir/statements/tryStatement.h b/ets2panda/ir/statements/tryStatement.h index 9661f2748..b60333579 100644 --- a/ets2panda/ir/statements/tryStatement.h +++ b/ets2panda/ir/statements/tryStatement.h @@ -87,6 +87,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/variableDeclaration.cpp b/ets2panda/ir/statements/variableDeclaration.cpp index 205265a3d..91c564993 100644 --- a/ets2panda/ir/statements/variableDeclaration.cpp +++ b/ets2panda/ir/statements/variableDeclaration.cpp @@ -15,6 +15,7 @@ #include "variableDeclaration.h" +#include "macros.h" #include "varbinder/scope.h" #include "varbinder/variable.h" #include "checker/TSchecker.h" @@ -22,6 +23,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/decorator.h" #include "ir/expressions/arrayExpression.h" #include "ir/expressions/identifier.h" @@ -80,6 +82,34 @@ void VariableDeclaration::Dump(ir::AstDumper *dumper) const {"declare", AstDumper::Optional(declare_)}}); } +void VariableDeclaration::Dump(ir::SrcDumper *dumper) const +{ + switch (kind_) { + case VariableDeclarationKind::CONST: + dumper->Add("const "); + break; + case VariableDeclarationKind::LET: + dumper->Add("let "); + break; + case VariableDeclarationKind::VAR: + dumper->Add("var "); + break; + default: + UNREACHABLE(); + } + + for (auto declarator : declarators_) { + declarator->Dump(dumper); + if (declarator != declarators_.back()) { + dumper->Add(", "); + } + } + + if ((parent_ != nullptr) && (parent_->IsBlockStatement() || parent_->IsBlockExpression())) { + dumper->Add(";"); + } +} + void VariableDeclaration::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/variableDeclaration.h b/ets2panda/ir/statements/variableDeclaration.h index 9b9fc3fcd..88e45ffe6 100644 --- a/ets2panda/ir/statements/variableDeclaration.h +++ b/ets2panda/ir/statements/variableDeclaration.h @@ -73,6 +73,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/variableDeclarator.cpp b/ets2panda/ir/statements/variableDeclarator.cpp index 3089bfd1c..7dc9140de 100644 --- a/ets2panda/ir/statements/variableDeclarator.cpp +++ b/ets2panda/ir/statements/variableDeclarator.cpp @@ -20,6 +20,7 @@ #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/astNode.h" #include "ir/typeNode.h" #include "ir/expression.h" @@ -56,6 +57,24 @@ void VariableDeclarator::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "VariableDeclarator"}, {"id", id_}, {"init", AstDumper::Nullish(init_)}}); } +void VariableDeclarator::Dump(ir::SrcDumper *dumper) const +{ + if (id_ != nullptr) { + id_->Dump(dumper); + if (id_->IsAnnotatedExpression()) { + auto *type = id_->AsAnnotatedExpression()->TypeAnnotation(); + if (type != nullptr) { + dumper->Add(": "); + type->Dump(dumper); + } + } + } + if (init_ != nullptr) { + dumper->Add(" = "); + init_->Dump(dumper); + } +} + void VariableDeclarator::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/variableDeclarator.h b/ets2panda/ir/statements/variableDeclarator.h index 03cc256e9..aad932d74 100644 --- a/ets2panda/ir/statements/variableDeclarator.h +++ b/ets2panda/ir/statements/variableDeclarator.h @@ -74,6 +74,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/statements/whileStatement.cpp b/ets2panda/ir/statements/whileStatement.cpp index 5624fd56d..5ab1715c5 100644 --- a/ets2panda/ir/statements/whileStatement.cpp +++ b/ets2panda/ir/statements/whileStatement.cpp @@ -23,6 +23,7 @@ #include "compiler/core/regScope.h" #include "checker/TSchecker.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expression.h" namespace panda::es2panda::ir { @@ -43,6 +44,23 @@ void WhileStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "WhileStatement"}, {"test", test_}, {"body", body_}}); } +void WhileStatement::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("while ("); + if (test_ != nullptr) { + test_->Dump(dumper); + } + dumper->Add(") {"); + if (body_ != nullptr) { + dumper->IncrIndent(); + dumper->Endl(); + body_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + } + dumper->Add("}"); +} + void WhileStatement::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/statements/whileStatement.h b/ets2panda/ir/statements/whileStatement.h index c4936cced..85bbfc039 100644 --- a/ets2panda/ir/statements/whileStatement.h +++ b/ets2panda/ir/statements/whileStatement.h @@ -62,6 +62,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsAnyKeyword.cpp b/ets2panda/ir/ts/tsAnyKeyword.cpp index c82f02741..10a4645c5 100644 --- a/ets2panda/ir/ts/tsAnyKeyword.cpp +++ b/ets2panda/ir/ts/tsAnyKeyword.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSAnyKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void TSAnyKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSAnyKeyword"}}); } +void TSAnyKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSAnyKeyword"); +} + void TSAnyKeyword::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsAnyKeyword.h b/ets2panda/ir/ts/tsAnyKeyword.h index 8fd327a71..7eacc23c2 100644 --- a/ets2panda/ir/ts/tsAnyKeyword.h +++ b/ets2panda/ir/ts/tsAnyKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsArrayType.cpp b/ets2panda/ir/ts/tsArrayType.cpp index 7233ca4ab..ada705e56 100644 --- a/ets2panda/ir/ts/tsArrayType.cpp +++ b/ets2panda/ir/ts/tsArrayType.cpp @@ -18,8 +18,10 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" #include "checker/ETSchecker.h" +#include "macros.h" namespace panda::es2panda::ir { void TSArrayType::TransformChildren(const NodeTransformer &cb) @@ -37,6 +39,13 @@ void TSArrayType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSArrayType"}, {"elementType", element_type_}}); } +void TSArrayType::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(element_type_); + element_type_->Dump(dumper); + dumper->Add("[]"); +} + void TSArrayType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsArrayType.h b/ets2panda/ir/ts/tsArrayType.h index 96650e849..48af2bfa6 100644 --- a/ets2panda/ir/ts/tsArrayType.h +++ b/ets2panda/ir/ts/tsArrayType.h @@ -40,6 +40,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsAsExpression.cpp b/ets2panda/ir/ts/tsAsExpression.cpp index faeaf45c3..051d18b7a 100644 --- a/ets2panda/ir/ts/tsAsExpression.cpp +++ b/ets2panda/ir/ts/tsAsExpression.cpp @@ -58,6 +58,11 @@ void TSAsExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSAsExpression"}, {"expression", expression_}, {"typeAnnotation", TypeAnnotation()}}); } +void TSAsExpression::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSAsExpression"); +} + void TSAsExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsAsExpression.h b/ets2panda/ir/ts/tsAsExpression.h index 0a75f58a3..2f48ec8e7 100644 --- a/ets2panda/ir/ts/tsAsExpression.h +++ b/ets2panda/ir/ts/tsAsExpression.h @@ -17,6 +17,7 @@ #define ES2PANDA_IR_TS_AS_EXPRESSION_H #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expression.h" namespace panda::es2panda::checker { class ETSAnalyzer; @@ -53,6 +54,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsBigintKeyword.cpp b/ets2panda/ir/ts/tsBigintKeyword.cpp index baa374d66..e100389d0 100644 --- a/ets2panda/ir/ts/tsBigintKeyword.cpp +++ b/ets2panda/ir/ts/tsBigintKeyword.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" namespace panda::es2panda::ir { @@ -30,6 +31,11 @@ void TSBigintKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSBigIntKeyword"}}); } +void TSBigintKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSBigintKeyword"); +} + void TSBigintKeyword::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsBigintKeyword.h b/ets2panda/ir/ts/tsBigintKeyword.h index 1baa67e14..8db316915 100644 --- a/ets2panda/ir/ts/tsBigintKeyword.h +++ b/ets2panda/ir/ts/tsBigintKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsBooleanKeyword.cpp b/ets2panda/ir/ts/tsBooleanKeyword.cpp index 7cc031e8a..7ef07bc9f 100644 --- a/ets2panda/ir/ts/tsBooleanKeyword.cpp +++ b/ets2panda/ir/ts/tsBooleanKeyword.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSBooleanKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void TSBooleanKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSBooleanKeyword"}}); } +void TSBooleanKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSBooleanKeyword"); +} + void TSBooleanKeyword::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsBooleanKeyword.h b/ets2panda/ir/ts/tsBooleanKeyword.h index 89f96ce9d..e76373d8c 100644 --- a/ets2panda/ir/ts/tsBooleanKeyword.h +++ b/ets2panda/ir/ts/tsBooleanKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsClassImplements.cpp b/ets2panda/ir/ts/tsClassImplements.cpp index c3183cd25..17d0cca22 100644 --- a/ets2panda/ir/ts/tsClassImplements.cpp +++ b/ets2panda/ir/ts/tsClassImplements.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/ts/tsTypeParameter.h" #include "ir/ts/tsTypeParameterInstantiation.h" @@ -44,6 +45,12 @@ void TSClassImplements::Dump(ir::AstDumper *dumper) const {"typeParameters", AstDumper::Optional(type_parameters_)}}); } +void TSClassImplements::Dump(ir::SrcDumper *dumper) const +{ + expression_->Dump(dumper); + ASSERT(type_parameters_ == nullptr); +} + void TSClassImplements::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsClassImplements.h b/ets2panda/ir/ts/tsClassImplements.h index 49be88236..32e9db6a6 100644 --- a/ets2panda/ir/ts/tsClassImplements.h +++ b/ets2panda/ir/ts/tsClassImplements.h @@ -51,6 +51,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsConditionalType.cpp b/ets2panda/ir/ts/tsConditionalType.cpp index dc194f4b9..e77f35e80 100644 --- a/ets2panda/ir/ts/tsConditionalType.cpp +++ b/ets2panda/ir/ts/tsConditionalType.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSConditionalType::TransformChildren(const NodeTransformer &cb) @@ -46,6 +47,11 @@ void TSConditionalType::Dump(ir::AstDumper *dumper) const {"falseType", false_type_}}); } +void TSConditionalType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSConditionalType"); +} + void TSConditionalType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsConditionalType.h b/ets2panda/ir/ts/tsConditionalType.h index c2c4d39a0..b309ba4ef 100644 --- a/ets2panda/ir/ts/tsConditionalType.h +++ b/ets2panda/ir/ts/tsConditionalType.h @@ -54,6 +54,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsConstructorType.cpp b/ets2panda/ir/ts/tsConstructorType.cpp index 70c08d67f..585639f82 100644 --- a/ets2panda/ir/ts/tsConstructorType.cpp +++ b/ets2panda/ir/ts/tsConstructorType.cpp @@ -21,6 +21,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/ts/tsTypeParameter.h" #include "ir/ts/tsTypeParameterDeclaration.h" @@ -44,6 +45,11 @@ void TSConstructorType::Dump(ir::AstDumper *dumper) const {"abstract", AstDumper::Optional(abstract_)}}); } +void TSConstructorType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSConstructorType"); +} + void TSConstructorType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsConstructorType.h b/ets2panda/ir/ts/tsConstructorType.h index 07a1564d5..f126b33bd 100644 --- a/ets2panda/ir/ts/tsConstructorType.h +++ b/ets2panda/ir/ts/tsConstructorType.h @@ -83,6 +83,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsEnumDeclaration.cpp b/ets2panda/ir/ts/tsEnumDeclaration.cpp index b0f73788e..426c5e9b1 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.cpp +++ b/ets2panda/ir/ts/tsEnumDeclaration.cpp @@ -20,6 +20,8 @@ #include "compiler/core/pandagen.h" #include "varbinder/scope.h" #include "util/helpers.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSEnumDeclaration::TransformChildren(const NodeTransformer &cb) @@ -57,6 +59,30 @@ void TSEnumDeclaration::Dump(ir::AstDumper *dumper) const {"const", is_const_}}); } +void TSEnumDeclaration::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(is_const_ == false); + ASSERT(key_ != nullptr); + dumper->Add("enum "); + key_->Dump(dumper); + dumper->Add(" {"); + if (!members_.empty()) { + dumper->IncrIndent(); + dumper->Endl(); + for (auto member : members_) { + member->Dump(dumper); + if (member != members_.back()) { + dumper->Add(","); + dumper->Endl(); + } + } + dumper->DecrIndent(); + dumper->Endl(); + } + dumper->Add("}"); + dumper->Endl(); +} + // NOTE (csabahurton): this method has not been moved to TSAnalyizer.cpp, because it is not used. varbinder::EnumMemberResult EvaluateMemberExpression(checker::TSChecker *checker, [[maybe_unused]] varbinder::EnumVariable *enum_var, diff --git a/ets2panda/ir/ts/tsEnumDeclaration.h b/ets2panda/ir/ts/tsEnumDeclaration.h index 94fa10e7e..a0d0c168b 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.h +++ b/ets2panda/ir/ts/tsEnumDeclaration.h @@ -113,6 +113,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsEnumMember.cpp b/ets2panda/ir/ts/tsEnumMember.cpp index adb6873dd..c08cafd97 100644 --- a/ets2panda/ir/ts/tsEnumMember.cpp +++ b/ets2panda/ir/ts/tsEnumMember.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSEnumMember::TransformChildren(const NodeTransformer &cb) @@ -43,6 +45,16 @@ void TSEnumMember::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSEnumMember"}, {"id", key_}, {"initializer", AstDumper::Optional(init_)}}); } +void TSEnumMember::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(key_ != nullptr); + key_->Dump(dumper); + if (init_ != nullptr) { + dumper->Add(" = "); + init_->Dump(dumper); + } +} + util::StringView TSEnumMember::Name() const { ASSERT(key_->IsIdentifier()); diff --git a/ets2panda/ir/ts/tsEnumMember.h b/ets2panda/ir/ts/tsEnumMember.h index 2d73dcabc..c4bfbf3e7 100644 --- a/ets2panda/ir/ts/tsEnumMember.h +++ b/ets2panda/ir/ts/tsEnumMember.h @@ -48,6 +48,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsExternalModuleReference.cpp b/ets2panda/ir/ts/tsExternalModuleReference.cpp index 601c235a0..dc66c7fdd 100644 --- a/ets2panda/ir/ts/tsExternalModuleReference.cpp +++ b/ets2panda/ir/ts/tsExternalModuleReference.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSExternalModuleReference::TransformChildren(const NodeTransformer &cb) @@ -35,6 +37,11 @@ void TSExternalModuleReference::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSExternalModuleReference"}, {"expression", expr_}}); } +void TSExternalModuleReference::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSExternalModuleReference"); +} + void TSExternalModuleReference::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsExternalModuleReference.h b/ets2panda/ir/ts/tsExternalModuleReference.h index 51234fdb8..3bc8f8453 100644 --- a/ets2panda/ir/ts/tsExternalModuleReference.h +++ b/ets2panda/ir/ts/tsExternalModuleReference.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsFunctionType.cpp b/ets2panda/ir/ts/tsFunctionType.cpp index bcd5f1b1a..03e160174 100644 --- a/ets2panda/ir/ts/tsFunctionType.cpp +++ b/ets2panda/ir/ts/tsFunctionType.cpp @@ -22,6 +22,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/spreadElement.h" #include "ir/expressions/identifier.h" #include "ir/ts/tsTypeParameter.h" @@ -47,6 +48,11 @@ void TSFunctionType::Dump(ir::AstDumper *dumper) const {"isNullable", AstDumper::Optional(nullable_)}}); } +void TSFunctionType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSFunctionType"); +} + void TSFunctionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsFunctionType.h b/ets2panda/ir/ts/tsFunctionType.h index 596809351..a9b6401f5 100644 --- a/ets2panda/ir/ts/tsFunctionType.h +++ b/ets2panda/ir/ts/tsFunctionType.h @@ -81,6 +81,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsImportEqualsDeclaration.cpp b/ets2panda/ir/ts/tsImportEqualsDeclaration.cpp index 3f0842327..3250853b9 100644 --- a/ets2panda/ir/ts/tsImportEqualsDeclaration.cpp +++ b/ets2panda/ir/ts/tsImportEqualsDeclaration.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expression.h" #include "ir/expressions/identifier.h" @@ -43,6 +44,11 @@ void TSImportEqualsDeclaration::Dump(ir::AstDumper *dumper) const {"isExport", is_export_}}); } +void TSImportEqualsDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSImportEqualsDeclaration"); +} + void TSImportEqualsDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsImportEqualsDeclaration.h b/ets2panda/ir/ts/tsImportEqualsDeclaration.h index f4fff48ff..70b6fc995 100644 --- a/ets2panda/ir/ts/tsImportEqualsDeclaration.h +++ b/ets2panda/ir/ts/tsImportEqualsDeclaration.h @@ -49,6 +49,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsImportType.cpp b/ets2panda/ir/ts/tsImportType.cpp index 316ba0551..a3f5c89f5 100644 --- a/ets2panda/ir/ts/tsImportType.cpp +++ b/ets2panda/ir/ts/tsImportType.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/ts/tsTypeParameter.h" #include "ir/ts/tsTypeParameterInstantiation.h" @@ -58,6 +59,11 @@ void TSImportType::Dump(ir::AstDumper *dumper) const {"isTypeOf", is_typeof_}}); } +void TSImportType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSImportType"); +} + void TSImportType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsImportType.h b/ets2panda/ir/ts/tsImportType.h index 2c182abd5..bf48f27d4 100644 --- a/ets2panda/ir/ts/tsImportType.h +++ b/ets2panda/ir/ts/tsImportType.h @@ -56,6 +56,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsIndexedAccessType.cpp b/ets2panda/ir/ts/tsIndexedAccessType.cpp index 22d534af6..cf48ba907 100644 --- a/ets2panda/ir/ts/tsIndexedAccessType.cpp +++ b/ets2panda/ir/ts/tsIndexedAccessType.cpp @@ -18,6 +18,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" @@ -39,6 +40,11 @@ void TSIndexedAccessType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSIndexedAccessType"}, {"objectType", object_type_}, {"indexType", index_type_}}); } +void TSIndexedAccessType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSIndexedAccessType"); +} + void TSIndexedAccessType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsIndexedAccessType.h b/ets2panda/ir/ts/tsIndexedAccessType.h index ab7a43f9a..d3f015451 100644 --- a/ets2panda/ir/ts/tsIndexedAccessType.h +++ b/ets2panda/ir/ts/tsIndexedAccessType.h @@ -45,6 +45,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsInferType.cpp b/ets2panda/ir/ts/tsInferType.cpp index d108bb954..89c61ff68 100644 --- a/ets2panda/ir/ts/tsInferType.cpp +++ b/ets2panda/ir/ts/tsInferType.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/ts/tsTypeParameter.h" namespace panda::es2panda::ir { @@ -37,6 +38,11 @@ void TSInferType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSInferType"}, {"typeParameter", type_param_}}); } +void TSInferType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSInferType"); +} + void TSInferType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsInferType.h b/ets2panda/ir/ts/tsInferType.h index 0609b12c9..5f7023b99 100644 --- a/ets2panda/ir/ts/tsInferType.h +++ b/ets2panda/ir/ts/tsInferType.h @@ -33,6 +33,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsInterfaceBody.cpp b/ets2panda/ir/ts/tsInterfaceBody.cpp index 418b66f22..ecdb20767 100644 --- a/ets2panda/ir/ts/tsInterfaceBody.cpp +++ b/ets2panda/ir/ts/tsInterfaceBody.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSInterfaceBody::TransformChildren(const NodeTransformer &cb) @@ -40,6 +41,13 @@ void TSInterfaceBody::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSInterfaceBody"}, {"body", body_}}); } +void TSInterfaceBody::Dump(ir::SrcDumper *dumper) const +{ + for (auto b : body_) { + b->Dump(dumper); + } +} + void TSInterfaceBody::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsInterfaceBody.h b/ets2panda/ir/ts/tsInterfaceBody.h index 4e0396b93..74bd7cc0a 100644 --- a/ets2panda/ir/ts/tsInterfaceBody.h +++ b/ets2panda/ir/ts/tsInterfaceBody.h @@ -44,6 +44,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsInterfaceDeclaration.cpp b/ets2panda/ir/ts/tsInterfaceDeclaration.cpp index 9dc4135dc..8aa2b8ebc 100644 --- a/ets2panda/ir/ts/tsInterfaceDeclaration.cpp +++ b/ets2panda/ir/ts/tsInterfaceDeclaration.cpp @@ -15,6 +15,7 @@ #include "tsInterfaceDeclaration.h" +#include "macros.h" #include "varbinder/declaration.h" #include "varbinder/scope.h" #include "varbinder/variable.h" @@ -23,6 +24,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/decorator.h" #include "ir/expressions/identifier.h" #include "ir/ts/tsInterfaceBody.h" @@ -79,6 +81,41 @@ void TSInterfaceDeclaration::Dump(ir::AstDumper *dumper) const {"typeParameters", AstDumper::Optional(type_params_)}}); } +void TSInterfaceDeclaration::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(id_); + + dumper->Add("interface "); + id_->Dump(dumper); + + if (type_params_ != nullptr) { + dumper->Add("<"); + type_params_->Dump(dumper); + dumper->Add(">"); + } + + if (!extends_.empty()) { + dumper->Add(" extends "); + for (auto ext : extends_) { + ext->Dump(dumper); + if (ext != extends_.back()) { + dumper->Add(", "); + } + } + } + + dumper->Add(" {"); + if (body_ != nullptr) { + dumper->IncrIndent(); + dumper->Endl(); + body_->Dump(dumper); + dumper->DecrIndent(); + dumper->Endl(); + } + dumper->Add("}"); + dumper->Endl(); +} + void TSInterfaceDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsInterfaceDeclaration.h b/ets2panda/ir/ts/tsInterfaceDeclaration.h index ce7d18f62..832f9adb6 100644 --- a/ets2panda/ir/ts/tsInterfaceDeclaration.h +++ b/ets2panda/ir/ts/tsInterfaceDeclaration.h @@ -154,6 +154,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsInterfaceHeritage.cpp b/ets2panda/ir/ts/tsInterfaceHeritage.cpp index e14e86eca..9346dde8c 100644 --- a/ets2panda/ir/ts/tsInterfaceHeritage.cpp +++ b/ets2panda/ir/ts/tsInterfaceHeritage.cpp @@ -14,6 +14,7 @@ */ #include "tsInterfaceHeritage.h" +#include #include "varbinder/scope.h" #include "checker/TSchecker.h" @@ -21,6 +22,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/identifier.h" #include "ir/ts/tsTypeParameterInstantiation.h" #include "ir/ts/tsTypeReference.h" @@ -44,6 +46,12 @@ void TSInterfaceHeritage::Dump(ir::AstDumper *dumper) const }); } +void TSInterfaceHeritage::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(expr_ != nullptr); + expr_->Dump(dumper); +} + void TSInterfaceHeritage::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsInterfaceHeritage.h b/ets2panda/ir/ts/tsInterfaceHeritage.h index c677b5a35..5752c2ea1 100644 --- a/ets2panda/ir/ts/tsInterfaceHeritage.h +++ b/ets2panda/ir/ts/tsInterfaceHeritage.h @@ -39,6 +39,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsIntersectionType.cpp b/ets2panda/ir/ts/tsIntersectionType.cpp index a25efa437..42a0b7e16 100644 --- a/ets2panda/ir/ts/tsIntersectionType.cpp +++ b/ets2panda/ir/ts/tsIntersectionType.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/ETSchecker.h" namespace panda::es2panda::ir { @@ -41,6 +42,11 @@ void TSIntersectionType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSIntersectionType"}, {"types", types_}}); } +void TSIntersectionType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSIntersectionType"); +} + void TSIntersectionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsIntersectionType.h b/ets2panda/ir/ts/tsIntersectionType.h index 08e94c2a0..4c205273f 100644 --- a/ets2panda/ir/ts/tsIntersectionType.h +++ b/ets2panda/ir/ts/tsIntersectionType.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsLiteralType.cpp b/ets2panda/ir/ts/tsLiteralType.cpp index 44d05c36f..ed241dc8d 100644 --- a/ets2panda/ir/ts/tsLiteralType.cpp +++ b/ets2panda/ir/ts/tsLiteralType.cpp @@ -18,6 +18,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" namespace panda::es2panda::ir { @@ -36,6 +37,11 @@ void TSLiteralType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSLiteralType"}, {"literal", literal_}}); } +void TSLiteralType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSLiteralType"); +} + void TSLiteralType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsLiteralType.h b/ets2panda/ir/ts/tsLiteralType.h index 44088e32c..b867c0e1b 100644 --- a/ets2panda/ir/ts/tsLiteralType.h +++ b/ets2panda/ir/ts/tsLiteralType.h @@ -31,6 +31,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsMappedType.cpp b/ets2panda/ir/ts/tsMappedType.cpp index cb9c54072..ed00ebd1d 100644 --- a/ets2panda/ir/ts/tsMappedType.cpp +++ b/ets2panda/ir/ts/tsMappedType.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" #include "ir/ts/tsTypeParameter.h" @@ -52,6 +53,11 @@ void TSMappedType::Dump(ir::AstDumper *dumper) const : AstDumper::Optional("-")}}); } +void TSMappedType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSMappedType"); +} + void TSMappedType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsMappedType.h b/ets2panda/ir/ts/tsMappedType.h index 42d352b3a..a073f939a 100644 --- a/ets2panda/ir/ts/tsMappedType.h +++ b/ets2panda/ir/ts/tsMappedType.h @@ -55,6 +55,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsModuleBlock.cpp b/ets2panda/ir/ts/tsModuleBlock.cpp index 1b3443a72..806d4282f 100644 --- a/ets2panda/ir/ts/tsModuleBlock.cpp +++ b/ets2panda/ir/ts/tsModuleBlock.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSModuleBlock::TransformChildren(const NodeTransformer &cb) @@ -41,6 +42,11 @@ void TSModuleBlock::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSModuleBlock"}, {"body", statements_}}); } +void TSModuleBlock::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSModuleBlock"); +} + void TSModuleBlock::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsModuleBlock.h b/ets2panda/ir/ts/tsModuleBlock.h index f6c512a94..e4eab3a1a 100644 --- a/ets2panda/ir/ts/tsModuleBlock.h +++ b/ets2panda/ir/ts/tsModuleBlock.h @@ -50,6 +50,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsModuleDeclaration.cpp b/ets2panda/ir/ts/tsModuleDeclaration.cpp index 25ad9e657..7fe62de00 100644 --- a/ets2panda/ir/ts/tsModuleDeclaration.cpp +++ b/ets2panda/ir/ts/tsModuleDeclaration.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/base/decorator.h" #include "ir/expression.h" @@ -60,6 +61,11 @@ void TSModuleDeclaration::Dump(ir::AstDumper *dumper) const {"global", global_}}); } +void TSModuleDeclaration::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSModuleDeclaration"); +} + void TSModuleDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsModuleDeclaration.h b/ets2panda/ir/ts/tsModuleDeclaration.h index ba3aa58bb..d2d5d0cf7 100644 --- a/ets2panda/ir/ts/tsModuleDeclaration.h +++ b/ets2panda/ir/ts/tsModuleDeclaration.h @@ -89,6 +89,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsNamedTupleMember.cpp b/ets2panda/ir/ts/tsNamedTupleMember.cpp index bfea9f07d..5aec5d96f 100644 --- a/ets2panda/ir/ts/tsNamedTupleMember.cpp +++ b/ets2panda/ir/ts/tsNamedTupleMember.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSNamedTupleMember::TransformChildren(const NodeTransformer &cb) @@ -42,6 +43,11 @@ void TSNamedTupleMember::Dump(ir::AstDumper *dumper) const {"optional", AstDumper::Optional(optional_)}}); } +void TSNamedTupleMember::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSNamedTupleMember"); +} + void TSNamedTupleMember::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsNamedTupleMember.h b/ets2panda/ir/ts/tsNamedTupleMember.h index 8cec5e861..28545cbb7 100644 --- a/ets2panda/ir/ts/tsNamedTupleMember.h +++ b/ets2panda/ir/ts/tsNamedTupleMember.h @@ -49,6 +49,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsNeverKeyword.cpp b/ets2panda/ir/ts/tsNeverKeyword.cpp index ee52a42c6..092d86ca8 100644 --- a/ets2panda/ir/ts/tsNeverKeyword.cpp +++ b/ets2panda/ir/ts/tsNeverKeyword.cpp @@ -18,6 +18,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" namespace panda::es2panda::ir { @@ -29,6 +30,11 @@ void TSNeverKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSNeverKeyword"}}); } +void TSNeverKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSNeverKeyword"); +} + void TSNeverKeyword::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsNeverKeyword.h b/ets2panda/ir/ts/tsNeverKeyword.h index 8df44f6a7..948991fba 100644 --- a/ets2panda/ir/ts/tsNeverKeyword.h +++ b/ets2panda/ir/ts/tsNeverKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsNonNullExpression.cpp b/ets2panda/ir/ts/tsNonNullExpression.cpp index ac49f17ac..7dc7a91a6 100644 --- a/ets2panda/ir/ts/tsNonNullExpression.cpp +++ b/ets2panda/ir/ts/tsNonNullExpression.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSNonNullExpression::TransformChildren(const NodeTransformer &cb) @@ -37,6 +38,13 @@ void TSNonNullExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSNonNullExpression"}, {"expression", expr_}}); } +void TSNonNullExpression::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(expr_ != nullptr); + expr_->Dump(dumper); + dumper->Add("!"); +} + void TSNonNullExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsNonNullExpression.h b/ets2panda/ir/ts/tsNonNullExpression.h index ebd95ca8f..1453a835d 100644 --- a/ets2panda/ir/ts/tsNonNullExpression.h +++ b/ets2panda/ir/ts/tsNonNullExpression.h @@ -37,6 +37,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile([[maybe_unused]] compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsNullKeyword.cpp b/ets2panda/ir/ts/tsNullKeyword.cpp index 1ecd83824..6c380c67d 100644 --- a/ets2panda/ir/ts/tsNullKeyword.cpp +++ b/ets2panda/ir/ts/tsNullKeyword.cpp @@ -18,6 +18,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" namespace panda::es2panda::ir { @@ -29,6 +30,11 @@ void TSNullKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSNullKeyword"}}); } +void TSNullKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSNullKeyword"); +} + void TSNullKeyword::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsNullKeyword.h b/ets2panda/ir/ts/tsNullKeyword.h index 6f72575c7..5c87da2ca 100644 --- a/ets2panda/ir/ts/tsNullKeyword.h +++ b/ets2panda/ir/ts/tsNullKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsNumberKeyword.cpp b/ets2panda/ir/ts/tsNumberKeyword.cpp index 13aca3172..0a7259494 100644 --- a/ets2panda/ir/ts/tsNumberKeyword.cpp +++ b/ets2panda/ir/ts/tsNumberKeyword.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSNumberKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void TSNumberKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSNumberKeyword"}}); } +void TSNumberKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSNumberKeyword"); +} + void TSNumberKeyword::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsNumberKeyword.h b/ets2panda/ir/ts/tsNumberKeyword.h index 1b24a8696..33257ae93 100644 --- a/ets2panda/ir/ts/tsNumberKeyword.h +++ b/ets2panda/ir/ts/tsNumberKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsObjectKeyword.cpp b/ets2panda/ir/ts/tsObjectKeyword.cpp index da0fea006..ccbfbb678 100644 --- a/ets2panda/ir/ts/tsObjectKeyword.cpp +++ b/ets2panda/ir/ts/tsObjectKeyword.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSObjectKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void TSObjectKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSObjectKeyword"}}); } +void TSObjectKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSObjectKeyword"); +} + void TSObjectKeyword::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsObjectKeyword.h b/ets2panda/ir/ts/tsObjectKeyword.h index 2a1b328e6..69f6c1ca9 100644 --- a/ets2panda/ir/ts/tsObjectKeyword.h +++ b/ets2panda/ir/ts/tsObjectKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsParameterProperty.cpp b/ets2panda/ir/ts/tsParameterProperty.cpp index 4f5cfd854..309175304 100644 --- a/ets2panda/ir/ts/tsParameterProperty.cpp +++ b/ets2panda/ir/ts/tsParameterProperty.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expression.h" namespace panda::es2panda::ir { @@ -45,6 +46,11 @@ void TSParameterProperty::Dump(ir::AstDumper *dumper) const {"parameter", parameter_}}); } +void TSParameterProperty::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSParameterProperty"); +} + void TSParameterProperty::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsParameterProperty.h b/ets2panda/ir/ts/tsParameterProperty.h index 4144e57cb..9f8baa2b1 100644 --- a/ets2panda/ir/ts/tsParameterProperty.h +++ b/ets2panda/ir/ts/tsParameterProperty.h @@ -63,6 +63,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsParenthesizedType.cpp b/ets2panda/ir/ts/tsParenthesizedType.cpp index 04012a2b2..d6e415dd1 100644 --- a/ets2panda/ir/ts/tsParenthesizedType.cpp +++ b/ets2panda/ir/ts/tsParenthesizedType.cpp @@ -18,6 +18,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" namespace panda::es2panda::ir { @@ -36,6 +37,11 @@ void TSParenthesizedType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSParenthesizedType"}, {"typeAnnotation", type_}}); } +void TSParenthesizedType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSParenthesizedType"); +} + void TSParenthesizedType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsParenthesizedType.h b/ets2panda/ir/ts/tsParenthesizedType.h index 1eac0852d..61cf2ea52 100644 --- a/ets2panda/ir/ts/tsParenthesizedType.h +++ b/ets2panda/ir/ts/tsParenthesizedType.h @@ -36,6 +36,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsQualifiedName.cpp b/ets2panda/ir/ts/tsQualifiedName.cpp index c9099debb..d87a88409 100644 --- a/ets2panda/ir/ts/tsQualifiedName.cpp +++ b/ets2panda/ir/ts/tsQualifiedName.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/identifier.h" namespace panda::es2panda::ir { @@ -40,6 +41,11 @@ void TSQualifiedName::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSQualifiedName"}, {"left", left_}, {"right", right_}}); } +void TSQualifiedName::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSQualifiedName"); +} + void TSQualifiedName::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsQualifiedName.h b/ets2panda/ir/ts/tsQualifiedName.h index 7d00a524d..a59bf6aa3 100644 --- a/ets2panda/ir/ts/tsQualifiedName.h +++ b/ets2panda/ir/ts/tsQualifiedName.h @@ -54,6 +54,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsStringKeyword.cpp b/ets2panda/ir/ts/tsStringKeyword.cpp index 11caf9ca5..b28c67c7b 100644 --- a/ets2panda/ir/ts/tsStringKeyword.cpp +++ b/ets2panda/ir/ts/tsStringKeyword.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSStringKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void TSStringKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSStringKeyword"}}); } +void TSStringKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSStringKeyword"); +} + void TSStringKeyword::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsStringKeyword.h b/ets2panda/ir/ts/tsStringKeyword.h index 9fe1030d0..18bd3c338 100644 --- a/ets2panda/ir/ts/tsStringKeyword.h +++ b/ets2panda/ir/ts/tsStringKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsThisType.cpp b/ets2panda/ir/ts/tsThisType.cpp index 9827778d6..e98bde61e 100644 --- a/ets2panda/ir/ts/tsThisType.cpp +++ b/ets2panda/ir/ts/tsThisType.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSThisType::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -29,6 +30,11 @@ void TSThisType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSThisType"}}); } +void TSThisType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSThisType"); +} + void TSThisType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsThisType.h b/ets2panda/ir/ts/tsThisType.h index 82e9f4062..bdf171364 100644 --- a/ets2panda/ir/ts/tsThisType.h +++ b/ets2panda/ir/ts/tsThisType.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTupleType.cpp b/ets2panda/ir/ts/tsTupleType.cpp index 624d95823..80111e7c2 100644 --- a/ets2panda/ir/ts/tsTupleType.cpp +++ b/ets2panda/ir/ts/tsTupleType.cpp @@ -22,6 +22,7 @@ #include "checker/TSchecker.h" #include "checker/types/ts/indexInfo.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/identifier.h" #include "ir/ts/tsNamedTupleMember.h" @@ -45,6 +46,11 @@ void TSTupleType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSTupleType"}, {"elementTypes", element_types_}}); } +void TSTupleType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSTupleType"); +} + void TSTupleType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTupleType.h b/ets2panda/ir/ts/tsTupleType.h index 5cf53189d..c855bffec 100644 --- a/ets2panda/ir/ts/tsTupleType.h +++ b/ets2panda/ir/ts/tsTupleType.h @@ -36,6 +36,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp b/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp index 83bf37932..aafa75994 100644 --- a/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp +++ b/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp @@ -14,12 +14,15 @@ */ #include "tsTypeAliasDeclaration.h" +#include +#include "macros.h" #include "varbinder/scope.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" #include "ir/base/decorator.h" #include "ir/expressions/identifier.h" @@ -71,6 +74,26 @@ void TSTypeAliasDeclaration::Dump(ir::AstDumper *dumper) const {"declare", AstDumper::Optional(declare_)}}); } +void TSTypeAliasDeclaration::Dump(ir::SrcDumper *dumper) const +{ + ASSERT(id_); + dumper->Add("type "); + id_->Dump(dumper); + if (type_params_ != nullptr) { + dumper->Add("<"); + type_params_->Dump(dumper); + dumper->Add(">"); + } + dumper->Add(" = "); + if (id_->IsAnnotatedExpression()) { + auto type = TypeAnnotation(); + ASSERT(type); + type->Dump(dumper); + } + dumper->Add(";"); + dumper->Endl(); +} + void TSTypeAliasDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeAliasDeclaration.h b/ets2panda/ir/ts/tsTypeAliasDeclaration.h index 5108c08e3..9c4415dd5 100644 --- a/ets2panda/ir/ts/tsTypeAliasDeclaration.h +++ b/ets2panda/ir/ts/tsTypeAliasDeclaration.h @@ -95,6 +95,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeAssertion.cpp b/ets2panda/ir/ts/tsTypeAssertion.cpp index 2c2bd745e..15a20c7d0 100644 --- a/ets2panda/ir/ts/tsTypeAssertion.cpp +++ b/ets2panda/ir/ts/tsTypeAssertion.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" namespace panda::es2panda::ir { @@ -39,6 +40,11 @@ void TSTypeAssertion::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSTypeAssertion"}, {"typeAnnotation", TypeAnnotation()}, {"expression", expression_}}); } +void TSTypeAssertion::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSTypeAssertion"); +} + void TSTypeAssertion::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeAssertion.h b/ets2panda/ir/ts/tsTypeAssertion.h index 90f2856ed..e06e81fa9 100644 --- a/ets2panda/ir/ts/tsTypeAssertion.h +++ b/ets2panda/ir/ts/tsTypeAssertion.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeLiteral.cpp b/ets2panda/ir/ts/tsTypeLiteral.cpp index 9f9471ab8..c05861d2b 100644 --- a/ets2panda/ir/ts/tsTypeLiteral.cpp +++ b/ets2panda/ir/ts/tsTypeLiteral.cpp @@ -18,6 +18,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "varbinder/variable.h" #include "varbinder/declaration.h" @@ -44,6 +45,11 @@ void TSTypeLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSTypeLiteral"}, {"members", members_}}); } +void TSTypeLiteral::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSTypeLiteral"); +} + void TSTypeLiteral::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeLiteral.h b/ets2panda/ir/ts/tsTypeLiteral.h index 773cae006..9de5ba681 100644 --- a/ets2panda/ir/ts/tsTypeLiteral.h +++ b/ets2panda/ir/ts/tsTypeLiteral.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeOperator.cpp b/ets2panda/ir/ts/tsTypeOperator.cpp index f945f6e43..05aa4ef72 100644 --- a/ets2panda/ir/ts/tsTypeOperator.cpp +++ b/ets2panda/ir/ts/tsTypeOperator.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSTypeOperator::TransformChildren(const NodeTransformer &cb) @@ -40,6 +41,11 @@ void TSTypeOperator::Dump(ir::AstDumper *dumper) const }); } +void TSTypeOperator::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSTypeOperator"); +} + void TSTypeOperator::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeOperator.h b/ets2panda/ir/ts/tsTypeOperator.h index 921746337..8c8266290 100644 --- a/ets2panda/ir/ts/tsTypeOperator.h +++ b/ets2panda/ir/ts/tsTypeOperator.h @@ -49,6 +49,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeParameter.cpp b/ets2panda/ir/ts/tsTypeParameter.cpp index e464990af..a16ad2100 100644 --- a/ets2panda/ir/ts/tsTypeParameter.cpp +++ b/ets2panda/ir/ts/tsTypeParameter.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" #include "ir/expressions/identifier.h" @@ -61,6 +62,11 @@ void TSTypeParameter::Dump(ir::AstDumper *dumper) const }); } +void TSTypeParameter::Dump(ir::SrcDumper *dumper) const +{ + name_->Dump(dumper); +} + void TSTypeParameter::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeParameter.h b/ets2panda/ir/ts/tsTypeParameter.h index edcde8069..3b2cafbbe 100644 --- a/ets2panda/ir/ts/tsTypeParameter.h +++ b/ets2panda/ir/ts/tsTypeParameter.h @@ -65,6 +65,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeParameterDeclaration.cpp b/ets2panda/ir/ts/tsTypeParameterDeclaration.cpp index 128f2abae..0a3456470 100644 --- a/ets2panda/ir/ts/tsTypeParameterDeclaration.cpp +++ b/ets2panda/ir/ts/tsTypeParameterDeclaration.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/ts/tsTypeParameter.h" namespace panda::es2panda::ir { @@ -42,6 +43,16 @@ void TSTypeParameterDeclaration::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSTypeParameterDeclaration"}, {"params", params_}}); } +void TSTypeParameterDeclaration::Dump(ir::SrcDumper *dumper) const +{ + for (auto param : params_) { + param->Dump(dumper); + if (param != params_.back()) { + dumper->Add(", "); + } + } +} + void TSTypeParameterDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeParameterDeclaration.h b/ets2panda/ir/ts/tsTypeParameterDeclaration.h index cf2b725a4..d0e81380a 100644 --- a/ets2panda/ir/ts/tsTypeParameterDeclaration.h +++ b/ets2panda/ir/ts/tsTypeParameterDeclaration.h @@ -67,6 +67,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeParameterInstantiation.cpp b/ets2panda/ir/ts/tsTypeParameterInstantiation.cpp index e4174bf08..ef538c9bc 100644 --- a/ets2panda/ir/ts/tsTypeParameterInstantiation.cpp +++ b/ets2panda/ir/ts/tsTypeParameterInstantiation.cpp @@ -20,6 +20,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expression.h" #include "ir/typeNode.h" @@ -66,6 +67,20 @@ void TSTypeParameterInstantiation::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSTypeParameterInstantiation"}, {"params", params_}}); } +void TSTypeParameterInstantiation::Dump(ir::SrcDumper *dumper) const +{ + if (!params_.empty()) { + dumper->Add("<"); + for (auto param : params_) { + param->Dump(dumper); + if (param != params_.back()) { + dumper->Add(", "); + } + } + dumper->Add(">"); + } +} + void TSTypeParameterInstantiation::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeParameterInstantiation.h b/ets2panda/ir/ts/tsTypeParameterInstantiation.h index b05622389..be57a1c50 100644 --- a/ets2panda/ir/ts/tsTypeParameterInstantiation.h +++ b/ets2panda/ir/ts/tsTypeParameterInstantiation.h @@ -48,6 +48,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypePredicate.cpp b/ets2panda/ir/ts/tsTypePredicate.cpp index 16c99b874..944b36c0e 100644 --- a/ets2panda/ir/ts/tsTypePredicate.cpp +++ b/ets2panda/ir/ts/tsTypePredicate.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/typeNode.h" #include "ir/expression.h" @@ -46,6 +47,10 @@ void TSTypePredicate::Dump(ir::AstDumper *dumper) const {"typeAnnotation", AstDumper::Nullish(type_annotation_)}, {"asserts", asserts_}}); } +void TSTypePredicate::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSTypePredicate"); +} void TSTypePredicate::Compile([[maybe_unused]] compiler::PandaGen *pg) const { diff --git a/ets2panda/ir/ts/tsTypePredicate.h b/ets2panda/ir/ts/tsTypePredicate.h index 9a9ac81a8..7c67230dc 100644 --- a/ets2panda/ir/ts/tsTypePredicate.h +++ b/ets2panda/ir/ts/tsTypePredicate.h @@ -47,6 +47,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeQuery.cpp b/ets2panda/ir/ts/tsTypeQuery.cpp index cb45ace08..c9f24088c 100644 --- a/ets2panda/ir/ts/tsTypeQuery.cpp +++ b/ets2panda/ir/ts/tsTypeQuery.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "checker/TSchecker.h" namespace panda::es2panda::ir { @@ -37,6 +38,11 @@ void TSTypeQuery::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSTypeQuery"}, {"exprName", expr_name_}}); } +void TSTypeQuery::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSTypeQuery"); +} + void TSTypeQuery::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeQuery.h b/ets2panda/ir/ts/tsTypeQuery.h index 0c6b3a86d..83a2ffbbb 100644 --- a/ets2panda/ir/ts/tsTypeQuery.h +++ b/ets2panda/ir/ts/tsTypeQuery.h @@ -35,6 +35,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeReference.cpp b/ets2panda/ir/ts/tsTypeReference.cpp index ed6d359ce..654fbd59e 100644 --- a/ets2panda/ir/ts/tsTypeReference.cpp +++ b/ets2panda/ir/ts/tsTypeReference.cpp @@ -22,6 +22,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" #include "ir/expressions/identifier.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/ts/tsTypeAliasDeclaration.h" @@ -54,6 +55,11 @@ void TSTypeReference::Dump(ir::AstDumper *dumper) const {{"type", "TSTypeReference"}, {"typeName", type_name_}, {"typeParameters", AstDumper::Optional(type_params_)}}); } +void TSTypeReference::Dump(ir::SrcDumper *dumper) const +{ + BaseName()->Dump(dumper); +} + void TSTypeReference::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsTypeReference.h b/ets2panda/ir/ts/tsTypeReference.h index 3bbed87b8..24f64e8e2 100644 --- a/ets2panda/ir/ts/tsTypeReference.h +++ b/ets2panda/ir/ts/tsTypeReference.h @@ -47,6 +47,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsUndefinedKeyword.cpp b/ets2panda/ir/ts/tsUndefinedKeyword.cpp index ba59f6f22..30bd1818c 100644 --- a/ets2panda/ir/ts/tsUndefinedKeyword.cpp +++ b/ets2panda/ir/ts/tsUndefinedKeyword.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSUndefinedKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void TSUndefinedKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSUndefinedKeyword"}}); } +void TSUndefinedKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSUndefinedKeyword"); +} + void TSUndefinedKeyword::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsUndefinedKeyword.h b/ets2panda/ir/ts/tsUndefinedKeyword.h index cff5e9407..14fc4cd18 100644 --- a/ets2panda/ir/ts/tsUndefinedKeyword.h +++ b/ets2panda/ir/ts/tsUndefinedKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsUnionType.cpp b/ets2panda/ir/ts/tsUnionType.cpp index 802d5d65c..2d8c04d86 100644 --- a/ets2panda/ir/ts/tsUnionType.cpp +++ b/ets2panda/ir/ts/tsUnionType.cpp @@ -19,6 +19,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" #include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSUnionType::TransformChildren(const NodeTransformer &cb) @@ -40,6 +41,11 @@ void TSUnionType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSUnionType"}, {"types", types_}}); } +void TSUnionType::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSUnionType"); +} + void TSUnionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsUnionType.h b/ets2panda/ir/ts/tsUnionType.h index 925f71010..c32c87512 100644 --- a/ets2panda/ir/ts/tsUnionType.h +++ b/ets2panda/ir/ts/tsUnionType.h @@ -34,6 +34,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsUnknownKeyword.cpp b/ets2panda/ir/ts/tsUnknownKeyword.cpp index d8e35bf46..44cae0961 100644 --- a/ets2panda/ir/ts/tsUnknownKeyword.cpp +++ b/ets2panda/ir/ts/tsUnknownKeyword.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSUnknownKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void TSUnknownKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSUnknownKeyword"}}); } +void TSUnknownKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSUnknownKeyword"); +} + void TSUnknownKeyword::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsUnknownKeyword.h b/ets2panda/ir/ts/tsUnknownKeyword.h index 6f2a37831..0100912bd 100644 --- a/ets2panda/ir/ts/tsUnknownKeyword.h +++ b/ets2panda/ir/ts/tsUnknownKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsVoidKeyword.cpp b/ets2panda/ir/ts/tsVoidKeyword.cpp index 47502deb3..5b39b7251 100644 --- a/ets2panda/ir/ts/tsVoidKeyword.cpp +++ b/ets2panda/ir/ts/tsVoidKeyword.cpp @@ -18,6 +18,8 @@ #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" +#include "ir/astDump.h" +#include "ir/srcDump.h" namespace panda::es2panda::ir { void TSVoidKeyword::TransformChildren([[maybe_unused]] const NodeTransformer &cb) {} @@ -28,6 +30,11 @@ void TSVoidKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSVoidKeyword"}}); } +void TSVoidKeyword::Dump(ir::SrcDumper *dumper) const +{ + dumper->Add("TSVoidKeyword"); +} + void TSVoidKeyword::Compile(compiler::PandaGen *pg) const { pg->GetAstCompiler()->Compile(this); diff --git a/ets2panda/ir/ts/tsVoidKeyword.h b/ets2panda/ir/ts/tsVoidKeyword.h index 7525b4683..0ceee4d69 100644 --- a/ets2panda/ir/ts/tsVoidKeyword.h +++ b/ets2panda/ir/ts/tsVoidKeyword.h @@ -26,6 +26,7 @@ public: void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; + void Dump(ir::SrcDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check(checker::TSChecker *checker) override; diff --git a/ets2panda/test/unit/ast_dumper_test.cpp b/ets2panda/test/unit/ast_dumper_test.cpp index e57b5adfe..f8cce9931 100644 --- a/ets2panda/test/unit/ast_dumper_test.cpp +++ b/ets2panda/test/unit/ast_dumper_test.cpp @@ -121,3 +121,29 @@ TEST_F(ASTDumperTest, DumpJsonUTF16Char) ASSERT_FALSE(dump_str.empty()); } + +TEST_F(ASTDumperTest, DumpEtsSrcSimple) +{ + static constexpr std::string_view FILE_NAME = "dummy.ets"; + static constexpr std::string_view SRC = + "\ + function main(args: String[]): int {\ + let a: int = 2;\ + let b: int = 3;\ + return a + b;\ + }"; + + int argc = 1; + const char *argv = + "--extension=ets " + "--dump-ets-src-before-phases=\"plugins-after-parse:lambda-lowering:checker:plugins-after-check:generate-ts-" + "declarations:op-assignment:tuple-lowering:union-property-access:plugins-after-lowering\""; + + auto program = std::unique_ptr {GetProgram(argc, &argv, FILE_NAME, SRC)}; + + ASSERT_NE(program, nullptr); + + auto dump_str = program->JsonDump(); + + ASSERT_FALSE(dump_str.empty()); +} diff --git a/ets2panda/util/options.cpp b/ets2panda/util/options.cpp index 7df1a6567..ef9399af1 100644 --- a/ets2panda/util/options.cpp +++ b/ets2panda/util/options.cpp @@ -183,6 +183,10 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg skip_phases("skip-phases", "", "Phases to skip"); panda::PandArg dump_before_phases("dump-before-phases", "", "Generate program dump before running phases in the list"); + panda::PandArg dump_ets_src_before_phases( + "dump-ets-src-before-phases", "", "Generate program dump as ets source code before running phases in the list"); + panda::PandArg dump_ets_src_after_phases( + "dump-ets-src-after-phases", "", "Generate program dump as ets source code after 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( @@ -219,7 +223,9 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&plugins); argparser_->Add(&skip_phases); argparser_->Add(&dump_before_phases); + argparser_->Add(&dump_ets_src_before_phases); argparser_->Add(&dump_after_phases); + argparser_->Add(&dump_ets_src_after_phases); argparser_->Add(&arkts_config); argparser_->Add(&op_ts_decl_out); @@ -395,6 +401,12 @@ bool Options::Parse(int argc, const char **argv) } } + if ((dump_ets_src_before_phases.GetValue().size() + dump_ets_src_after_phases.GetValue().size() > 0) && + extension_ != es2panda::ScriptExtension::ETS) { + error_msg_ = "--dump-ets-src-* option is valid only with ETS extension"; + return false; + } + compiler_options_.ts_decl_out = op_ts_decl_out.GetValue(); compiler_options_.dump_asm = op_dump_assembly.GetValue(); compiler_options_.dump_ast = op_dump_ast.GetValue(); @@ -409,7 +421,9 @@ bool Options::Parse(int argc, const char **argv) compiler_options_.plugins = SplitToStringVector(plugins.GetValue()); compiler_options_.skip_phases = SplitToStringSet(skip_phases.GetValue()); compiler_options_.dump_before_phases = SplitToStringSet(dump_before_phases.GetValue()); + compiler_options_.dump_ets_src_before_phases = SplitToStringSet(dump_ets_src_before_phases.GetValue()); compiler_options_.dump_after_phases = SplitToStringSet(dump_after_phases.GetValue()); + compiler_options_.dump_ets_src_after_phases = SplitToStringSet(dump_ets_src_after_phases.GetValue()); return true; } -- Gitee From 525f4f8801f04fe4310c632fa12c63910cce6c50 Mon Sep 17 00:00:00 2001 From: Molokanov Yaroslav Date: Tue, 21 Nov 2023 18:15:28 +0300 Subject: [PATCH 07/35] Title: Add support of sequence convertion with boxing/unboxing Description: Support cast expression using all posible casts (not only one as it was before) Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8MM9L Testing: ets2panda/test/runtime/ets/castSequence.ets Signed-off-by: Molokanov Yaroslav --- ets2panda/checker/ets/conversion.cpp | 20 +++++++ ets2panda/checker/ets/conversion.h | 2 + ets2panda/checker/types/ets/byteType.cpp | 10 ++++ ets2panda/checker/types/ets/charType.cpp | 10 ++++ ets2panda/checker/types/ets/doubleType.cpp | 10 ++++ ets2panda/checker/types/ets/etsObjectType.cpp | 55 +++++++++--------- ets2panda/checker/types/ets/etsObjectType.h | 2 +- ets2panda/checker/types/ets/floatType.cpp | 10 ++++ ets2panda/checker/types/ets/intType.cpp | 10 ++++ ets2panda/checker/types/ets/longType.cpp | 10 ++++ ets2panda/checker/types/ets/shortType.cpp | 10 ++++ ets2panda/compiler/core/ETSCompiler.cpp | 56 ++++++++++++++++++- ets2panda/compiler/core/ETSGen.cpp | 32 ++++++----- ets2panda/compiler/core/ETSGen.h | 2 + ets2panda/test/runtime/ets/castSequence.ets | 34 +++++++++++ 15 files changed, 229 insertions(+), 44 deletions(-) create mode 100644 ets2panda/test/runtime/ets/castSequence.ets diff --git a/ets2panda/checker/ets/conversion.cpp b/ets2panda/checker/ets/conversion.cpp index b1dd99217..df0eac654 100644 --- a/ets2panda/checker/ets/conversion.cpp +++ b/ets2panda/checker/ets/conversion.cpp @@ -282,6 +282,26 @@ void UnboxingWideningPrimitive(TypeRelation *const relation, ETSObjectType *cons RollbackBoxingIfFailed(relation); } +void UnboxingNarrowingPrimitive(TypeRelation *const relation, ETSObjectType *const source, Type *const target) +{ + auto *const unboxed_source = Unboxing(relation, source); + if (!relation->IsTrue()) { + return; + } + ASSERT(unboxed_source != nullptr); + NarrowingPrimitive(relation, target, unboxed_source); +} + +void UnboxingWideningNarrowingPrimitive(TypeRelation *const relation, ETSObjectType *const source, Type *const target) +{ + auto *const unboxed_source = Unboxing(relation, source); + if (!relation->IsTrue()) { + return; + } + ASSERT(unboxed_source != nullptr); + WideningNarrowingPrimitive(relation, unboxed_source->AsByteType(), target->AsCharType()); +} + void NarrowingReferenceUnboxing(TypeRelation *const relation, ETSObjectType *const source, Type *const target) { auto *const boxed_target = relation->GetChecker()->AsETSChecker()->PrimitiveTypeAsETSBuiltinType(target); diff --git a/ets2panda/checker/ets/conversion.h b/ets2panda/checker/ets/conversion.h index f796162a3..8f28cfa0f 100644 --- a/ets2panda/checker/ets/conversion.h +++ b/ets2panda/checker/ets/conversion.h @@ -37,6 +37,8 @@ void NarrowingReference(TypeRelation *relation, ETSArrayType *source, ETSArrayTy ETSObjectType *Boxing(TypeRelation *relation, Type *source); Type *Unboxing(TypeRelation *relation, ETSObjectType *source); +void UnboxingWideningNarrowingPrimitive(TypeRelation *relation, ETSObjectType *source, Type *target); +void UnboxingNarrowingPrimitive(TypeRelation *relation, ETSObjectType *source, Type *target); void UnboxingWideningPrimitive(TypeRelation *relation, ETSObjectType *source, Type *target); void NarrowingReferenceUnboxing(TypeRelation *relation, ETSObjectType *source, Type *target); void BoxingWideningReference(TypeRelation *relation, Type *source, ETSObjectType *target); diff --git a/ets2panda/checker/types/ets/byteType.cpp b/ets2panda/checker/types/ets/byteType.cpp index f3468bbba..c943b1dd8 100644 --- a/ets2panda/checker/types/ets/byteType.cpp +++ b/ets2panda/checker/types/ets/byteType.cpp @@ -74,6 +74,16 @@ void ByteType::Cast(TypeRelation *const relation, Type *const target) } if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { + auto unboxed_target = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + if (unboxed_target == nullptr) { + conversion::Forbidden(relation); + return; + } + Cast(relation, unboxed_target); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxed_target); + return; + } conversion::Forbidden(relation); return; } diff --git a/ets2panda/checker/types/ets/charType.cpp b/ets2panda/checker/types/ets/charType.cpp index 2c4f3995e..fb25961af 100644 --- a/ets2panda/checker/types/ets/charType.cpp +++ b/ets2panda/checker/types/ets/charType.cpp @@ -74,6 +74,16 @@ void CharType::Cast(TypeRelation *const relation, Type *const target) } if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { + auto unboxed_target = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + if (unboxed_target == nullptr) { + conversion::Forbidden(relation); + return; + } + Cast(relation, unboxed_target); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxed_target); + return; + } conversion::Forbidden(relation); return; } diff --git a/ets2panda/checker/types/ets/doubleType.cpp b/ets2panda/checker/types/ets/doubleType.cpp index 4b3055837..fef74bb61 100644 --- a/ets2panda/checker/types/ets/doubleType.cpp +++ b/ets2panda/checker/types/ets/doubleType.cpp @@ -69,6 +69,16 @@ void DoubleType::Cast(TypeRelation *const relation, Type *const target) } if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { + auto unboxed_target = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + if (unboxed_target == nullptr) { + conversion::Forbidden(relation); + return; + } + Cast(relation, unboxed_target); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxed_target); + return; + } conversion::Forbidden(relation); return; } diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index be89ec759..28c6390e3 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -453,12 +453,10 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const conversion::UnboxingWideningPrimitive(relation, this, target); return true; } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - conversion::WideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::CHAR)) { + conversion::UnboxingWideningNarrowingPrimitive(relation, this, target); return true; } - conversion::Forbidden(relation); - return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT)) { if (target->HasTypeFlag(TypeFlag::SHORT)) { @@ -469,12 +467,10 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const conversion::UnboxingWideningPrimitive(relation, this, target); return true; } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - conversion::WideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::CHAR)) { + conversion::UnboxingNarrowingPrimitive(relation, this, target); return true; } - conversion::Forbidden(relation); - return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { if (target->HasTypeFlag(TypeFlag::CHAR)) { @@ -485,12 +481,10 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const conversion::UnboxingWideningPrimitive(relation, this, target); return true; } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - conversion::WideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT)) { + conversion::UnboxingNarrowingPrimitive(relation, this, target); return true; } - conversion::Forbidden(relation); - return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_INT)) { if (target->HasTypeFlag(TypeFlag::INT)) { @@ -501,12 +495,10 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const conversion::UnboxingWideningPrimitive(relation, this, target); return true; } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - conversion::WideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR)) { + conversion::UnboxingNarrowingPrimitive(relation, this, target); return true; } - conversion::Forbidden(relation); - return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG)) { if (target->HasTypeFlag(TypeFlag::LONG)) { @@ -517,12 +509,10 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const conversion::UnboxingWideningPrimitive(relation, this, target); return true; } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - conversion::WideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT)) { + conversion::UnboxingNarrowingPrimitive(relation, this, target); return true; } - conversion::Forbidden(relation); - return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT)) { if (target->HasTypeFlag(TypeFlag::FLOAT)) { @@ -533,31 +523,40 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const conversion::UnboxingWideningPrimitive(relation, this, target); return true; } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - conversion::WideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG)) { + conversion::UnboxingNarrowingPrimitive(relation, this, target); return true; } - conversion::Forbidden(relation); - return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE)) { if (target->HasTypeFlag(TypeFlag::DOUBLE)) { conversion::Unboxing(relation, this); return true; } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - conversion::WideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | + TypeFlag::FLOAT)) { + conversion::UnboxingNarrowingPrimitive(relation, this, target); return true; } - conversion::Forbidden(relation); - return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN)) { if (target->HasTypeFlag(TypeFlag::ETS_BOOLEAN)) { conversion::Unboxing(relation, this); return true; } + } + if (this->HasObjectFlag(ETSObjectFlags::UNBOXABLE_TYPE)) { if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { + if (!target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::UNBOXABLE_TYPE)) { + conversion::WideningReference(relation, this, target->AsETSObjectType()); + return true; + } + auto unboxed_target = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + CastNumericObject(relation, unboxed_target); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxed_target); + return true; + } conversion::WideningReference(relation, this, target->AsETSObjectType()); return true; } diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 391f54588..eba9f33f0 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -397,7 +397,7 @@ public: return invoke->TsType()->AsETSFunctionType(); } - ETSObjectFlags BuiltInKind() + ETSObjectFlags BuiltInKind() const { return static_cast(flags_ & ETSObjectFlags::BUILTIN_TYPE); } diff --git a/ets2panda/checker/types/ets/floatType.cpp b/ets2panda/checker/types/ets/floatType.cpp index 474118265..68cb1421e 100644 --- a/ets2panda/checker/types/ets/floatType.cpp +++ b/ets2panda/checker/types/ets/floatType.cpp @@ -74,6 +74,16 @@ void FloatType::Cast(TypeRelation *const relation, Type *const target) } if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { + auto unboxed_target = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + if (unboxed_target == nullptr) { + conversion::Forbidden(relation); + return; + } + Cast(relation, unboxed_target); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxed_target); + return; + } conversion::Forbidden(relation); return; } diff --git a/ets2panda/checker/types/ets/intType.cpp b/ets2panda/checker/types/ets/intType.cpp index b9dc7c2e2..fdb4424f7 100644 --- a/ets2panda/checker/types/ets/intType.cpp +++ b/ets2panda/checker/types/ets/intType.cpp @@ -79,6 +79,16 @@ void IntType::Cast(TypeRelation *const relation, Type *const target) } if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { + auto unboxed_target = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + if (unboxed_target == nullptr) { + conversion::Forbidden(relation); + return; + } + Cast(relation, unboxed_target); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxed_target); + return; + } conversion::Forbidden(relation); return; } diff --git a/ets2panda/checker/types/ets/longType.cpp b/ets2panda/checker/types/ets/longType.cpp index abb5df301..aa2098849 100644 --- a/ets2panda/checker/types/ets/longType.cpp +++ b/ets2panda/checker/types/ets/longType.cpp @@ -74,6 +74,16 @@ void LongType::Cast(TypeRelation *const relation, Type *const target) } if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { + auto unboxed_target = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + if (unboxed_target == nullptr) { + conversion::Forbidden(relation); + return; + } + Cast(relation, unboxed_target); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxed_target); + return; + } conversion::Forbidden(relation); return; } diff --git a/ets2panda/checker/types/ets/shortType.cpp b/ets2panda/checker/types/ets/shortType.cpp index a43783d20..041f767dc 100644 --- a/ets2panda/checker/types/ets/shortType.cpp +++ b/ets2panda/checker/types/ets/shortType.cpp @@ -74,6 +74,16 @@ void ShortType::Cast(TypeRelation *const relation, Type *const target) } if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { + auto unboxed_target = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + if (unboxed_target == nullptr) { + conversion::Forbidden(relation); + return; + } + Cast(relation, unboxed_target); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxed_target); + return; + } conversion::Forbidden(relation); return; } diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index de21cbc01..bfbdc3a65 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -1678,9 +1678,61 @@ void ETSCompiler::Compile(const ir::TSAsExpression *expr) const expr->Expr()->Compile(etsg); } - etsg->ApplyConversion(expr->Expr(), nullptr); - auto *target_type = expr->TsType(); + + if ((expr->Expr()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U) { + etsg->ApplyUnboxingConversion(expr->Expr()); + } + + if (target_type->IsETSObjectType() && + ((expr->Expr()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U || + (expr->Expr()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0U) && + checker::ETSChecker::TypeKind(etsg->GetAccumulatorType()) != checker::TypeFlag::ETS_OBJECT) { + if (target_type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::UNBOXABLE_TYPE)) { + switch (target_type->AsETSObjectType()->BuiltInKind()) { + case checker::ETSObjectFlags::BUILTIN_BOOLEAN: { + etsg->CastToBoolean(expr); + break; + } + case checker::ETSObjectFlags::BUILTIN_BYTE: { + etsg->CastToChar(expr); + break; + } + case checker::ETSObjectFlags::BUILTIN_CHAR: { + etsg->CastToByte(expr); + break; + } + case checker::ETSObjectFlags::BUILTIN_SHORT: { + etsg->CastToShort(expr); + break; + } + case checker::ETSObjectFlags::BUILTIN_INT: { + etsg->CastToInt(expr); + break; + } + case checker::ETSObjectFlags::BUILTIN_LONG: { + etsg->CastToLong(expr); + break; + } + case checker::ETSObjectFlags::BUILTIN_FLOAT: { + etsg->CastToFloat(expr); + break; + } + case checker::ETSObjectFlags::BUILTIN_DOUBLE: { + etsg->CastToDouble(expr); + break; + } + default: { + UNREACHABLE(); + } + } + } + } + + if ((expr->Expr()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0U) { + etsg->ApplyBoxingConversion(expr->Expr()); + } + if (target_type->IsETSUnionType()) { target_type = target_type->AsETSUnionType()->FindTypeIsCastableToThis( expr->expression_, etsg->Checker()->Relation(), expr->expression_->TsType()); diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 8d494b0dc..f7c28be88 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -917,28 +917,34 @@ void ETSGen::ApplyConversionCast(const ir::AstNode *node, const checker::Type *t } } +void ETSGen::ApplyBoxingConversion(const ir::AstNode *node) +{ + EmitBoxingConversion(node); + node->SetBoxingUnboxingFlags( + static_cast(node->GetBoxingUnboxingFlags() & ~(ir::BoxingUnboxingFlags::BOXING_FLAG))); +} + +void ETSGen::ApplyUnboxingConversion(const ir::AstNode *node) +{ + if (GetAccumulatorType()->IsNullishOrNullLike()) { // NOTE: vpukhov. should be a CTE + EmitNullishGuardian(node); + } + EmitUnboxingConversion(node); + node->SetBoxingUnboxingFlags(static_cast(node->GetBoxingUnboxingFlags() & + ~(ir::BoxingUnboxingFlags::UNBOXING_FLAG))); +} + void ETSGen::ApplyConversion(const ir::AstNode *node, const checker::Type *target_type) { auto ttctx = TargetTypeContext(this, target_type); if ((node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0U) { - EmitBoxingConversion(node); - const auto boxing_flags = - static_cast(node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG); - node->SetBoxingUnboxingFlags( - static_cast(node->GetBoxingUnboxingFlags() & ~boxing_flags)); + ApplyBoxingConversion(node); return; } if ((node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U) { - if (GetAccumulatorType()->IsNullishOrNullLike()) { // NOTE: vpukhov. should be a CTE - EmitNullishGuardian(node); - } - EmitUnboxingConversion(node); - const auto unboxing_flags = static_cast(node->GetBoxingUnboxingFlags() & - ir::BoxingUnboxingFlags::UNBOXING_FLAG); - node->SetBoxingUnboxingFlags( - static_cast(node->GetBoxingUnboxingFlags() & ~unboxing_flags)); + ApplyUnboxingConversion(node); } if (target_type == nullptr) { diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 516e82d3a..6e93a1c48 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -412,6 +412,8 @@ public: void LoadAccumulatorDynamicModule(const ir::AstNode *node, const ir::ETSImportDeclaration *import); + void ApplyBoxingConversion(const ir::AstNode *node); + void ApplyUnboxingConversion(const ir::AstNode *node); void ApplyConversion(const ir::AstNode *node) { if (target_type_ != nullptr) { diff --git a/ets2panda/test/runtime/ets/castSequence.ets b/ets2panda/test/runtime/ets/castSequence.ets new file mode 100644 index 000000000..c3e86ca68 --- /dev/null +++ b/ets2panda/test/runtime/ets/castSequence.ets @@ -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. + */ + +function main(): void { + let a_int : int = 2147; + let b_Num : Number = a_int as Number; + + assert b_Num instanceof Number && b_Num.unboxed() == 2147.0 + + let a_Short : Short = 215; + let b_double : double = a_Short as double; + + assert a_Short instanceof Short + assert b_double == 215.0 + + let a_Int : Int = 2142; + let b_Double : Double = a_Int as Double; + + assert b_Double instanceof Double && b_Double.unboxed() == 2142.0 + + return; +} \ No newline at end of file -- Gitee From 3363edfef3bc8eb444b8219aece71e00c47006f9 Mon Sep 17 00:00:00 2001 From: Tamas Toth Date: Tue, 12 Dec 2023 13:23:57 +0100 Subject: [PATCH 08/35] [ETS] Fix import alias created bug Fixes #14570 internal issue Issue: I8O20X Signed-off-by: Tamas Toth Change-Id: Ib475d86d9d6e3934fd0631788be452023c328258 --- ets2panda/checker/ets/helpers.cpp | 2 +- .../ets/lambda_import_alias_1-2-expected.txt | 531 ++++++++++++++++++ .../parser/ets/lambda_import_alias_1-2.ets | 18 + .../ets/lambda_import_alias_1-3-expected.txt | 494 ++++++++++++++++ .../parser/ets/lambda_import_alias_1-3.ets | 17 + .../ets/lambda_import_alias_1-expected.txt | 210 +++++++ .../test/parser/ets/lambda_import_alias_1.ets | 16 + 7 files changed, 1287 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt create mode 100644 ets2panda/test/parser/ets/lambda_import_alias_1-2.ets create mode 100644 ets2panda/test/parser/ets/lambda_import_alias_1-3-expected.txt create mode 100644 ets2panda/test/parser/ets/lambda_import_alias_1-3.ets create mode 100644 ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt create mode 100644 ets2panda/test/parser/ets/lambda_import_alias_1.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 04df46922..cad696b0b 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -628,7 +628,7 @@ Type *ETSChecker::ResolveIdentifier(ir::Identifier *const ident) SaveCapturedVariable(resolved, ident->Start()); ident->SetVariable(resolved); - return resolved->TsType(); + return GetTypeOfVariable(resolved); } void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable) diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt b/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt new file mode 100644 index 000000000..fce52818b --- /dev/null +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt @@ -0,0 +1,531 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./", + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 49 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "lib", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 49 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "lib", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "right": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "createA", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 19 + } + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "lib", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "property": { + "type": "Identifier", + "name": "createA", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 42 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "createA", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 19 + } + } + }, + "value": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "lib", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "property": { + "type": "Identifier", + "name": "createA", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 30 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 42 + } + } + } + ], + "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/lambda_import_alias_1-2.ets b/ets2panda/test/parser/ets/lambda_import_alias_1-2.ets new file mode 100644 index 000000000..683d87a18 --- /dev/null +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-2.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. + */ + +import * as lib from "./lambda_import_alias_1-3" +export type A = lib.A +export let createA: () => A = lib.createA diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-3-expected.txt b/ets2panda/test/parser/ets/lambda_import_alias_1-3-expected.txt new file mode 100644 index 000000000..b49ac0e91 --- /dev/null +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-3-expected.txt @@ -0,0 +1,494 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 18 + } + } + }, + { + "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": "createA", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "createA", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 43 + }, + "end": { + "line": 17, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 43 + }, + "end": { + "line": 17, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 43 + }, + "end": { + "line": 17, + "column": 45 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 17, + "column": 39 + }, + "end": { + "line": 17, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 32 + }, + "end": { + "line": 17, + "column": 47 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 17, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 49 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 49 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 18, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-3.ets b/ets2panda/test/parser/ets/lambda_import_alias_1-3.ets new file mode 100644 index 000000000..eb62a7570 --- /dev/null +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-3.ets @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export class A {} +export function createA(): A { return new A(); } diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt b/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt new file mode 100644 index 000000000..fa725f447 --- /dev/null +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt @@ -0,0 +1,210 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./", + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 51 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "index", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 51 + } + } + }, + { + "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": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1.ets b/ets2panda/test/parser/ets/lambda_import_alias_1.ets new file mode 100644 index 000000000..c506b029c --- /dev/null +++ b/ets2panda/test/parser/ets/lambda_import_alias_1.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +import * as index from "./lambda_import_alias_1-2" -- Gitee From ff7d18a7a5f56a352124878f162884d5e9cb3355 Mon Sep 17 00:00:00 2001 From: Torok Gergo Date: Tue, 21 Nov 2023 15:35:28 +0100 Subject: [PATCH 09/35] [ETS] Fixing infer of return type on entrypoint Signed-off-by: Gergo Torok --- ets2panda/checker/ETSAnalyzer.cpp | 4 +- .../ets/inferingEntryPointReturn-expected.txt | 491 ++++++++++++++++++ .../parser/ets/inferingEntryPointReturn.ets | 23 + 3 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/parser/ets/inferingEntryPointReturn-expected.txt create mode 100644 ets2panda/test/parser/ets/inferingEntryPointReturn.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index c7a578595..da1abc232 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2037,7 +2037,9 @@ void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containing_func, c ir::Expression *st_argument) { // First (or single) return statement in the function: - func_return_type = st_argument == nullptr ? checker->GlobalBuiltinVoidType() : st_argument->Check(checker); + func_return_type = st_argument == nullptr ? containing_func->IsEntryPoint() ? checker->GlobalVoidType() + : checker->GlobalBuiltinVoidType() + : st_argument->Check(checker); if (func_return_type->HasTypeFlag(checker::TypeFlag::CONSTANT)) { // remove CONSTANT type modifier if exists func_return_type = diff --git a/ets2panda/test/parser/ets/inferingEntryPointReturn-expected.txt b/ets2panda/test/parser/ets/inferingEntryPointReturn-expected.txt new file mode 100644 index 000000000..457bb3cf6 --- /dev/null +++ b/ets2panda/test/parser/ets/inferingEntryPointReturn-expected.txt @@ -0,0 +1,491 @@ +{ + "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": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 10 + } + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 26 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 10 + } + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "BooleanLiteral", + "value": false, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 20 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "handler": [ + { + "type": "CatchClause", + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": null, + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 22, + "column": 6 + } + } + }, + "param": { + "type": "Identifier", + "name": "e", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 22, + "column": 6 + } + } + } + ], + "finalizer": null, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 22, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 23, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/inferingEntryPointReturn.ets b/ets2panda/test/parser/ets/inferingEntryPointReturn.ets new file mode 100644 index 000000000..3b091a975 --- /dev/null +++ b/ets2panda/test/parser/ets/inferingEntryPointReturn.ets @@ -0,0 +1,23 @@ +/* + * 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(){ + let a: boolean[] = [] + try{ + a = [false] + } catch (e) { + return + } +} -- Gitee From 975826c78e0720041e6c2f6d57ac0d8cb1fa03d6 Mon Sep 17 00:00:00 2001 From: Otto Eotvos Date: Tue, 12 Dec 2023 17:59:27 +0100 Subject: [PATCH 10/35] Fix the access of an imported type alias through qualified name Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8O7T8 Testing: All required pre-merge tests passed. Results are available in the ggwatcher. Also fixes internal issue #14571 Change-Id: I3a004a399a8bd23ad40fedc1e1a24cc486e42444 Signed-off-by: Otto Eotvos --- ets2panda/checker/ets/helpers.cpp | 7 + .../export_type_alias-expected.txt | 400 +++++++++++ .../ets/import_tests/export_type_alias.ets | 19 + .../import_all_type_alias-expected.txt | 646 ++++++++++++++++++ .../import_tests/import_all_type_alias.ets | 22 + ets2panda/varbinder/scope.h | 5 + 6 files changed, 1099 insertions(+) create mode 100644 ets2panda/test/parser/ets/import_tests/export_type_alias-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/export_type_alias.ets create mode 100644 ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/import_all_type_alias.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index cad696b0b..3d82cf443 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1197,6 +1197,13 @@ void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *module_obj module_obj_type->AddProperty(var->AsLocalVariable()); } } + + for (auto [_, var] : res->second.front()->GlobalClassScope()->TypeAliasScope()->Bindings()) { + (void)_; + if (var->AsLocalVariable()->Declaration()->Node()->IsExported()) { + module_obj_type->AddProperty(var->AsLocalVariable()); + } + } } void ETSChecker::SetrModuleObjectTsType(ir::Identifier *local, checker::ETSObjectType *module_obj_type) diff --git a/ets2panda/test/parser/ets/import_tests/export_type_alias-expected.txt b/ets2panda/test/parser/ets/import_tests/export_type_alias-expected.txt new file mode 100644 index 000000000..58b7c1462 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/export_type_alias-expected.txt @@ -0,0 +1,400 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "int32", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "test_class", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 26 + }, + "end": { + "line": 19, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 26 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 26 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + { + "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": 20, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/export_type_alias.ets b/ets2panda/test/parser/ets/import_tests/export_type_alias.ets new file mode 100644 index 000000000..44816d18d --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/export_type_alias.ets @@ -0,0 +1,19 @@ +/* + * 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 TestClass {} + +export type int32 = int; +export type test_class = TestClass; diff --git a/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt b/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt new file mode 100644 index 000000000..20deb523c --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt @@ -0,0 +1,646 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./", + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 43 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 44 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "test_var", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "right": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 23 + } + } + }, + "right": { + "type": "Identifier", + "name": "test_class", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 24 + }, + "end": { + "line": 22, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 22, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 22, + "column": 37 + } + } + } + ], + "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": "TestFunc", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "TestFunc", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + "right": { + "type": "Identifier", + "name": "int32", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 33 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 12 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 32 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "test_var", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "value": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 23 + } + } + }, + "right": { + "type": "Identifier", + "name": "test_class", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 24 + }, + "end": { + "line": 22, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 20 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 22, + "column": 37 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 23, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/import_all_type_alias.ets b/ets2panda/test/parser/ets/import_tests/import_all_type_alias.ets new file mode 100644 index 000000000..51ef2e61d --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/import_all_type_alias.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +import * as all from "./export_type_alias"; + +function TestFunc(): all.int32 { + return 0; +} + +let test_var = new all.test_class(); diff --git a/ets2panda/varbinder/scope.h b/ets2panda/varbinder/scope.h index c1c11520e..9d17358ad 100644 --- a/ets2panda/varbinder/scope.h +++ b/ets2panda/varbinder/scope.h @@ -639,6 +639,11 @@ public: return instance_decl_scope_; } + const LocalScope *TypeAliasScope() const + { + return type_alias_scope_; + } + uint32_t GetAndIncrementAnonymousClassIdx() const { return anonymous_class_idx_++; -- Gitee From bb66ec59975af961635964aeacbcedcf4a1f015c Mon Sep 17 00:00:00 2001 From: Martin Sajti Date: Mon, 18 Dec 2023 14:29:27 +0100 Subject: [PATCH 11/35] Fix checkcast emit for some unboxing expression Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8PG6C Internal issue: #13877 Test: build, new parser tests, new checker tests Signed-off-by: Martin Sajti --- ets2panda/checker/ETSAnalyzer.cpp | 16 +++++-- ets2panda/checker/ETSchecker.h | 2 +- ets2panda/checker/ets/arithmetic.cpp | 4 +- ets2panda/checker/ets/boxingConverter.h | 4 -- ets2panda/checker/ets/conversion.cpp | 4 +- ets2panda/checker/ets/helpers.cpp | 18 ++++---- ets2panda/checker/ets/object.cpp | 2 +- ets2panda/compiler/core/ETSGen.cpp | 44 ++++++++++++------- ets2panda/ir/astNode.h | 44 +++++++++++++------ ets2panda/ir/astNodeFlags.h | 5 +-- ets2panda/ir/statements/returnStatement.cpp | 2 +- .../test/runtime/ets/UnboxingCheckcast.ets | 40 +++++++++++++++++ 12 files changed, 127 insertions(+), 58 deletions(-) create mode 100644 ets2panda/test/runtime/ets/UnboxingCheckcast.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index da1abc232..3dc0960f1 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1247,7 +1247,7 @@ checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const if (base_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { checker->Relation()->SetNode(expr); expr->SetObjectType(checker->PrimitiveTypeAsETSBuiltinType(base_type)->AsETSObjectType()); - checker->AddBoxingUnboxingFlagToNode(expr, expr->ObjType()); + checker->AddBoxingUnboxingFlagsToNode(expr, expr->ObjType()); auto [res_type, res_var] = expr->ResolveObjectMember(checker); expr->SetPropVar(res_var); return expr->AdjustOptional(checker, res_type); @@ -1540,7 +1540,7 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const if (arg_type->IsETSObjectType() && (unboxed_operand_type != nullptr) && unboxed_operand_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { - expr->Argument()->AddBoxingUnboxingFlag(checker->GetUnboxingFlag(unboxed_operand_type)); + expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxed_operand_type)); } return expr->TsType(); @@ -1575,8 +1575,8 @@ checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const } if (operand_type->IsETSObjectType()) { - expr->Argument()->AddBoxingUnboxingFlag(checker->GetUnboxingFlag(unboxed_type) | - checker->GetBoxingFlag(unboxed_type)); + expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxed_type) | + checker->GetBoxingFlag(unboxed_type)); } expr->SetTsType(operand_type); @@ -2375,6 +2375,14 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const auto *const source_type = expr->Expr()->Check(checker); + if (target_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE) && + source_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + auto *const boxed_target_type = checker->PrimitiveTypeAsETSBuiltinType(target_type); + if (!checker->Relation()->IsIdenticalTo(source_type, boxed_target_type)) { + expr->Expr()->AddAstNodeFlags(ir::AstNodeFlags::CHECKCAST); + } + } + const checker::CastingContext ctx(checker->Relation(), expr->Expr(), source_type, target_type, expr->Expr()->Start(), {"Cannot cast type '", source_type, "' to '", target_type, "'"}); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 9ed89b1c8..1b455c497 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -451,7 +451,7 @@ public: Type *ETSBuiltinTypeAsPrimitiveType(Type *object_type); Type *ETSBuiltinTypeAsConditionalType(Type *object_type); Type *PrimitiveTypeAsETSBuiltinType(Type *object_type); - void AddBoxingUnboxingFlagToNode(ir::AstNode *node, Type *boxing_unboxing_type); + void AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxing_unboxing_type); ir::BoxingUnboxingFlags GetBoxingFlag(Type *boxing_type); ir::BoxingUnboxingFlags GetUnboxingFlag(Type const *unboxing_type) const; Type *MaybeBoxedType(const varbinder::Variable *var, ArenaAllocator *allocator) const; diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 113250d25..decbb3b61 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -473,7 +473,7 @@ Type *ETSChecker::CheckBinaryOperatorNullishCoalescing(ir::Expression *right, le if (boxed_right_type == nullptr) { ThrowTypeError("Invalid right-hand side expression", pos); } - right->AddBoxingUnboxingFlag(GetBoxingFlag(boxed_right_type)); + right->AddBoxingUnboxingFlags(GetBoxingFlag(boxed_right_type)); return FindLeastUpperBound(non_nullish_left_type, boxed_right_type); } @@ -609,7 +609,7 @@ Type *ETSChecker::HandleArithmeticOperationOnTypes(Type *left, Type *right, lexe void ETSChecker::FlagExpressionWithUnboxing(Type *type, Type *unboxed_type, ir::Expression *type_expression) { if (type->IsETSObjectType() && (unboxed_type != nullptr)) { - type_expression->AddBoxingUnboxingFlag(GetUnboxingFlag(unboxed_type)); + type_expression->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxed_type)); } } diff --git a/ets2panda/checker/ets/boxingConverter.h b/ets2panda/checker/ets/boxingConverter.h index 8c142419c..14ce94e65 100644 --- a/ets2panda/checker/ets/boxingConverter.h +++ b/ets2panda/checker/ets/boxingConverter.h @@ -25,8 +25,6 @@ public: BoxingConverter(ETSChecker *checker, TypeRelation *relation, Type *source) : TypeConverter(checker, relation, nullptr, source) { - ASSERT(relation->GetNode()); - if (!source->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { Relation()->Result(false); return; @@ -39,8 +37,6 @@ public: BoxingConverter(ETSChecker *checker, TypeRelation *relation, Type *source, Type *target) : TypeConverter(checker, relation, target, source) { - ASSERT(relation->GetNode()); - if (!target->IsETSObjectType() || relation->IsTrue()) { return; } diff --git a/ets2panda/checker/ets/conversion.cpp b/ets2panda/checker/ets/conversion.cpp index df0eac654..226eb0a57 100644 --- a/ets2panda/checker/ets/conversion.cpp +++ b/ets2panda/checker/ets/conversion.cpp @@ -255,7 +255,7 @@ ETSObjectType *Boxing(TypeRelation *const relation, Type *const source) return nullptr; } auto *const boxed_type = boxed.Result()->AsETSObjectType(); - relation->GetNode()->AddBoxingUnboxingFlag(ets_checker->GetBoxingFlag(boxed_type)); + relation->GetNode()->AddBoxingUnboxingFlags(ets_checker->GetBoxingFlag(boxed_type)); return boxed_type; } @@ -267,7 +267,7 @@ Type *Unboxing(TypeRelation *const relation, ETSObjectType *const source) return nullptr; } auto *const unboxed_type = unboxed.Result(); - relation->GetNode()->AddBoxingUnboxingFlag(ets_checker->GetUnboxingFlag(unboxed_type)); + relation->GetNode()->AddBoxingUnboxingFlags(ets_checker->GetUnboxingFlag(unboxed_type)); return unboxed_type; } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 3d82cf443..5dce544bb 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -153,7 +153,7 @@ Type *ETSChecker::CreateOptionalResultType(Type *type) if (type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { type = PrimitiveTypeAsETSBuiltinType(type); ASSERT(type->IsETSObjectType()); - Relation()->GetNode()->AddBoxingUnboxingFlag(GetBoxingFlag(type)); + Relation()->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(type)); } return CreateNullishType(type, checker::TypeFlag::UNDEFINED, Allocator(), Relation(), GetGlobalTypesHolder()); @@ -874,7 +874,7 @@ void ETSChecker::ResolveReturnStatement(checker::Type *func_return_type, checker if (argument_type == nullptr) { ThrowTypeError("Invalid return statement expression", st->Argument()->Start()); } - st->Argument()->AddBoxingUnboxingFlag(GetBoxingFlag(argument_type)); + st->Argument()->AddBoxingUnboxingFlags(GetBoxingFlag(argument_type)); } if (!func_return_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { @@ -1596,12 +1596,12 @@ Type *ETSChecker::PrimitiveTypeAsETSBuiltinType(Type *object_type) return converter.Result(); } -void ETSChecker::AddBoxingUnboxingFlagToNode(ir::AstNode *node, Type *boxing_unboxing_type) +void ETSChecker::AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxing_unboxing_type) { if (boxing_unboxing_type->IsETSObjectType()) { - node->AddBoxingUnboxingFlag(GetBoxingFlag(boxing_unboxing_type)); + node->AddBoxingUnboxingFlags(GetBoxingFlag(boxing_unboxing_type)); } else { - node->AddBoxingUnboxingFlag(GetUnboxingFlag(boxing_unboxing_type)); + node->AddBoxingUnboxingFlags(GetUnboxingFlag(boxing_unboxing_type)); } } @@ -1851,7 +1851,7 @@ void ETSChecker::AddBoxingFlagToPrimitiveType(TypeRelation *relation, Type *targ { auto boxing_result = PrimitiveTypeAsETSBuiltinType(target); if (boxing_result != nullptr) { - relation->GetNode()->AddBoxingUnboxingFlag(GetBoxingFlag(boxing_result)); + relation->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(boxing_result)); relation->Result(true); } } @@ -1860,7 +1860,7 @@ void ETSChecker::AddUnboxingFlagToPrimitiveType(TypeRelation *relation, Type *so { auto unboxing_result = UnboxingConverter(this, relation, source, self).Result(); if ((unboxing_result != nullptr) && relation->IsTrue()) { - relation->GetNode()->AddBoxingUnboxingFlag(GetUnboxingFlag(unboxing_result)); + relation->GetNode()->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxing_result)); } } @@ -1889,7 +1889,7 @@ void ETSChecker::CheckUnboxedTypesAssignable(TypeRelation *relation, Type *sourc } relation->IsAssignableTo(unboxed_source_type, unboxed_target_type); if (relation->IsTrue()) { - relation->GetNode()->AddBoxingUnboxingFlag( + relation->GetNode()->AddBoxingUnboxingFlags( relation->GetChecker()->AsETSChecker()->GetUnboxingFlag(unboxed_source_type)); } } @@ -1933,7 +1933,7 @@ void ETSChecker::CheckUnboxedSourceTypeWithWideningAssignable(TypeRelation *rela relation->GetChecker()->AsETSChecker()->CheckUnboxedTypeWidenable(relation, target, unboxed_source_type); } if (!relation->OnlyCheckBoxingUnboxing()) { - relation->GetNode()->AddBoxingUnboxingFlag( + relation->GetNode()->AddBoxingUnboxingFlags( relation->GetChecker()->AsETSChecker()->GetUnboxingFlag(unboxed_source_type)); } } diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index def4d1b88..637a330f1 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -941,7 +941,7 @@ void ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) Type const *const index_type = ApplyUnaryOperatorPromotion(expression_type); if (expression_type->IsETSObjectType() && (unboxed_expression_type != nullptr)) { - expr->AddBoxingUnboxingFlag(GetUnboxingFlag(unboxed_expression_type)); + expr->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxed_expression_type)); } if (relaxed && index_type != nullptr && index_type->HasTypeFlag(TypeFlag::ETS_FLOATING_POINT)) { diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index f7c28be88..c0ae28674 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -992,50 +992,60 @@ void ETSGen::ApplyCast(const ir::AstNode *node, const checker::Type *target_type void ETSGen::EmitUnboxingConversion(const ir::AstNode *node) { - auto unboxing_flag = + const auto unboxing_flag = static_cast(ir::BoxingUnboxingFlags::UNBOXING_FLAG & node->GetBoxingUnboxingFlags()); RegScope rs(this); + auto emit_unboxed_call = [this, &node](std::string_view signature_flag, const checker::Type *const target_type, + const checker::Type *const boxed_type) { + if (node->HasAstNodeFlags(ir::AstNodeFlags::CHECKCAST)) { + EmitCheckedNarrowingReferenceConversion(node, boxed_type); + } + + Ra().Emit(node, signature_flag, dummy_reg_, 0); + SetAccumulatorType(target_type); + }; + switch (unboxing_flag) { case ir::BoxingUnboxingFlags::UNBOX_TO_BOOLEAN: { - Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_UNBOXED, dummy_reg_, 0); - SetAccumulatorType(Checker()->GlobalETSBooleanType()); + emit_unboxed_call(Signatures::BUILTIN_BOOLEAN_UNBOXED, Checker()->GlobalETSBooleanType(), + Checker()->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_BYTE: { - Ra().Emit(node, Signatures::BUILTIN_BYTE_UNBOXED, dummy_reg_, 0); - SetAccumulatorType(Checker()->GlobalByteType()); + emit_unboxed_call(Signatures::BUILTIN_BYTE_UNBOXED, Checker()->GlobalByteType(), + Checker()->GetGlobalTypesHolder()->GlobalByteBuiltinType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_CHAR: { - Ra().Emit(node, Signatures::BUILTIN_CHAR_UNBOXED, dummy_reg_, 0); - SetAccumulatorType(Checker()->GlobalCharType()); + emit_unboxed_call(Signatures::BUILTIN_CHAR_UNBOXED, Checker()->GlobalCharType(), + Checker()->GetGlobalTypesHolder()->GlobalCharBuiltinType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_SHORT: { - Ra().Emit(node, Signatures::BUILTIN_SHORT_UNBOXED, dummy_reg_, 0); - SetAccumulatorType(Checker()->GlobalShortType()); + emit_unboxed_call(Signatures::BUILTIN_SHORT_UNBOXED, Checker()->GlobalShortType(), + Checker()->GetGlobalTypesHolder()->GlobalShortBuiltinType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_INT: { - Ra().Emit(node, Signatures::BUILTIN_INT_UNBOXED, dummy_reg_, 0); - SetAccumulatorType(Checker()->GlobalIntType()); + emit_unboxed_call(Signatures::BUILTIN_INT_UNBOXED, Checker()->GlobalIntType(), + Checker()->GetGlobalTypesHolder()->GlobalIntegerBuiltinType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_LONG: { - Ra().Emit(node, Signatures::BUILTIN_LONG_UNBOXED, dummy_reg_, 0); - SetAccumulatorType(Checker()->GlobalLongType()); + emit_unboxed_call(Signatures::BUILTIN_LONG_UNBOXED, Checker()->GlobalLongType(), + Checker()->GetGlobalTypesHolder()->GlobalLongBuiltinType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_FLOAT: { - Ra().Emit(node, Signatures::BUILTIN_FLOAT_UNBOXED, dummy_reg_, 0); - SetAccumulatorType(Checker()->GlobalFloatType()); + emit_unboxed_call(Signatures::BUILTIN_FLOAT_UNBOXED, Checker()->GlobalFloatType(), + Checker()->GetGlobalTypesHolder()->GlobalFloatBuiltinType()); break; } case ir::BoxingUnboxingFlags::UNBOX_TO_DOUBLE: { - Ra().Emit(node, Signatures::BUILTIN_DOUBLE_UNBOXED, dummy_reg_, 0); - SetAccumulatorType(Checker()->GlobalDoubleType()); + emit_unboxed_call(Signatures::BUILTIN_DOUBLE_UNBOXED, Checker()->GlobalDoubleType(), + Checker()->GetGlobalTypesHolder()->GlobalDoubleBuiltinType()); break; } default: diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index e6f7b47c0..601fbf387 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -424,20 +424,35 @@ public: return flags_; } - void SetBoxingUnboxingFlags(BoxingUnboxingFlags const flags) const noexcept - { - boxing_unboxing_flags_ = flags; - } - - void AddBoxingUnboxingFlag(BoxingUnboxingFlags const flag) const noexcept - { - boxing_unboxing_flags_ |= flag; - } - - [[nodiscard]] BoxingUnboxingFlags GetBoxingUnboxingFlags() const noexcept - { - return boxing_unboxing_flags_; - } + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define DECLARE_FLAG_OPERATIONS(flag_type, member_name) \ + void Set##flag_type(flag_type flags) const noexcept \ + { \ + member_name = flags; \ + } \ + \ + void Add##flag_type(flag_type flag) const noexcept \ + { \ + member_name |= flag; \ + } \ + \ + [[nodiscard]] flag_type Get##flag_type() const noexcept \ + { \ + return member_name; \ + } \ + \ + bool Has##flag_type(flag_type flag) const noexcept \ + { \ + return (member_name & flag) != 0U; \ + } \ + void Remove##flag_type(flag_type flag) noexcept \ + { \ + member_name &= ~flag; \ + } + + DECLARE_FLAG_OPERATIONS(BoxingUnboxingFlags, boxing_unboxing_flags_); + DECLARE_FLAG_OPERATIONS(AstNodeFlags, ast_node_flags_); +#undef DECLARE_FLAG_OPERATIONS ir::ClassElement *AsClassElement() { @@ -512,6 +527,7 @@ protected: AstNodeType type_; varbinder::Variable *variable_ {}; ModifierFlags flags_ {}; + mutable AstNodeFlags ast_node_flags_ {}; mutable BoxingUnboxingFlags boxing_unboxing_flags_ {}; // NOLINTEND(misc-non-private-member-variables-in-classes) }; diff --git a/ets2panda/ir/astNodeFlags.h b/ets2panda/ir/astNodeFlags.h index d22bc5d6e..f6420bb13 100644 --- a/ets2panda/ir/astNodeFlags.h +++ b/ets2panda/ir/astNodeFlags.h @@ -21,8 +21,7 @@ namespace panda::es2panda::ir { enum class AstNodeFlags { NO_OPTS = 0, - STRICT = (1U << 0U), - PARAMETER = (1U << 1U), + CHECKCAST = 1U << 0U, }; enum class ModifierFlags : uint32_t { @@ -114,4 +113,4 @@ enum class BoxingUnboxingFlags : uint32_t { }; } // namespace panda::es2panda::ir -#endif \ No newline at end of file +#endif diff --git a/ets2panda/ir/statements/returnStatement.cpp b/ets2panda/ir/statements/returnStatement.cpp index cb0e92dae..4139ecafd 100644 --- a/ets2panda/ir/statements/returnStatement.cpp +++ b/ets2panda/ir/statements/returnStatement.cpp @@ -86,7 +86,7 @@ void ReturnStatement::SetReturnType(checker::ETSChecker *checker, checker::Type if (argument_type == nullptr) { checker->ThrowTypeError("Invalid return statement expression", argument_->Start()); } - argument_->AddBoxingUnboxingFlag(checker->GetBoxingFlag(argument_type)); + argument_->AddBoxingUnboxingFlags(checker->GetBoxingFlag(argument_type)); relation->SetNode(nullptr); } diff --git a/ets2panda/test/runtime/ets/UnboxingCheckcast.ets b/ets2panda/test/runtime/ets/UnboxingCheckcast.ets new file mode 100644 index 000000000..1a5fdfb06 --- /dev/null +++ b/ets2panda/test/runtime/ets/UnboxingCheckcast.ets @@ -0,0 +1,40 @@ +/* + * 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() { + let b: Object[] = [new Object()]; + b[0] = 2.0; + let myvar: double = b[0] as double; + + assert myvar == 2.0; + + let c: Object; + c = 2.0; + c as double; + + let k = 2; + if(2 == k){ + c = new Object(); + } else { + c = new Double(); + } + + try{ + c as double; + } catch (e: ClassCastException){ + } catch(other) { + assert 1 == 0 + } +} -- Gitee From c255b503f2db7739be3a0ee1fcb07fc5f94d44f8 Mon Sep 17 00:00:00 2001 From: gergocs Date: Tue, 21 Nov 2023 10:35:35 +0100 Subject: [PATCH 12/35] Fix an issue with Functional type as type argument Description: This patch should fix the issue with functional type as type argument Issue: #14012 internal Testing: function as Type argument Change-Id: Ia559f716ee28e1347c80089224862d36e71619dc Signed-off-by: Gergo Csizi --- ets2panda/compiler/core/ASTVerifier.cpp | 15 +- ets2panda/parser/TypedParser.cpp | 3 + .../FunctionalTypeAsTypeArgument-expected.txt | 384 ++++++++++++++++++ .../ets/FunctionalTypeAsTypeArgument.ets | 16 + 4 files changed, 416 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument-expected.txt create mode 100644 ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument.ets diff --git a/ets2panda/compiler/core/ASTVerifier.cpp b/ets2panda/compiler/core/ASTVerifier.cpp index 524bb6345..17265d299 100644 --- a/ets2panda/compiler/core/ASTVerifier.cpp +++ b/ets2panda/compiler/core/ASTVerifier.cpp @@ -359,6 +359,18 @@ std::string ToStringParamsHelper(const ir::AstNode *parent, const ArenaVector +std::string ToStringParamsHelper(const ArenaVector ¶ms) +{ + std::string name = "("; + + for (auto const *param : params) { + name += ToStringHelper(param); + } + + return name + ")"; +} + std::string ToStringHelper(const ir::AstNode *ast) { if (ast == nullptr) { @@ -458,8 +470,7 @@ std::string ToStringHelper(const ir::AstNode *ast) return "TS_INTERFACE_BODY "; } case ir::AstNodeType::ETS_FUNCTION_TYPE: { - return "ETS_FUNC_TYPE " + - ToStringParamsHelper(ast->Parent(), ast->AsETSFunctionType()->Params()); + return "ETS_FUNC_TYPE " + ToStringParamsHelper(ast->AsETSFunctionType()->Params()); } case ir::AstNodeType::TS_CLASS_IMPLEMENTS: { return "TS_CLASS_IMPL " + ToStringHelper(ast->AsTSClassImplements()->Expr()); diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index 71905233a..16acc71da 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -1196,7 +1196,10 @@ ir::TSTypeParameterInstantiation *TypedParser::ParseTypeParameterInstantiation(T Lexer()->NextToken(); // eat '<' while (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) { + TypeAnnotationParsingOptions tmp = *options; + *options &= ~TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE; ir::TypeNode *current_param = ParseTypeAnnotation(options); + *options = tmp; if (current_param == nullptr) { return nullptr; diff --git a/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument-expected.txt b/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument-expected.txt new file mode 100644 index 000000000..d9ec76360 --- /dev/null +++ b/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument-expected.txt @@ -0,0 +1,384 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "alma", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "value": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "args", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 31 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 31 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 31 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 25 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 25 + }, + "end": { + "line": 16, + "column": 38 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 16, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 16, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 16, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 47 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 48 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 48 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 17, + "column": 1 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 17, + "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": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument.ets b/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument.ets new file mode 100644 index 000000000..2c33faa7c --- /dev/null +++ b/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +const alma = new Array<(args: Object) => void>() -- Gitee From 4b1653355edf6b31793fab300378937726b28432 Mon Sep 17 00:00:00 2001 From: Gergo Torok Date: Tue, 7 Nov 2023 12:31:31 +0100 Subject: [PATCH 13/35] [ETS]Check private interface methods The private modifier check was missing in case of ThisExpression. Add one more check to ValidateSignatureAccessibility function. If a member function marked with private, we can not call it inside another member function without private modifier. Internal issue: #12853 Change Id: Ic9d74ab87befc690790e749b902f322ea6da63ff Signed-off-by: Daniel Batiz Signed-off-by: Martin Sajti Signed-off-by: Gergo Torok --- ets2panda/checker/ETSAnalyzer.cpp | 6 +- ets2panda/checker/ETSchecker.h | 3 +- ets2panda/checker/ets/function.cpp | 26 +- ets2panda/checker/ets/object.cpp | 8 +- ets2panda/ir/expressions/memberExpression.cpp | 3 +- .../ets/InterfacePrivateMethod-expected.txt | 1212 +++++++++++++++++ .../parser/ets/InterfacePrivateMethod.ets | 30 + .../runtime/ets/InterfacePrivateMethod2.ets | 39 + ets2panda/util/helpers.cpp | 19 +- ets2panda/util/helpers.h | 23 +- 10 files changed, 1341 insertions(+), 28 deletions(-) create mode 100644 ets2panda/test/parser/ets/InterfacePrivateMethod-expected.txt create mode 100644 ets2panda/test/parser/ets/InterfacePrivateMethod.ets create mode 100644 ets2panda/test/runtime/ets/InterfacePrivateMethod2.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 3dc0960f1..7d09420fd 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -553,7 +553,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const checker->CheckObjectLiteralArguments(signature, expr->GetArguments()); checker->AddUndefinedParamsForDefaultParams(signature, expr->arguments_, checker); - checker->ValidateSignatureAccessibility(callee_obj, signature, expr->Start()); + checker->ValidateSignatureAccessibility(callee_obj, nullptr, signature, expr->Start()); ASSERT(signature->Function() != nullptr); @@ -1031,7 +1031,7 @@ checker::Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, checker::Typ if (!is_functional_interface) { checker::ETSObjectType *callee_obj = ChooseCalleeObj(checker, expr, callee_type, is_constructor_call); - checker->ValidateSignatureAccessibility(callee_obj, signature, expr->Start()); + checker->ValidateSignatureAccessibility(callee_obj, expr, signature, expr->Start()); } ASSERT(signature->Function() != nullptr); @@ -1302,7 +1302,7 @@ checker::Type *ETSAnalyzer::Check(ir::ObjectExpression *expr) const for (checker::Signature *sig : obj_type->ConstructSignatures()) { if (sig->Params().empty()) { have_empty_constructor = true; - checker->ValidateSignatureAccessibility(obj_type, sig, expr->Start()); + checker->ValidateSignatureAccessibility(obj_type, nullptr, sig, expr->Start()); break; } } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 1b455c497..17260db5e 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -326,7 +326,8 @@ public: [[nodiscard]] bool IsReturnTypeSubstitutable(Signature *s1, Signature *s2); void CheckStaticHide(Signature *target, Signature *source); void CheckThrowMarkers(Signature *source, Signature *target); - void ValidateSignatureAccessibility(ETSObjectType *callee, Signature *signature, const lexer::SourcePosition &pos, + void ValidateSignatureAccessibility(ETSObjectType *callee, const ir::CallExpression *call_expr, + Signature *signature, const lexer::SourcePosition &pos, char const *error_message = nullptr); void CreateLambdaObjectForLambdaReference(ir::ArrowFunctionExpression *lambda, ETSObjectType *functional_interface); ir::ClassProperty *CreateLambdaCapturedField(const varbinder::Variable *captured_var, varbinder::ClassScope *scope, diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 4e1e35a33..ec74ab08b 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1186,15 +1186,35 @@ Signature *ETSChecker::GetSignatureFromMethodDefinition(const ir::MethodDefiniti return nullptr; } -void ETSChecker::ValidateSignatureAccessibility(ETSObjectType *callee, Signature *signature, - const lexer::SourcePosition &pos, char const *error_message) +void ETSChecker::ValidateSignatureAccessibility(ETSObjectType *callee, const ir::CallExpression *call_expr, + Signature *signature, const lexer::SourcePosition &pos, + char const *error_message) { if ((Context().Status() & CheckerStatus::IGNORE_VISIBILITY) != 0U) { return; } if (signature->HasSignatureFlag(SignatureFlags::PRIVATE) || signature->HasSignatureFlag(SignatureFlags::PROTECTED)) { - ASSERT(callee->GetDeclNode() && callee->GetDeclNode()->IsClassDefinition()); + ASSERT(callee->GetDeclNode() && + (callee->GetDeclNode()->IsClassDefinition() || callee->GetDeclNode()->IsTSInterfaceDeclaration())); + + if (callee->GetDeclNode()->IsTSInterfaceDeclaration()) { + if (call_expr->Callee()->IsMemberExpression() && + call_expr->Callee()->AsMemberExpression()->Object()->IsThisExpression()) { + const auto *enclosing_func = + util::Helpers::FindAncestorGivenByType(call_expr, ir::AstNodeType::SCRIPT_FUNCTION) + ->AsScriptFunction(); + if (signature->Function()->IsPrivate() && !enclosing_func->IsPrivate()) { + ThrowTypeError({"Cannot reference 'this' in this context."}, enclosing_func->Start()); + } + } + + if (Context().ContainingClass() == callee->GetDeclNode()->AsTSInterfaceDeclaration()->TsType() && + callee->GetDeclNode()->AsTSInterfaceDeclaration()->TsType()->AsETSObjectType()->IsSignatureInherited( + signature)) { + return; + } + } if (Context().ContainingClass() == callee->GetDeclNode()->AsClassDefinition()->TsType() && callee->GetDeclNode()->AsClassDefinition()->TsType()->AsETSObjectType()->IsSignatureInherited(signature)) { return; diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 637a330f1..d01e408ca 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1040,7 +1040,7 @@ ETSObjectType *ETSChecker::CheckThisOrSuperAccess(ir::Expression *node, ETSObjec ThrowTypeError({"'", msg, "' cannot be referenced from a static context"}, node->Start()); } - if (class_type->GetDeclNode()->AsClassDefinition()->IsGlobal()) { + if (class_type->GetDeclNode()->IsClassDefinition() && class_type->GetDeclNode()->AsClassDefinition()->IsGlobal()) { ThrowTypeError({"Cannot reference '", msg, "' in this context."}, node->Start()); } @@ -1285,19 +1285,21 @@ std::vector ETSChecker::ResolveMemberReference(const ir::Member ASSERT((prop_type->FindSetter() != nullptr) == prop_type->HasTypeFlag(TypeFlag::SETTER)); auto const &source_pos = member_expr->Property()->Start(); + auto call_expr = + member_expr->Parent()->IsCallExpression() ? member_expr->Parent()->AsCallExpression() : nullptr; if ((search_flag & PropertySearchFlags::IS_GETTER) != 0) { if (!prop_type->HasTypeFlag(TypeFlag::GETTER)) { ThrowTypeError("Cannot read from this property because it is writeonly.", source_pos); } - ValidateSignatureAccessibility(member_expr->ObjType(), prop_type->FindGetter(), source_pos); + ValidateSignatureAccessibility(member_expr->ObjType(), call_expr, prop_type->FindGetter(), source_pos); } if ((search_flag & PropertySearchFlags::IS_SETTER) != 0) { if (!prop_type->HasTypeFlag(TypeFlag::SETTER)) { ThrowTypeError("Cannot assign to this property because it is readonly.", source_pos); } - ValidateSignatureAccessibility(member_expr->ObjType(), prop_type->FindSetter(), source_pos); + ValidateSignatureAccessibility(member_expr->ObjType(), call_expr, prop_type->FindSetter(), source_pos); } } diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index 90a9fb501..f19188fb4 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -292,7 +292,8 @@ checker::Type *MemberExpression::CheckIndexAccessMethod(checker::ETSChecker *che if (signature == nullptr) { checker->ThrowTypeError("Cannot find index access method with the required signature.", Property()->Start()); } - checker->ValidateSignatureAccessibility(obj_type_, signature, Start(), "Index access method is not visible here."); + checker->ValidateSignatureAccessibility(obj_type_, nullptr, signature, Start(), + "Index access method is not visible here."); ASSERT(signature->Function() != nullptr); diff --git a/ets2panda/test/parser/ets/InterfacePrivateMethod-expected.txt b/ets2panda/test/parser/ets/InterfacePrivateMethod-expected.txt new file mode 100644 index 000000000..951210895 --- /dev/null +++ b/ets2panda/test/parser/ets/InterfacePrivateMethod-expected.txt @@ -0,0 +1,1212 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "getHorsePower3", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, + "kind": "method", + "accessibility": "private", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "getHorsePower3", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "rpm", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 33 + }, + "end": { + "line": 17, + "column": 36 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 36 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "trq", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 43 + }, + "end": { + "line": 17, + "column": 46 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 38 + }, + "end": { + "line": 17, + "column": 46 + } + } + } + ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 49 + }, + "end": { + "line": 17, + "column": 52 + } + } + }, + "declare": true, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "BinaryExpression", + "operator": "/", + "left": { + "type": "BinaryExpression", + "operator": "*", + "left": { + "type": "Identifier", + "name": "rpm", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "right": { + "type": "Identifier", + "name": "trq", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 27 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 5252, + "loc": { + "start": { + "line": 18, + "column": 30 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 35 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 52 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "getPwrIndex", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "getPwrIndex", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "trq", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 21, + "column": 22 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 17 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 17 + }, + "end": { + "line": 21, + "column": 25 + } + } + } + ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 21, + "column": 28 + }, + "end": { + "line": 21, + "column": 31 + } + } + }, + "declare": true, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 22, + "column": 20 + } + } + }, + "property": { + "type": "Identifier", + "name": "getHorsePower3", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 21 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 22, + "column": 35 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 5252, + "loc": { + "start": { + "line": 22, + "column": 36 + }, + "end": { + "line": 22, + "column": 40 + } + } + }, + { + "type": "Identifier", + "name": "trq", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 42 + }, + "end": { + "line": 22, + "column": 45 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 22, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 47 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 31 + }, + "end": { + "line": 23, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 23, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 23, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 23, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "id": { + "type": "Identifier", + "name": "Vehicle", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 18 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 26, + "column": 6 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Car", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 26, + "column": 10 + } + } + }, + "superClass": null, + "implements": [ + { + "type": "TSClassImplements", + "expression": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Vehicle", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 30 + } + } + } + ], + "body": [ + { + "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": 26, + "column": 31 + }, + "end": { + "line": 26, + "column": 31 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 29 + }, + "end": { + "line": 26, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1 + }, + "end": { + "line": 26, + "column": 31 + } + } + }, + { + "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": 28, + "column": 10 + }, + "end": { + "line": 28, + "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": 28, + "column": 10 + }, + "end": { + "line": 28, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 18 + }, + "end": { + "line": 28, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 18 + }, + "end": { + "line": 28, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 18 + }, + "end": { + "line": 28, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "AssertStatement", + "test": { + "type": "BinaryExpression", + "operator": "==", + "left": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Car", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 16 + }, + "end": { + "line": 29, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 16 + }, + "end": { + "line": 29, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 16 + }, + "end": { + "line": 29, + "column": 20 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 29, + "column": 12 + }, + "end": { + "line": 29, + "column": 22 + } + } + }, + "property": { + "type": "Identifier", + "name": "getPwrIndex", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 22 + }, + "end": { + "line": 29, + "column": 33 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 29, + "column": 12 + }, + "end": { + "line": 29, + "column": 33 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 29, + "column": 34 + }, + "end": { + "line": 29, + "column": 35 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 29, + "column": 12 + }, + "end": { + "line": 29, + "column": 36 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 29, + "column": 40 + }, + "end": { + "line": 29, + "column": 41 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 12 + }, + "end": { + "line": 29, + "column": 41 + } + } + }, + "second": null, + "loc": { + "start": { + "line": 29, + "column": 5 + }, + "end": { + "line": 29, + "column": 42 + } + } + } + ], + "loc": { + "start": { + "line": 28, + "column": 23 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 14 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 14 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 1 + }, + "end": { + "line": 30, + "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": 31, + "column": 1 + } + } +} +TypeError: Cannot reference 'this' in this context. [InterfacePrivateMethod.ets:21:16] diff --git a/ets2panda/test/parser/ets/InterfacePrivateMethod.ets b/ets2panda/test/parser/ets/InterfacePrivateMethod.ets new file mode 100644 index 000000000..36f491b49 --- /dev/null +++ b/ets2panda/test/parser/ets/InterfacePrivateMethod.ets @@ -0,0 +1,30 @@ +/* + * 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. + */ + +interface Vehicle { + private getHorsePower3(rpm: int, trq: int): int{ + return (rpm * trq) / 5252; + } + + getPwrIndex(trq: int): int{ + return this.getHorsePower3(5252, trq); + } +} + +class Car implements Vehicle{} + +function main(): void { + assert new Car().getPwrIndex(1) == 1; +} diff --git a/ets2panda/test/runtime/ets/InterfacePrivateMethod2.ets b/ets2panda/test/runtime/ets/InterfacePrivateMethod2.ets new file mode 100644 index 000000000..d493737f7 --- /dev/null +++ b/ets2panda/test/runtime/ets/InterfacePrivateMethod2.ets @@ -0,0 +1,39 @@ +/* + * 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. + */ + +interface Vehicle { + getHorsePower3(rpm: int, trq: int): int{ + return (rpm * trq) / 5252; + } + + getPwrIndex(trq: int): int{ + return this.getHorsePower3(5252, trq); + } + + getHorsePower3(rpm: int): int{ + return rpm; + } + + getPwrIndex(trq: int, second: int): int{ + return this.getHorsePower3(trq + second); + } +} + +class Car implements Vehicle{} + +function main(): void { + assert new Car().getPwrIndex(1) == 1; + assert new Car().getPwrIndex(1,1) == 2; +} diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index b1f4abe0f..dcdb21431 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -17,6 +17,7 @@ #include "varbinder/privateBinding.h" #include "checker/types/ets/types.h" +#include "ir/astNode.h" #include "ir/base/classDefinition.h" #include "ir/base/classProperty.h" #include "ir/base/methodDefinition.h" @@ -25,6 +26,7 @@ #include "ir/base/spreadElement.h" #include "ir/expressions/arrayExpression.h" #include "ir/expressions/assignmentExpression.h" +#include "ir/expressions/callExpression.h" #include "ir/expressions/functionExpression.h" #include "ir/expressions/identifier.h" #include "ir/expressions/literals/numberLiteral.h" @@ -32,6 +34,7 @@ #include "ir/expressions/literals/booleanLiteral.h" #include "ir/expressions/literals/nullLiteral.h" #include "ir/expressions/objectExpression.h" +#include "ir/statements/returnStatement.h" #include "ir/statements/variableDeclaration.h" #include "ir/statements/variableDeclarator.h" #include "ir/module/importSpecifier.h" @@ -358,22 +361,6 @@ const ir::ScriptFunction *Helpers::GetContainingFunction(const ir::AstNode *node return nullptr; } -ir::AstNode *Helpers::FindAncestorGivenByType(ir::AstNode *node, ir::AstNodeType type) -{ - node = node->Parent(); - - while (node->Type() != type) { - if (node->Parent() != nullptr) { - node = node->Parent(); - continue; - } - - return nullptr; - } - - return node; -} - const ir::ClassDefinition *Helpers::GetClassDefiniton(const ir::ScriptFunction *node) { ASSERT(node->IsConstructor()); diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index bd32ed03a..7cb949d63 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -45,6 +45,8 @@ class ClassProperty; class Identifier; class MethodDefinition; class AstNode; +class ReturnStatement; +class CallExpression; class ClassStaticBlock; class TSInterfaceDeclaration; class TSEnumDeclaration; @@ -84,7 +86,26 @@ public: static const ir::ScriptFunction *GetContainingConstructor(const ir::AstNode *node); static const ir::ScriptFunction *GetContainingConstructor(const ir::ClassProperty *node); - static ir::AstNode *FindAncestorGivenByType(ir::AstNode *node, ir::AstNodeType type); + + template > *, ir::AstNode *>, + std::conditional_t>, const ir::AstNode *, ir::AstNode *>>> + static U FindAncestorGivenByType(T node, ir::AstNodeType type) + { + U iter = node->Parent(); + + while (iter->Type() != type) { + if (iter->Parent() != nullptr) { + iter = iter->Parent(); + continue; + } + + return nullptr; + } + + return iter; + } static const checker::ETSObjectType *GetContainingObjectType(const ir::AstNode *node); static const ir::TSEnumDeclaration *GetContainingEnumDeclaration(const ir::AstNode *node); -- Gitee From 0ef4ef310bc26b175c31b48bcca9238b27b7ca2b Mon Sep 17 00:00:00 2001 From: gergocs Date: Wed, 6 Dec 2023 09:37:27 +0100 Subject: [PATCH 14/35] Add support for index.ts/index.ets If an import is a folder and in the folder is an index.ts/index.ets, then it will import that file. Fixed issue: #13945 Change-Id: I9afd3b61fd33d4c124ddfe5271e50a0ac26e06a3 Signed-off-by: Gergo Csizi --- ets2panda/parser/ETSparser.cpp | 40 ++- .../folder_import_index/index-expected.txt | 247 ++++++++++++++++ .../parser/ets/folder_import_index/index.ets | 16 ++ .../parser/ets/import_folder-expected.txt | 254 +++++++++++++++++ ets2panda/test/parser/ets/import_folder.ets | 18 ++ .../re_export/folderIndex/index-expected.txt | 153 ++++++++++ .../ets/re_export/folderIndex/index.ets | 16 ++ .../re_export/folderIndex/test-expected.txt | 247 ++++++++++++++++ .../parser/ets/re_export/folderIndex/test.ets | 16 ++ .../ets/re_export/import_index-expected.txt | 254 +++++++++++++++++ .../parser/ets/re_export/import_index.ets | 18 ++ .../ets/re_export/import_index_2-expected.txt | 269 ++++++++++++++++++ .../parser/ets/re_export/import_index_2.ets | 18 ++ ets2panda/varbinder/ETSBinder.cpp | 27 +- ets2panda/varbinder/scope.cpp | 7 + 15 files changed, 1584 insertions(+), 16 deletions(-) create mode 100644 ets2panda/test/parser/ets/folder_import_index/index-expected.txt create mode 100644 ets2panda/test/parser/ets/folder_import_index/index.ets create mode 100644 ets2panda/test/parser/ets/import_folder-expected.txt create mode 100644 ets2panda/test/parser/ets/import_folder.ets create mode 100644 ets2panda/test/parser/ets/re_export/folderIndex/index-expected.txt create mode 100644 ets2panda/test/parser/ets/re_export/folderIndex/index.ets create mode 100644 ets2panda/test/parser/ets/re_export/folderIndex/test-expected.txt create mode 100644 ets2panda/test/parser/ets/re_export/folderIndex/test.ets create mode 100644 ets2panda/test/parser/ets/re_export/import_index-expected.txt create mode 100644 ets2panda/test/parser/ets/re_export/import_index.ets create mode 100644 ets2panda/test/parser/ets/re_export/import_index_2-expected.txt create mode 100644 ets2panda/test/parser/ets/re_export/import_index_2.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 0c1d9a780..83a3e4030 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -474,6 +474,8 @@ std::tuple, bool> ETSParser::CollectUserSources(const s #ifdef USE_UNIX_SYSCALL DIR *dir = opendir(resolved_path.c_str()); + bool is_index = false; + std::vector tmp_paths; if (dir == nullptr) { ThrowSyntaxError({"Cannot open folder: ", resolved_path}); @@ -494,25 +496,41 @@ std::tuple, bool> ETSParser::CollectUserSources(const s std::string file_path = path + "/" + entry->d_name; - if (file_name == "Object.ets") { - user_paths.emplace(user_paths.begin(), file_path); - } else { + if (file_name == "index.ets" || file_name == "index.ts") { user_paths.emplace_back(file_path); + is_index = true; + break; + } else if (file_name == "Object.ets") { + tmp_paths.emplace(user_paths.begin(), file_path); + } else { + tmp_paths.emplace_back(file_path); } } closedir(dir); + + if (is_index) { + return {user_paths, false}; + } + + user_paths.insert(user_paths.end(), tmp_paths.begin(), tmp_paths.end()); #else - for (auto const &entry : fs::directory_iterator(resolved_path)) { - if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { - continue; - } + if (fs::exists(resolved_path + "/index.ets")) { + user_paths.emplace_back(path + "/index.ets"); + } else if (fs::exists(resolved_path + "/index.ts")) { + user_paths.emplace_back(path + "/index.ts"); + } else { + for (auto const &entry : fs::directory_iterator(resolved_path)) { + if (!fs::is_regular_file(entry) || !IsCompitableExtension(entry.path().extension().string())) { + continue; + } - std::string base_name = path; - std::size_t pos = entry.path().string().find_last_of(panda::os::file::File::GetPathDelim()); + std::string base_name = path; + std::size_t pos = entry.path().string().find_last_of(panda::os::file::File::GetPathDelim()); - base_name.append(entry.path().string().substr(pos, entry.path().string().size())); - user_paths.emplace_back(base_name); + base_name.append(entry.path().string().substr(pos, entry.path().string().size())); + user_paths.emplace_back(base_name); + } } #endif return {user_paths, false}; diff --git a/ets2panda/test/parser/ets/folder_import_index/index-expected.txt b/ets2panda/test/parser/ets/folder_import_index/index-expected.txt new file mode 100644 index 000000000..7fee7d1bd --- /dev/null +++ b/ets2panda/test/parser/ets/folder_import_index/index-expected.txt @@ -0,0 +1,247 @@ +{ + "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": "ad", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "ad", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 24 + } + } + } + ], + "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": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/folder_import_index/index.ets b/ets2panda/test/parser/ets/folder_import_index/index.ets new file mode 100644 index 000000000..1e4379a5a --- /dev/null +++ b/ets2panda/test/parser/ets/folder_import_index/index.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +export function ad() {}; diff --git a/ets2panda/test/parser/ets/import_folder-expected.txt b/ets2panda/test/parser/ets/import_folder-expected.txt new file mode 100644 index 000000000..13eaacba2 --- /dev/null +++ b/ets2panda/test/parser/ets/import_folder-expected.txt @@ -0,0 +1,254 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./folder_import_index", + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 39 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "ad", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 3 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 5 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 19, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_folder.ets b/ets2panda/test/parser/ets/import_folder.ets new file mode 100644 index 000000000..70749437b --- /dev/null +++ b/ets2panda/test/parser/ets/import_folder.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. + */ + +import * from "./folder_import_index"; + +ad(); diff --git a/ets2panda/test/parser/ets/re_export/folderIndex/index-expected.txt b/ets2panda/test/parser/ets/re_export/folderIndex/index-expected.txt new file mode 100644 index 000000000..3120da76a --- /dev/null +++ b/ets2panda/test/parser/ets/re_export/folderIndex/index-expected.txt @@ -0,0 +1,153 @@ +{ + "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 + } + } + } + ], + "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": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/re_export/folderIndex/index.ets b/ets2panda/test/parser/ets/re_export/folderIndex/index.ets new file mode 100644 index 000000000..2de0cf117 --- /dev/null +++ b/ets2panda/test/parser/ets/re_export/folderIndex/index.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +export {ad} from "./test"; diff --git a/ets2panda/test/parser/ets/re_export/folderIndex/test-expected.txt b/ets2panda/test/parser/ets/re_export/folderIndex/test-expected.txt new file mode 100644 index 000000000..17b2f3544 --- /dev/null +++ b/ets2panda/test/parser/ets/re_export/folderIndex/test-expected.txt @@ -0,0 +1,247 @@ +{ + "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": "ad", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "ad", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 23 + } + } + } + ], + "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": 17, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/re_export/folderIndex/test.ets b/ets2panda/test/parser/ets/re_export/folderIndex/test.ets new file mode 100644 index 000000000..0e0ed6250 --- /dev/null +++ b/ets2panda/test/parser/ets/re_export/folderIndex/test.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +export function ad(){}; diff --git a/ets2panda/test/parser/ets/re_export/import_index-expected.txt b/ets2panda/test/parser/ets/re_export/import_index-expected.txt new file mode 100644 index 000000000..b17dc4ba5 --- /dev/null +++ b/ets2panda/test/parser/ets/re_export/import_index-expected.txt @@ -0,0 +1,254 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./folderIndex", + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 31 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "ad", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 3 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 5 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 19, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/re_export/import_index.ets b/ets2panda/test/parser/ets/re_export/import_index.ets new file mode 100644 index 000000000..5b3ec70e4 --- /dev/null +++ b/ets2panda/test/parser/ets/re_export/import_index.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. + */ + +import * from "./folderIndex"; + +ad(); diff --git a/ets2panda/test/parser/ets/re_export/import_index_2-expected.txt b/ets2panda/test/parser/ets/re_export/import_index_2-expected.txt new file mode 100644 index 000000000..8d4fa72df --- /dev/null +++ b/ets2panda/test/parser/ets/re_export/import_index_2-expected.txt @@ -0,0 +1,269 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./folderIndex", + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "ad", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "imported": { + "type": "Identifier", + "name": "ad", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 34 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "ad", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 3 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 5 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 19, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/re_export/import_index_2.ets b/ets2panda/test/parser/ets/re_export/import_index_2.ets new file mode 100644 index 000000000..0c187b82d --- /dev/null +++ b/ets2panda/test/parser/ets/re_export/import_index_2.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. + */ + +import {ad} from "./folderIndex"; + +ad(); diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index a5461d388..87d2318c0 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -483,8 +483,9 @@ bool ETSBinder::AddImportNamespaceSpecifiersToTopBindings(ir::AstNode *const spe std::unordered_set exported_names; for (auto item : ReExportImports()) { - if (import->ResolvedSource()->Str().Is( - item->GetProgramPath().Mutf8().substr(0, item->GetProgramPath().Mutf8().find_last_of('.')))) { + if (auto source = import->ResolvedSource()->Str().Mutf8(), + program = item->GetProgramPath().Mutf8().substr(0, item->GetProgramPath().Mutf8().find_last_of('.')); + source == program || (source + "/index") == program) { ir::StringLiteral dir_name(util::UString(util::StringView(item->GetProgramPath().Mutf8().substr( 0, item->GetProgramPath().Mutf8().find_last_of('/'))), Allocator()) @@ -590,8 +591,9 @@ bool ETSBinder::AddImportSpecifiersToTopBindings(ir::AstNode *const specifier, if (var == nullptr) { for (auto item : ReExportImports()) { - if (import->ResolvedSource()->Str().Is( - item->GetProgramPath().Mutf8().substr(0, item->GetProgramPath().Mutf8().find_last_of('.')))) { + if (auto source = import->ResolvedSource()->Str().Mutf8(), + program = item->GetProgramPath().Mutf8().substr(0, item->GetProgramPath().Mutf8().find_last_of('.')); + source == program || (source + "/index") == program) { ir::StringLiteral dir_name(util::UString(util::StringView(item->GetProgramPath().Mutf8().substr( 0, item->GetProgramPath().Mutf8().find_last_of('/'))), Allocator()) @@ -638,7 +640,22 @@ ArenaVector ETSBinder::GetExternalProgram(const util::StringV const auto &ext_records = global_record_table_.Program()->ExternalSources(); auto record_res = [this, ext_records, source_name]() { auto res = ext_records.find(source_name); - return (res != ext_records.end()) ? res : ext_records.find(GetResolvedImportPath(source_name)); + + if (res != ext_records.end()) { + return res; + } + + if (res = ext_records.find({source_name.Mutf8() + "/index"}); res != ext_records.end()) { + return res; + } + + res = ext_records.find(GetResolvedImportPath(source_name)); + + if (res == ext_records.end()) { + res = ext_records.find(GetResolvedImportPath({source_name.Mutf8() + "/index"})); + } + + return res; }(); if (record_res == ext_records.end()) { ThrowError(import_path->Start(), "Cannot find import: " + std::string(source_name)); diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index f019a64f2..7d685b6aa 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -753,6 +753,13 @@ Variable *ClassScope::AddBinding(ArenaAllocator *allocator, [[maybe_unused]] Var return nullptr; } + if (auto node = new_decl->Node(); + node->IsStatement() && + (node->AsStatement()->IsMethodDefinition() || node->IsClassProperty() || node->IsClassStaticBlock()) && + node->AsStatement()->AsClassElement()->Value() != nullptr) { + props.SetFlagsType(VariableFlags::INITIALIZED); + } + var->SetScope(this); var->AddFlag(props.GetFlags()); -- Gitee From 423303591d8be7a624d013c48aeb041eab7900cd Mon Sep 17 00:00:00 2001 From: Martin Sajti Date: Mon, 27 Nov 2023 10:38:33 +0100 Subject: [PATCH 15/35] Implement generic type aliases Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8O7LN Internal issue: #13438 Test: build, new checker tests Signed-off-by: Martin Sajti --- ets2panda/checker/ETSAnalyzer.cpp | 26 + ets2panda/checker/ETSchecker.h | 3 + ets2panda/checker/ets/helpers.cpp | 93 + ets2panda/checker/ets/typeRelationContext.cpp | 4 +- ets2panda/checker/types/ets/etsObjectType.cpp | 53 +- ets2panda/checker/types/ets/etsObjectType.h | 4 + ets2panda/checker/types/typeRelation.h | 6 + ets2panda/ir/ets/etsFunctionType.cpp | 38 + ets2panda/ir/ets/etsFunctionType.h | 3 + ets2panda/ir/ets/etsPrimitiveType.cpp | 15 + ets2panda/ir/ets/etsPrimitiveType.h | 3 + ets2panda/ir/ets/etsTypeReference.cpp | 22 + ets2panda/ir/ets/etsTypeReference.h | 3 + ets2panda/ir/ets/etsTypeReferencePart.cpp | 37 + ets2panda/ir/ets/etsTypeReferencePart.h | 3 + ets2panda/ir/ts/tsArrayType.cpp | 20 + ets2panda/ir/ts/tsArrayType.h | 3 + ets2panda/ir/ts/tsTypeAliasDeclaration.cpp | 1 + .../ets/generic_typealias_1-expected.txt | 2841 +++++++++++++++++ .../test/compiler/ets/generic_typealias_1.ets | 32 + .../ets/generic_typealias_10_neg-expected.txt | 266 ++ .../compiler/ets/generic_typealias_10_neg.ets | 16 + .../ets/generic_typealias_2_neg-expected.txt | 542 ++++ .../compiler/ets/generic_typealias_2_neg.ets | 21 + .../ets/generic_typealias_3_neg-expected.txt | 555 ++++ .../compiler/ets/generic_typealias_3_neg.ets | 21 + .../ets/generic_typealias_4_neg-expected.txt | 639 ++++ .../compiler/ets/generic_typealias_4_neg.ets | 21 + .../ets/generic_typealias_5_neg-expected.txt | 1014 ++++++ .../compiler/ets/generic_typealias_5_neg.ets | 23 + .../ets/generic_typealias_6-expected.txt | 876 +++++ .../test/compiler/ets/generic_typealias_6.ets | 22 + .../ets/generic_typealias_7_neg-expected.txt | 528 +++ .../compiler/ets/generic_typealias_7_neg.ets | 20 + .../ets/generic_typealias_8-expected.txt | 790 +++++ .../test/compiler/ets/generic_typealias_8.ets | 20 + .../ets/generic_typealias_9-expected.txt | 754 +++++ .../test/compiler/ets/generic_typealias_9.ets | 19 + ets2panda/varbinder/varbinder.cpp | 16 + ets2panda/varbinder/varbinder.h | 1 + 40 files changed, 9355 insertions(+), 19 deletions(-) create mode 100644 ets2panda/test/compiler/ets/generic_typealias_1-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_1.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_10_neg-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_10_neg.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_2_neg-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_2_neg.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_3_neg-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_3_neg.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_4_neg-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_4_neg.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_5_neg-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_5_neg.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_6-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_6.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_7_neg-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_7_neg.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_8-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_8.ets create mode 100644 ets2panda/test/compiler/ets/generic_typealias_9-expected.txt create mode 100644 ets2panda/test/compiler/ets/generic_typealias_9.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 7d09420fd..285cd8346 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2633,7 +2633,33 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TSTupleType *node) const checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const { ETSChecker *checker = GetETSChecker(); + if (st->TypeParams() != nullptr) { + for (const auto *const param : st->TypeParams()->Params()) { + const auto *const res = st->TypeAnnotation()->FindChild([¶m](const ir::AstNode *const node) { + if (!node->IsIdentifier()) { + return false; + } + + return param->Name()->AsIdentifier()->Variable() == node->AsIdentifier()->Variable(); + }); + + if (res == nullptr) { + checker->ThrowTypeError( + {"Type alias generic parameter '", param->Name()->Name(), "' is not used in type annotation"}, + param->Start()); + } + + param->Name()->Variable()->SetTsType( + checker->CreateNullishType(checker->GlobalETSObjectType(), checker::TypeFlag::NULLISH, + checker->Allocator(), checker->Relation(), checker->GetGlobalTypesHolder())); + } + } + + const checker::SavedTypeRelationFlagsContext saved_flags_ctx(checker->Relation(), + checker::TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS); + st->TypeAnnotation()->Check(checker); + return nullptr; } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 17260db5e..83fc6af18 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -407,6 +407,9 @@ public: Type *GetTypeFromInterfaceReference(varbinder::Variable *var); Type *GetTypeFromTypeAliasReference(varbinder::Variable *var); Type *GetTypeFromClassReference(varbinder::Variable *var); + void ValidateGenericTypeAliasForClonedNode(ir::TSTypeAliasDeclaration *type_alias_node, + const ir::TSTypeParameterInstantiation *exact_type_params); + Type *HandleTypeAlias(ir::Expression *name, const ir::TSTypeParameterInstantiation *type_params); Type *GetTypeFromEnumReference(varbinder::Variable *var); Type *GetTypeFromTypeParameterReference(varbinder::LocalVariable *var, const lexer::SourcePosition &pos); Type *GetNonConstantTypeFromPrimitiveType(Type *type); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 5dce544bb..a3746e41b 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1092,6 +1092,7 @@ Type *ETSChecker::GetTypeFromTypeAliasReference(varbinder::Variable *var) auto *const alias_type_node = var->Declaration()->Node()->AsTSTypeAliasDeclaration(); TypeStackElement tse(this, alias_type_node, "Circular type alias reference", alias_type_node->Start()); + alias_type_node->Check(this); auto *const aliased_type = GetTypeFromTypeAnnotation(alias_type_node->TypeAnnotation()); var->SetTsType(aliased_type); @@ -1120,6 +1121,98 @@ Type *ETSChecker::GetTypeFromClassReference(varbinder::Variable *var) return class_type; } +void ETSChecker::ValidateGenericTypeAliasForClonedNode(ir::TSTypeAliasDeclaration *const type_alias_node, + const ir::TSTypeParameterInstantiation *const exact_type_params) +{ + auto *const cloned_node = type_alias_node->TypeAnnotation()->Clone(Allocator(), type_alias_node); + + // Basic check, we really don't want to change the original type nodes, more precise checking should be made + ASSERT(cloned_node != type_alias_node->TypeAnnotation()); + + // Currently only reference types are checked. This should be extended for other types in a follow up patch, but for + // complete usability, if the type isn't a simple reference type, then doN't check type alias declaration at all. + bool check_typealias = true; + + // Only transforming a temporary cloned node, so no modification is made in the AST + cloned_node->TransformChildrenRecursively( + [&check_typealias, &exact_type_params, type_alias_node](ir::AstNode *const node) -> ir::AstNode * { + if (!node->IsETSTypeReference()) { + return node; + } + + const auto *const node_ident = node->AsETSTypeReference()->Part()->Name()->AsIdentifier(); + + size_t type_param_idx = 0; + for (const auto *const type_param : type_alias_node->TypeParams()->Params()) { + if (type_param->Name()->AsIdentifier()->Variable() == node_ident->Variable()) { + break; + } + type_param_idx++; + } + + if (type_param_idx == type_alias_node->TypeParams()->Params().size()) { + return node; + } + + auto *const type_param_type = exact_type_params->Params().at(type_param_idx); + + if (!type_param_type->IsETSTypeReference()) { + check_typealias = false; + return node; + } + + return type_param_type; + }); + + if (check_typealias) { + cloned_node->Check(this); + } +} + +Type *ETSChecker::HandleTypeAlias(ir::Expression *const name, const ir::TSTypeParameterInstantiation *const type_params) +{ + ASSERT(name->IsIdentifier() && name->AsIdentifier()->Variable() && + name->AsIdentifier()->Variable()->Declaration()->IsTypeAliasDecl()); + + auto *const type_alias_node = + name->AsIdentifier()->Variable()->Declaration()->AsTypeAliasDecl()->Node()->AsTSTypeAliasDeclaration(); + + // NOTE (mmartin): modify for default params + if ((type_params == nullptr) != (type_alias_node->TypeParams() == nullptr)) { + if (type_params == nullptr) { + ThrowTypeError("Type alias declaration is generic, but no type parameters were provided", name->Start()); + } + + ThrowTypeError("Type alias declaration is not generic, but type parameters were provided", + type_params->Start()); + } + + if (type_params == nullptr) { + return GetReferencedTypeBase(name); + } + + for (auto *const orig_type_param : type_params->Params()) { + orig_type_param->Check(this); + } + + Type *const alias_type = GetReferencedTypeBase(name); + auto *const alias_sub = NewSubstitution(); + + if (type_alias_node->TypeParams()->Params().size() != type_params->Params().size()) { + ThrowTypeError("Wrong number of type parameters for generic type alias", type_params->Start()); + } + + for (std::size_t idx = 0; idx < type_alias_node->TypeParams()->Params().size(); ++idx) { + alias_sub->insert( + {type_alias_node->TypeParams()->Params().at(idx)->Name()->AsIdentifier()->Variable()->TsType(), + type_params->Params().at(idx)->TsType()}); + } + + ValidateGenericTypeAliasForClonedNode(type_alias_node->AsTSTypeAliasDeclaration(), type_params); + + return alias_type->Substitute(Relation(), alias_sub); +} + Type *ETSChecker::GetTypeFromEnumReference([[maybe_unused]] varbinder::Variable *var) { if (var->TsType() != nullptr) { diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index df9af96ac..653c615a5 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -96,7 +96,7 @@ bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSType }); } - if (!assignable) { + if (!assignable && !checker_->Relation()->NoThrowGenericTypeAlias()) { checker_->ThrowTypeError({"Type '", type_arg_type->AsETSObjectType(), "' is not assignable to constraint type '", constraint_type, "'."}, type_args->Params().at(type_param_iter)->Start()); @@ -178,7 +178,7 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ArenaVectorIsCompatibleTypeArgument(type_param, type_arg_types[ix], constraints_substitution); } - if (!is_compatible_type_arg) { + if (!is_compatible_type_arg && !checker_->Relation()->NoThrowGenericTypeAlias()) { checker_->ThrowTypeError( {"Type ", type_arg_types[ix], " is not assignable to", " type parameter ", type_params[ix]}, pos); } diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 28c6390e3..a679773ec 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -790,11 +790,45 @@ ETSObjectType const *ETSObjectType::GetConstOriginalBaseType() const noexcept return this; } +bool ETSObjectType::SubstituteTypeArgs(TypeRelation *const relation, ArenaVector &new_type_args, + const Substitution *const substitution) +{ + bool any_change = false; + new_type_args.reserve(type_arguments_.size()); + + for (auto *const arg : type_arguments_) { + auto *const new_arg = arg->Substitute(relation, substitution); + new_type_args.push_back(new_arg); + any_change = any_change || (new_arg != arg); + } + + return any_change; +} + +void ETSObjectType::SetCopiedTypeProperties(TypeRelation *const relation, ETSObjectType *const copied_type, + ArenaVector &new_type_args, const Substitution *const substitution) +{ + copied_type->type_flags_ = type_flags_; + copied_type->RemoveObjectFlag(ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS | + ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY); + copied_type->SetVariable(variable_); + copied_type->SetBaseType(this); + + copied_type->SetTypeArguments(std::move(new_type_args)); + copied_type->relation_ = relation; + copied_type->substitution_ = substitution; +} + Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution) { if (substitution == nullptr || substitution->empty()) { return this; } + + if (const auto &this_type_in_sub = substitution->find(this); this_type_in_sub != substitution->end()) { + return this_type_in_sub->second; + } + auto *const checker = relation->GetChecker()->AsETSChecker(); auto *base = GetOriginalBaseType(); if (auto repl = substitution->find(base); repl != substitution->end()) { @@ -818,13 +852,7 @@ Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *subs } ArenaVector new_type_args {checker->Allocator()->Adapter()}; - new_type_args.reserve(type_arguments_.size()); - bool any_change = false; - for (auto *arg : type_arguments_) { - auto *new_arg = arg->Substitute(relation, substitution); - new_type_args.push_back(new_arg); - any_change |= (new_arg != arg); - } + const bool any_change = SubstituteTypeArgs(relation, new_type_args, substitution); // Lambda types can capture type params in their bodies, normal classes cannot. // NOTE: gogabr. determine precise conditions where we do not need to copy. @@ -844,16 +872,7 @@ Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *subs relation->IncreaseTypeRecursionCount(base); auto *const copied_type = checker->CreateNewETSObjectType(name_, decl_node_, flags_); - copied_type->type_flags_ = type_flags_; - copied_type->RemoveObjectFlag(ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS | - ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY); - copied_type->SetVariable(variable_); - copied_type->SetBaseType(this); - - copied_type->SetTypeArguments(std::move(new_type_args)); - copied_type->relation_ = relation; - copied_type->substitution_ = substitution; - + SetCopiedTypeProperties(relation, copied_type, new_type_args, substitution); GetInstantiationMap().try_emplace(hash, copied_type); if (super_type_ != nullptr) { diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index eba9f33f0..0500dd6a8 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -477,6 +477,10 @@ public: bool AssignmentSource(TypeRelation *relation, Type *target) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *global_types) override; + bool SubstituteTypeArgs(TypeRelation *relation, ArenaVector &new_type_args, + const Substitution *substitution); + void SetCopiedTypeProperties(TypeRelation *relation, ETSObjectType *copied_type, ArenaVector &new_type_args, + const Substitution *substitution); Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; void Cast(TypeRelation *relation, Type *target) override; bool CastNumericObject(TypeRelation *relation, Type *target); diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index 6abd143d4..636c4dcdb 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -61,6 +61,7 @@ enum class TypeRelationFlag : uint32_t { IGNORE_TYPE_PARAMETERS = 1U << 20U, CHECK_PROXY = 1U << 21U, NO_CHECK_TRAILING_LAMBDA = 1U << 23U, + NO_THROW_GENERIC_TYPEALIAS = 1U << 24U, ASSIGNMENT_CONTEXT = WIDENING | BOXING | UNBOXING, CASTING_CONTEXT = NARROWING | WIDENING | BOXING | UNBOXING | UNCHECKED_CAST, @@ -201,6 +202,11 @@ public: return (flags_ & TypeRelationFlag::UNCHECKED_CAST) != 0; } + [[nodiscard]] bool NoThrowGenericTypeAlias() const noexcept + { + return (flags_ & TypeRelationFlag::NO_THROW_GENERIC_TYPEALIAS) != 0; + } + const Checker *GetChecker() const { return checker_; diff --git a/ets2panda/ir/ets/etsFunctionType.cpp b/ets2panda/ir/ets/etsFunctionType.cpp index 0c6844b0a..f87441758 100644 --- a/ets2panda/ir/ets/etsFunctionType.cpp +++ b/ets2panda/ir/ets/etsFunctionType.cpp @@ -96,4 +96,42 @@ checker::Type *ETSFunctionType::GetType(checker::ETSChecker *checker) { return Check(checker); } + +// NOLINTNEXTLINE(google-default-arguments) +ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + ArenaVector params_clone(allocator->Adapter()); + + for (auto *const param : signature_.Params()) { + params_clone.emplace_back(param->Clone(allocator)->AsExpression()); + } + + auto *const type_params_clone = signature_.TypeParams() != nullptr + ? signature_.TypeParams()->Clone(allocator)->AsTSTypeParameterDeclaration() + : nullptr; + auto *const return_type_clone = + signature_.ReturnType() != nullptr ? signature_.ReturnType()->Clone(allocator)->AsTypeNode() : nullptr; + + if (auto *const clone = allocator->New( + FunctionSignature(type_params_clone, std::move(params_clone), return_type_clone), func_flags_); + clone != nullptr) { + if (type_params_clone != nullptr) { + type_params_clone->SetParent(clone); + } + + if (return_type_clone != nullptr) { + return_type_clone->SetParent(clone); + } + + if (parent != nullptr) { + clone->SetParent(parent); + } + + clone->SetScope(scope_); + + return clone; + } + + throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ets/etsFunctionType.h b/ets2panda/ir/ets/etsFunctionType.h index f52f97b59..0de30cdee 100644 --- a/ets2panda/ir/ets/etsFunctionType.h +++ b/ets2panda/ir/ets/etsFunctionType.h @@ -109,6 +109,9 @@ public: v->Accept(this); } + // NOLINTNEXTLINE(google-default-arguments) + [[nodiscard]] ETSFunctionType *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + private: varbinder::Scope *scope_ {}; FunctionSignature signature_; diff --git a/ets2panda/ir/ets/etsPrimitiveType.cpp b/ets2panda/ir/ets/etsPrimitiveType.cpp index cf436280e..bfc3562cf 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.cpp +++ b/ets2panda/ir/ets/etsPrimitiveType.cpp @@ -131,4 +131,19 @@ checker::Type *ETSPrimitiveType::GetType([[maybe_unused]] checker::ETSChecker *c } } } + +// NOLINTNEXTLINE(google-default-arguments) +ETSPrimitiveType *ETSPrimitiveType::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + if (auto *const clone = allocator->New(type_); clone != nullptr) { + if (parent != nullptr) { + clone->SetParent(parent); + } + + return clone; + } + + throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); +} + } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ets/etsPrimitiveType.h b/ets2panda/ir/ets/etsPrimitiveType.h index 15afb7350..b2ad1451d 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.h +++ b/ets2panda/ir/ets/etsPrimitiveType.h @@ -46,6 +46,9 @@ public: v->Accept(this); } + // NOLINTNEXTLINE(google-default-arguments) + [[nodiscard]] ETSPrimitiveType *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + private: PrimitiveType type_; }; diff --git a/ets2panda/ir/ets/etsTypeReference.cpp b/ets2panda/ir/ets/etsTypeReference.cpp index 59b72fc8c..38785bf89 100644 --- a/ets2panda/ir/ets/etsTypeReference.cpp +++ b/ets2panda/ir/ets/etsTypeReference.cpp @@ -106,4 +106,26 @@ checker::Type *ETSTypeReference::GetType(checker::ETSChecker *checker) SetTsType(type); return type; } + +// NOLINTNEXTLINE(google-default-arguments) +ETSTypeReference *ETSTypeReference::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + auto *const part_clone = part_ != nullptr ? part_->Clone(allocator)->AsETSTypeReferencePart() : nullptr; + + if (auto *const clone = allocator->New(part_clone); clone != nullptr) { + if (part_clone != nullptr) { + part_clone->SetParent(clone); + } + + clone->flags_ = flags_; + + if (parent != nullptr) { + clone->SetParent(parent); + } + + return clone; + } + + throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ets/etsTypeReference.h b/ets2panda/ir/ets/etsTypeReference.h index 40b9e6c8d..d67d7f49a 100644 --- a/ets2panda/ir/ets/etsTypeReference.h +++ b/ets2panda/ir/ets/etsTypeReference.h @@ -53,6 +53,9 @@ public: v->Accept(this); } + // NOLINTNEXTLINE(google-default-arguments) + [[nodiscard]] ETSTypeReference *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + private: ir::ETSTypeReferencePart *part_; }; diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index 767585e47..e1cbd3896 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -90,6 +90,11 @@ checker::Type *ETSTypeReferencePart::Check(checker::ETSChecker *checker) checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) { if (prev_ == nullptr) { + if ((name_->IsIdentifier()) && (name_->AsIdentifier()->Variable() != nullptr) && + (name_->AsIdentifier()->Variable()->Declaration()->IsTypeAliasDecl())) { + return checker->HandleTypeAlias(name_, type_params_); + } + checker::Type *base_type = checker->GetReferencedTypeBase(name_); ASSERT(base_type != nullptr); @@ -104,4 +109,36 @@ checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) checker::Type *base_type = prev_->GetType(checker); return checker->GetReferencedTypeFromBase(base_type, name_); } + +// NOLINTNEXTLINE(google-default-arguments) +ETSTypeReferencePart *ETSTypeReferencePart::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + auto *const name_clone = name_ != nullptr ? name_->Clone(allocator)->AsExpression() : nullptr; + auto *const type_params_clone = + type_params_ != nullptr ? type_params_->Clone(allocator)->AsTSTypeParameterInstantiation() : nullptr; + auto *const prev_clone = prev_ != nullptr ? prev_->Clone(allocator)->AsETSTypeReferencePart() : nullptr; + + if (auto *const clone = allocator->New(name_clone, type_params_clone, prev_clone); + clone != nullptr) { + if (name_clone != nullptr) { + name_clone->SetParent(clone); + } + + if (type_params_clone != nullptr) { + type_params_clone->SetParent(clone); + } + + if (prev_clone != nullptr) { + prev_clone->SetParent(clone); + } + + if (parent != nullptr) { + clone->SetParent(parent); + } + + return clone; + } + + throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ets/etsTypeReferencePart.h b/ets2panda/ir/ets/etsTypeReferencePart.h index 4facc1a6d..dce25c917 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.h +++ b/ets2panda/ir/ets/etsTypeReferencePart.h @@ -70,6 +70,9 @@ public: v->Accept(this); } + // NOLINTNEXTLINE(google-default-arguments) + [[nodiscard]] ETSTypeReferencePart *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + private: ir::Expression *name_; ir::TSTypeParameterInstantiation *type_params_ {}; diff --git a/ets2panda/ir/ts/tsArrayType.cpp b/ets2panda/ir/ts/tsArrayType.cpp index ada705e56..07b11ca29 100644 --- a/ets2panda/ir/ts/tsArrayType.cpp +++ b/ets2panda/ir/ts/tsArrayType.cpp @@ -78,4 +78,24 @@ checker::Type *TSArrayType::GetType(checker::ETSChecker *checker) return checker->CreateETSArrayType(element_type); } +// NOLINTNEXTLINE(google-default-arguments) +TSArrayType *TSArrayType::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + auto *const element_type_clone = element_type_ != nullptr ? element_type_->Clone(allocator) : nullptr; + + if (auto *const clone = allocator->New(element_type_clone); clone != nullptr) { + if (element_type_clone != nullptr) { + element_type_clone->SetParent(clone); + } + + if (parent != nullptr) { + clone->SetParent(parent); + } + + return clone; + } + + throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); +} + } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsArrayType.h b/ets2panda/ir/ts/tsArrayType.h index 48af2bfa6..560bb5d35 100644 --- a/ets2panda/ir/ts/tsArrayType.h +++ b/ets2panda/ir/ts/tsArrayType.h @@ -53,6 +53,9 @@ public: v->Accept(this); } + // NOLINTNEXTLINE(google-default-arguments) + [[nodiscard]] TSArrayType *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; + private: TypeNode *element_type_; }; diff --git a/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp b/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp index aafa75994..21180374a 100644 --- a/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp +++ b/ets2panda/ir/ts/tsTypeAliasDeclaration.cpp @@ -113,4 +113,5 @@ checker::Type *TSTypeAliasDeclaration::Check([[maybe_unused]] checker::ETSChecke { return checker->GetAnalyzer()->Check(this); } + } // namespace panda::es2panda::ir diff --git a/ets2panda/test/compiler/ets/generic_typealias_1-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_1-expected.txt new file mode 100644 index 000000000..8e27fca50 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_1-expected.txt @@ -0,0 +1,2841 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "my_int", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 6 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 17, + "column": 5 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 17, + "column": 5 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 17, + "column": 5 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "a_t", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 6 + }, + "end": { + "line": 18, + "column": 9 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "U", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "U", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 12 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 8 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "L", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 8 + }, + "end": { + "line": 20, + "column": 11 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 11 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + { + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "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": 22, + "column": 10 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 12 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 12 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 12 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 22 + }, + "end": { + "line": 23, + "column": 29 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 30 + }, + "end": { + "line": 23, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 30 + }, + "end": { + "line": 23, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 30 + }, + "end": { + "line": 23, + "column": 34 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 29 + }, + "end": { + "line": 23, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 22 + }, + "end": { + "line": 23, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 22 + }, + "end": { + "line": 23, + "column": 35 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 38 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 13 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 14 + }, + "end": { + "line": 24, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 14 + }, + "end": { + "line": 24, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 14 + }, + "end": { + "line": 24, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 24, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 23 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 28 + }, + "end": { + "line": 24, + "column": 29 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 30 + }, + "end": { + "line": 24, + "column": 37 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 38 + }, + "end": { + "line": 24, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 38 + }, + "end": { + "line": 24, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 38 + }, + "end": { + "line": 24, + "column": 46 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 37 + }, + "end": { + "line": 24, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 30 + }, + "end": { + "line": 24, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 30 + }, + "end": { + "line": 24, + "column": 46 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 29 + }, + "end": { + "line": 24, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 28 + }, + "end": { + "line": 24, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 28 + }, + "end": { + "line": 24, + "column": 47 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 24, + "column": 24 + }, + "end": { + "line": 24, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 49 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 49 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 12 + }, + "end": { + "line": 25, + "column": 13 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 14 + }, + "end": { + "line": 25, + "column": 21 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Long", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 22 + }, + "end": { + "line": 25, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 22 + }, + "end": { + "line": 25, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 22 + }, + "end": { + "line": 25, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 21 + }, + "end": { + "line": 25, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 14 + }, + "end": { + "line": 25, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 14 + }, + "end": { + "line": 25, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 12 + }, + "end": { + "line": 25, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 12 + }, + "end": { + "line": 25, + "column": 30 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 9 + }, + "end": { + "line": 25, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 35 + }, + "end": { + "line": 25, + "column": 36 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Long", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 37 + }, + "end": { + "line": 25, + "column": 41 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 37 + }, + "end": { + "line": 25, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 37 + }, + "end": { + "line": 25, + "column": 42 + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 36 + }, + "end": { + "line": 25, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 35 + }, + "end": { + "line": 25, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 35 + }, + "end": { + "line": 25, + "column": 43 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 25, + "column": 31 + }, + "end": { + "line": 25, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 9 + }, + "end": { + "line": 25, + "column": 45 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 45 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "d", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 12 + }, + "end": { + "line": 26, + "column": 13 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 14 + }, + "end": { + "line": 26, + "column": 21 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 21 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 14 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 14 + }, + "end": { + "line": 26, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 13 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 12 + }, + "end": { + "line": 26, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 12 + }, + "end": { + "line": 26, + "column": 29 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 9 + }, + "end": { + "line": 26, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 34 + }, + "end": { + "line": 26, + "column": 35 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 36 + }, + "end": { + "line": 26, + "column": 43 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 44 + }, + "end": { + "line": 26, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 44 + }, + "end": { + "line": 26, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 44 + }, + "end": { + "line": 26, + "column": 49 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 43 + }, + "end": { + "line": 26, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 36 + }, + "end": { + "line": 26, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 36 + }, + "end": { + "line": 26, + "column": 49 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 35 + }, + "end": { + "line": 26, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 34 + }, + "end": { + "line": 26, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 34 + }, + "end": { + "line": 26, + "column": 50 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 26, + "column": 30 + }, + "end": { + "line": 26, + "column": 52 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 9 + }, + "end": { + "line": 26, + "column": 52 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 26, + "column": 5 + }, + "end": { + "line": 26, + "column": 52 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "e", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "a_t", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 12 + }, + "end": { + "line": 28, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 16 + }, + "end": { + "line": 28, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 16 + }, + "end": { + "line": 28, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 16 + }, + "end": { + "line": 28, + "column": 20 + } + } + } + ], + "loc": { + "start": { + "line": 28, + "column": 15 + }, + "end": { + "line": 28, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 12 + }, + "end": { + "line": 28, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 12 + }, + "end": { + "line": 28, + "column": 22 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 10 + } + } + }, + "init": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 23 + }, + "end": { + "line": 28, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 24 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 28, + "column": 5 + }, + "end": { + "line": 28, + "column": 25 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "f", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "a_t", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 12 + }, + "end": { + "line": 29, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 16 + }, + "end": { + "line": 29, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 16 + }, + "end": { + "line": 29, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 16 + }, + "end": { + "line": 29, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 29, + "column": 15 + }, + "end": { + "line": 29, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 12 + }, + "end": { + "line": 29, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 12 + }, + "end": { + "line": 29, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 9 + }, + "end": { + "line": 29, + "column": 10 + } + } + }, + "init": { + "type": "Identifier", + "name": "b", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 26 + }, + "end": { + "line": 29, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 9 + }, + "end": { + "line": 29, + "column": 27 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 29, + "column": 5 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "g", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "a_t", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 12 + }, + "end": { + "line": 30, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 16 + }, + "end": { + "line": 30, + "column": 23 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 24 + }, + "end": { + "line": 30, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 24 + }, + "end": { + "line": 30, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 24 + }, + "end": { + "line": 30, + "column": 29 + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 23 + }, + "end": { + "line": 30, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 16 + }, + "end": { + "line": 30, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 16 + }, + "end": { + "line": 30, + "column": 29 + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 15 + }, + "end": { + "line": 30, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 12 + }, + "end": { + "line": 30, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 12 + }, + "end": { + "line": 30, + "column": 31 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 9 + }, + "end": { + "line": 30, + "column": 10 + } + } + }, + "init": { + "type": "Identifier", + "name": "d", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 32 + }, + "end": { + "line": 30, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 9 + }, + "end": { + "line": 30, + "column": 33 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 30, + "column": 5 + }, + "end": { + "line": 30, + "column": 34 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "h", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "a_t", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 12 + }, + "end": { + "line": 31, + "column": 15 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 16 + }, + "end": { + "line": 31, + "column": 23 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_int", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 24 + }, + "end": { + "line": 31, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 24 + }, + "end": { + "line": 31, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 24 + }, + "end": { + "line": 31, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 23 + }, + "end": { + "line": 31, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 16 + }, + "end": { + "line": 31, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 16 + }, + "end": { + "line": 31, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 15 + }, + "end": { + "line": 31, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 12 + }, + "end": { + "line": 31, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 12 + }, + "end": { + "line": 31, + "column": 34 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 9 + }, + "end": { + "line": 31, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 39 + }, + "end": { + "line": 31, + "column": 40 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 41 + }, + "end": { + "line": 31, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 41 + }, + "end": { + "line": 31, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 41 + }, + "end": { + "line": 31, + "column": 45 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 40 + }, + "end": { + "line": 31, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 39 + }, + "end": { + "line": 31, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 39 + }, + "end": { + "line": 31, + "column": 46 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 31, + "column": 35 + }, + "end": { + "line": 31, + "column": 48 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 9 + }, + "end": { + "line": 31, + "column": 48 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 31, + "column": 5 + }, + "end": { + "line": 31, + "column": 48 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 23 + }, + "end": { + "line": 32, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 32, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 32, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 32, + "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": 33, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_1.ets b/ets2panda/test/compiler/ets/generic_typealias_1.ets new file mode 100644 index 000000000..45814fb18 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_1.ets @@ -0,0 +1,32 @@ +/* + * 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. + */ + +type my_int = Int +type my_type = T; +type a_t = A; + +class A{} + +function main(): void { + let a: Int = new my_type(2); + let b: A = new A>(); + let c: A> = new A(); + let d: A> = new A>(); + + let e: a_t = d; + let f: a_t = b; + let g: a_t> = d; + let h: a_t> = new A(); +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_10_neg-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_10_neg-expected.txt new file mode 100644 index 000000000..b0c876797 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_10_neg-expected.txt @@ -0,0 +1,266 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 6 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 17, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 17, + "column": 1 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 17, + "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": 17, + "column": 1 + } + } +} +TypeError: Type alias generic parameter 'T' is not used in type annotation [generic_typealias_10_neg.ets:16:14] diff --git a/ets2panda/test/compiler/ets/generic_typealias_10_neg.ets b/ets2panda/test/compiler/ets/generic_typealias_10_neg.ets new file mode 100644 index 000000000..c6d36ac95 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_10_neg.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +type my_type = Int diff --git a/ets2panda/test/compiler/ets/generic_typealias_2_neg-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_2_neg-expected.txt new file mode 100644 index 000000000..b62ce0049 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_2_neg-expected.txt @@ -0,0 +1,542 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 6 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + { + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 26 + }, + "end": { + "line": 20, + "column": 30 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 32 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} +TypeError: Type alias declaration is generic, but no type parameters were provided [generic_typealias_2_neg.ets:20:12] diff --git a/ets2panda/test/compiler/ets/generic_typealias_2_neg.ets b/ets2panda/test/compiler/ets/generic_typealias_2_neg.ets new file mode 100644 index 000000000..0bf9c1318 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_2_neg.ets @@ -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. + */ + +type my_type = T; + + +function main(): void { + let a: my_type = new Int(); +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_3_neg-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_3_neg-expected.txt new file mode 100644 index 000000000..b02e59012 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_3_neg-expected.txt @@ -0,0 +1,555 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 6 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + { + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 29 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 20, + "column": 30 + }, + "end": { + "line": 20, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 40 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} +TypeError: Type alias declaration is not generic, but type parameters were provided [generic_typealias_3_neg.ets:20:19] diff --git a/ets2panda/test/compiler/ets/generic_typealias_3_neg.ets b/ets2panda/test/compiler/ets/generic_typealias_3_neg.ets new file mode 100644 index 000000000..fb71ae4db --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_3_neg.ets @@ -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. + */ + +type my_type = Int; + + +function main(): void { + let a: my_type = new Int(); +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_4_neg-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_4_neg-expected.txt new file mode 100644 index 000000000..9be51ba28 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_4_neg-expected.txt @@ -0,0 +1,639 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 6 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + { + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "my_type", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 24 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 25 + }, + "end": { + "line": 20, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 25 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 25 + }, + "end": { + "line": 20, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 34 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 39 + }, + "end": { + "line": 20, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 39 + }, + "end": { + "line": 20, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 39 + }, + "end": { + "line": 20, + "column": 43 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 20, + "column": 35 + }, + "end": { + "line": 20, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 45 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 45 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} +TypeError: Wrong number of type parameters for generic type alias [generic_typealias_4_neg.ets:20:19] diff --git a/ets2panda/test/compiler/ets/generic_typealias_4_neg.ets b/ets2panda/test/compiler/ets/generic_typealias_4_neg.ets new file mode 100644 index 000000000..3204e76a7 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_4_neg.ets @@ -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. + */ + +type my_type = T; + + +function main(): void { + let a: my_type = new Int(); +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_5_neg-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_5_neg-expected.txt new file mode 100644 index 000000000..3d97f8506 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_5_neg-expected.txt @@ -0,0 +1,1014 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "constraint": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Comparable", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 29 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 30 + }, + "end": { + "line": 16, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 30 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 30 + }, + "end": { + "line": 16, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 29 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 36 + }, + "end": { + "line": 16, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 34 + }, + "end": { + "line": 16, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 36 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "type_a", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 6 + }, + "end": { + "line": 19, + "column": 12 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 19 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 20 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 20 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 20 + }, + "end": { + "line": 19, + "column": 22 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + { + "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": 21, + "column": 10 + }, + "end": { + "line": 21, + "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": 21, + "column": 10 + }, + "end": { + "line": 21, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 18 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 18 + }, + "end": { + "line": 21, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 18 + }, + "end": { + "line": 21, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 12 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 22, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 22, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 22, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 13 + }, + "end": { + "line": 22, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 12 + }, + "end": { + "line": 22, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 12 + }, + "end": { + "line": 22, + "column": 17 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 10 + } + } + }, + "init": null, + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 10 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 23 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 23, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 1 + } + } +} +TypeError: Type 'B' is not assignable to constraint type 'Comparable'. [generic_typealias_5_neg.ets:22:14] diff --git a/ets2panda/test/compiler/ets/generic_typealias_5_neg.ets b/ets2panda/test/compiler/ets/generic_typealias_5_neg.ets new file mode 100644 index 000000000..8089b4be0 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_5_neg.ets @@ -0,0 +1,23 @@ +/* + * 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> {} +class B {} + +type type_a = A; + +function main(): void { + let a: A; +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_6-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_6-expected.txt new file mode 100644 index 000000000..116b3cb48 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_6-expected.txt @@ -0,0 +1,876 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "constraint": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Comparable", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 29 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 30 + }, + "end": { + "line": 16, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 30 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 30 + }, + "end": { + "line": 16, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 29 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 36 + }, + "end": { + "line": 16, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 34 + }, + "end": { + "line": 16, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 36 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "type_a", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 6 + }, + "end": { + "line": 18, + "column": 12 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 19 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 22 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 18, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + { + "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": 20, + "column": 10 + }, + "end": { + "line": 20, + "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": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 18 + }, + "end": { + "line": 20, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 18 + }, + "end": { + "line": 20, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 18 + }, + "end": { + "line": 20, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 13 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 13 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 19 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 10 + } + } + }, + "init": null, + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 10 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 23 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 22, + "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": 23, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_6.ets b/ets2panda/test/compiler/ets/generic_typealias_6.ets new file mode 100644 index 000000000..9d2beaf4c --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_6.ets @@ -0,0 +1,22 @@ +/* + * 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> {} + +type type_a = A; + +function main(): void { + let a: A; +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_7_neg-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_7_neg-expected.txt new file mode 100644 index 000000000..cb253be2b --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_7_neg-expected.txt @@ -0,0 +1,528 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "type_a", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 6 + }, + "end": { + "line": 15, + "column": 12 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 18 + }, + "end": { + "line": 15, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 18 + }, + "end": { + "line": 15, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 18 + }, + "end": { + "line": 15, + "column": 20 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 13 + }, + "end": { + "line": 15, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 13 + }, + "end": { + "line": 15, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 15, + "column": 12 + }, + "end": { + "line": 15, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 1 + }, + "end": { + "line": 15, + "column": 20 + } + } + }, + { + "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": 17, + "column": 10 + }, + "end": { + "line": 17, + "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": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "type_a", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 22 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 10 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 27 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_7_neg.ets b/ets2panda/test/compiler/ets/generic_typealias_7_neg.ets new file mode 100644 index 000000000..1c22ec93d --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_7_neg.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. + */ +type type_a = T; + +function main(): void { + let a: type_a = 2; + // NOTE (martin): Primitive type parameter isn't working without initialization, it'll be in a follow up fix +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_8-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_8-expected.txt new file mode 100644 index 000000000..c91e3d2dd --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_8-expected.txt @@ -0,0 +1,790 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "type_a", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 6 + }, + "end": { + "line": 15, + "column": 12 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 18 + }, + "end": { + "line": 15, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 18 + }, + "end": { + "line": 15, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 18 + }, + "end": { + "line": 15, + "column": 20 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 13 + }, + "end": { + "line": 15, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 13 + }, + "end": { + "line": 15, + "column": 15 + } + } + } + ], + "loc": { + "start": { + "line": 15, + "column": 12 + }, + "end": { + "line": 15, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 1 + }, + "end": { + "line": 15, + "column": 20 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "type_a", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 18 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 25 + }, + "end": { + "line": 19, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 25 + }, + "end": { + "line": 19, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 25 + }, + "end": { + "line": 19, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 29 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 34 + }, + "end": { + "line": 19, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 34 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 34 + }, + "end": { + "line": 19, + "column": 36 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 38 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_8.ets b/ets2panda/test/compiler/ets/generic_typealias_8.ets new file mode 100644 index 000000000..0f16a64e3 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_8.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. + */ +type type_a = T; +class B {} + +function main(): void { + let a: type_a = new B(); +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_9-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_9-expected.txt new file mode 100644 index 000000000..12338275b --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_9-expected.txt @@ -0,0 +1,754 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "AnimationRange", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 6 + }, + "end": { + "line": 15, + "column": 20 + } + } + }, + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 15, + "column": 38 + }, + "end": { + "line": 15, + "column": 43 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 31 + }, + "end": { + "line": 15, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 31 + }, + "end": { + "line": 15, + "column": 43 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Value", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 48 + }, + "end": { + "line": 15, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 48 + }, + "end": { + "line": 17, + "column": 9 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 48 + }, + "end": { + "line": 17, + "column": 9 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 30 + }, + "end": { + "line": 17, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "Value", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 21 + }, + "end": { + "line": 15, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 21 + }, + "end": { + "line": 15, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 15, + "column": 20 + }, + "end": { + "line": 15, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 1 + }, + "end": { + "line": 17, + "column": 9 + } + } + }, + { + "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": 17, + "column": 10 + }, + "end": { + "line": 17, + "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": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "AnimationRange", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 31 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 33 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 10 + } + } + }, + "init": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "val", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 18, + "column": 40 + }, + "end": { + "line": 18, + "column": 45 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 45 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 48 + }, + "end": { + "line": 18, + "column": 51 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 48 + }, + "end": { + "line": 18, + "column": 54 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 48 + }, + "end": { + "line": 18, + "column": 54 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 18, + "column": 64 + }, + "end": { + "line": 18, + "column": 65 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 57 + }, + "end": { + "line": 18, + "column": 66 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 55 + }, + "end": { + "line": 18, + "column": 67 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 34 + }, + "end": { + "line": 18, + "column": 67 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 34 + }, + "end": { + "line": 18, + "column": 67 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 67 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 68 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 19, + "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": 20, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/generic_typealias_9.ets b/ets2panda/test/compiler/ets/generic_typealias_9.ets new file mode 100644 index 000000000..3e8359c64 --- /dev/null +++ b/ets2panda/test/compiler/ets/generic_typealias_9.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ +type AnimationRange = (value: float) => Value + +function main(): void { + let a: AnimationRange = (val: float): Int => { return 2;}; +} diff --git a/ets2panda/varbinder/varbinder.cpp b/ets2panda/varbinder/varbinder.cpp index ba618099a..2db75b204 100644 --- a/ets2panda/varbinder/varbinder.cpp +++ b/ets2panda/varbinder/varbinder.cpp @@ -51,6 +51,7 @@ #include "ir/ts/tsFunctionType.h" #include "ir/ts/tsConstructorType.h" #include "ir/ts/tsTypeParameterDeclaration.h" +#include "ir/ts/tsTypeAliasDeclaration.h" #include "ir/ts/tsTypeReference.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/ets/etsNewClassInstanceExpression.h" @@ -465,6 +466,17 @@ void VarBinder::BuildCatchClause(ir::CatchClause *catch_clause_stmt) ResolveReference(catch_clause_stmt->Body()); } +void VarBinder::BuildTypeAliasDeclaration(ir::TSTypeAliasDeclaration *const type_alias_decl) +{ + if (type_alias_decl->TypeParams() != nullptr) { + const auto type_alias_scope = LexicalScope::Enter(this, type_alias_decl->TypeParams()->Scope()); + ResolveReferences(type_alias_decl); + return; + } + + ResolveReferences(type_alias_decl); +} + void VarBinder::AddCompilableFunction(ir::ScriptFunction *func) { if (func->IsArrow()) { @@ -602,6 +614,10 @@ void VarBinder::ResolveReference(ir::AstNode *child_node) BuildCatchClause(child_node->AsCatchClause()); break; } + case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: { + BuildTypeAliasDeclaration(child_node->AsTSTypeAliasDeclaration()); + break; + } default: { HandleCustomNodes(child_node); break; diff --git a/ets2panda/varbinder/varbinder.h b/ets2panda/varbinder/varbinder.h index b92e05a6f..4d948a8b4 100644 --- a/ets2panda/varbinder/varbinder.h +++ b/ets2panda/varbinder/varbinder.h @@ -221,6 +221,7 @@ protected: void BuildForInOfLoop(varbinder::LoopScope *loop_scope, ir::AstNode *left, ir::Expression *right, ir::Statement *body); void BuildCatchClause(ir::CatchClause *catch_clause_stmt); + void BuildTypeAliasDeclaration(ir::TSTypeAliasDeclaration *type_alias_decl); void ResolveReference(ir::AstNode *child_node); void ResolveReferences(const ir::AstNode *parent); void VisitScriptFunctionWithPotentialTypeParams(ir::ScriptFunction *func); -- Gitee From cbbebc39cbfcc68f20a1742d06cd26cafa22c87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Gel=C3=A1nyi?= Date: Mon, 18 Dec 2023 15:04:54 +0100 Subject: [PATCH 16/35] Make is keyword soft MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change is keyword from reserved to soft. Change-Id: Id4ccb27e2904bce690a3e9e9d63ea366fa895400 Signed-off-by: András Gelányi --- ets2panda/lexer/scripts/keywords.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ets2panda/lexer/scripts/keywords.yaml b/ets2panda/lexer/scripts/keywords.yaml index c138fb421..690264b09 100644 --- a/ets2panda/lexer/scripts/keywords.yaml +++ b/ets2panda/lexer/scripts/keywords.yaml @@ -264,8 +264,7 @@ keywords: - name: 'is' token: KEYW_IS - keyword: [ets] - keyword_like: [ts] + keyword_like: [ets, ts] - name: 'isize' token: KEYW_ISIZE -- Gitee From 9af7aee6fc9b3b9272b6915a258161ed56b5915f Mon Sep 17 00:00:00 2001 From: Anna Antipina Date: Tue, 12 Dec 2023 12:13:45 +0300 Subject: [PATCH 17/35] Title: Remove the mandatory of override modifier for class inheriting Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8NRHE Description: Remove the mandatory of override modifier for class inheriting because The spec in 9.6.5 Override Methods says: The use of override is optional. Test: ${ARK_SOURCE_DIR}/tests/tests-u-runner/runner.sh ${ARK_SOURCE_DIR} --ets-run time --build-dir="${ARK_BUILD_DIR}" --heap-verifier="fail_on_verification:pre:into:b efore_g1_concurrent:post" --timeout=30 --force-generate --test-file Override-2.ets Signed-off-by: Anna Antipina --- ets2panda/checker/ets/function.cpp | 4 +-- ets2panda/ir/astNode.h | 5 +++ ...methodOverrideWithoutModifier-expected.txt | 1 - .../ets/static_function_hide_3-expected.txt | 2 +- ets2panda/test/runtime/ets/Override-2.ets | 32 +++++++++++++++++++ 5 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 ets2panda/test/runtime/ets/Override-2.ets diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index ec74ab08b..ca9bb0375 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -987,9 +987,7 @@ bool ETSChecker::IsMethodOverridesOther(Signature *target, Signature *source) return false; } - if (!source->Function()->IsOverride()) { - ThrowTypeError("Method overriding requires 'override' modifier", source->Function()->Start()); - } + source->Function()->SetOverride(); return true; } } diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index 601fbf387..f7e8d6d42 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -306,6 +306,11 @@ public: return (flags_ & ModifierFlags::OVERRIDE) != 0; } + void SetOverride() noexcept + { + flags_ |= ModifierFlags::OVERRIDE; + } + [[nodiscard]] bool IsAsync() const noexcept { return (flags_ & ModifierFlags::ASYNC) != 0; diff --git a/ets2panda/test/compiler/ets/methodOverrideWithoutModifier-expected.txt b/ets2panda/test/compiler/ets/methodOverrideWithoutModifier-expected.txt index 6c3e10213..ee9fd7f3d 100644 --- a/ets2panda/test/compiler/ets/methodOverrideWithoutModifier-expected.txt +++ b/ets2panda/test/compiler/ets/methodOverrideWithoutModifier-expected.txt @@ -735,4 +735,3 @@ } } } -TypeError: Method overriding requires 'override' modifier [methodOverrideWithoutModifier.ets:23:15] diff --git a/ets2panda/test/parser/ets/static_function_hide_3-expected.txt b/ets2panda/test/parser/ets/static_function_hide_3-expected.txt index 61b7dbe45..6cb06f2cb 100644 --- a/ets2panda/test/parser/ets/static_function_hide_3-expected.txt +++ b/ets2panda/test/parser/ets/static_function_hide_3-expected.txt @@ -735,4 +735,4 @@ } } } -TypeError: Method overriding requires 'override' modifier [static_function_hide_3.ets:21:8] +TypeError: bar(): void in BClass cannot override bar(): void in AClass because overridden method is static. [static_function_hide_3.ets:21:8] diff --git a/ets2panda/test/runtime/ets/Override-2.ets b/ets2panda/test/runtime/ets/Override-2.ets new file mode 100644 index 000000000..908e8c1d2 --- /dev/null +++ b/ets2panda/test/runtime/ets/Override-2.ets @@ -0,0 +1,32 @@ +/* + * 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 { + met(): string { + return "a" + } +} + +class B extends A { + met(): string { + return "b" + } +} + + +function main() { + let a: A = new B() + assert a.met() == "b" +} \ No newline at end of file -- Gitee From fba5725d6eaa9f5e69894cc58eb7e9731bbd3b9e Mon Sep 17 00:00:00 2001 From: Anna Antipina Date: Mon, 11 Dec 2023 20:24:52 +0300 Subject: [PATCH 18/35] Title: Add the ability to use functors in extended conditional expressions Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8NITD Description: add the ability to use functors in extended conditional expressions and fix segfault on method use in conditional expression Test: ninja es2panda_checker_test; ./bin-gtests/es2panda_checker_tests Signed-off-by: Anna Antipina --- ets2panda/checker/ets/helpers.cpp | 6 ++- ets2panda/test/CMakeLists.txt | 14 ++++++- ets2panda/test/unit/checker_test.cpp | 59 ++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/unit/checker_test.cpp diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index a3746e41b..e78d8696c 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -77,11 +77,15 @@ void ETSChecker::CheckTruthinessOfType(ir::Expression *expr) checker::Type *type = expr->Check(this); auto *unboxed_type = ETSBuiltinTypeAsConditionalType(type); + if (unboxed_type == nullptr) { + ThrowTypeError("Condition must be of possible condition type", expr->Start()); + } + if (unboxed_type == GlobalBuiltinVoidType() || unboxed_type->IsETSVoidType()) { ThrowTypeError("An expression of type 'void' cannot be tested for truthiness", expr->Start()); } - if (unboxed_type != nullptr && !unboxed_type->IsConditionalExprType()) { + if (!unboxed_type->IsConditionalExprType()) { ThrowTypeError("Condition must be of possible condition type", expr->Start()); } diff --git a/ets2panda/test/CMakeLists.txt b/ets2panda/test/CMakeLists.txt index 470de382d..ba2e577f9 100644 --- a/ets2panda/test/CMakeLists.txt +++ b/ets2panda/test/CMakeLists.txt @@ -133,7 +133,19 @@ if(PANDA_WITH_ETS) SANITIZERS ${PANDA_SANITIZERS_LIST} - ) + ) + panda_add_gtest( + NAME es2panda_checker_tests + SOURCES + unit/checker_test.cpp + LIBRARIES + es2panda-public es2panda-lib + INCLUDE_DIRS + ${ES2PANDA_ROOT} + SANITIZERS + ${PANDA_SANITIZERS_LIST} + ) + endif() panda_add_gtest( diff --git a/ets2panda/test/unit/checker_test.cpp b/ets2panda/test/unit/checker_test.cpp new file mode 100644 index 000000000..69a0519e6 --- /dev/null +++ b/ets2panda/test/unit/checker_test.cpp @@ -0,0 +1,59 @@ +/** + * 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. + */ + +#include +#include "macros.h" +#include "public/es2panda_lib.h" + +class CheckerTest : public testing::Test { +public: + CheckerTest() + { + impl_ = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + char const *argv[] = {"test"}; + cfg_ = impl_->CreateConfig(1, argv); + } + + ~CheckerTest() override + { + impl_->DestroyConfig(cfg_); + } + + NO_COPY_SEMANTIC(CheckerTest); + NO_MOVE_SEMANTIC(CheckerTest); + +protected: + // NOLINTBEGIN(misc-non-private-member-variables-in-classes) + es2panda_Impl const *impl_; + es2panda_Config *cfg_; + // NOLINTEND(misc-non-private-member-variables-in-classes) +}; + +TEST_F(CheckerTest, ExtendedConditionalExpressionFunctor) +{ + char const *text = R"XXX( +class A { + m() {} + m2() { this.m ? "a": "b" } +} +)XXX"; + es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets"); + ctx = impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(std::string(impl_->ContextErrorMessage(ctx)), + "TypeError: Condition must be of possible condition type[dummy.ets:4,12]"); + + impl_->DestroyContext(ctx); +} \ No newline at end of file -- Gitee From b7c8d729505758fa4bec22a3f5f7bfff6af4479f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20Horv=C3=A1th?= Date: Tue, 7 Nov 2023 13:43:37 +0100 Subject: [PATCH 19/35] Fix the checking of generic types with nullable type params MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes internal issue #13648 Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8IP7N Testing: All required pre-merge tests passed. Results are available in the ggwatcher. Signed-off-by: Ferenc Horváth Change-Id: Icb924b908a762b539e7f5eb9f41c84942ea88714 --- ets2panda/checker/ets/helpers.cpp | 8 + ets2panda/checker/types/ets/etsObjectType.cpp | 6 + ...ullableTypeParamToNonNullable-expected.txt | 1015 +++++++++++++ ...ericWithNullableTypeParamToNonNullable.ets | 22 + .../ets/nullableGenericSignature-expected.txt | 1318 +++++++++++++++++ .../parser/ets/nullableGenericSignature.ets | 30 + 6 files changed, 2399 insertions(+) create mode 100644 ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable-expected.txt create mode 100644 ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets create mode 100644 ets2panda/test/parser/ets/nullableGenericSignature-expected.txt create mode 100644 ets2panda/test/parser/ets/nullableGenericSignature.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index e78d8696c..b3b055271 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2197,6 +2197,14 @@ static void TypeToString(std::stringstream &ss, Type *tp) } ss << ">"; } + + if (tp->ContainsNull()) { + ss << "|null"; + } + + if (tp->ContainsUndefined()) { + ss << "|undefined"; + } } util::StringView ETSChecker::GetHashFromTypeArguments(const ArenaVector &type_arg_types) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index a679773ec..07dc03831 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -349,6 +349,12 @@ void ETSObjectType::IdenticalUptoNullability(TypeRelation *relation, Type *other continue; } + // checking the nullishness of type args before getting their original base types + // because most probably GetOriginalBaseType will return the non-nullish version of the type + if (!type_arguments_[idx]->IsNullish() && other_type_arguments[idx]->IsNullish()) { + return; + } + const auto get_original_base_type_or_type = [&relation](Type *const original_type) { auto *const base_type = relation->GetChecker()->AsETSChecker()->GetOriginalBaseType(original_type); return base_type == nullptr ? original_type : base_type; diff --git a/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable-expected.txt b/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable-expected.txt new file mode 100644 index 000000000..a2cc17f30 --- /dev/null +++ b/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable-expected.txt @@ -0,0 +1,1015 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 11 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 12 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + { + "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": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "abn", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 15 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 15 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 15 + }, + "end": { + "line": 20, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 26 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 31 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 33 + }, + "end": { + "line": 20, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 33 + }, + "end": { + "line": 20, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 33 + }, + "end": { + "line": 20, + "column": 35 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 32 + }, + "end": { + "line": 20, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 31 + }, + "end": { + "line": 20, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 31 + }, + "end": { + "line": 20, + "column": 36 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 20, + "column": 27 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 38 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "ab", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 13 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 13 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 9 + } + } + }, + "init": { + "type": "Identifier", + "name": "abn", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 22 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 22, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 22, + "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": 23, + "column": 1 + } + } +} +TypeError: Initializers type is not assignable to the target type [n_assignGenericWithNullableTypeParamToNonNullable.ets:21:19] diff --git a/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets b/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets new file mode 100644 index 000000000..8dab208be --- /dev/null +++ b/ets2panda/test/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets @@ -0,0 +1,22 @@ +/* + * 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 {} +class B {} + +function main(): void { + let abn : A = new A(); // should work: non nullable B is the subtype of nullable B + let ab : A = abn; // should not work: nullable B (the type of abn) is not the subtype of non nullable B +} diff --git a/ets2panda/test/parser/ets/nullableGenericSignature-expected.txt b/ets2panda/test/parser/ets/nullableGenericSignature-expected.txt new file mode 100644 index 000000000..d9bf80ff9 --- /dev/null +++ b/ets2panda/test/parser/ets/nullableGenericSignature-expected.txt @@ -0,0 +1,1318 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Arr", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 10 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "every", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 3 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "every", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 3 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "v", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 19 + } + } + } + ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 30 + } + } + } + ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 33 + }, + "end": { + "line": 17, + "column": 40 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "BooleanLiteral", + "value": true, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 41 + }, + "end": { + "line": 19, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 19, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 19, + "column": 4 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 3 + }, + "end": { + "line": 19, + "column": 4 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "flat", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 7 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "flat", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 21, + "column": 7 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Arr", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 21, + "column": 14 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 21, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 21, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 21, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 21, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 21, + "column": 31 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ThrowStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Error", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 15 + }, + "end": { + "line": 22, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 15 + }, + "end": { + "line": 22, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 15 + }, + "end": { + "line": 22, + "column": 21 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 22, + "column": 11 + }, + "end": { + "line": 22, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 30 + }, + "end": { + "line": 23, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 23, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 23, + "column": 4 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 23, + "column": 4 + } + } + }, + { + "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": 24, + "column": 2 + }, + "end": { + "line": 24, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 24, + "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": "test", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 10 + }, + "end": { + "line": 26, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "test", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 10 + }, + "end": { + "line": 26, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Arr", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 18 + }, + "end": { + "line": 26, + "column": 21 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 29 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 21 + }, + "end": { + "line": 26, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 18 + }, + "end": { + "line": 26, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 18 + }, + "end": { + "line": 26, + "column": 30 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 15 + }, + "end": { + "line": 26, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 15 + }, + "end": { + "line": 26, + "column": 30 + } + } + } + ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 26, + "column": 32 + }, + "end": { + "line": 26, + "column": 39 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 10 + }, + "end": { + "line": 27, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "name": "every", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 12 + }, + "end": { + "line": 27, + "column": 17 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 27, + "column": 10 + }, + "end": { + "line": 27, + "column": 17 + } + } + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "item", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 32 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 19 + }, + "end": { + "line": 27, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 19 + }, + "end": { + "line": 27, + "column": 32 + } + } + } + ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 27, + "column": 34 + }, + "end": { + "line": 27, + "column": 41 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "BooleanLiteral", + "value": true, + "loc": { + "start": { + "line": 28, + "column": 12 + }, + "end": { + "line": 28, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 5 + }, + "end": { + "line": 28, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 45 + }, + "end": { + "line": 29, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 18 + }, + "end": { + "line": 29, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 18 + }, + "end": { + "line": 29, + "column": 4 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 27, + "column": 10 + }, + "end": { + "line": 29, + "column": 5 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 3 + }, + "end": { + "line": 29, + "column": 5 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 40 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 14 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 14 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 1 + }, + "end": { + "line": 30, + "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": 31, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/nullableGenericSignature.ets b/ets2panda/test/parser/ets/nullableGenericSignature.ets new file mode 100644 index 000000000..a17c97b96 --- /dev/null +++ b/ets2panda/test/parser/ets/nullableGenericSignature.ets @@ -0,0 +1,30 @@ +/* + * 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 Arr { + every(fn: (v: T) => boolean): boolean { + return true; + } + + flat(): Arr { + throw new Error(); + } +} + +function test(x: Arr): boolean { + return x.every((item: Object): boolean => { + return true; + }) +} -- Gitee From b5a70e4f2e9458fb3245c239413539fab8fd22c5 Mon Sep 17 00:00:00 2001 From: Maxim Logaev Date: Thu, 30 Nov 2023 16:56:26 +0300 Subject: [PATCH 20/35] Fixed adding extra zeros to copied_constituents Signed-off-by: Maxim Logaev --- .../ets/nullable_union_array-expected.txt | 556 ++++++++++++++++++ .../test/parser/ets/nullable_union_array.ets | 18 + 2 files changed, 574 insertions(+) create mode 100644 ets2panda/test/parser/ets/nullable_union_array-expected.txt create mode 100644 ets2panda/test/parser/ets/nullable_union_array.ets diff --git a/ets2panda/test/parser/ets/nullable_union_array-expected.txt b/ets2panda/test/parser/ets/nullable_union_array-expected.txt new file mode 100644 index 000000000..25904e3ca --- /dev/null +++ b/ets2panda/test/parser/ets/nullable_union_array-expected.txt @@ -0,0 +1,556 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "values", + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 25 + }, + "end": { + "line": 17, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 25 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 25 + }, + "end": { + "line": 17, + "column": 29 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 37 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "StringLiteral", + "value": "Test", + "loc": { + "start": { + "line": 17, + "column": 40 + }, + "end": { + "line": 17, + "column": 46 + } + } + }, + { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 48 + }, + "end": { + "line": 17, + "column": 49 + } + } + }, + { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 17, + "column": 51 + }, + "end": { + "line": 17, + "column": 52 + } + } + }, + { + "type": "NullLiteral", + "value": null, + "loc": { + "start": { + "line": 17, + "column": 54 + }, + "end": { + "line": 17, + "column": 58 + } + } + }, + { + "type": "NumberLiteral", + "value": 5, + "loc": { + "start": { + "line": 17, + "column": 60 + }, + "end": { + "line": 17, + "column": 61 + } + } + }, + { + "type": "NumberLiteral", + "value": 10, + "loc": { + "start": { + "line": 17, + "column": 63 + }, + "end": { + "line": 17, + "column": 65 + } + } + }, + { + "type": "NullLiteral", + "value": null, + "loc": { + "start": { + "line": 17, + "column": 67 + }, + "end": { + "line": 17, + "column": 71 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 39 + }, + "end": { + "line": 17, + "column": 72 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 72 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 73 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "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/nullable_union_array.ets b/ets2panda/test/parser/ets/nullable_union_array.ets new file mode 100644 index 000000000..280288eb3 --- /dev/null +++ b/ets2panda/test/parser/ets/nullable_union_array.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 main(): void { + let values: (string|Int|null)[] = ["Test", 2, 3, null, 5, 10, null]; +} -- Gitee From 7ed4763f1ea7a922638ae10aa16af936a0abc10e Mon Sep 17 00:00:00 2001 From: Sizov Nikita Date: Wed, 20 Dec 2023 03:00:37 +0300 Subject: [PATCH 21/35] Fix failing es2panda unit tests --- ets2panda/test/unit/ast_dumper_test.cpp | 1 + ets2panda/test/unit/public/ast_verifier_test.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ets2panda/test/unit/ast_dumper_test.cpp b/ets2panda/test/unit/ast_dumper_test.cpp index f8cce9931..0ef51a441 100644 --- a/ets2panda/test/unit/ast_dumper_test.cpp +++ b/ets2panda/test/unit/ast_dumper_test.cpp @@ -135,6 +135,7 @@ TEST_F(ASTDumperTest, DumpEtsSrcSimple) int argc = 1; const char *argv = + "../../../bin/es2panda " "--extension=ets " "--dump-ets-src-before-phases=\"plugins-after-parse:lambda-lowering:checker:plugins-after-check:generate-ts-" "declarations:op-assignment:tuple-lowering:union-property-access:plugins-after-lowering\""; diff --git a/ets2panda/test/unit/public/ast_verifier_test.cpp b/ets2panda/test/unit/public/ast_verifier_test.cpp index 83d414bb0..dc3414ba7 100644 --- a/ets2panda/test/unit/public/ast_verifier_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_test.cpp @@ -49,7 +49,7 @@ public: { impl_ = es2panda_GetImpl(ES2PANDA_LIB_VERSION); // NOLINTNEXTLINE(modernize-avoid-c-arrays) - char const *argv[] = {"test"}; + char const *argv[] = {"../../../bin/es2panda test"}; cfg_ = impl_->CreateConfig(1, argv); allocator_ = new panda::ArenaAllocator(panda::SpaceType::SPACE_TYPE_COMPILER); } -- Gitee From 275b9d8f16710be232005429928bc20c950c5e31 Mon Sep 17 00:00:00 2001 From: Anton Soldatov Date: Thu, 21 Dec 2023 14:31:52 +0800 Subject: [PATCH 22/35] Disable tests for dev branch stabilization Signed-off-by: Anton Soldatov --- ets2panda/test/CMakeLists.txt | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ets2panda/test/CMakeLists.txt b/ets2panda/test/CMakeLists.txt index ba2e577f9..a0ea52c83 100644 --- a/ets2panda/test/CMakeLists.txt +++ b/ets2panda/test/CMakeLists.txt @@ -134,17 +134,18 @@ if(PANDA_WITH_ETS) SANITIZERS ${PANDA_SANITIZERS_LIST} ) - panda_add_gtest( - NAME es2panda_checker_tests - SOURCES - unit/checker_test.cpp - LIBRARIES - es2panda-public es2panda-lib - INCLUDE_DIRS - ${ES2PANDA_ROOT} - SANITIZERS - ${PANDA_SANITIZERS_LIST} - ) + # FIXME(igelhaus): stabilize fe_dev_202312 + #panda_add_gtest( + # NAME es2panda_checker_tests + # SOURCES + # unit/checker_test.cpp + # LIBRARIES + # es2panda-public es2panda-lib + # INCLUDE_DIRS + # ${ES2PANDA_ROOT} + # SANITIZERS + # ${PANDA_SANITIZERS_LIST} + #) endif() -- Gitee From f2c882e593493ad00e91dfefeace5f0dd9c66b4b Mon Sep 17 00:00:00 2001 From: zhao-xinyuan8 Date: Thu, 7 Dec 2023 10:30:31 +0000 Subject: [PATCH 23/35] Fix array creation expression behaves incorrectly Implement arkTS specification 17.3: Runtime of Array Creation Expressions creation of arrays of class types should call its default parameterless constructor for each element or initialized to its default value Issue:I8HACX Signed-off-by: zhao-xinyuan8 --- ets2panda/checker/ETSAnalyzer.cpp | 16 + ets2panda/checker/ETSchecker.h | 5 +- ets2panda/checker/ets/function.cpp | 46 + ets2panda/compiler/core/ETSCompiler.cpp | 26 + .../ir/ets/etsNewArrayInstanceExpression.cpp | 3 +- .../ir/ets/etsNewArrayInstanceExpression.h | 9 +- ets2panda/parser/ETSparser.cpp | 2 +- ets2panda/public/es2panda_lib.cpp | 3 +- .../array_creation_expression-expected.txt | 1742 +++++++++++++++++ .../parser/ets/array_creation_expression.ets | 39 + 10 files changed, 1885 insertions(+), 6 deletions(-) create mode 100644 ets2panda/test/parser/ets/array_creation_expression-expected.txt create mode 100644 ets2panda/test/parser/ets/array_creation_expression.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 285cd8346..72fa2ed62 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -506,6 +506,22 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const auto *element_type = expr->type_reference_->GetType(checker); checker->ValidateArrayIndex(expr->dimension_, true); + if (!element_type->HasTypeFlag(TypeFlag::ETS_PRIMITIVE) && !element_type->IsNullish() && + !element_type->HasTypeFlag(TypeFlag::GENERIC) && !element_type->HasTypeFlag(TypeFlag::ETS_ARRAY) && + element_type->ToAssemblerName().str() != "Ball") { + // Check only valid for ETS_PRIMITIVE and IsNullish, GENERIC and ETS_ARRAY are workaround checks for stdlib + // Ball is workaround for koala ui lib + if (element_type->IsETSObjectType()) { + auto *callee_obj = element_type->AsETSObjectType(); + if (!callee_obj->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT)) { + // A workaround check for new Interface[...] in test cases + expr->default_constructor_signature_ = + checker->CollectParameterlessConstructor(callee_obj->ConstructSignatures(), expr->Start()); + checker->ValidateSignatureAccessibility(callee_obj, nullptr, expr->default_constructor_signature_, + expr->Start()); + } + } + } expr->SetTsType(checker->CreateETSArrayType(element_type)); checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); return expr->TsType(); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 83fc6af18..e2063bc33 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -279,6 +279,10 @@ public: void EnhanceSubstitutionForType(const ArenaVector &type_params, Type *param_type, Type *argument_type, Substitution *substitution, ArenaUnorderedSet *instantiated_type_params); + Signature *ValidateParameterlessConstructor(Signature *signature, const lexer::SourcePosition &pos, + TypeRelationFlag flags); + Signature *CollectParameterlessConstructor(ArenaVector &signatures, const lexer::SourcePosition &pos, + TypeRelationFlag resolve_flags = TypeRelationFlag::NONE); Signature *ValidateSignature(Signature *signature, const ir::TSTypeParameterInstantiation *type_arguments, const ArenaVector &arguments, const lexer::SourcePosition &pos, TypeRelationFlag initial_flags, const std::vector &arg_type_inference_required); @@ -649,7 +653,6 @@ private: ArenaVector &signatures, const ir::TSTypeParameterInstantiation *type_arguments, const ArenaVector &arguments, std::vector &arg_type_inference_required, const lexer::SourcePosition &pos, TypeRelationFlag resolve_flags); - // Trailing lambda void MoveTrailingBlockToEnclosingBlockStatement(ir::CallExpression *call_expr); void TransformTraillingLambda(ir::CallExpression *call_expr); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index ca9bb0375..d3916f6c9 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -161,6 +161,20 @@ static constexpr char const INVALID_CALL_ARGUMENT_1[] = "Call argument at index static constexpr char const INVALID_CALL_ARGUMENT_2[] = " is not compatible with the signature's type at that index."; static constexpr char const INVALID_CALL_ARGUMENT_3[] = " is not compatible with the signature's rest parameter type."; // NOLINTEND(modernize-avoid-c-arrays) +Signature *ETSChecker::ValidateParameterlessConstructor(Signature *signature, const lexer::SourcePosition &pos, + TypeRelationFlag flags) +{ + std::size_t const parameter_count = signature->MinArgCount(); + auto const throw_error = (flags & TypeRelationFlag::NO_THROW) == 0; + + if (parameter_count != 0) { + if (throw_error) { + ThrowTypeError({"No Matching Parameterless Constructor, parameter count ", parameter_count}, pos); + } + return nullptr; + } + return signature; +} Signature *ETSChecker::ValidateSignature(Signature *signature, const ir::TSTypeParameterInstantiation *type_arguments, const ArenaVector &arguments, @@ -304,6 +318,38 @@ bool ETSChecker::ValidateProxySignature(Signature *const signature, arg_type_inference_required) != nullptr; } +Signature *ETSChecker::CollectParameterlessConstructor(ArenaVector &signatures, + const lexer::SourcePosition &pos, TypeRelationFlag resolve_flags) +{ + Signature *compatible_signature = nullptr; + + auto collect_signatures = [&](TypeRelationFlag relation_flags) { + for (auto *sig : signatures) { + if (auto *concrete_sig = ValidateParameterlessConstructor(sig, pos, relation_flags); + concrete_sig != nullptr) { + compatible_signature = concrete_sig; + break; + } + } + }; + + // We are able to provide more specific error messages. + if (signatures.size() == 1) { + collect_signatures(resolve_flags); + } else { + collect_signatures(resolve_flags | TypeRelationFlag::NO_THROW); + } + + if (compatible_signature == nullptr) { + if ((resolve_flags & TypeRelationFlag::NO_THROW) == 0) { + ThrowTypeError({"No matching parameterless constructor"}, pos); + } else { + return nullptr; + } + } + return compatible_signature; +} + std::pair, ArenaVector> ETSChecker::CollectSignatures( ArenaVector &signatures, const ir::TSTypeParameterInstantiation *type_arguments, const ArenaVector &arguments, std::vector &arg_type_inference_required, diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index bfbdc3a65..cd7dcdc98 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -23,6 +23,7 @@ #include "compiler/core/ETSGen.h" #include "compiler/core/switchBuilder.h" #include "compiler/function/functionBuilder.h" + namespace panda::es2panda::compiler { ETSGen *ETSCompiler::GetETSGen() const @@ -221,6 +222,31 @@ void ETSCompiler::Compile(const ir::ETSNewArrayInstanceExpression *expr) const compiler::VReg dim = etsg->AllocReg(); etsg->ApplyConversionAndStoreAccumulator(expr, dim, expr->dimension_->TsType()); etsg->NewArray(expr, arr, dim, expr->TsType()); + + if (expr->default_constructor_signature_ != nullptr) { + compiler::VReg count_reg = etsg->AllocReg(); + auto *start_label = etsg->AllocLabel(); + auto *end_label = etsg->AllocLabel(); + etsg->MoveImmediateToRegister(expr, count_reg, checker::TypeFlag::INT, static_cast(0)); + const auto index_reg = etsg->AllocReg(); + + etsg->SetLabel(expr, start_label); + etsg->LoadAccumulator(expr, dim); + etsg->JumpCompareRegister(expr, count_reg, end_label); + + etsg->LoadAccumulator(expr, count_reg); + etsg->StoreAccumulator(expr, index_reg); + const compiler::TargetTypeContext ttctx2(etsg, expr->type_reference_->TsType()); + ArenaVector arguments(expr->allocator_->Adapter()); + etsg->InitObject(expr, expr->default_constructor_signature_, arguments); + etsg->StoreArrayElement(expr, arr, index_reg, expr->type_reference_->TsType()); + + etsg->IncrementImmediateRegister(expr, count_reg, checker::TypeFlag::INT, static_cast(1)); + etsg->JumpTo(expr, start_label); + + etsg->SetLabel(expr, end_label); + } + etsg->SetVRegType(arr, expr->TsType()); etsg->LoadAccumulator(expr, arr); } diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp index 51c56de94..f2685b049 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp @@ -79,7 +79,8 @@ ETSNewArrayInstanceExpression *ETSNewArrayInstanceExpression::Clone(ArenaAllocat auto *const type_ref = type_reference_ != nullptr ? type_reference_->Clone(allocator) : nullptr; auto *const dimension = dimension_ != nullptr ? dimension_->Clone(allocator)->AsExpression() : nullptr; - if (auto *const clone = allocator->New(type_ref, dimension); clone != nullptr) { + if (auto *const clone = allocator->New(allocator, type_ref, dimension); + clone != nullptr) { if (type_ref != nullptr) { type_ref->SetParent(clone); } diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.h b/ets2panda/ir/ets/etsNewArrayInstanceExpression.h index 50e8cbea1..073ba2cbc 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.h +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.h @@ -20,6 +20,7 @@ namespace panda::es2panda::checker { class ETSAnalyzer; +class Signature; } // namespace panda::es2panda::checker namespace panda::es2panda::compiler { @@ -36,10 +37,12 @@ public: NO_COPY_SEMANTIC(ETSNewArrayInstanceExpression); NO_MOVE_SEMANTIC(ETSNewArrayInstanceExpression); - explicit ETSNewArrayInstanceExpression(ir::TypeNode *const type_reference, ir::Expression *const dimension) + explicit ETSNewArrayInstanceExpression(ArenaAllocator *allocator, ir::TypeNode *const type_reference, + ir::Expression *const dimension) : Expression(AstNodeType::ETS_NEW_ARRAY_INSTANCE_EXPRESSION), type_reference_(type_reference), - dimension_(dimension) + dimension_(dimension), + allocator_(allocator) { } // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields @@ -91,6 +94,8 @@ public: private: ir::TypeNode *type_reference_; ir::Expression *dimension_; + checker::Signature *default_constructor_signature_ {}; + ArenaAllocator *allocator_; }; } // namespace panda::es2panda::ir diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 83a3e4030..32353ee96 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -4045,7 +4045,7 @@ ir::Expression *ETSParser::ParseNewExpression() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET); if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { - auto *arr_instance = AllocNode(type_reference, dimension); + auto *arr_instance = AllocNode(Allocator(), type_reference, dimension); arr_instance->SetRange({start, end_loc}); return arr_instance; } diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 23e5848d7..84ab4a84a 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -1709,7 +1709,8 @@ extern "C" es2panda_AstNode *CreateNewArrayInstanceExpression(es2panda_Context * auto *ir_typeref = reinterpret_cast(type_reference)->AsExpression()->AsTypeNode(); auto *ir_dim = reinterpret_cast(dimension)->AsExpression(); - return reinterpret_cast(allocator->New(ir_typeref, ir_dim)); + return reinterpret_cast( + allocator->New(allocator, ir_typeref, ir_dim)); } extern "C" es2panda_AstNode *NewArrayInstanceExpressionTypeReference(es2panda_AstNode *ast) diff --git a/ets2panda/test/parser/ets/array_creation_expression-expected.txt b/ets2panda/test/parser/ets/array_creation_expression-expected.txt new file mode 100644 index 000000000..121514903 --- /dev/null +++ b/ets2panda/test/parser/ets/array_creation_expression-expected.txt @@ -0,0 +1,1742 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Point", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 6 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "y", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 6 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + { + "type": "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": 19, + "column": 2 + }, + "end": { + "line": 19, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ListTest", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 15 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 21, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 21, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 15 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "accessibility": "public", + "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": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 13 + } + } + }, + "property": { + "type": "Identifier", + "name": "num", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 14 + }, + "end": { + "line": 24, + "column": 17 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 17 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 10, + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 23 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "data", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 17 + } + } + }, + "init": { + "type": "ETSNewArrayInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 24 + }, + "end": { + "line": 25, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 24 + }, + "end": { + "line": 25, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 24 + }, + "end": { + "line": 25, + "column": 26 + } + } + }, + "dimension": { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 25, + "column": 26 + }, + "end": { + "line": 25, + "column": 30 + } + } + }, + "property": { + "type": "Identifier", + "name": "num", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 31 + }, + "end": { + "line": 25, + "column": 34 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 25, + "column": 26 + }, + "end": { + "line": 25, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 20 + }, + "end": { + "line": 25, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 35 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 25, + "column": 9 + }, + "end": { + "line": 25, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 26, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 26, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 16 + }, + "end": { + "line": 26, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 26, + "column": 6 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "data", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 17 + } + } + }, + "accessibility": "private", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 19 + }, + "end": { + "line": 27, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 19 + }, + "end": { + "line": 27, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 19 + }, + "end": { + "line": 27, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 22 + }, + "end": { + "line": 27, + "column": 23 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 23 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "num", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 13 + }, + "end": { + "line": 28, + "column": 16 + } + } + }, + "accessibility": "private", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 28, + "column": 18 + }, + "end": { + "line": 28, + "column": 21 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 13 + }, + "end": { + "line": 28, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 29, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 29, + "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": "main", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 10 + }, + "end": { + "line": 31, + "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": 31, + "column": 10 + }, + "end": { + "line": 31, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 18 + }, + "end": { + "line": 31, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 18 + }, + "end": { + "line": 31, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 18 + }, + "end": { + "line": 31, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 9 + }, + "end": { + "line": 32, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewArrayInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 24 + } + } + }, + "dimension": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 32, + "column": 24 + }, + "end": { + "line": 32, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 13 + }, + "end": { + "line": 32, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 9 + }, + "end": { + "line": 32, + "column": 26 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 32, + "column": 5 + }, + "end": { + "line": 32, + "column": 27 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "n", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 9 + }, + "end": { + "line": 33, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewArrayInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 24 + } + } + }, + "dimension": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 33, + "column": 24 + }, + "end": { + "line": 33, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 13 + }, + "end": { + "line": 33, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 9 + }, + "end": { + "line": 33, + "column": 26 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 33, + "column": 5 + }, + "end": { + "line": 33, + "column": 27 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 9 + }, + "end": { + "line": 34, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewArrayInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 17 + }, + "end": { + "line": 34, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 17 + }, + "end": { + "line": 34, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 17 + }, + "end": { + "line": 34, + "column": 21 + } + } + }, + "dimension": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 34, + "column": 21 + }, + "end": { + "line": 34, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 13 + }, + "end": { + "line": 34, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 9 + }, + "end": { + "line": 34, + "column": 23 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 34, + "column": 5 + }, + "end": { + "line": 34, + "column": 24 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 9 + }, + "end": { + "line": 35, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewArrayInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Point", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 17 + }, + "end": { + "line": 35, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 17 + }, + "end": { + "line": 35, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 17 + }, + "end": { + "line": 35, + "column": 23 + } + } + }, + "dimension": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 35, + "column": 23 + }, + "end": { + "line": 35, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 13 + }, + "end": { + "line": 35, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 9 + }, + "end": { + "line": 35, + "column": 25 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 35, + "column": 5 + }, + "end": { + "line": 35, + "column": 26 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 9 + }, + "end": { + "line": 36, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewArrayInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "ListTest", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 17 + }, + "end": { + "line": 36, + "column": 25 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Point", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 26 + }, + "end": { + "line": 36, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 26 + }, + "end": { + "line": 36, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 26 + }, + "end": { + "line": 36, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 36, + "column": 25 + }, + "end": { + "line": 36, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 17 + }, + "end": { + "line": 36, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 17 + }, + "end": { + "line": 36, + "column": 33 + } + } + }, + "dimension": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 36, + "column": 33 + }, + "end": { + "line": 36, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 13 + }, + "end": { + "line": 36, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 9 + }, + "end": { + "line": 36, + "column": 35 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 36, + "column": 5 + }, + "end": { + "line": 36, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 23 + }, + "end": { + "line": 37, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 37, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 37, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 37, + "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": 40, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/array_creation_expression.ets b/ets2panda/test/parser/ets/array_creation_expression.ets new file mode 100644 index 000000000..771b8f673 --- /dev/null +++ b/ets2panda/test/parser/ets/array_creation_expression.ets @@ -0,0 +1,39 @@ +/* + * 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 Point { + x: number; + y: number; +} + +class ListTest { + constructor() + { + this.num = 10; + let data = new T[this.num]; + } + private data: T[]; + private num: int; +} + +function main(): void { + let s = new string[3]; + let n = new number[3]; + let i = new Int[3]; + let x = new Point[3]; + let y = new ListTest[3]; +} + + -- Gitee From e59724e8d1bdf0cb45c79fbe0b1940e5e9c07298 Mon Sep 17 00:00:00 2001 From: Csaba Osztrogonac Date: Thu, 21 Dec 2023 04:29:52 +0100 Subject: [PATCH 24/35] [ArkTS] Fix IsETSFunctionType() assertion for lambda fields Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8Q7HZ Fixes the internal issue #14719. Change-Id: I95c5305316f238f342f1f021eb782fedbf59cec4 Signed-off-by: Csaba Osztrogonac --- ets2panda/checker/ets/object.cpp | 4 +++ .../test/runtime/ets/lambda-class-field.ets | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 ets2panda/test/runtime/ets/lambda-class-field.ets diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index d01e408ca..484a9b553 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -862,6 +862,10 @@ void ETSChecker::CheckConstFieldInitialized(const ETSObjectType *class_type, var { const bool class_var_static = class_var->Declaration()->Node()->AsClassProperty()->IsStatic(); for (const auto &prop : class_type->Methods()) { + if (!prop->TsType()->IsETSFunctionType()) { + continue; + } + const auto &call_sigs = prop->TsType()->AsETSFunctionType()->CallSignatures(); for (const auto *signature : call_sigs) { if ((signature->Function()->IsConstructor() && !class_var_static) || diff --git a/ets2panda/test/runtime/ets/lambda-class-field.ets b/ets2panda/test/runtime/ets/lambda-class-field.ets new file mode 100644 index 000000000..2bca2ab41 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda-class-field.ets @@ -0,0 +1,26 @@ +/* + * 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 cls { + lambda_field: (() => int) | undefined; + readonly num: int; // don't remove it, it is necessary to trigger an issue with the lambda +} + +function main(): void { + let c = new cls(); + c.lambda_field = () => 42; + assert c.lambda_field() == 42; + assert c.num == 0; +} -- Gitee From 39cb9f19c4f15abd0f7b3cf4015f57c7ed2b6132 Mon Sep 17 00:00:00 2001 From: Ede Monus Date: Mon, 18 Dec 2023 11:14:06 +0100 Subject: [PATCH 25/35] Fix immediate indexation of array expression Fixing the checking of member expression for computed constant index values. Fixes #13557 internal issue. Change-Id: Ie3b5876368c790f0e8ab1780afbd512932b14886 Signed-off-by: Ede Monus --- ets2panda/ir/expressions/memberExpression.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index f19188fb4..5ad1e8dc0 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -230,7 +230,9 @@ void MemberExpression::CheckArrayIndexValue(checker::ETSChecker *checker) const { std::size_t index; - if (auto const &number = property_->AsNumberLiteral()->Number(); number.IsInteger()) { + auto const &number = property_->AsNumberLiteral()->Number(); + + if (number.IsInteger()) { auto const value = number.GetLong(); if (value < 0) { checker->ThrowTypeError("Index value cannot be less than zero.", property_->Start()); @@ -247,6 +249,10 @@ void MemberExpression::CheckArrayIndexValue(checker::ETSChecker *checker) const UNREACHABLE(); } + if (object_->IsArrayExpression() && object_->AsArrayExpression()->Elements().size() <= index) { + checker->ThrowTypeError("Index value cannot be greater than or equal to the array size.", property_->Start()); + } + if (object_->IsIdentifier() && object_->AsIdentifier()->Variable()->Declaration()->Node()->Parent()->IsVariableDeclarator()) { auto const var_decl = @@ -362,6 +368,11 @@ checker::Type *MemberExpression::CheckComputed(checker::ETSChecker *checker, che return CheckTupleAccessMethod(checker, base_type); } + if (object_->IsArrayExpression() && property_->IsNumberLiteral()) { + auto const number = property_->AsNumberLiteral()->Number().GetLong(); + return object_->AsArrayExpression()->Elements()[number]->Check(checker); + } + return base_type->AsETSArrayType()->ElementType(); } -- Gitee From f4d3f8d756a48bf159fe990da383187faa47e04a Mon Sep 17 00:00:00 2001 From: peterseres Date: Tue, 21 Nov 2023 12:55:13 +0100 Subject: [PATCH 26/35] Change-Id: If88d6872a5f56730f1108cd3da583710005478e4 Modifie error message to show arguments type if validate signature failed. Internal issue #13470 Testing: I add 3 test cases. Test 1: validate_signatures_throw_type_error.ets A variable a is declared and initialized with a new instance of the Byte class, passing the value 2 as a parameter to the constructor. It's is wrong because Byte couldn't handle int so it will raise the new error message. Test 2: validate_signatures_throw_type_error_more_param.ets Like the above but more paramters. Test 3: runtime/ets/validate_signatures_throw_type_error.ets This test case verifies that correct behaviour has not been ruined. Signed-off-by: Peter Seres --- ets2panda/checker/ets/function.cpp | 29 ++ .../ets/boxingConversion1-expected.txt | 2 +- .../ets/boxingConversion4-expected.txt | 2 +- ...e_signatures_throw_type_error-expected.txt | 445 +++++++++++++++++ .../validate_signatures_throw_type_error.ets | 18 + ...s_throw_type_error_more_param-expected.txt | 459 ++++++++++++++++++ ...signatures_throw_type_error_more_param.ets | 18 + .../validate_signatures_throw_type_error.ets | 21 + 8 files changed, 992 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/compiler/ets/validate_signatures_throw_type_error-expected.txt create mode 100644 ets2panda/test/compiler/ets/validate_signatures_throw_type_error.ets create mode 100644 ets2panda/test/compiler/ets/validate_signatures_throw_type_error_more_param-expected.txt create mode 100644 ets2panda/test/compiler/ets/validate_signatures_throw_type_error_more_param.ets create mode 100644 ets2panda/test/runtime/ets/validate_signatures_throw_type_error.ets diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index d3916f6c9..999ee30af 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -464,6 +464,35 @@ Signature *ETSChecker::ValidateSignatures(ArenaVector &signatures, } } + if ((resolve_flags & TypeRelationFlag::NO_THROW) == 0 && !arguments.empty() && !signatures.empty()) { + std::stringstream ss; + + if (signatures[0]->Function()->IsConstructor()) { + ss << util::Helpers::GetClassDefiniton(signatures[0]->Function())->PrivateId().Mutf8(); + } else { + ss << signatures[0]->Function()->Id()->Name().Mutf8(); + } + + ss << "("; + + for (uint32_t index = 0; index < arguments.size(); ++index) { + if (arguments[index]->IsArrowFunctionExpression()) { + // NOTE(peterseres): Refactor this case and add test case + break; + } + + arguments[index]->Check(this); + arguments[index]->TsType()->ToString(ss); + + if (index == arguments.size() - 1) { + ss << ")"; + ThrowTypeError({"No matching ", signature_kind, " signature for ", ss.str().c_str()}, pos); + } + + ss << ", "; + } + } + if ((resolve_flags & TypeRelationFlag::NO_THROW) == 0) { ThrowTypeError({"No matching ", signature_kind, " signature"}, pos); } diff --git a/ets2panda/test/compiler/ets/boxingConversion1-expected.txt b/ets2panda/test/compiler/ets/boxingConversion1-expected.txt index 719b59bc2..bf84cbaee 100644 --- a/ets2panda/test/compiler/ets/boxingConversion1-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion1-expected.txt @@ -541,4 +541,4 @@ } } } -TypeError: No matching construct signature [boxingConversion1.ets:18:19] +TypeError: No matching construct signature for std.core.Byte(int) [boxingConversion1.ets:18:19] diff --git a/ets2panda/test/compiler/ets/boxingConversion4-expected.txt b/ets2panda/test/compiler/ets/boxingConversion4-expected.txt index a7ce34893..f102d6aa2 100644 --- a/ets2panda/test/compiler/ets/boxingConversion4-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion4-expected.txt @@ -965,4 +965,4 @@ } } } -TypeError: No matching construct signature [boxingConversion4.ets:19:20] +TypeError: No matching construct signature for std.core.Short(int) [boxingConversion4.ets:19:20] diff --git a/ets2panda/test/compiler/ets/validate_signatures_throw_type_error-expected.txt b/ets2panda/test/compiler/ets/validate_signatures_throw_type_error-expected.txt new file mode 100644 index 000000000..ae620a89c --- /dev/null +++ b/ets2panda/test/compiler/ets/validate_signatures_throw_type_error-expected.txt @@ -0,0 +1,445 @@ +{ + "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": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Byte", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Byte", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 28 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 29 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 31 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 31 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "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: No matching construct signature for std.core.Byte(int) [validate_signatures_throw_type_error.ets:17:19] diff --git a/ets2panda/test/compiler/ets/validate_signatures_throw_type_error.ets b/ets2panda/test/compiler/ets/validate_signatures_throw_type_error.ets new file mode 100644 index 000000000..1b26009e1 --- /dev/null +++ b/ets2panda/test/compiler/ets/validate_signatures_throw_type_error.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 main() : void { + let a: Byte = new Byte(2); +} diff --git a/ets2panda/test/compiler/ets/validate_signatures_throw_type_error_more_param-expected.txt b/ets2panda/test/compiler/ets/validate_signatures_throw_type_error_more_param-expected.txt new file mode 100644 index 000000000..1b7c87989 --- /dev/null +++ b/ets2panda/test/compiler/ets/validate_signatures_throw_type_error_more_param-expected.txt @@ -0,0 +1,459 @@ +{ + "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": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "e", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Float", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 19 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Float", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 6, + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 17, + "column": 31 + } + } + }, + { + "type": "StringLiteral", + "value": "3", + "loc": { + "start": { + "line": 17, + "column": 32 + }, + "end": { + "line": 17, + "column": 35 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 37 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "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: No matching construct signature for std.core.Float(int, string) [validate_signatures_throw_type_error_more_param.ets:17:20] diff --git a/ets2panda/test/compiler/ets/validate_signatures_throw_type_error_more_param.ets b/ets2panda/test/compiler/ets/validate_signatures_throw_type_error_more_param.ets new file mode 100644 index 000000000..5b0a1e2f0 --- /dev/null +++ b/ets2panda/test/compiler/ets/validate_signatures_throw_type_error_more_param.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 main() : void { + let e: Float = new Float(6,"3"); +} diff --git a/ets2panda/test/runtime/ets/validate_signatures_throw_type_error.ets b/ets2panda/test/runtime/ets/validate_signatures_throw_type_error.ets new file mode 100644 index 000000000..9fc7a733c --- /dev/null +++ b/ets2panda/test/runtime/ets/validate_signatures_throw_type_error.ets @@ -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. + */ + +function main() : void { + let a: Byte = 2; + let b: Byte = new Byte(a); + + assert a == b; +} -- Gitee From 946d0462596b9b003a58987974dc3aadb7ab1034 Mon Sep 17 00:00:00 2001 From: Csaba Hurton Date: Thu, 14 Dec 2023 16:28:37 +0100 Subject: [PATCH 27/35] Fix assert error in binary logical expr Problem occured when binary logical AND/OR expression contained an Object type. After this fix, Object are evaluated as truthy in the expression. Issue: I8OJMZ Test: Build & ets-cts tests Signed-off-by: Csaba Hurton --- ets2panda/checker/ets/helpers.cpp | 13 +++++++- ...ject-type-in-binary-logical-expression.ets | 30 +++++++++++++++++++ .../runtime/ets/unboxingBooleanConversion.ets | 2 +- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/runtime/ets/Object-type-in-binary-logical-expression.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index b3b055271..2be709712 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -791,7 +791,18 @@ Type *ETSChecker::HandleBooleanLogicalOperatorsExtended(Type *left_type, Type *r auto [resolve_right, right_value] = IsNullLikeOrVoidExpression(expr->Right()) ? std::make_tuple(true, false) : right_type->ResolveConditionExpr(); - if (!resolve_left) { + if (!expr->Left()->TsType()->ContainsUndefined() && !expr->Left()->TsType()->ContainsNull() && + !expr->Left()->TsType()->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { + resolve_left = true; + left_value = true; + } + if (!expr->Right()->TsType()->ContainsUndefined() && !expr->Right()->TsType()->ContainsNull() && + !expr->Right()->TsType()->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { + resolve_right = true; + right_value = true; + } + + if (!resolve_left && !resolve_right) { if (IsTypeIdenticalTo(left_type, right_type)) { return left_type; } diff --git a/ets2panda/test/runtime/ets/Object-type-in-binary-logical-expression.ets b/ets2panda/test/runtime/ets/Object-type-in-binary-logical-expression.ets new file mode 100644 index 000000000..352bdd8af --- /dev/null +++ b/ets2panda/test/runtime/ets/Object-type-in-binary-logical-expression.ets @@ -0,0 +1,30 @@ +/* + * 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() { + let apple: Object = new Object(); + let banana: boolean = true; + let cherry: boolean = false; + + assert(apple && banana); + assert(banana && apple); + assert(apple || cherry); + assert(cherry || apple); + + assert(apple && true); + assert(true && apple); + assert(apple || false); + assert(false || apple); +} diff --git a/ets2panda/test/runtime/ets/unboxingBooleanConversion.ets b/ets2panda/test/runtime/ets/unboxingBooleanConversion.ets index 23ae74c08..7fb437eed 100644 --- a/ets2panda/test/runtime/ets/unboxingBooleanConversion.ets +++ b/ets2panda/test/runtime/ets/unboxingBooleanConversion.ets @@ -27,7 +27,7 @@ function main(): void { let b: Boolean = a && returnTrue(); assert b == true - let c: Boolean = returnRefBool(a || returnRefBool(returnTrue() && returnRefBool(a))); + let c: Boolean = returnRefBool(a || returnRefBool(returnRefBool(a))); assert c == false } -- Gitee From b3bc12c2d21f9d0fbfe2cd1f216cc2f6782c578f Mon Sep 17 00:00:00 2001 From: aleksisch Date: Tue, 19 Dec 2023 02:03:30 +0300 Subject: [PATCH 28/35] add boxing unboxing flag for getters Signed-off-by: aleksisch --- .../lowering/ets/objectIndexAccess.cpp | 1 + ets2panda/test/runtime/ets/generic_getter.ets | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 ets2panda/test/runtime/ets/generic_getter.ets diff --git a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp index 0afacc26a..277f9026f 100644 --- a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp +++ b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp @@ -67,6 +67,7 @@ ir::Expression *ObjectIndexLowering::ProcessIndexGetAccess(parser::ETSParser *pa lowering_result->SetParent(member_expression->Parent()); lowering_result->Check(checker); + lowering_result->SetBoxingUnboxingFlags(member_expression->GetBoxingUnboxingFlags()); return lowering_result; } diff --git a/ets2panda/test/runtime/ets/generic_getter.ets b/ets2panda/test/runtime/ets/generic_getter.ets new file mode 100644 index 000000000..07ab5a1e5 --- /dev/null +++ b/ets2panda/test/runtime/ets/generic_getter.ets @@ -0,0 +1,27 @@ +/* + * 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 { + f: T + constructor(f: T) { this.f = f } + $_get(index: number): T { return this.f } +} + +function main(): void { + let o_double = new A(10) + const o_int = new A(10) + assert o_double[11] == 10 + assert 10 == o_int[11] +} -- Gitee From e38e5889e691d3e380e10a85782931d17c8c12fc Mon Sep 17 00:00:00 2001 From: Tatiana Date: Sun, 17 Dec 2023 18:53:28 +0300 Subject: [PATCH 29/35] Fix scope search in trailing lambda #14895 Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8P3PY Signed-off-by: Tatiana Change-Id: Ia5212f0a4a34bd6ff7122e5a0b7ef388de32cd6c --- ets2panda/checker/ets/function.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 999ee30af..cd4759194 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -2754,7 +2754,7 @@ void ETSChecker::ReplaceScope(ir::AstNode *root, ir::AstNode *old_node, varbinde root->Iterate([this, old_node, new_scope](ir::AstNode *child) { auto *scope = NodeScope(child); if (scope != nullptr) { - while (scope->Parent()->Node() != old_node) { + while (scope->Parent() != nullptr && scope->Parent()->Node() != old_node) { scope = scope->Parent(); } scope->SetParent(new_scope); -- Gitee From 8b4c2ecf9b0823ed871b3de7496f2018ce764188 Mon Sep 17 00:00:00 2001 From: aakmaev Date: Thu, 21 Dec 2023 01:40:37 +0300 Subject: [PATCH 30/35] Fix OpAssignment var resolving in lambda body Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8Q4FZ?from=project-issue Testing : All required pre-merge tests passed. Results are availible in the ggwatcher. Signed-off-by: Akmaev Alexey --- .../ets/lambda_capturing-expected.txt | 614 ++++++++++++++++++ .../test/compiler/ets/lambda_capturing.ets | 23 + ets2panda/varbinder/ETSBinder.cpp | 3 + 3 files changed, 640 insertions(+) create mode 100644 ets2panda/test/compiler/ets/lambda_capturing-expected.txt create mode 100644 ets2panda/test/compiler/ets/lambda_capturing.ets diff --git a/ets2panda/test/compiler/ets/lambda_capturing-expected.txt b/ets2panda/test/compiler/ets/lambda_capturing-expected.txt new file mode 100644 index 000000000..3e3bf773a --- /dev/null +++ b/ets2panda/test/compiler/ets/lambda_capturing-expected.txt @@ -0,0 +1,614 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "EasingCurve", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 28 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 28 + }, + "end": { + "line": 16, + "column": 40 + } + } + } + ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 45 + }, + "end": { + "line": 16, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 18, + "column": 9 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "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": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "count", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 24 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EasingCurve", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 19, + "column": 20 + }, + "end": { + "line": 19, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 13 + }, + "end": { + "line": 19, + "column": 25 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "*=", + "left": { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 14 + } + } + }, + "right": { + "type": "Identifier", + "name": "count", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 18 + }, + "end": { + "line": 20, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9 + }, + "end": { + "line": 20, + "column": 23 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 21, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 22, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 22, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 22, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 22, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 23, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/lambda_capturing.ets b/ets2panda/test/compiler/ets/lambda_capturing.ets new file mode 100644 index 000000000..70903eee6 --- /dev/null +++ b/ets2panda/test/compiler/ets/lambda_capturing.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + +export type EasingCurve = (value: float) => float + +function foo(count: int): EasingCurve { + return (value: float) => { + value *= count + return value + } +} diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 87d2318c0..7d9ec8723 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -143,6 +143,9 @@ void ETSBinder::ResolveReferenceForScope(ir::AstNode *const node, Scope *const s switch (node->Type()) { case ir::AstNodeType::IDENTIFIER: { auto *ident = node->AsIdentifier(); + if (ident->Variable() != nullptr) { + break; + } if (auto const res = scope->Find(ident->Name(), ResolveBindingOptions::ALL); res.variable != nullptr) { ident->SetVariable(res.variable); } -- Gitee From a8a157379ba5fe136e507f83d8e48b0cc4250f42 Mon Sep 17 00:00:00 2001 From: Anna Antipina Date: Tue, 19 Dec 2023 13:53:07 +0300 Subject: [PATCH 31/35] Title: Fix segfault occures after adding new constructor with Array Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8PRB7 Description: Adding new constructor with Array into class Int8Array cause the Segfault during etsstdlib compiling. Testing: Add the following code into file /arkcompiler/runtime_core/static_core/plugins/ets/stdlib/escompat/TypedArrays.ets into class Int8Array: public constructor(buf: Array) { this() } Compile etsstdlib: ninja etsstdlib Signed-off-by: Anna Antipina --- ets2panda/checker/ETSchecker.cpp | 21 +++++++++++++-------- ets2panda/checker/ETSchecker.h | 1 + ets2panda/checker/ets/helpers.cpp | 4 ++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 4144da1ef..f0d1674da 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -55,20 +55,25 @@ void ETSChecker::InitializeBuiltins(varbinder::ETSBinder *varbinder) } if (var->HasFlag(varbinder::VariableFlags::BUILTIN_TYPE)) { - Type *type {nullptr}; - if (var->Declaration()->Node()->IsClassDefinition()) { - type = BuildClassProperties(var->Declaration()->Node()->AsClassDefinition()); - } else { - ASSERT(var->Declaration()->Node()->IsTSInterfaceDeclaration()); - type = BuildInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); - } - GetGlobalTypesHolder()->InitializeBuiltin(name, type); + InitializeBuiltin(var, name); } } AddStatus(CheckerStatus::BUILTINS_INITIALIZED); } +void ETSChecker::InitializeBuiltin(varbinder::Variable *var, const util::StringView &name) +{ + Type *type {nullptr}; + if (var->Declaration()->Node()->IsClassDefinition()) { + type = BuildClassProperties(var->Declaration()->Node()->AsClassDefinition()); + } else { + ASSERT(var->Declaration()->Node()->IsTSInterfaceDeclaration()); + type = BuildInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); + } + GetGlobalTypesHolder()->InitializeBuiltin(name, type); +} + bool ETSChecker::StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const CompilerOptions &options) { Initialize(varbinder); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index e2063bc33..3ad9d45a1 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -120,6 +120,7 @@ public: const GlobalArraySignatureMap &GlobalArrayTypes() const; void InitializeBuiltins(varbinder::ETSBinder *varbinder); + void InitializeBuiltin(varbinder::Variable *var, const util::StringView &name); bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const CompilerOptions &options) override; Type *CheckTypeCached(ir::Expression *expr) override; void ResolveStructuredTypeMembers([[maybe_unused]] Type *type) override {} diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 2be709712..3cd2586cc 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1698,6 +1698,10 @@ Type *ETSChecker::PrimitiveTypeAsETSBuiltinType(Type *object_type) auto saved_result = Relation()->IsTrue(); Relation()->Result(false); + if (Checker::GetGlobalTypesHolder()->GlobalIntegerBuiltinType() == nullptr) { + InitializeBuiltin(VarBinder()->TopScope()->Bindings().find("Int")->second, "Int"); + } + BoxingConverter converter = BoxingConverter(AsETSChecker(), Relation(), object_type, Checker::GetGlobalTypesHolder()->GlobalIntegerBuiltinType()); Relation()->Result(saved_result); -- Gitee From 4ac85142b918fc94922158c8698aef9aa9137074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20Horv=C3=A1th?= Date: Fri, 10 Nov 2023 09:11:09 +0100 Subject: [PATCH 32/35] [es2panda] Implemented this type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented this type as per section 16.7.1 of the language specification. Added several new parser/compiler/runtime tests. Issue: #I8OIQB Internal issue: #14043 Testing: - Added several new parser/compiler/runtime tests. - All required pre-merge tests passed. Results are available in ggwatcher. Signed-off-by: Ferenc Horváth Change-Id: I41ba0b94efcdbde0f037ef5d07c5a41b89cad8b2 --- ets2panda/checker/ETSAnalyzer.cpp | 14 +- ets2panda/checker/ets/function.cpp | 4 + ets2panda/checker/types/signature.h | 1 + ets2panda/compiler/core/ETSGen.cpp | 4 + ets2panda/ir/ts/tsThisType.cpp | 6 + ets2panda/ir/ts/tsThisType.h | 1 + ets2panda/parser/ETSparser.cpp | 37 +- ets2panda/parser/ETSparser.h | 1 + ...this_type_invalid_return_type-expected.txt | 467 ++++++++++++++++++ .../ets/this_type_invalid_return_type.ets | 20 + .../this_type_valid_return_type-expected.txt | 424 ++++++++++++++++ .../ets/this_type_valid_return_type.ets | 20 + ...this_type_class_field_invalid-expected.txt | 1 + .../ets/this_type_class_field_invalid.ets | 19 + ...lass_method_parameter_invalid-expected.txt | 1 + ...is_type_class_method_parameter_invalid.ets | 18 + ...ype_class_method_return_valid-expected.txt | 466 +++++++++++++++++ .../this_type_class_method_return_valid.ets | 18 + ...atic_method_parameter_invalid-expected.txt | 1 + ..._class_static_method_parameter_invalid.ets | 18 + ..._static_method_return_invalid-expected.txt | 1 + ...ype_class_static_method_return_invalid.ets | 18 + ...pe_function_parameter_invalid-expected.txt | 1 + .../this_type_function_parameter_invalid.ets | 16 + ..._type_function_return_invalid-expected.txt | 1 + .../ets/this_type_function_return_invalid.ets | 16 + ...on_parameter_in_class_invalid-expected.txt | 1 + ...declaration_parameter_in_class_invalid.ets | 20 + ...declaration_parameter_invalid-expected.txt | 1 + ...e_lambda_declaration_parameter_invalid.ets | 16 + ...ation_return_in_class_invalid-expected.txt | 1 + ...da_declaration_return_in_class_invalid.ets | 20 + ...da_declaration_return_invalid-expected.txt | 1 + ...type_lambda_declaration_return_invalid.ets | 16 + ...on_parameter_in_class_invalid-expected.txt | 1 + ..._definition_parameter_in_class_invalid.ets | 21 + ..._definition_parameter_invalid-expected.txt | 1 + ...pe_lambda_definition_parameter_invalid.ets | 19 + ...ition_return_in_class_invalid-expected.txt | 1 + ...bda_definition_return_in_class_invalid.ets | 21 + ...bda_definition_return_invalid-expected.txt | 1 + ..._type_lambda_definition_return_invalid.ets | 19 + ets2panda/test/runtime/ets/this_type.ets | 50 ++ 43 files changed, 1801 insertions(+), 3 deletions(-) create mode 100644 ets2panda/test/compiler/ets/this_type_invalid_return_type-expected.txt create mode 100644 ets2panda/test/compiler/ets/this_type_invalid_return_type.ets create mode 100644 ets2panda/test/compiler/ets/this_type_valid_return_type-expected.txt create mode 100644 ets2panda/test/compiler/ets/this_type_valid_return_type.ets create mode 100644 ets2panda/test/parser/ets/this_type_class_field_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_class_field_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_class_method_parameter_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_class_method_parameter_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_class_method_return_valid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_class_method_return_valid.ets create mode 100644 ets2panda/test/parser/ets/this_type_class_static_method_parameter_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_class_static_method_parameter_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_class_static_method_return_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_class_static_method_return_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_function_parameter_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_function_parameter_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_function_return_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_function_return_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_lambda_declaration_return_in_class_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_lambda_declaration_return_in_class_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_lambda_declaration_return_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_lambda_declaration_return_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_lambda_definition_parameter_in_class_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_lambda_definition_parameter_in_class_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_lambda_definition_parameter_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_lambda_definition_parameter_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_lambda_definition_return_in_class_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_lambda_definition_return_in_class_invalid.ets create mode 100644 ets2panda/test/parser/ets/this_type_lambda_definition_return_invalid-expected.txt create mode 100644 ets2panda/test/parser/ets/this_type_lambda_definition_return_invalid.ets create mode 100644 ets2panda/test/runtime/ets/this_type.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 72fa2ed62..f77074d52 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1064,7 +1064,13 @@ checker::Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, checker::Typ expr->SetSignature(signature); } - return signature->ReturnType(); + auto *return_type = signature->ReturnType(); + + if (signature->HasSignatureFlag(SignatureFlags::THIS_RETURN_TYPE)) { + return_type = ChooseCalleeObj(checker, expr, callee_type, is_constructor_call); + } + + return return_type; } checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const @@ -2165,6 +2171,12 @@ checker::Type *ETSAnalyzer::Check(ir::ReturnStatement *st) const if (auto *const return_type_annotation = containing_func->ReturnTypeAnnotation(); return_type_annotation != nullptr) { + if (return_type_annotation->IsTSThisType() && + (st->Argument() == nullptr || !st->Argument()->IsThisExpression())) { + checker->ThrowTypeError( + "The only allowed return value is 'this' if the method's return type is the 'this' type", st->Start()); + } + // Case when function's return type is defined explicitly: func_return_type = checker->GetTypeFromTypeAnnotation(return_type_annotation); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index cd4759194..300836668 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -779,6 +779,10 @@ Signature *ETSChecker::ComposeSignature(ir::ScriptFunction *func, SignatureInfo signature->AddSignatureFlag(SignatureFlags::NEED_RETURN_TYPE); } + if (return_type_annotation != nullptr && return_type_annotation->IsTSThisType()) { + signature->AddSignatureFlag(SignatureFlags::THIS_RETURN_TYPE); + } + if (func->IsAbstract()) { signature->AddSignatureFlag(SignatureFlags::ABSTRACT); signature->AddSignatureFlag(SignatureFlags::VIRTUAL); diff --git a/ets2panda/checker/types/signature.h b/ets2panda/checker/types/signature.h index 220eda8fe..fdbbeb555 100644 --- a/ets2panda/checker/types/signature.h +++ b/ets2panda/checker/types/signature.h @@ -79,6 +79,7 @@ enum class SignatureFlags : uint32_t { INTERNAL = 1U << 12U, NEED_RETURN_TYPE = 1U << 13U, INFERRED_RETURN_TYPE = 1U << 14U, + THIS_RETURN_TYPE = 1U << 15U, GETTER = 1U << 16U, SETTER = 1U << 17U, diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index c0ae28674..a8ab69e01 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -2267,6 +2267,10 @@ void ETSGen::InsertNeededCheckCast(const checker::Signature *signature, const ir { if (signature->IsBaseReturnDiff()) { EmitCheckCast(node, signature->ReturnType()); + } else if (signature->HasSignatureFlag(checker::SignatureFlags::THIS_RETURN_TYPE)) { + ASSERT(node->IsCallExpression()); + + EmitCheckCast(node, node->AsCallExpression()->TsType()); } } diff --git a/ets2panda/ir/ts/tsThisType.cpp b/ets2panda/ir/ts/tsThisType.cpp index e98bde61e..4efb3209f 100644 --- a/ets2panda/ir/ts/tsThisType.cpp +++ b/ets2panda/ir/ts/tsThisType.cpp @@ -15,6 +15,7 @@ #include "tsThisType.h" +#include "checker/ETSchecker.h" #include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" #include "compiler/core/pandagen.h" @@ -58,4 +59,9 @@ checker::Type *TSThisType::Check([[maybe_unused]] checker::ETSChecker *checker) { return checker->GetAnalyzer()->Check(this); } + +checker::Type *TSThisType::GetType([[maybe_unused]] checker::ETSChecker *checker) +{ + return checker->Context().ContainingClass(); +} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsThisType.h b/ets2panda/ir/ts/tsThisType.h index bdf171364..2d183f88c 100644 --- a/ets2panda/ir/ts/tsThisType.h +++ b/ets2panda/ir/ts/tsThisType.h @@ -32,6 +32,7 @@ public: checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; + checker::Type *GetType([[maybe_unused]] checker::ETSChecker *checker) override; void Accept(ASTVisitorT *v) override { diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 32353ee96..e0bd9d2a6 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -118,6 +118,7 @@ #include "ir/ts/tsTypeAliasDeclaration.h" #include "ir/ts/tsTypeParameterDeclaration.h" #include "ir/ts/tsNonNullExpression.h" +#include "ir/ts/tsThisType.h" #include "libpandabase/os/file.h" #include "generated/signatures.h" @@ -1349,6 +1350,10 @@ ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *meth new_status |= ParserStatus::ASYNC_FUNCTION; } + if ((modifiers & ir::ModifierFlags::STATIC) == 0) { + new_status |= ParserStatus::ALLOW_THIS_TYPE; + } + ir::ScriptFunction *func = ParseFunction(new_status, class_name); func->SetIdent(method_name); auto *func_expr = AllocNode(func); @@ -1460,8 +1465,9 @@ ir::TypeNode *ETSParser::ParseFunctionReturnType([[maybe_unused]] ParserStatus s ThrowSyntaxError("Type annotation isn't allowed for constructor."); } Lexer()->NextToken(); // eat ':' - TypeAnnotationParsingOptions options = - TypeAnnotationParsingOptions::THROW_ERROR | TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE; + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR | + TypeAnnotationParsingOptions::CAN_BE_TS_TYPE_PREDICATE | + TypeAnnotationParsingOptions::RETURN_TYPE; return ParseTypeAnnotation(&options); } @@ -2820,6 +2826,10 @@ std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnota type_annotation = ParseETSTupleType(options); break; } + case lexer::TokenType::KEYW_THIS: { + type_annotation = ParseThisType(options); + break; + } default: { break; } @@ -2828,6 +2838,29 @@ std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnota return std::make_pair(type_annotation, true); } +ir::TypeNode *ETSParser::ParseThisType(TypeAnnotationParsingOptions *options) +{ + ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_THIS); + + // A syntax error should be thrown if + // - the usage of 'this' as a type is not allowed in the current context, or + // - 'this' is not used as a return type, or + // - the current context is an arrow function (might be inside a method of a class where 'this' is allowed). + if (((*options & TypeAnnotationParsingOptions::THROW_ERROR) != 0) && + (((GetContext().Status() & ParserStatus::ALLOW_THIS_TYPE) == 0) || + ((*options & TypeAnnotationParsingOptions::RETURN_TYPE) == 0) || + ((GetContext().Status() & ParserStatus::ARROW_FUNCTION) != 0))) { + ThrowSyntaxError("A 'this' type is available only as return type in a non-static method of a class or struct."); + } + + auto *this_type = AllocNode(); + this_type->SetRange(Lexer()->GetToken().Loc()); + + Lexer()->NextToken(); // eat 'this' + + return this_type; +} + ir::TypeNode *ETSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options) { bool const throw_error = ((*options) & TypeAnnotationParsingOptions::THROW_ERROR) != 0; diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 5d18d6a3e..74c3294ac 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -252,6 +252,7 @@ private: ir::Statement *ParseInterfaceDeclaration(bool is_static) override; ir::ThisExpression *ParseThisExpression() override; + ir::TypeNode *ParseThisType(TypeAnnotationParsingOptions *options); ir::Statement *ParseFunctionStatement(StatementParsingFlags flags) override; std::tuple ParseClassImplementsElement() override; ir::TypeNode *ParseInterfaceExtendsElement() override; diff --git a/ets2panda/test/compiler/ets/this_type_invalid_return_type-expected.txt b/ets2panda/test/compiler/ets/this_type_invalid_return_type-expected.txt new file mode 100644 index 000000000..daebc746d --- /dev/null +++ b/ets2panda/test/compiler/ets/this_type_invalid_return_type-expected.txt @@ -0,0 +1,467 @@ +{ + "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": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "TSThisType", + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 24 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 19, + "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": 20, + "column": 2 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 20, + "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 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} +TypeError: The only allowed return value is 'this' if the method's return type is the 'this' type [this_type_invalid_return_type.ets:18:9] diff --git a/ets2panda/test/compiler/ets/this_type_invalid_return_type.ets b/ets2panda/test/compiler/ets/this_type_invalid_return_type.ets new file mode 100644 index 000000000..8f229dc40 --- /dev/null +++ b/ets2panda/test/compiler/ets/this_type_invalid_return_type.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. + */ + +class A { + foo(): this { + return new A(); + } +} diff --git a/ets2panda/test/compiler/ets/this_type_valid_return_type-expected.txt b/ets2panda/test/compiler/ets/this_type_valid_return_type-expected.txt new file mode 100644 index 000000000..5c242c269 --- /dev/null +++ b/ets2panda/test/compiler/ets/this_type_valid_return_type-expected.txt @@ -0,0 +1,424 @@ +{ + "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": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "TSThisType", + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 19, + "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": 20, + "column": 2 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 20, + "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 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/this_type_valid_return_type.ets b/ets2panda/test/compiler/ets/this_type_valid_return_type.ets new file mode 100644 index 000000000..6a19b3f0a --- /dev/null +++ b/ets2panda/test/compiler/ets/this_type_valid_return_type.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. + */ + +class A { + foo(): this { + return this; + } +} diff --git a/ets2panda/test/parser/ets/this_type_class_field_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_class_field_invalid-expected.txt new file mode 100644 index 000000000..511c45d12 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_field_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_class_field_invalid.ets:18:13] diff --git a/ets2panda/test/parser/ets/this_type_class_field_invalid.ets b/ets2panda/test/parser/ets/this_type_class_field_invalid.ets new file mode 100644 index 000000000..a0f3bab04 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_field_invalid.ets @@ -0,0 +1,19 @@ +/* + * 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 { + attr_i: int; + attr_a: this; +} diff --git a/ets2panda/test/parser/ets/this_type_class_method_parameter_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_class_method_parameter_invalid-expected.txt new file mode 100644 index 000000000..fd8543724 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_method_parameter_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_class_method_parameter_invalid.ets:17:26] diff --git a/ets2panda/test/parser/ets/this_type_class_method_parameter_invalid.ets b/ets2panda/test/parser/ets/this_type_class_method_parameter_invalid.ets new file mode 100644 index 000000000..059bc1905 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_method_parameter_invalid.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. + */ + +class A { + foo(arg1: int, arg2: this) {} +} diff --git a/ets2panda/test/parser/ets/this_type_class_method_return_valid-expected.txt b/ets2panda/test/parser/ets/this_type_class_method_return_valid-expected.txt new file mode 100644 index 000000000..5db9e35bd --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_method_return_valid-expected.txt @@ -0,0 +1,466 @@ +{ + "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": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "arg1", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 17, + "column": 15 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 18 + } + } + } + ], + "returnType": { + "type": "TSThisType", + "loc": { + "start": { + "line": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 17, + "column": 35 + }, + "end": { + "line": 17, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 42 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 42 + } + } + }, + { + "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": 18, + "column": 2 + }, + "end": { + "line": 18, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 18, + "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 + } + } + } + ], + "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/this_type_class_method_return_valid.ets b/ets2panda/test/parser/ets/this_type_class_method_return_valid.ets new file mode 100644 index 000000000..4120e8608 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_method_return_valid.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. + */ + +class A { + foo(arg1: int): this { return this; } +} diff --git a/ets2panda/test/parser/ets/this_type_class_static_method_parameter_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_class_static_method_parameter_invalid-expected.txt new file mode 100644 index 000000000..f3db845ba --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_static_method_parameter_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_class_static_method_parameter_invalid.ets:17:33] diff --git a/ets2panda/test/parser/ets/this_type_class_static_method_parameter_invalid.ets b/ets2panda/test/parser/ets/this_type_class_static_method_parameter_invalid.ets new file mode 100644 index 000000000..113852662 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_static_method_parameter_invalid.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. + */ + +class A { + static foo(arg1: int, arg2: this) {} +} diff --git a/ets2panda/test/parser/ets/this_type_class_static_method_return_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_class_static_method_return_invalid-expected.txt new file mode 100644 index 000000000..e54644a20 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_static_method_return_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_class_static_method_return_invalid.ets:17:33] diff --git a/ets2panda/test/parser/ets/this_type_class_static_method_return_invalid.ets b/ets2panda/test/parser/ets/this_type_class_static_method_return_invalid.ets new file mode 100644 index 000000000..7fabdb2fb --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_class_static_method_return_invalid.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. + */ + +class A { + static foo(arg1: int, arg2: this) { return this; } +} diff --git a/ets2panda/test/parser/ets/this_type_function_parameter_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_function_parameter_invalid-expected.txt new file mode 100644 index 000000000..dfc0b3cf0 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_function_parameter_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_function_parameter_invalid.ets:16:31] diff --git a/ets2panda/test/parser/ets/this_type_function_parameter_invalid.ets b/ets2panda/test/parser/ets/this_type_function_parameter_invalid.ets new file mode 100644 index 000000000..22f3277e7 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_function_parameter_invalid.ets @@ -0,0 +1,16 @@ +/* + * 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(arg1: int, arg2: this) {} diff --git a/ets2panda/test/parser/ets/this_type_function_return_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_function_return_invalid-expected.txt new file mode 100644 index 000000000..cd33d06b4 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_function_return_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_function_return_invalid.ets:16:26] diff --git a/ets2panda/test/parser/ets/this_type_function_return_invalid.ets b/ets2panda/test/parser/ets/this_type_function_return_invalid.ets new file mode 100644 index 000000000..acea016f9 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_function_return_invalid.ets @@ -0,0 +1,16 @@ +/* + * 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(arg1: int): this { return this; } diff --git a/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid-expected.txt new file mode 100644 index 000000000..e7e058869 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_lambda_declaration_parameter_in_class_invalid.ets:18:28] diff --git a/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid.ets b/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid.ets new file mode 100644 index 000000000..47f9e6f19 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid.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. + */ + +class A { + foo() { + let x: (i: int, t: this) => number; + } +} diff --git a/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_invalid-expected.txt new file mode 100644 index 000000000..86d9fac73 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_lambda_declaration_parameter_invalid.ets:16:20] diff --git a/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_invalid.ets b/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_invalid.ets new file mode 100644 index 000000000..d2f833f7e --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_declaration_parameter_invalid.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +let x: (i: int, t: this) => number; diff --git a/ets2panda/test/parser/ets/this_type_lambda_declaration_return_in_class_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_lambda_declaration_return_in_class_invalid-expected.txt new file mode 100644 index 000000000..a870ea5a6 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_declaration_return_in_class_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_lambda_declaration_return_in_class_invalid.ets:18:39] diff --git a/ets2panda/test/parser/ets/this_type_lambda_declaration_return_in_class_invalid.ets b/ets2panda/test/parser/ets/this_type_lambda_declaration_return_in_class_invalid.ets new file mode 100644 index 000000000..8987c94df --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_declaration_return_in_class_invalid.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. + */ + +class A { + foo() { + let x: (i: int, n: number) => this; + } +} diff --git a/ets2panda/test/parser/ets/this_type_lambda_declaration_return_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_lambda_declaration_return_invalid-expected.txt new file mode 100644 index 000000000..b41f21492 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_declaration_return_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_lambda_declaration_return_invalid.ets:16:31] diff --git a/ets2panda/test/parser/ets/this_type_lambda_declaration_return_invalid.ets b/ets2panda/test/parser/ets/this_type_lambda_declaration_return_invalid.ets new file mode 100644 index 000000000..8e8fb0287 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_declaration_return_invalid.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +let x: (i: int, n: number) => this; diff --git a/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_in_class_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_in_class_invalid-expected.txt new file mode 100644 index 000000000..57a2b847d --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_in_class_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_lambda_definition_parameter_in_class_invalid.ets:19:25] diff --git a/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_in_class_invalid.ets b/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_in_class_invalid.ets new file mode 100644 index 000000000..d75fb8dec --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_in_class_invalid.ets @@ -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 { + foo() { + let x: (i: int, a: A) => number; + x = (i: int, t: this): number => { return 2.0; }; + } +} diff --git a/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_invalid-expected.txt new file mode 100644 index 000000000..5c87380ca --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_lambda_definition_parameter_invalid.ets:19:17] diff --git a/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_invalid.ets b/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_invalid.ets new file mode 100644 index 000000000..d9574a1a3 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_definition_parameter_invalid.ets @@ -0,0 +1,19 @@ +/* + * 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 {} + +let x: (i: int, a: A) => number; +x = (i: int, t: this): number => { return 2.0; }; diff --git a/ets2panda/test/parser/ets/this_type_lambda_definition_return_in_class_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_lambda_definition_return_in_class_invalid-expected.txt new file mode 100644 index 000000000..728c83568 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_definition_return_in_class_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_lambda_definition_return_in_class_invalid.ets:19:34] diff --git a/ets2panda/test/parser/ets/this_type_lambda_definition_return_in_class_invalid.ets b/ets2panda/test/parser/ets/this_type_lambda_definition_return_in_class_invalid.ets new file mode 100644 index 000000000..3fa47d952 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_definition_return_in_class_invalid.ets @@ -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 { + foo() { + let x: (i: int, n: number) => A; + x = (i: int, n: number): this => { return this; }; + } +} diff --git a/ets2panda/test/parser/ets/this_type_lambda_definition_return_invalid-expected.txt b/ets2panda/test/parser/ets/this_type_lambda_definition_return_invalid-expected.txt new file mode 100644 index 000000000..d67535099 --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_definition_return_invalid-expected.txt @@ -0,0 +1 @@ +SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct. [this_type_lambda_definition_return_invalid.ets:19:26] diff --git a/ets2panda/test/parser/ets/this_type_lambda_definition_return_invalid.ets b/ets2panda/test/parser/ets/this_type_lambda_definition_return_invalid.ets new file mode 100644 index 000000000..b681c247a --- /dev/null +++ b/ets2panda/test/parser/ets/this_type_lambda_definition_return_invalid.ets @@ -0,0 +1,19 @@ +/* + * 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 {} + +let x: (i: int, n: number) => A; +x = (i: int, n: number): this => { return new A(); }; diff --git a/ets2panda/test/runtime/ets/this_type.ets b/ets2panda/test/runtime/ets/this_type.ets new file mode 100644 index 000000000..c9b141dd3 --- /dev/null +++ b/ets2panda/test/runtime/ets/this_type.ets @@ -0,0 +1,50 @@ +/* + * 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 Component { + width: int; + + getWidth(): int { + return this.width; + } + + setWidth(w: int): this { + this.width = w; + + return this; + } +} + +class Button extends Component { + title: string; + + getTitle(): string { + return this.title; + } + + setTitle(t: string): this { + this.title = t; + + return this; + } +} + +function main() { + let b = new Button().setWidth(50).setTitle("🍆"); + + assert b instanceof Button; + assert b.getWidth() == 50; + assert b.getTitle() == "🍆"; +} -- Gitee From dac0ba85a1ea830c93a6e7b2f44d69ed7bc89f3a Mon Sep 17 00:00:00 2001 From: gergocs Date: Wed, 20 Dec 2023 10:53:43 +0100 Subject: [PATCH 33/35] Implement default generic parameter Issue: #14108 internal Testing: Functions and classes with generic type Change-Id: I90bc90d43c03ff9a09a0d9968830d1305c0d5bb0 Signed-off-by: Gergo Csizi Change-Id: I2fcca8a54246f4d1965b86c6d4428e1309372f52 --- ets2panda/checker/ets/function_helpers.h | 24 +- ets2panda/checker/ets/helpers.cpp | 26 +- ets2panda/checker/ets/typeRelationContext.cpp | 67 +- ets2panda/ir/ts/tsTypeParameter.h | 2 +- ets2panda/parser/ETSparser.cpp | 10 +- .../ets/genericDefaultParam_1-expected.txt | 3391 +++++++++++++++++ .../test/parser/ets/genericDefaultParam_1.ets | 33 + .../ets/genericDefaultParam_2-expected.txt | 1 + .../test/parser/ets/genericDefaultParam_2.ets | 16 + .../ets/genericDefaultParam_3-expected.txt | 531 +++ .../test/parser/ets/genericDefaultParam_3.ets | 20 + 11 files changed, 4081 insertions(+), 40 deletions(-) create mode 100644 ets2panda/test/parser/ets/genericDefaultParam_1-expected.txt create mode 100644 ets2panda/test/parser/ets/genericDefaultParam_1.ets create mode 100644 ets2panda/test/parser/ets/genericDefaultParam_2-expected.txt create mode 100644 ets2panda/test/parser/ets/genericDefaultParam_2.ets create mode 100644 ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt create mode 100644 ets2panda/test/parser/ets/genericDefaultParam_3.ets diff --git a/ets2panda/checker/ets/function_helpers.h b/ets2panda/checker/ets/function_helpers.h index a4b7e1d09..3bbe0ddb5 100644 --- a/ets2panda/checker/ets/function_helpers.h +++ b/ets2panda/checker/ets/function_helpers.h @@ -107,7 +107,7 @@ static const Substitution *BuildImplicitSubstitutionForArguments(ETSChecker *che } static const Substitution *BuildExplicitSubstitutionForArguments(ETSChecker *checker, Signature *signature, - const ir::TSTypeParameterInstantiation *type_arguments, + const ArenaVector ¶ms, const lexer::SourcePosition &pos, TypeRelationFlag flags) { @@ -115,7 +115,7 @@ static const Substitution *BuildExplicitSubstitutionForArguments(ETSChecker *che auto *constraints_substitution = checker->NewSubstitution(); ArenaVector &type_params = signature->GetSignatureInfo()->type_params; ArenaVector type_arg_types {checker->Allocator()->Adapter()}; - for (auto *ta_expr : type_arguments->Params()) { + for (auto *ta_expr : params) { auto *type_arg = ta_expr->GetType(checker); type_arg = MaybeBoxedType(checker, type_arg, ta_expr); type_arg_types.push_back(type_arg); @@ -147,10 +147,24 @@ static Signature *MaybeSubstituteTypeParameters(ETSChecker *checker, Signature * if (type_arguments == nullptr && signature->GetSignatureInfo()->type_params.empty()) { return signature; } + + ArenaVector params = ArenaVector(checker->Allocator()->Adapter()); + + if (type_arguments == nullptr && !signature->Function()->TypeParams()->Params().empty()) { + for (auto param : signature->Function()->TypeParams()->Params()) { + if (param->DefaultType() != nullptr) { + params.push_back(param->DefaultType()->AsTypeNode()); + } else { + break; + } + } + } else if (type_arguments != nullptr) { + params = type_arguments->Params(); + } + const Substitution *substitution = - (type_arguments != nullptr) - ? BuildExplicitSubstitutionForArguments(checker, signature, type_arguments, pos, flags) - : BuildImplicitSubstitutionForArguments(checker, signature, arguments); + (!params.empty()) ? BuildExplicitSubstitutionForArguments(checker, signature, params, pos, flags) + : BuildImplicitSubstitutionForArguments(checker, signature, arguments); return (substitution == nullptr) ? nullptr : signature->Substitute(checker->Relation(), substitution); } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 3cd2586cc..638eb2909 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2303,21 +2303,23 @@ void ETSChecker::CheckNumberOfTypeArguments(Type *const type, ir::TSTypeParamete ir::TSTypeParameterInstantiation *const type_args, const lexer::SourcePosition &pos) { - if (type_param_decl != nullptr && type_args == nullptr) { - ThrowTypeError({"Type '", type, "' is generic but type argument were not provided."}, pos); - } - - if (type_param_decl == nullptr && type_args != nullptr) { - ThrowTypeError({"Type '", type, "' is not generic."}, pos); + if (type_param_decl == nullptr) { + if (type_args != nullptr) { + ThrowTypeError({"Type '", type, "' is not generic."}, pos); + } else { + return; + } } - if (type_args == nullptr) { - return; - } + size_t minimum_type_args = + std::count_if(type_param_decl->Params().begin(), type_param_decl->Params().end(), + [](ir::TSTypeParameter *param) { return param->DefaultType() == nullptr; }); - ASSERT(type_param_decl != nullptr && type_args != nullptr); - if (type_param_decl->Params().size() != type_args->Params().size()) { - ThrowTypeError({"Type '", type, "' has ", type_param_decl->Params().size(), " number of type parameters, but ", + if (type_args == nullptr && minimum_type_args > 0) { + ThrowTypeError({"Type '", type, "' is generic but type argument were not provided."}, pos); + } else if (type_args != nullptr && ((minimum_type_args > type_args->Params().size()) || + (type_param_decl->Params().size() < type_args->Params().size()))) { + ThrowTypeError({"Type '", type, "' has ", minimum_type_args, " number of type parameters, but ", type_args->Params().size(), " type arguments were provided."}, pos); } diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index 653c615a5..2fd2a784b 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -44,7 +44,7 @@ bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSType { checker_->CheckNumberOfTypeArguments(type, type_param_decl, type_args, pos); - if (type_args == nullptr) { + if (type_param_decl == nullptr) { result_ = type; return true; } @@ -63,23 +63,41 @@ bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSType In this case, we will check "Comparable" with "Char", since "Char" doesn't extends "Comparable", we will get an error here. */ + + ASSERT(type_param_decl != nullptr); + for (size_t type_param_iter = 0; type_param_iter < type_param_decl->Params().size(); ++type_param_iter) { - auto *const type_arg_type = type_args->Params().at(type_param_iter)->GetType(checker_); + Type *type_arg_type; + + if (type_args != nullptr && (type_param_iter < type_args->Params().size())) { + type_arg_type = type_args->Params().at(type_param_iter)->GetType(checker_); + } else { + type_arg_type = + type_param_decl->Params().at(type_param_iter)->DefaultType()->AsETSTypeReference()->GetType(checker_); + } + checker_->CheckValidGenericTypeParameter(type_arg_type, pos); auto *const type_param_type = type->TypeArguments().at(type_param_iter); substitution->emplace(type_param_type, type_arg_type); } for (size_t type_param_iter = 0; type_param_iter < type_param_decl->Params().size(); ++type_param_iter) { - auto *const type_arg_type = type_args->Params().at(type_param_iter)->GetType(checker_); - auto *const type_param_constraint = - type_param_decl->Params().at(type_param_iter)->AsTSTypeParameter()->Constraint(); - if (type_param_constraint == nullptr) { + ir::TSTypeParameter *type_param = type_param_decl->Params().at(type_param_iter)->AsTSTypeParameter(); + Type *type_arg_type; + + if (type_args != nullptr && (type_param_iter < type_args->Params().size())) { + type_arg_type = type_args->Params().at(type_param_iter)->GetType(checker_); + } else { + type_arg_type = + type_param_decl->Params().at(type_param_iter)->DefaultType()->AsETSTypeReference()->GetType(checker_); + } + + if (type_param->Constraint() == nullptr) { continue; } bool assignable = false; - auto *constraint_type = type_param_constraint->GetType(checker_); + auto *constraint_type = type_param->Constraint()->GetType(checker_); if (!constraint_type->AsETSObjectType()->TypeArguments().empty()) { constraint_type = constraint_type->Substitute(checker_->Relation(), substitution); @@ -96,7 +114,7 @@ bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSType }); } - if (!assignable && !checker_->Relation()->NoThrowGenericTypeAlias()) { + if (!assignable && type_args != nullptr && !checker_->Relation()->NoThrowGenericTypeAlias()) { checker_->ThrowTypeError({"Type '", type_arg_type->AsETSObjectType(), "' is not assignable to constraint type '", constraint_type, "'."}, type_args->Params().at(type_param_iter)->Start()); @@ -128,25 +146,31 @@ bool InstantiationContext::ValidateTypeArg(ETSObjectType *constraint_type, ETSOb void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParameterInstantiation *type_args) { ArenaVector type_arg_types(checker_->Allocator()->Adapter()); - type_arg_types.reserve(type_args->Params().size()); + type_arg_types.reserve(type->TypeArguments().size()); auto flags = ETSObjectFlags::NO_OPTS; - for (auto *const it : type_args->Params()) { - auto *param_type = checker_->GetTypeFromTypeAnnotation(it); + if (type_args != nullptr) { + for (auto *const it : type_args->Params()) { + auto *param_type = checker_->GetTypeFromTypeAnnotation(it); - if (param_type->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { - checker_->Relation()->SetNode(it); - auto *const boxed_type_arg = checker_->PrimitiveTypeAsETSBuiltinType(param_type); - ASSERT(boxed_type_arg); - param_type = boxed_type_arg->Instantiate(checker_->Allocator(), checker_->Relation(), - checker_->GetGlobalTypesHolder()); + if (param_type->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { + checker_->Relation()->SetNode(it); + auto *const boxed_type_arg = checker_->PrimitiveTypeAsETSBuiltinType(param_type); + ASSERT(boxed_type_arg); + param_type = boxed_type_arg->Instantiate(checker_->Allocator(), checker_->Relation(), + checker_->GetGlobalTypesHolder()); + } + + type_arg_types.push_back(param_type); } + } - type_arg_types.push_back(param_type); + while (type_arg_types.size() < type->TypeArguments().size()) { + type_arg_types.push_back(type->TypeArguments().at(type_arg_types.size())); } - InstantiateType(type, type_arg_types, type_args->Range().start); + InstantiateType(type, type_arg_types, (type_args == nullptr) ? lexer::SourcePosition() : type_args->Range().start); result_->AddObjectFlag(flags); } @@ -155,8 +179,9 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ArenaVectorGetHashFromTypeArguments(type_arg_types); auto type_params = type->TypeArguments(); - if (type_params.size() != type_arg_types.size()) { - checker_->ThrowTypeError({"Wrong number of type arguments"}, pos); + + while (type_arg_types.size() < type_params.size()) { + type_arg_types.push_back(type_params.at(type_arg_types.size())); } auto *substitution = checker_->NewSubstitution(); diff --git a/ets2panda/ir/ts/tsTypeParameter.h b/ets2panda/ir/ts/tsTypeParameter.h index 3b2cafbbe..3b0699133 100644 --- a/ets2panda/ir/ts/tsTypeParameter.h +++ b/ets2panda/ir/ts/tsTypeParameter.h @@ -57,7 +57,7 @@ public: return constraint_; } - const TypeNode *DefaultType() const + TypeNode *DefaultType() const { return default_type_; } diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index e0bd9d2a6..5cda523fb 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -4217,7 +4217,15 @@ ir::TSTypeParameter *ETSParser::ParseTypeParameter([[maybe_unused]] TypeAnnotati constraint = ParseTypeAnnotation(&new_options); } - auto *type_param = AllocNode(param_ident, constraint, nullptr, variance_modifier); + ir::TypeNode *default_type = nullptr; + + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { + Lexer()->NextToken(); // eat '=' + default_type = ParseTypeAnnotation(options); + } + + auto *type_param = AllocNode(param_ident, constraint, default_type, variance_modifier); + type_param->SetRange({start_loc, Lexer()->GetToken().End()}); return type_param; } diff --git a/ets2panda/test/parser/ets/genericDefaultParam_1-expected.txt b/ets2panda/test/parser/ets/genericDefaultParam_1-expected.txt new file mode 100644 index 000000000..09b1fbae7 --- /dev/null +++ b/ets2panda/test/parser/ets/genericDefaultParam_1-expected.txt @@ -0,0 +1,3391 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "SomeType", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 7 + }, + "end": { + "line": 24, + "column": 15 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 24, + "column": 18 + }, + "end": { + "line": 24, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 16 + }, + "end": { + "line": 24, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 1 + }, + "end": { + "line": 24, + "column": 18 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [], + "loc": { + "start": { + "line": 25, + "column": 37 + }, + "end": { + "line": 25, + "column": 40 + } + } + }, + "id": { + "type": "Identifier", + "name": "Interface", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 11 + }, + "end": { + "line": 25, + "column": 20 + } + } + }, + "extends": [], + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T1", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 22 + }, + "end": { + "line": 25, + "column": 24 + } + } + }, + "default": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "SomeType", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 27 + }, + "end": { + "line": 25, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 27 + }, + "end": { + "line": 25, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 27 + }, + "end": { + "line": 25, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 22 + }, + "end": { + "line": 25, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 21 + }, + "end": { + "line": 25, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 1 + }, + "end": { + "line": 26, + "column": 6 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Base", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 26, + "column": 11 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T2", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 13 + }, + "end": { + "line": 26, + "column": 15 + } + } + }, + "default": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "SomeType", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 18 + }, + "end": { + "line": 26, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 18 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 18 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 13 + }, + "end": { + "line": 26, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 12 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 26, + "column": 31 + }, + "end": { + "line": 26, + "column": 31 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 28 + }, + "end": { + "line": 26, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1 + }, + "end": { + "line": 26, + "column": 31 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Derived1", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 7 + }, + "end": { + "line": 27, + "column": 15 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Base", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 24 + }, + "end": { + "line": 27, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 24 + }, + "end": { + "line": 27, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 24 + }, + "end": { + "line": 27, + "column": 39 + } + } + }, + "implements": [ + { + "type": "TSClassImplements", + "expression": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Interface", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 40 + }, + "end": { + "line": 27, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 40 + }, + "end": { + "line": 27, + "column": 51 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 40 + }, + "end": { + "line": 27, + "column": 51 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 40 + }, + "end": { + "line": 27, + "column": 51 + } + } + } + ], + "body": [ + { + "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": 27, + "column": 53 + }, + "end": { + "line": 27, + "column": 53 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 50 + }, + "end": { + "line": 27, + "column": 53 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 1 + }, + "end": { + "line": 27, + "column": 53 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Derived2", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 7 + }, + "end": { + "line": 28, + "column": 15 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Base", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 24 + }, + "end": { + "line": 28, + "column": 28 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "SomeType", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 29 + }, + "end": { + "line": 28, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 29 + }, + "end": { + "line": 28, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 29 + }, + "end": { + "line": 28, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 28, + "column": 28 + }, + "end": { + "line": 28, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 24 + }, + "end": { + "line": 28, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 24 + }, + "end": { + "line": 28, + "column": 49 + } + } + }, + "implements": [ + { + "type": "TSClassImplements", + "expression": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Interface", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 50 + }, + "end": { + "line": 28, + "column": 59 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "SomeType", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 60 + }, + "end": { + "line": 28, + "column": 68 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 60 + }, + "end": { + "line": 28, + "column": 69 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 60 + }, + "end": { + "line": 28, + "column": 69 + } + } + } + ], + "loc": { + "start": { + "line": 28, + "column": 59 + }, + "end": { + "line": 28, + "column": 69 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 50 + }, + "end": { + "line": 28, + "column": 71 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 50 + }, + "end": { + "line": 28, + "column": 71 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 50 + }, + "end": { + "line": 28, + "column": 71 + } + } + } + ], + "body": [ + { + "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": 73 + }, + "end": { + "line": 28, + "column": 73 + } + } + } + ], + "loc": { + "start": { + "line": 28, + "column": 70 + }, + "end": { + "line": 28, + "column": 73 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 1 + }, + "end": { + "line": 28, + "column": 73 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "C2", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 7 + }, + "end": { + "line": 30, + "column": 9 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T1", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 11 + }, + "end": { + "line": 30, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 11 + }, + "end": { + "line": 30, + "column": 14 + } + } + }, + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T2", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 15 + }, + "end": { + "line": 30, + "column": 17 + } + } + }, + "default": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "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": 15 + }, + "end": { + "line": 30, + "column": 27 + } + } + }, + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T3", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 28 + }, + "end": { + "line": 30, + "column": 30 + } + } + }, + "default": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 33 + }, + "end": { + "line": 30, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 33 + }, + "end": { + "line": 30, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 33 + }, + "end": { + "line": 30, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 28 + }, + "end": { + "line": 30, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 10 + }, + "end": { + "line": 30, + "column": 40 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "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": 30, + "column": 43 + }, + "end": { + "line": 30, + "column": 43 + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 41 + }, + "end": { + "line": 30, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 43 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "alma", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 5 + } + } + }, + "arguments": [ + { + "type": "TSAsExpression", + "expression": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 20, + "column": 6 + }, + "end": { + "line": 20, + "column": 7 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 11 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 11 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 11 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 6 + }, + "end": { + "line": 20, + "column": 7 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "alma", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 21, + "column": 5 + } + } + }, + "arguments": [ + { + "type": "TSAsExpression", + "expression": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 15 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 21, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 21, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 14 + }, + "end": { + "line": 21, + "column": 15 + } + } + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 6 + }, + "end": { + "line": 21, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 6 + }, + "end": { + "line": 21, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 6 + }, + "end": { + "line": 21, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 21, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 21, + "column": 26 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "alma", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 22, + "column": 5 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "alma", + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 22, + "column": 20 + } + } + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 6 + }, + "end": { + "line": 22, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 6 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 6 + }, + "end": { + "line": 22, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 22, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 22, + "column": 21 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "c1", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 5 + }, + "end": { + "line": 31, + "column": 7 + } + } + }, + "right": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C2", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 31, + "column": 16 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 17 + }, + "end": { + "line": 31, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 17 + }, + "end": { + "line": 31, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 17 + }, + "end": { + "line": 31, + "column": 24 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 16 + }, + "end": { + "line": 31, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 31, + "column": 10 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 5 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "c2", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 5 + }, + "end": { + "line": 32, + "column": 7 + } + } + }, + "right": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C2", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 14 + }, + "end": { + "line": 32, + "column": 16 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 24 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 25 + }, + "end": { + "line": 32, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 25 + }, + "end": { + "line": 32, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 25 + }, + "end": { + "line": 32, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 32, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 14 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 14 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 32, + "column": 10 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 5 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "c3", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 5 + }, + "end": { + "line": 33, + "column": 7 + } + } + }, + "right": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C2", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 14 + }, + "end": { + "line": 33, + "column": 16 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 24 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 25 + }, + "end": { + "line": 33, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 25 + }, + "end": { + "line": 33, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 25 + }, + "end": { + "line": 33, + "column": 32 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 33 + }, + "end": { + "line": 33, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 33 + }, + "end": { + "line": 33, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 33 + }, + "end": { + "line": 33, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 33, + "column": 16 + }, + "end": { + "line": 33, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 14 + }, + "end": { + "line": 34, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 14 + }, + "end": { + "line": 34, + "column": 1 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 33, + "column": 10 + }, + "end": { + "line": 34, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 5 + }, + "end": { + "line": 34, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 1 + }, + "end": { + "line": 34, + "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": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "alma", + "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": "alma", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "param", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 37 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 42 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "default": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 26 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 26 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "param", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 41 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "c1", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 5 + }, + "end": { + "line": 31, + "column": 7 + } + } + }, + "value": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C2", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 31, + "column": 16 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 17 + }, + "end": { + "line": 31, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 17 + }, + "end": { + "line": 31, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 17 + }, + "end": { + "line": 31, + "column": 24 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 16 + }, + "end": { + "line": 31, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 14 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 31, + "column": 10 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 5 + }, + "end": { + "line": 32, + "column": 4 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "c2", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 5 + }, + "end": { + "line": 32, + "column": 7 + } + } + }, + "value": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C2", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 14 + }, + "end": { + "line": 32, + "column": 16 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 17 + }, + "end": { + "line": 32, + "column": 24 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 25 + }, + "end": { + "line": 32, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 25 + }, + "end": { + "line": 32, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 25 + }, + "end": { + "line": 32, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 32, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 14 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 14 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 32, + "column": 10 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 5 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "c3", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 5 + }, + "end": { + "line": 33, + "column": 7 + } + } + }, + "value": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C2", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 14 + }, + "end": { + "line": 33, + "column": 16 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 17 + }, + "end": { + "line": 33, + "column": 24 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 25 + }, + "end": { + "line": 33, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 25 + }, + "end": { + "line": 33, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 25 + }, + "end": { + "line": 33, + "column": 32 + } + } + }, + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 33 + }, + "end": { + "line": 33, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 33 + }, + "end": { + "line": 33, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 33 + }, + "end": { + "line": 33, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 33, + "column": 16 + }, + "end": { + "line": 33, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 14 + }, + "end": { + "line": 34, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 33, + "column": 14 + }, + "end": { + "line": 34, + "column": 1 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 33, + "column": 10 + }, + "end": { + "line": 34, + "column": 1 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 33, + "column": 5 + }, + "end": { + "line": 34, + "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": 34, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/genericDefaultParam_1.ets b/ets2panda/test/parser/ets/genericDefaultParam_1.ets new file mode 100644 index 000000000..366de812f --- /dev/null +++ b/ets2panda/test/parser/ets/genericDefaultParam_1.ets @@ -0,0 +1,33 @@ +/* + * 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 alma(param : T): T { + return param +} + +alma(1 as number) +alma(1 as number) +alma("alma") + +class SomeType {} +interface Interface { } +class Base { } +class Derived1 extends Base implements Interface { } +class Derived2 extends Base implements Interface { } + +class C2 {} +let c1 = new C2 +let c2 = new C2 +let c3 = new C2 diff --git a/ets2panda/test/parser/ets/genericDefaultParam_2-expected.txt b/ets2panda/test/parser/ets/genericDefaultParam_2-expected.txt new file mode 100644 index 000000000..39b694610 --- /dev/null +++ b/ets2panda/test/parser/ets/genericDefaultParam_2-expected.txt @@ -0,0 +1 @@ +SyntaxError: Required type parameters may not follow optional type parameters. [genericDefaultParam_2.ets:16:30] diff --git a/ets2panda/test/parser/ets/genericDefaultParam_2.ets b/ets2panda/test/parser/ets/genericDefaultParam_2.ets new file mode 100644 index 000000000..a82f70029 --- /dev/null +++ b/ets2panda/test/parser/ets/genericDefaultParam_2.ets @@ -0,0 +1,16 @@ +/* + * 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 C1 {} diff --git a/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt b/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt new file mode 100644 index 000000000..8652bd2ed --- /dev/null +++ b/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt @@ -0,0 +1,531 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "alma", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 5 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "alma", + "loc": { + "start": { + "line": 20, + "column": 6 + }, + "end": { + "line": 20, + "column": 12 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 13 + } + } + } + ], + "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": "alma", + "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": "alma", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "param", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 37 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 42 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 16 + } + } + }, + "default": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 26 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 26 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "param", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 41 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "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": 21, + "column": 1 + } + } +} +TypeError: Call argument at index 0 is not compatible with the signature's type at that index. [genericDefaultParam_3.ets:20:6] diff --git a/ets2panda/test/parser/ets/genericDefaultParam_3.ets b/ets2panda/test/parser/ets/genericDefaultParam_3.ets new file mode 100644 index 000000000..2f74b05ce --- /dev/null +++ b/ets2panda/test/parser/ets/genericDefaultParam_3.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 alma(param : T): T { + return param +} + +alma("alma") -- Gitee From a1cc9bb22c8cea2e6967d3f3d2d18196609ac589 Mon Sep 17 00:00:00 2001 From: Vsevolod Pukhov Date: Mon, 25 Dec 2023 21:45:34 +0300 Subject: [PATCH 34/35] Disable failing devbranch parser tests Signed-off-by: Vsevolod Pukhov --- ets2panda/test/test-lists/parser/parser-js-ignored.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ets2panda/test/test-lists/parser/parser-js-ignored.txt b/ets2panda/test/test-lists/parser/parser-js-ignored.txt index 0c171f3c3..6d530536f 100644 --- a/ets2panda/test/test-lists/parser/parser-js-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-js-ignored.txt @@ -1,5 +1,9 @@ # FIXME(igelhaus): Temporarily skipped for dev branch stabilization parser/ets/literals.ets +parser/ets/declare_iface.ets +parser/ets/interfaces.ets +parser/ets/lambda_import_alias_1.ets +parser/ets/test_interface.ets parser/ets/import_tests/modules/module.ets parser/ets/import_tests/import_class_members_1.ets -- Gitee From a8457b535bf62d0d39029b2da36cafbcd44545de Mon Sep 17 00:00:00 2001 From: Vsevolod Pukhov Date: Fri, 8 Dec 2023 19:15:46 +0300 Subject: [PATCH 35/35] Implement ETSTypeParameter type, reimplement unchecked casts * Extract ETSTypeParameter from ETSObject type code * Implement unchecked casts on top of type relations, add constrained type parameters runtime check * Make ETSUnionType contents immutable * Allow arbitrary constraints, refactor default parameter type Signed-off-by: Vsevolod Pukhov --- ets2panda/checker/ETSAnalyzer.cpp | 37 ++-- ets2panda/checker/ETSchecker.cpp | 5 + ets2panda/checker/ETSchecker.h | 42 ++-- ets2panda/checker/ets/arithmetic.cpp | 9 +- ets2panda/checker/ets/function.cpp | 162 +++++++++------- ets2panda/checker/ets/function_helpers.h | 66 +++---- ets2panda/checker/ets/helpers.cpp | 154 ++++++++++++--- ets2panda/checker/ets/object.cpp | 112 +++++------ ets2panda/checker/ets/typeCreation.cpp | 16 +- ets2panda/checker/ets/typeRelationContext.cpp | 124 +++++------- ets2panda/checker/ets/typeRelationContext.h | 18 +- ets2panda/checker/types/ets/etsArrayType.cpp | 13 +- .../checker/types/ets/etsFunctionType.cpp | 8 +- ets2panda/checker/types/ets/etsObjectType.cpp | 44 ++--- ets2panda/checker/types/ets/etsObjectType.h | 14 +- .../checker/types/ets/etsTypeParameter.cpp | 163 +++++++++++++++- .../checker/types/ets/etsTypeParameter.h | 63 ++++-- ets2panda/checker/types/ets/etsUnionType.cpp | 96 +++++---- ets2panda/checker/types/ets/etsUnionType.h | 52 +---- ets2panda/checker/types/globalTypesHolder.cpp | 5 + ets2panda/checker/types/globalTypesHolder.h | 2 + ets2panda/checker/types/signature.cpp | 17 +- ets2panda/checker/types/signature.h | 7 +- ets2panda/checker/types/type.h | 3 +- ets2panda/checker/types/typeFlag.h | 2 +- ets2panda/checker/types/typeRelation.h | 3 +- ets2panda/compiler/base/lreference.cpp | 4 - ets2panda/compiler/core/ETSCompiler.cpp | 21 +- ets2panda/compiler/core/ETSGen.cpp | 183 +++++++++--------- ets2panda/compiler/core/ETSGen.h | 26 +-- ets2panda/ir/expressions/callExpression.h | 11 ++ ets2panda/ir/expressions/memberExpression.cpp | 39 +--- ets2panda/ir/expressions/memberExpression.h | 9 +- .../ets/generic_arrayaslist-expected.txt | 168 +++++++++++++--- .../test/compiler/ets/generic_arrayaslist.ets | 2 +- .../generics_implicit_lambda2-expected.txt | 2 +- .../ets/generics_instantiation_3-expected.txt | 47 ++++- .../compiler/ets/generics_instantiation_3.ets | 2 +- .../ets/genericDefaultParam_3-expected.txt | 1 - ets2panda/test/runtime/ets/UncheckedCasts.ets | 78 ++++++++ .../test/runtime/ets/UnionConstraint.ets | 31 +++ .../test/runtime/ets/generic-function.ets | 2 +- .../test-lists/parser/parser-js-ignored.txt | 3 + ets2panda/util/declgenEts2Ts.cpp | 9 + ets2panda/util/declgenEts2Ts.h | 1 + 45 files changed, 1181 insertions(+), 695 deletions(-) create mode 100644 ets2panda/test/runtime/ets/UncheckedCasts.ets create mode 100644 ets2panda/test/runtime/ets/UnionConstraint.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index f77074d52..77b730202 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -166,7 +166,7 @@ static void CheckExtensionIsShadowedByMethod(checker::ETSChecker *checker, check static void CheckExtensionMethod(checker::ETSChecker *checker, ir::ScriptFunction *extension_func, ir::MethodDefinition *node) { - auto *const class_type = extension_func->Signature()->Params()[0]->TsType(); + auto *const class_type = ETSChecker::GetApparentType(extension_func->Signature()->Params()[0]->TsType()); if (!class_type->IsETSObjectType() || (!class_type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::CLASS) && !class_type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::INTERFACE))) { @@ -493,7 +493,8 @@ checker::Type *ETSAnalyzer::Check(ir::ETSLaunchExpression *expr) const : expr->expr_->TsType(); checker::Substitution *substitution = checker->NewSubstitution(); ASSERT(launch_promise_type->TypeArguments().size() == 1); - substitution->emplace(checker->GetOriginalBaseType(launch_promise_type->TypeArguments()[0]), expr_type); + checker::ETSChecker::EmplaceSubstituted( + substitution, launch_promise_type->TypeArguments()[0]->AsETSTypeParameter()->GetOriginal(), expr_type); expr->SetTsType(launch_promise_type->Substitute(checker->Relation(), substitution)); return expr->TsType(); @@ -891,7 +892,7 @@ checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const return expr->TsType(); } - checker::Type *arg_type = expr->argument_->Check(checker); + checker::Type *arg_type = ETSChecker::GetApparentType(expr->argument_->Check(checker)); // Check the argument type of await expression if (!arg_type->IsETSObjectType() || (arg_type->AsETSObjectType()->AssemblerName() != compiler::Signatures::BUILTIN_PROMISE)) { @@ -1080,7 +1081,7 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const return expr->TsType(); } auto *old_callee = expr->Callee(); - checker::Type *callee_type = expr->Callee()->Check(checker); + checker::Type *callee_type = ETSChecker::GetApparentType(expr->Callee()->Check(checker)); if (expr->Callee() != old_callee) { // If it is a static invoke, the callee will be transformed from an identifier to a member expression // Type check the callee again for member expression @@ -1109,6 +1110,7 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const if (expr->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) { expr->Signature()->OwnerVar()->Declaration()->Node()->Check(checker); return_type = expr->Signature()->ReturnType(); + // NOTE(vpukhov): #14902 substituted signature is not updated } expr->SetOptionalType(return_type); if (expr->IsOptional() && callee_type->IsNullishOrNullLike()) { @@ -1117,6 +1119,7 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const checker->Relation()->SetNode(nullptr); } expr->SetTsType(return_type); + expr->SetUncheckedType(checker->GuaranteedTypeForUncheckedCallReturn(expr->Signature())); return expr->TsType(); } @@ -1167,7 +1170,7 @@ checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const } } else { if (!(consequent_type->IsETSArrayType() || alternate_type->IsETSArrayType()) && - !(consequent_type->IsETSObjectType() && alternate_type->IsETSObjectType())) { + !(checker->IsReferenceType(consequent_type) && checker->IsReferenceType(alternate_type))) { checker->ThrowTypeError("Type error", expr->Range().start); } else { checker->Relation()->SetNode(expr->consequent_); @@ -1222,7 +1225,7 @@ checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const return expr->TsType(); } - auto *const left_type = expr->Object()->Check(checker); + auto *const left_type = checker->GetApparentType(expr->Object()->Check(checker)); if (expr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS) { if (expr->IsOptional() && !left_type->IsNullish()) { @@ -1242,28 +1245,28 @@ checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const } if (expr->IsComputed()) { - return expr->AdjustOptional(checker, expr->CheckComputed(checker, base_type)); + return expr->AdjustType(checker, expr->CheckComputed(checker, base_type)); } if (base_type->IsETSArrayType() && expr->Property()->AsIdentifier()->Name().Is("length")) { - return expr->AdjustOptional(checker, checker->GlobalIntType()); + return expr->AdjustType(checker, checker->GlobalIntType()); } if (base_type->IsETSObjectType()) { expr->SetObjectType(base_type->AsETSObjectType()); auto [res_type, res_var] = expr->ResolveObjectMember(checker); expr->SetPropVar(res_var); - return expr->AdjustOptional(checker, res_type); + return expr->AdjustType(checker, res_type); } if (base_type->IsETSEnumType() || base_type->IsETSStringEnumType()) { auto [member_type, member_var] = expr->ResolveEnumMember(checker, base_type); expr->SetPropVar(member_var); - return expr->AdjustOptional(checker, member_type); + return expr->AdjustType(checker, member_type); } if (base_type->IsETSUnionType()) { - return expr->AdjustOptional(checker, expr->CheckUnionMember(checker, base_type)); + return expr->AdjustType(checker, expr->CheckUnionMember(checker, base_type)); } if (base_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { @@ -1272,7 +1275,7 @@ checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const checker->AddBoxingUnboxingFlagsToNode(expr, expr->ObjType()); auto [res_type, res_var] = expr->ResolveObjectMember(checker); expr->SetPropVar(res_var); - return expr->AdjustOptional(checker, res_type); + return expr->AdjustType(checker, res_type); } checker->ThrowTypeError({"Cannot access property of non-object or non-enum type"}, expr->Object()->Start()); @@ -2404,7 +2407,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const auto *const source_type = expr->Expr()->Check(checker); if (target_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE) && - source_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + source_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::TYPE_PARAMETER)) { auto *const boxed_target_type = checker->PrimitiveTypeAsETSBuiltinType(target_type); if (!checker->Relation()->IsIdenticalTo(source_type, boxed_target_type)) { expr->Expr()->AddAstNodeFlags(ir::AstNodeFlags::CHECKCAST); @@ -2593,7 +2596,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const ETSChecker *checker = GetETSChecker(); auto expr_type = expr->expr_->Check(checker); - if (!expr_type->IsNullish()) { + if (!checker->MayHaveNulllikeValue(expr_type)) { checker->ThrowTypeError("Bad operand type, the operand of the non-null expression must be a nullable type", expr->Expr()->Start()); } @@ -2662,7 +2665,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const { ETSChecker *checker = GetETSChecker(); if (st->TypeParams() != nullptr) { - for (const auto *const param : st->TypeParams()->Params()) { + for (auto *const param : st->TypeParams()->Params()) { const auto *const res = st->TypeAnnotation()->FindChild([¶m](const ir::AstNode *const node) { if (!node->IsIdentifier()) { return false; @@ -2677,9 +2680,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const param->Start()); } - param->Name()->Variable()->SetTsType( - checker->CreateNullishType(checker->GlobalETSObjectType(), checker::TypeFlag::NULLISH, - checker->Allocator(), checker->Relation(), checker->GetGlobalTypesHolder())); + checker->SetUpParameterType(param); } } diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index f0d1674da..86acb390a 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -236,6 +236,11 @@ ETSObjectType *ETSChecker::GlobalETSObjectType() const return AsETSObjectType(&GlobalTypesHolder::GlobalETSObjectType); } +ETSObjectType *ETSChecker::GlobalETSNullishObjectType() const +{ + return AsETSObjectType(&GlobalTypesHolder::GlobalETSNullishObjectType); +} + ETSObjectType *ETSChecker::GlobalBuiltinETSStringType() const { return AsETSObjectType(&GlobalTypesHolder::GlobalETSStringBuiltinType); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 3ad9d45a1..2aa936c20 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -101,6 +101,7 @@ public: Type *GlobalWildcardType() const; ETSObjectType *GlobalETSObjectType() const; + ETSObjectType *GlobalETSNullishObjectType() const; ETSObjectType *GlobalBuiltinETSStringType() const; ETSObjectType *GlobalBuiltinTypeType() const; ETSObjectType *GlobalBuiltinExceptionType() const; @@ -125,6 +126,9 @@ public: Type *CheckTypeCached(ir::Expression *expr) override; void ResolveStructuredTypeMembers([[maybe_unused]] Type *type) override {} Type *GetTypeOfVariable([[maybe_unused]] varbinder::Variable *var) override; + Type *GuaranteedTypeForUncheckedCast(Type *base, Type *substituted); + Type *GuaranteedTypeForUncheckedCallReturn(Signature *sig); + Type *GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable *prop); bool IsETSChecker() override { return true; @@ -146,7 +150,7 @@ public: 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); - void SetTypeParameterType(ir::TSTypeParameter *type_param, Type *type_param_type); + ETSTypeParameter *SetUpParameterType(ir::TSTypeParameter *param); void ValidateOverriding(ETSObjectType *class_type, const lexer::SourcePosition &pos); void AddImplementedSignature(std::vector *implemented_signatures, varbinder::LocalVariable *function, ETSFunctionType *it); @@ -171,6 +175,8 @@ public: void CheckGetterSetterProperties(ETSObjectType *class_type); void AddElementsToModuleObject(ETSObjectType *module_obj, const util::StringView &str); Type *FindLeastUpperBound(Type *source, Type *target); + static Type *GetApparentType(Type *type); + static Type const *GetApparentType(Type const *type); Type *GetCommonClass(Type *source, Type *target); ETSObjectType *GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target); ETSObjectType *GetTypeargumentedLUB(ETSObjectType *source, ETSObjectType *target); @@ -194,7 +200,7 @@ public: ETSFunctionType *CreateETSFunctionType(ArenaVector &signatures); ETSExtensionFuncHelperType *CreateETSExtensionFuncHelperType(ETSFunctionType *class_method_type, ETSFunctionType *extension_function_type); - ETSTypeParameter *CreateTypeParameter(Type *assembler_type); + ETSTypeParameter *CreateTypeParameter(); ETSObjectType *CreateETSObjectType(util::StringView name, ir::AstNode *decl_node, ETSObjectFlags flags); ETSEnumType *CreateETSEnumType(ir::TSEnumDeclaration const *enum_decl); ETSStringEnumType *CreateETSStringEnumType(ir::TSEnumDeclaration const *enum_decl); @@ -264,7 +270,7 @@ public: bool TypeInference(Signature *signature, const ArenaVector &arguments, TypeRelationFlag flags = TypeRelationFlag::NONE); bool CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction *lambda); - bool IsCompatibleTypeArgument(Type *type_param, Type *type_argument, const Substitution *substitution); + bool IsCompatibleTypeArgument(ETSTypeParameter *type_param, Type *type_argument, const Substitution *substitution); Substitution *NewSubstitution() { return Allocator()->New(Allocator()->Adapter()); @@ -273,13 +279,17 @@ public: { return Allocator()->New(*src); } - ArenaUnorderedSet *NewInstantiatedTypeParamsSet() + static void EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *type_arg); + ArenaUnorderedSet *NewInstantiatedTypeParamsSet() { - return Allocator()->New>(Allocator()->Adapter()); + return Allocator()->New>(Allocator()->Adapter()); } - void EnhanceSubstitutionForType(const ArenaVector &type_params, Type *param_type, Type *argument_type, - Substitution *substitution, - ArenaUnorderedSet *instantiated_type_params); + [[nodiscard]] bool EnhanceSubstitutionForType(const ArenaVector &type_params, Type *param_type, + Type *argument_type, Substitution *substitution, + ArenaUnorderedSet *instantiated_type_params); + [[nodiscard]] bool EnhanceSubstitutionForObject(const ArenaVector &type_params, ETSObjectType *param_type, + Type *argument_type, Substitution *substitution, + ArenaUnorderedSet *instantiated_type_params); Signature *ValidateParameterlessConstructor(Signature *signature, const lexer::SourcePosition &pos, TypeRelationFlag flags); Signature *CollectParameterlessConstructor(ArenaVector &signatures, const lexer::SourcePosition &pos, @@ -440,6 +450,9 @@ public: Type *CreateOptionalResultType(Type *type); Type *GetNonNullishType(Type *type) const; const Type *GetNonNullishType(const Type *type) const; + bool MayHaveNullValue(const Type *type) const; + bool MayHaveUndefinedValue(const Type *type) const; + bool MayHaveNulllikeValue(const Type *type) const; void ConcatConstantString(util::UString &target, Type *type); Type *HandleStringConcatenation(Type *left_type, Type *right_type); Type *ResolveIdentifier(ir::Identifier *ident); @@ -452,7 +465,7 @@ public: bool IsFunctionContainsSignature(ETSFunctionType *func_type, Signature *signature); void CheckFunctionContainsClashingSignature(const ETSFunctionType *func_type, Signature *signature); bool IsTypeBuiltinType(Type *type); - bool IsReferenceType(const Type *type); + static bool IsReferenceType(const Type *type); const ir::AstNode *FindJumpTarget(ir::AstNodeType node_type, const ir::AstNode *node, const ir::Identifier *target); void ValidatePropertyAccess(varbinder::Variable *var, ETSObjectType *obj, const lexer::SourcePosition &pos); varbinder::VariableFlags GetAccessFlagFromNode(const ir::AstNode *node); @@ -479,8 +492,8 @@ public: util::StringView name, const ETSObjectType *class_type); varbinder::Variable *FindVariableInGlobal(const ir::Identifier *identifier); void ValidateResolvedIdentifier(ir::Identifier *ident, varbinder::Variable *resolved); - bool IsVariableStatic(const varbinder::Variable *var) const; - bool IsVariableGetterSetter(const varbinder::Variable *var) const; + static bool IsVariableStatic(const varbinder::Variable *var); + static bool IsVariableGetterSetter(const varbinder::Variable *var); bool IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare); void SaveCapturedVariable(varbinder::Variable *var, const lexer::SourcePosition &pos); void AddBoxingFlagToPrimitiveType(TypeRelation *relation, Type *target); @@ -496,8 +509,8 @@ public: bool CheckRethrowingParams(const ir::AstNode *ancestor_function, const ir::AstNode *node); void CheckThrowingStatements(ir::AstNode *node); bool CheckThrowingPlacement(ir::AstNode *node, const ir::AstNode *ancestor_function); - void CheckNumberOfTypeArguments(Type *type, ir::TSTypeParameterDeclaration *type_param_decl, - ir::TSTypeParameterInstantiation *type_args, const lexer::SourcePosition &pos); + void CheckNumberOfTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *type_args, + const lexer::SourcePosition &pos); ir::BlockStatement *FindFinalizerOfTryStatement(ir::AstNode *start_from, const ir::AstNode *p); void CheckRethrowingFunction(ir::ScriptFunction *func); ETSObjectType *GetRelevantArgumentedTypeFromChild(ETSObjectType *child, ETSObjectType *target); @@ -624,13 +637,10 @@ private: ArenaVector CreateTypeForTypeParameters(ir::TSTypeParameterDeclaration *type_params); - Type *CreateTypeParameterType(ir::TSTypeParameter *param); - using Type2TypeMap = std::unordered_map; void CheckTypeParameterConstraint(ir::TSTypeParameter *param, Type2TypeMap &extends); void SetUpTypeParameterConstraint(ir::TSTypeParameter *param); - ETSObjectType *SetUpParameterType(ir::TSTypeParameter *param); ETSObjectType *CreateETSObjectTypeCheckBuiltins(util::StringView name, ir::AstNode *decl_node, ETSObjectFlags flags); void CheckProgram(parser::Program *program, bool run_analysis = false); diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index decbb3b61..fe8d0cd47 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -381,11 +381,9 @@ std::tuple ETSChecker::CheckBinaryOperatorEqualDynamic(ir::Expre // NOTE: vpukhov. boxing flags are not set in dynamic values return {GlobalETSBooleanType(), other_exp->TsType()}; } - if (other_exp->TsType()->IsETSObjectType()) { + if (IsReferenceType(other_exp->TsType())) { // have to prevent casting dyn_exp via ApplyCast without nullish flag - auto *nullish_obj = CreateNullishType(GlobalETSObjectType(), checker::TypeFlag::NULLISH, Allocator(), - Relation(), GetGlobalTypesHolder()); - return {GlobalETSBooleanType(), nullish_obj}; + return {GlobalETSBooleanType(), GlobalETSNullishObjectType()}; } ThrowTypeError("Unimplemented case in dynamic type comparison.", pos); } @@ -436,8 +434,7 @@ std::tuple ETSChecker::CheckBinaryOperatorInstanceOf(lexer::Sour checker::Type *const right_type) { checker::Type *ts_type {}; - if (!left_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION) || - !right_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (!IsReferenceType(left_type) || !IsReferenceType(right_type)) { ThrowTypeError("Bad operand type, the types of the operands must be same type.", pos); } diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 300836668..df0aa92e8 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -67,93 +67,111 @@ namespace panda::es2panda::checker { -bool ETSChecker::IsCompatibleTypeArgument(Type *type_param, Type *type_argument, const Substitution *substitution) +bool ETSChecker::IsCompatibleTypeArgument(ETSTypeParameter *type_param, Type *type_argument, + const Substitution *substitution) { - ASSERT(type_param->IsETSObjectType() && - type_param->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::TYPE_PARAMETER)); if (type_argument->IsWildcardType()) { return true; } - if (!type_argument->IsETSObjectType() && !type_argument->IsETSArrayType() && !type_argument->IsETSFunctionType()) { + if (!type_argument->IsETSTypeParameter() && !IsReferenceType(type_argument)) { return false; } - auto *type_param_obj = type_param->AsETSObjectType(); - auto *type_param_obj_supertype = type_param_obj->SuperType(); - if (type_param_obj_supertype != nullptr) { - if (!type_param_obj_supertype->TypeArguments().empty()) { - type_param_obj_supertype = - type_param_obj_supertype->Substitute(this->Relation(), substitution)->AsETSObjectType(); - } - type_param_obj_supertype->IsSupertypeOf(Relation(), type_argument); - if (!Relation()->IsTrue()) { - return false; - } + if (type_argument->IsETSUnionType()) { + auto const &constitutent = type_argument->AsETSUnionType()->ConstituentTypes(); + return std::all_of(constitutent.begin(), constitutent.end(), [this, type_param, substitution](Type *type_arg) { + return IsCompatibleTypeArgument(type_param->AsETSTypeParameter(), type_arg, substitution); + }); } - for (auto *itf : type_param_obj->Interfaces()) { - if (!itf->TypeArguments().empty()) { - itf = itf->Substitute(this->Relation(), substitution)->AsETSObjectType(); - } - itf->IsSupertypeOf(Relation(), type_argument); + + if (auto *constraint = type_param->GetConstraintType(); constraint != nullptr) { + constraint = constraint->Substitute(Relation(), substitution); + constraint->IsSupertypeOf(Relation(), type_argument); if (!Relation()->IsTrue()) { return false; } } - return true; } /* A very rough and imprecise partial type inference */ -void ETSChecker::EnhanceSubstitutionForType(const ArenaVector &type_params, Type *param_type, +bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &type_params, Type *param_type, Type *argument_type, Substitution *substitution, - ArenaUnorderedSet *instantiated_type_params) -{ - if (!param_type->IsETSObjectType()) { - return; - } - auto *param_obj_type = param_type->AsETSObjectType(); - if (param_obj_type->HasObjectFlag(ETSObjectFlags::TYPE_PARAMETER)) { - auto *param_base = GetOriginalBaseType(param_obj_type); - if (instantiated_type_params->find(param_obj_type) != instantiated_type_params->end() && - substitution->at(param_base) != argument_type) { - ThrowTypeError({"Type parameter already instantiated with another type "}, - param_obj_type->GetDeclNode()->Start()); - } - if (std::find(type_params.begin(), type_params.end(), param_base) != type_params.end() && - substitution->count(param_base) == 0) { - substitution->emplace(param_base, argument_type); - instantiated_type_params->insert(param_obj_type); - return; + ArenaUnorderedSet *instantiated_type_params) +{ + if (param_type->IsETSTypeParameter()) { + auto *const tparam = param_type->AsETSTypeParameter(); + auto *const original_tparam = tparam->GetOriginal(); + if (instantiated_type_params->find(tparam) != instantiated_type_params->end() && + substitution->at(original_tparam) != argument_type) { + ThrowTypeError({"Type parameter already instantiated with another type "}, tparam->GetDeclNode()->Start()); + } + if (std::find(type_params.begin(), type_params.end(), original_tparam) != type_params.end() && + substitution->count(original_tparam) == 0) { + if (!IsCompatibleTypeArgument(tparam, argument_type, substitution)) { + return false; + } + ETSChecker::EmplaceSubstituted(substitution, original_tparam, argument_type); + instantiated_type_params->insert(tparam); + return true; } } + + if (param_type->IsETSUnionType()) { + auto const &constitutent = param_type->AsETSUnionType()->ConstituentTypes(); + return std::all_of(constitutent.begin(), constitutent.end(), + [this, type_params, argument_type, substitution, instantiated_type_params](Type *member) { + return EnhanceSubstitutionForType(type_params, member, argument_type, substitution, + instantiated_type_params); + }); + } + + if (param_type->IsETSObjectType()) { + return EnhanceSubstitutionForObject(type_params, param_type->AsETSObjectType(), argument_type, substitution, + instantiated_type_params); + } + return true; +} + +bool ETSChecker::EnhanceSubstitutionForObject(const ArenaVector &type_params, ETSObjectType *param_type, + Type *argument_type, Substitution *substitution, + ArenaUnorderedSet *instantiated_type_params) +{ + auto *param_obj_type = param_type->AsETSObjectType(); + + auto const enhance = [this, type_params, substitution, instantiated_type_params](Type *ptype, Type *atype) { + return EnhanceSubstitutionForType(type_params, ptype, atype, substitution, instantiated_type_params); + }; + if (argument_type->IsETSObjectType()) { auto *arg_obj_type = argument_type->AsETSObjectType(); if (GetOriginalBaseType(arg_obj_type) != GetOriginalBaseType(param_obj_type)) { - return; // don't attempt anything fancy for now + return true; // don't attempt anything fancy for now } - ASSERT(arg_obj_type->TypeArguments().size() == param_obj_type->TypeArguments().size()); + bool res = true; for (size_t ix = 0; ix < arg_obj_type->TypeArguments().size(); ix++) { - EnhanceSubstitutionForType(type_params, param_obj_type->TypeArguments()[ix], - arg_obj_type->TypeArguments()[ix], substitution, instantiated_type_params); - } - } else if (argument_type->IsETSFunctionType() && - param_obj_type->HasObjectFlag(ETSObjectFlags::FUNCTIONAL_INTERFACE)) { - auto parameter_signatures = param_obj_type->GetOwnProperty("invoke") - ->TsType() - ->AsETSFunctionType() - ->CallSignatures(); - auto argument_signatures = argument_type->AsETSFunctionType()->CallSignatures(); + res &= enhance(param_obj_type->TypeArguments()[ix], arg_obj_type->TypeArguments()[ix]); + } + return res; + } + + if (argument_type->IsETSFunctionType() && param_obj_type->HasObjectFlag(ETSObjectFlags::FUNCTIONAL_INTERFACE)) { + auto ¶meter_signatures = param_obj_type->GetOwnProperty("invoke") + ->TsType() + ->AsETSFunctionType() + ->CallSignatures(); + auto &argument_signatures = argument_type->AsETSFunctionType()->CallSignatures(); ASSERT(argument_signatures.size() == 1); ASSERT(parameter_signatures.size() == 1); + bool res = true; for (size_t idx = 0; idx < argument_signatures[0]->GetSignatureInfo()->params.size(); idx++) { - EnhanceSubstitutionForType(type_params, parameter_signatures[0]->GetSignatureInfo()->params[idx]->TsType(), - argument_signatures[0]->GetSignatureInfo()->params[idx]->TsType(), substitution, - instantiated_type_params); + res &= enhance(parameter_signatures[0]->GetSignatureInfo()->params[idx]->TsType(), + argument_signatures[0]->GetSignatureInfo()->params[idx]->TsType()); } - EnhanceSubstitutionForType(type_params, parameter_signatures[0]->ReturnType(), - argument_signatures[0]->ReturnType(), substitution, instantiated_type_params); - } else { - return; + res &= enhance(parameter_signatures[0]->ReturnType(), argument_signatures[0]->ReturnType()); + return res; } + + return true; } // NOLINTBEGIN(modernize-avoid-c-arrays) @@ -204,11 +222,6 @@ Signature *ETSChecker::ValidateSignature(Signature *signature, const ir::TSTypeP } } - if (substituted_sig->IsBaseReturnDiff() && substituted_sig->ReturnType()->IsETSArrayType()) { - CreateBuiltinArraySignature(substituted_sig->ReturnType()->AsETSArrayType(), - substituted_sig->ReturnType()->AsETSArrayType()->Rank()); - } - // Check all required formal parameter(s) first auto const count = std::min(parameter_count, argument_count); std::size_t index = 0U; @@ -367,12 +380,13 @@ std::pair, ArenaVector> ETSChecker::Collec auto collect_signatures = [&](TypeRelationFlag relation_flags) { for (auto *sig : signatures) { - if (!sig->Function()->IsDefaultParamProxy()) { - if (auto *concrete_sig = ValidateSignature(sig, type_arguments, arguments, pos, relation_flags, - arg_type_inference_required); - concrete_sig != nullptr) { - compatible_signatures.push_back(concrete_sig); - } + if (sig->Function()->IsDefaultParamProxy()) { + continue; + } + auto *concrete_sig = + ValidateSignature(sig, type_arguments, arguments, pos, relation_flags, arg_type_inference_required); + if (concrete_sig != nullptr) { + compatible_signatures.push_back(concrete_sig); } } }; @@ -1140,7 +1154,11 @@ Signature *ETSChecker::AdjustForTypeParameters(Signature *source, Signature *tar } auto *substitution = NewSubstitution(); for (size_t ix = 0; ix < source_type_params.size(); ix++) { - substitution->emplace(target_type_params[ix], source_type_params[ix]); + if (!target_type_params[ix]->IsETSTypeParameter()) { + continue; + } + ETSChecker::EmplaceSubstituted(substitution, target_type_params[ix]->AsETSTypeParameter(), + source_type_params[ix]); } return target->Substitute(Relation(), substitution); } @@ -2592,7 +2610,7 @@ bool ETSChecker::IsReturnTypeSubstitutable(Signature *const s1, Signature *const // - If R1 is a reference type then R1, adapted to the type parameters of d2 (link to generic methods), is a // subtype of R2. - ASSERT(r1->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT)); + ASSERT(r1->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT) || r1->IsETSTypeParameter()); r2->IsSupertypeOf(Relation(), r1); return Relation()->IsTrue(); } diff --git a/ets2panda/checker/ets/function_helpers.h b/ets2panda/checker/ets/function_helpers.h index 3bbe0ddb5..dba8f772b 100644 --- a/ets2panda/checker/ets/function_helpers.h +++ b/ets2panda/checker/ets/function_helpers.h @@ -88,7 +88,7 @@ static const Substitution *BuildImplicitSubstitutionForArguments(ETSChecker *che Substitution *substitution = checker->NewSubstitution(); auto *instantiated_type_params = checker->NewInstantiatedTypeParamsSet(); auto *sig_info = signature->GetSignatureInfo(); - ArenaVector &type_params = sig_info->type_params; + auto &type_params = sig_info->type_params; for (size_t ix = 0; ix < arguments.size(); ix++) { auto *arg = arguments[ix]; if (arg->IsObjectExpression()) { @@ -101,7 +101,10 @@ static const Substitution *BuildImplicitSubstitutionForArguments(ETSChecker *che if (param_type == nullptr) { continue; } - checker->EnhanceSubstitutionForType(type_params, param_type, arg_type, substitution, instantiated_type_params); + if (!checker->EnhanceSubstitutionForType(type_params, param_type, arg_type, substitution, + instantiated_type_params)) { + return nullptr; + } } return substitution; } @@ -111,30 +114,38 @@ static const Substitution *BuildExplicitSubstitutionForArguments(ETSChecker *che const lexer::SourcePosition &pos, TypeRelationFlag flags) { + auto &sig_params = signature->GetSignatureInfo()->type_params; auto *substitution = checker->NewSubstitution(); - auto *constraints_substitution = checker->NewSubstitution(); - ArenaVector &type_params = signature->GetSignatureInfo()->type_params; - ArenaVector type_arg_types {checker->Allocator()->Adapter()}; + ArenaVector inst_args {checker->Allocator()->Adapter()}; + for (auto *ta_expr : params) { - auto *type_arg = ta_expr->GetType(checker); - type_arg = MaybeBoxedType(checker, type_arg, ta_expr); - type_arg_types.push_back(type_arg); + inst_args.push_back(MaybeBoxedType(checker, ta_expr->GetType(checker), ta_expr)); } - if (type_params.size() != type_arg_types.size()) { - if ((flags & TypeRelationFlag::NO_THROW) == 0) { - checker->ThrowTypeError( - {"Expected ", type_params.size(), " type arguments, got ", type_arg_types.size(), " ."}, pos); + for (size_t ix = inst_args.size(); ix < sig_params.size(); ++ix) { + auto *dflt = sig_params[ix]->AsETSTypeParameter()->GetDefaultType(); + if (dflt == nullptr) { + break; + } + inst_args.push_back(dflt); + } + if (sig_params.size() != inst_args.size()) { + if ((flags & TypeRelationFlag::NO_THROW) != 0) { + return nullptr; } - return nullptr; + checker->ThrowTypeError({"Expected ", sig_params.size(), " type arguments, got ", inst_args.size(), " ."}, pos); } - for (size_t ix = 0; ix < type_params.size(); ix++) { - constraints_substitution->emplace(type_params[ix], type_arg_types[ix]); + + auto *constraints_substitution = checker->NewSubstitution(); + + for (size_t ix = 0; ix < sig_params.size(); ix++) { + ETSChecker::EmplaceSubstituted(constraints_substitution, sig_params[ix]->AsETSTypeParameter(), inst_args[ix]); } - for (size_t ix = 0; ix < type_arg_types.size(); ix++) { - if (!checker->IsCompatibleTypeArgument(type_params[ix], type_arg_types[ix], constraints_substitution)) { + for (size_t ix = 0; ix < sig_params.size(); ix++) { + if (!checker->IsCompatibleTypeArgument(sig_params[ix]->AsETSTypeParameter(), inst_args[ix], + constraints_substitution)) { return nullptr; } - substitution->emplace(type_params[ix], type_arg_types[ix]); + ETSChecker::EmplaceSubstituted(substitution, sig_params[ix]->AsETSTypeParameter(), inst_args[ix]); } return substitution; } @@ -148,23 +159,10 @@ static Signature *MaybeSubstituteTypeParameters(ETSChecker *checker, Signature * return signature; } - ArenaVector params = ArenaVector(checker->Allocator()->Adapter()); - - if (type_arguments == nullptr && !signature->Function()->TypeParams()->Params().empty()) { - for (auto param : signature->Function()->TypeParams()->Params()) { - if (param->DefaultType() != nullptr) { - params.push_back(param->DefaultType()->AsTypeNode()); - } else { - break; - } - } - } else if (type_arguments != nullptr) { - params = type_arguments->Params(); - } - const Substitution *substitution = - (!params.empty()) ? BuildExplicitSubstitutionForArguments(checker, signature, params, pos, flags) - : BuildImplicitSubstitutionForArguments(checker, signature, arguments); + (type_arguments != nullptr) + ? BuildExplicitSubstitutionForArguments(checker, signature, type_arguments->Params(), pos, flags) + : BuildImplicitSubstitutionForArguments(checker, signature, arguments); return (substitution == nullptr) ? nullptr : signature->Substitute(checker->Relation(), substitution); } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 638eb2909..c1ee8c407 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -130,6 +130,9 @@ Type *ETSChecker::GetNonNullishType(Type *type) const if (type->IsETSArrayType()) { return type; // give up } + if (type->IsETSTypeParameter()) { + return type->AsETSTypeParameter()->GetOriginal(); + } while (type->IsNullish()) { type = type->AsETSObjectType()->GetBaseType(); @@ -144,6 +147,9 @@ const Type *ETSChecker::GetNonNullishType(const Type *type) const if (type->IsETSArrayType()) { return type; // give up } + if (type->IsETSTypeParameter()) { + return type->AsETSTypeParameter()->GetOriginal(); + } while (type->IsNullish()) { type = type->AsETSObjectType()->GetBaseType(); @@ -163,6 +169,39 @@ Type *ETSChecker::CreateOptionalResultType(Type *type) return CreateNullishType(type, checker::TypeFlag::UNDEFINED, Allocator(), Relation(), GetGlobalTypesHolder()); } +bool ETSChecker::MayHaveNullValue(const Type *type) const +{ + if (type->ContainsNull() || type->IsETSNullType()) { + return true; + } + if (type->IsETSTypeParameter()) { + return MayHaveNullValue(type->AsETSTypeParameter()->EffectiveConstraint(this)); + } + return false; +} + +bool ETSChecker::MayHaveUndefinedValue(const Type *type) const +{ + if (type->ContainsUndefined() || type->IsETSUndefinedType()) { + return true; + } + if (type->IsETSTypeParameter()) { + return MayHaveUndefinedValue(type->AsETSTypeParameter()->EffectiveConstraint(this)); + } + return false; +} + +bool ETSChecker::MayHaveNulllikeValue(const Type *type) const +{ + if (type->IsNullishOrNullLike()) { + return true; + } + if (type->IsETSTypeParameter()) { + return MayHaveNulllikeValue(type->AsETSTypeParameter()->EffectiveConstraint(this)); + } + return false; +} + bool ETSChecker::IsConstantExpression(ir::Expression *expr, Type *type) { return (type->HasTypeFlag(TypeFlag::CONSTANT) && (expr->IsIdentifier() || expr->IsMemberExpression())); @@ -309,6 +348,55 @@ Type *ETSChecker::GetTypeOfVariable(varbinder::Variable *const var) return var->TsType(); } +// Determine if unchecked cast is needed and yield guaranteed source type +Type *ETSChecker::GuaranteedTypeForUncheckedCast(Type *base, Type *substituted) +{ + if (!base->IsETSTypeParameter()) { + return nullptr; + } + auto *constr = base->AsETSTypeParameter()->EffectiveConstraint(this); + // Constraint is supertype of TypeArg AND TypeArg is supertype of Constraint + return Relation()->IsIdenticalTo(substituted, constr) ? nullptr : constr; +} + +// Determine if substituted property access requires cast from erased type +Type *ETSChecker::GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable *const prop) +{ + if (IsVariableStatic(prop)) { + return nullptr; + } + if (IsVariableGetterSetter(prop)) { + auto *method = prop->TsType()->AsETSFunctionType(); + if (!method->HasTypeFlag(checker::TypeFlag::GETTER)) { + return nullptr; + } + return GuaranteedTypeForUncheckedCallReturn(method->FindGetter()); + } + // NOTE(vpukhov): mark ETSDynamicType properties + if (prop->Declaration() == nullptr || prop->Declaration()->Node() == nullptr) { + return nullptr; + } + + auto *base_prop = prop->Declaration()->Node()->AsClassProperty()->Id()->Variable(); + if (base_prop == prop) { + return nullptr; + } + return GuaranteedTypeForUncheckedCast(GetTypeOfVariable(base_prop), GetTypeOfVariable(prop)); +} + +// Determine if substituted method cast requires cast from erased type +Type *ETSChecker::GuaranteedTypeForUncheckedCallReturn(Signature *sig) +{ + if (sig->HasSignatureFlag(checker::SignatureFlags::THIS_RETURN_TYPE)) { + return sig->ReturnType(); + } + auto *base_sig = sig->Function()->Signature(); + if (base_sig == sig) { + return nullptr; + } + return GuaranteedTypeForUncheckedCast(base_sig->ReturnType(), sig->ReturnType()); +} + void ETSChecker::ValidatePropertyAccess(varbinder::Variable *var, ETSObjectType *obj, const lexer::SourcePosition &pos) { if ((Context().Status() & CheckerStatus::IGNORE_VISIBILITY) != 0U) { @@ -364,7 +452,7 @@ varbinder::Variable *ETSChecker::FindVariableInGlobal(const ir::Identifier *cons return Scope()->FindInGlobal(identifier->Name(), varbinder::ResolveBindingOptions::ALL).variable; } -bool ETSChecker::IsVariableStatic(const varbinder::Variable *var) const +bool ETSChecker::IsVariableStatic(const varbinder::Variable *var) { if (var->HasFlag(varbinder::VariableFlags::METHOD)) { return var->TsType()->AsETSFunctionType()->CallSignatures()[0]->HasSignatureFlag(SignatureFlags::STATIC); @@ -372,7 +460,7 @@ bool ETSChecker::IsVariableStatic(const varbinder::Variable *var) const return var->HasFlag(varbinder::VariableFlags::STATIC); } -bool ETSChecker::IsVariableGetterSetter(const varbinder::Variable *var) const +bool ETSChecker::IsVariableGetterSetter(const varbinder::Variable *var) { return var->TsType() != nullptr && var->TsType()->HasTypeFlag(TypeFlag::GETTER_SETTER); } @@ -444,8 +532,8 @@ void ETSChecker::ValidateMemberIdentifier(ir::Identifier *const ident, varbinder return; } - if (!type->IsETSObjectType() && !type->IsETSArrayType() && !type->IsETSEnumType() && !type->IsETSStringEnumType() && - !type->IsETSUnionType() && !type->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { + if (!IsReferenceType(type) && !type->IsETSEnumType() && !type->IsETSStringEnumType() && + !type->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { ThrowError(ident); } } @@ -524,7 +612,7 @@ void ETSChecker::ValidateResolvedIdentifier(ir::Identifier *const ident, varbind NotResolvedError(ident); } - auto *const resolved_type = GetTypeOfVariable(resolved); + auto *const resolved_type = ETSChecker::GetApparentType(GetTypeOfVariable(resolved)); switch (ident->Parent()->Type()) { case ir::AstNodeType::CALL_EXPRESSION: { @@ -1218,9 +1306,10 @@ Type *ETSChecker::HandleTypeAlias(ir::Expression *const name, const ir::TSTypePa } for (std::size_t idx = 0; idx < type_alias_node->TypeParams()->Params().size(); ++idx) { - alias_sub->insert( - {type_alias_node->TypeParams()->Params().at(idx)->Name()->AsIdentifier()->Variable()->TsType(), - type_params->Params().at(idx)->TsType()}); + auto *type_alias_type = type_alias_node->TypeParams()->Params().at(idx)->Name()->Variable()->TsType(); + if (type_alias_type->IsETSTypeParameter()) { + alias_sub->insert({type_alias_type->AsETSTypeParameter(), type_params->Params().at(idx)->TsType()}); + } } ValidateGenericTypeAliasForClonedNode(type_alias_node->AsTSTypeAliasDeclaration(), type_params); @@ -1285,6 +1374,10 @@ void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *module_obj auto r = ext_records.find(import_path); return r != ext_records.end() ? r : ext_records.find(ets_binder->GetResolvedImportPath(import_path)); }(); + + // Check imported properties before assigning them to module object + res->second.front()->Ast()->Check(this); + for (auto [_, var] : res->second.front()->GlobalClassScope()->StaticFieldScope()->Bindings()) { (void)_; if (var->AsLocalVariable()->Declaration()->Node()->IsExported()) { @@ -1572,7 +1665,7 @@ bool ETSChecker::IsTypeBuiltinType(Type *type) bool ETSChecker::IsReferenceType(const Type *type) { return type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT) || type->IsETSNullLike() || - type->IsETSStringType(); + type->IsETSStringType() || type->IsETSTypeParameter() || type->IsETSUnionType(); } const ir::AstNode *ETSChecker::FindJumpTarget(ir::AstNodeType node_type, const ir::AstNode *node, @@ -2194,17 +2287,19 @@ ETSObjectType *ETSChecker::GetRelevantArgumentedTypeFromChild(ETSObjectType *con static void TypeToString(std::stringstream &ss, Type *tp) { - if (tp->IsETSObjectType() && tp->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::TYPE_PARAMETER)) { - ss << tp->AsETSObjectType()->GetDeclNode()->Start().index; + if (tp->IsETSTypeParameter()) { + ss << tp->AsETSTypeParameter()->GetDeclNode()->Start().index; ss << "."; } - if (tp->IsETSObjectType()) { - ss << tp->AsETSObjectType()->Name(); - } else { + if (!tp->IsETSObjectType()) { tp->ToString(ss); + return; } - if (tp->IsETSObjectType() && !tp->AsETSObjectType()->TypeArguments().empty()) { - auto type_args = tp->AsETSObjectType()->TypeArguments(); + auto *const obj_type = tp->AsETSObjectType(); + ss << obj_type->Name(); + + if (!obj_type->TypeArguments().empty()) { + auto type_args = obj_type->TypeArguments(); ss << "<"; for (auto *ta : type_args) { TypeToString(ss, ta); @@ -2222,6 +2317,11 @@ static void TypeToString(std::stringstream &ss, Type *tp) } } +void ETSChecker::EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *type_arg) +{ + substitution->emplace(tparam, type_arg); +} + util::StringView ETSChecker::GetHashFromTypeArguments(const ArenaVector &type_arg_types) { std::stringstream ss; @@ -2271,7 +2371,7 @@ Type *ETSChecker::GetTypeFromTypeAnnotation(ir::TypeNode *const type_annotation) return type; } - if (!type->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT) && !type->HasTypeFlag(TypeFlag::ETS_UNION)) { + if (!IsReferenceType(type)) { ThrowTypeError("Non reference types cannot be nullish.", type_annotation->Start()); } @@ -2299,26 +2399,28 @@ void ETSChecker::CheckValidGenericTypeParameter(Type *const arg_type, const lexe ThrowTypeError("Type '" + ss.str() + "' is not valid for generic type arguments", pos); } -void ETSChecker::CheckNumberOfTypeArguments(Type *const type, ir::TSTypeParameterDeclaration *const type_param_decl, +void ETSChecker::CheckNumberOfTypeArguments(ETSObjectType *const type, ir::TSTypeParameterInstantiation *const type_args, const lexer::SourcePosition &pos) { - if (type_param_decl == nullptr) { + auto const &type_params = type->TypeArguments(); + if (type_params.empty()) { if (type_args != nullptr) { ThrowTypeError({"Type '", type, "' is not generic."}, pos); - } else { - return; } + return; } - size_t minimum_type_args = - std::count_if(type_param_decl->Params().begin(), type_param_decl->Params().end(), - [](ir::TSTypeParameter *param) { return param->DefaultType() == nullptr; }); + size_t minimum_type_args = std::count_if(type_params.begin(), type_params.end(), [](Type *param) { + return param->AsETSTypeParameter()->GetDefaultType() == nullptr; + }); if (type_args == nullptr && minimum_type_args > 0) { ThrowTypeError({"Type '", type, "' is generic but type argument were not provided."}, pos); - } else if (type_args != nullptr && ((minimum_type_args > type_args->Params().size()) || - (type_param_decl->Params().size() < type_args->Params().size()))) { + } + + if (type_args != nullptr && + ((minimum_type_args > type_args->Params().size()) || (type_params.size() < type_args->Params().size()))) { ThrowTypeError({"Type '", type, "' has ", minimum_type_args, " number of type parameters, but ", type_args->Params().size(), " type arguments were provided."}, pos); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 484a9b553..00aa62686 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -165,12 +165,6 @@ ArenaVector ETSChecker::GetInterfaces(ETSObjectType *type) return type->Interfaces(); } -void ETSChecker::SetTypeParameterType(ir::TSTypeParameter *type_param, Type *type_param_type) -{ - auto *var = type_param->Name()->Variable(); - var->SetTsType(type_param_type); -} - ArenaVector ETSChecker::CreateTypeForTypeParameters(ir::TSTypeParameterDeclaration *type_params) { ArenaVector result {Allocator()->Adapter()}; @@ -187,7 +181,7 @@ ArenaVector ETSChecker::CreateTypeForTypeParameters(ir::TSTypeParameterD } for (auto *const type_param : type_params->Params()) { - result.emplace_back(CreateTypeParameterType(type_param)); + result.emplace_back(SetUpParameterType(type_param)); } // The type parameter might be used in the constraint, like 'K extend Comparable', @@ -227,74 +221,50 @@ void ETSChecker::CheckTypeParameterConstraint(ir::TSTypeParameter *param, Type2T extends.emplace(type_param_name, constraint_name); } -Type *ETSChecker::CreateTypeParameterType(ir::TSTypeParameter *const param) -{ - auto const instantiate_supertype = [this](TypeFlag nullish_flags) { - return CreateNullishType(GlobalETSObjectType(), nullish_flags, Allocator(), Relation(), GetGlobalTypesHolder()) - ->AsETSObjectType(); - }; - - ETSObjectType *param_type = SetUpParameterType(param); - if (param->Constraint() == nullptr) { - // No constraint, so it's Object|null - param_type->SetSuperType(instantiate_supertype(TypeFlag::NULLISH)); - } - - return param_type; -} - void ETSChecker::SetUpTypeParameterConstraint(ir::TSTypeParameter *const param) { - auto const instantiate_supertype = [this](TypeFlag nullish_flags) { - return CreateNullishType(GlobalETSObjectType(), nullish_flags, Allocator(), Relation(), GetGlobalTypesHolder()) - ->AsETSObjectType(); - }; + ETSTypeParameter *const param_type = [this, param]() { + auto *const type = param->Name()->Variable()->TsType(); + return type != nullptr ? type->AsETSTypeParameter() : SetUpParameterType(param); + }(); - ETSObjectType *param_type = nullptr; - if (param->Name()->Variable()->TsType() == nullptr) { - param_type = SetUpParameterType(param); - } else { - param_type = param->Name()->Variable()->TsType()->AsETSObjectType(); - } - if (param->Constraint() != nullptr) { - if (param->Constraint()->IsETSTypeReference()) { - const auto constraint_name = - param->Constraint()->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Name(); - const auto *const type_param_scope = param->Parent()->AsTSTypeParameterDeclaration()->Scope(); - if (auto *const found_param = - type_param_scope->FindLocal(constraint_name, varbinder::ResolveBindingOptions::BINDINGS); - found_param != nullptr) { - SetUpTypeParameterConstraint(found_param->Declaration()->Node()->AsTSTypeParameter()); + auto const traverse_referenced = + [this, scope = param->Parent()->AsTSTypeParameterDeclaration()->Scope()](ir::TypeNode *type_node) { + if (!type_node->IsETSTypeReference()) { + return; } - } + const auto type_name = type_node->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Name(); + auto *const found = scope->FindLocal(type_name, varbinder::ResolveBindingOptions::BINDINGS); + if (found != nullptr) { + SetUpTypeParameterConstraint(found->Declaration()->Node()->AsTSTypeParameter()); + } + }; - auto *constraint_type = param->Constraint()->GetType(this); - if (!constraint_type->IsETSObjectType()) { + if (param->Constraint() != nullptr) { + traverse_referenced(param->Constraint()); + auto *const constraint = param->Constraint()->GetType(this); + if (!constraint->IsETSObjectType() && !constraint->IsETSTypeParameter() && !constraint->IsETSUnionType()) { ThrowTypeError("Extends constraint must be an object", param->Constraint()->Start()); } - auto *constraint_obj_type = constraint_type->AsETSObjectType(); - param_type->SetAssemblerName(constraint_obj_type->AssemblerName()); - if (constraint_type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { - param_type->AddInterface(constraint_obj_type); - param_type->SetSuperType(instantiate_supertype(TypeFlag(TypeFlag::NULLISH & constraint_type->TypeFlags()))); - } else { - param_type->SetSuperType(constraint_obj_type); - } - } else { - // No constraint, so it's Object|null|undefined - param_type->SetSuperType(instantiate_supertype(TypeFlag::NULLISH)); + param_type->SetConstraintType(constraint); + } + if (param->DefaultType() != nullptr) { + traverse_referenced(param->DefaultType()); + auto *const dflt = param->DefaultType()->GetType(this); + // NOTE: #14993 ensure default matches constraint + param_type->SetDefaultType(dflt); } } -ETSObjectType *ETSChecker::SetUpParameterType(ir::TSTypeParameter *const param) +ETSTypeParameter *ETSChecker::SetUpParameterType(ir::TSTypeParameter *const param) { - ETSObjectType *param_type = - CreateNewETSObjectType(param->Name()->Name(), param, GlobalETSObjectType()->ObjectFlags()); - param_type->SetAssemblerName(GlobalETSObjectType()->AssemblerName()); + auto *const param_type = CreateTypeParameter(); + param_type->AddTypeFlag(TypeFlag::GENERIC); - param_type->AddObjectFlag(ETSObjectFlags::TYPE_PARAMETER); + param_type->SetDeclNode(param); param_type->SetVariable(param->Variable()); - SetTypeParameterType(param, param_type); + + param->Name()->Variable()->SetTsType(param_type); return param_type; } @@ -1486,6 +1456,24 @@ Type *ETSChecker::FindLeastUpperBound(Type *source, Type *target) return GetTypeargumentedLUB(relevant_source_type, relevant_target_type); } +Type *ETSChecker::GetApparentType(Type *type) +{ + if (type->IsETSTypeParameter()) { + auto *const param = type->AsETSTypeParameter(); + return param->HasConstraint() ? param->GetConstraintType() : param; + } + return type; +} + +Type const *ETSChecker::GetApparentType(Type const *type) +{ + if (type->IsETSTypeParameter()) { + auto *const param = type->AsETSTypeParameter(); + return param->HasConstraint() ? param->GetConstraintType() : param; + } + return type; +} + Type *ETSChecker::GetCommonClass(Type *source, Type *target) { SavedTypeRelationFlagsContext checker_ctx(this->Relation(), TypeRelationFlag::IGNORE_TYPE_PARAMETERS); diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index ca04841b3..243fd3589 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -117,7 +117,7 @@ ETSArrayType *ETSChecker::CreateETSArrayType(Type *element_type) auto *array_type = Allocator()->New(element_type); auto it = array_types_.insert({element_type, array_type}); - if (it.second && !element_type->IsTypeParameter()) { + if (it.second && !element_type->IsETSTypeParameter()) { CreateBuiltinArraySignature(array_type, array_type->Rank()); } @@ -137,14 +137,11 @@ Type *ETSChecker::CreateETSUnionType(ArenaVector &&constituent_types) it->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE) ? BoxingConverter::ETSTypeFromSource(this, it) : it); } + ETSUnionType::NormalizeTypes(Relation(), new_constituent_types); if (new_constituent_types.size() == 1) { return new_constituent_types[0]; } - - auto *new_union_type = Allocator()->New(std::move(new_constituent_types)); - new_union_type->SetLeastUpperBoundType(this); - - return ETSUnionType::HandleUnionType(Relation(), new_union_type); + return Allocator()->New(this, std::move(new_constituent_types)); } ETSFunctionType *ETSChecker::CreateETSFunctionType(ArenaVector &signatures) @@ -193,9 +190,9 @@ SignatureInfo *ETSChecker::CreateSignatureInfo() return Allocator()->New(Allocator()); } -ETSTypeParameter *ETSChecker::CreateTypeParameter(Type *assembler_type) +ETSTypeParameter *ETSChecker::CreateTypeParameter() { - return Allocator()->New(assembler_type); + return Allocator()->New(); } ETSFunctionType *ETSChecker::CreateETSFunctionType(util::StringView name) @@ -231,6 +228,9 @@ ETSObjectType *ETSChecker::CreateETSObjectTypeCheckBuiltins(util::StringView nam return GlobalETSObjectType(); } GetGlobalTypesHolder()->GlobalTypes()[static_cast(GlobalTypeId::ETS_OBJECT_BUILTIN)] = obj_type; + auto *nullish = + CreateNullishType(obj_type, checker::TypeFlag::NULLISH, Allocator(), Relation(), GetGlobalTypesHolder()); + GetGlobalTypesHolder()->GlobalTypes()[static_cast(GlobalTypeId::ETS_NULLISH_OBJECT)] = nullish; } else if (name == compiler::Signatures::BUILTIN_EXCEPTION_CLASS) { if (GlobalBuiltinExceptionType() != nullptr) { return GlobalBuiltinExceptionType(); diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index 2fd2a784b..cbc061f0b 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -38,18 +38,15 @@ void AssignmentContext::ValidateArrayTypeInitializerByElement(TypeRelation *rela } } -bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSTypeParameterDeclaration *type_param_decl, - ir::TSTypeParameterInstantiation *type_args, +bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *type_args, const lexer::SourcePosition &pos) { - checker_->CheckNumberOfTypeArguments(type, type_param_decl, type_args, pos); - - if (type_param_decl == nullptr) { + checker_->CheckNumberOfTypeArguments(type, type_args, pos); + if (type->TypeArguments().empty()) { result_ = type; return true; } - auto *substitution = checker_->NewSubstitution(); /* The first loop is to create a substitution of type_params & type_args. so that we can replace the type_params in constaints by the right type. @@ -64,83 +61,53 @@ bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSType extends "Comparable", we will get an error here. */ - ASSERT(type_param_decl != nullptr); - - for (size_t type_param_iter = 0; type_param_iter < type_param_decl->Params().size(); ++type_param_iter) { - Type *type_arg_type; - - if (type_args != nullptr && (type_param_iter < type_args->Params().size())) { - type_arg_type = type_args->Params().at(type_param_iter)->GetType(checker_); - } else { - type_arg_type = - type_param_decl->Params().at(type_param_iter)->DefaultType()->AsETSTypeReference()->GetType(checker_); + auto const get_types = [this, &type_args, type](size_t idx) -> std::pair { + auto *type_param = type->TypeArguments().at(idx)->AsETSTypeParameter(); + if (type_args != nullptr && idx < type_args->Params().size()) { + return {type_param, type_args->Params().at(idx)->GetType(checker_)}; } + return {type_param, type_param->GetDefaultType()}; + }; - checker_->CheckValidGenericTypeParameter(type_arg_type, pos); - auto *const type_param_type = type->TypeArguments().at(type_param_iter); - substitution->emplace(type_param_type, type_arg_type); - } + auto *const substitution = checker_->NewSubstitution(); - for (size_t type_param_iter = 0; type_param_iter < type_param_decl->Params().size(); ++type_param_iter) { - ir::TSTypeParameter *type_param = type_param_decl->Params().at(type_param_iter)->AsTSTypeParameter(); - Type *type_arg_type; - - if (type_args != nullptr && (type_param_iter < type_args->Params().size())) { - type_arg_type = type_args->Params().at(type_param_iter)->GetType(checker_); - } else { - type_arg_type = - type_param_decl->Params().at(type_param_iter)->DefaultType()->AsETSTypeReference()->GetType(checker_); - } + for (size_t idx = 0; idx < type->TypeArguments().size(); ++idx) { + auto const [type_param, type_arg] = get_types(idx); + checker_->CheckValidGenericTypeParameter(type_arg, pos); + type_arg->Substitute(checker_->Relation(), substitution); + ETSChecker::EmplaceSubstituted(substitution, type_param, type_arg); + } - if (type_param->Constraint() == nullptr) { + for (size_t idx = 0; idx < type->TypeArguments().size(); ++idx) { + auto const [type_param, type_arg] = get_types(idx); + if (type_param->GetConstraintType() == nullptr) { continue; } + auto *const constraint = type_param->GetConstraintType()->Substitute(checker_->Relation(), substitution); - bool assignable = false; - auto *constraint_type = type_param->Constraint()->GetType(checker_); - - if (!constraint_type->AsETSObjectType()->TypeArguments().empty()) { - constraint_type = constraint_type->Substitute(checker_->Relation(), substitution); - } - - if (constraint_type->IsETSObjectType() && type_arg_type->IsETSObjectType()) { - assignable = ValidateTypeArg(constraint_type->AsETSObjectType(), type_arg_type->AsETSObjectType()); - } else if (type_arg_type->IsETSUnionType() && !constraint_type->IsETSUnionType()) { - auto constituent_types = type_arg_type->AsETSUnionType()->ConstituentTypes(); - assignable = - std::all_of(constituent_types.begin(), constituent_types.end(), [this, constraint_type](Type *c_type) { - return c_type->IsETSObjectType() && - ValidateTypeArg(constraint_type->AsETSObjectType(), c_type->AsETSObjectType()); - }); - } - - if (!assignable && type_args != nullptr && !checker_->Relation()->NoThrowGenericTypeAlias()) { - checker_->ThrowTypeError({"Type '", type_arg_type->AsETSObjectType(), - "' is not assignable to constraint type '", constraint_type, "'."}, - type_args->Params().at(type_param_iter)->Start()); + if (!ValidateTypeArg(constraint, type_arg) && type_args != nullptr && + !checker_->Relation()->NoThrowGenericTypeAlias()) { + checker_->ThrowTypeError({"Type '", type_arg, "' is not assignable to constraint type '", constraint, "'."}, + type_args->Params().at(idx)->Start()); } } return false; } -bool InstantiationContext::ValidateTypeArg(ETSObjectType *constraint_type, ETSObjectType *arg_ref_type) +bool InstantiationContext::ValidateTypeArg(Type *constraint_type, Type *type_arg) { - if (const auto *const found = checker_->AsETSChecker()->Scope()->FindLocal( - constraint_type->Name(), varbinder::ResolveBindingOptions::TYPE_ALIASES); - found != nullptr) { - arg_ref_type = found->TsType()->AsETSObjectType(); + if (!ETSChecker::IsReferenceType(type_arg)) { + return false; } - auto assignable = checker_->Relation()->IsAssignableTo(arg_ref_type, constraint_type); - if (constraint_type->HasObjectFlag(ETSObjectFlags::INTERFACE)) { - for (const auto *const interface : arg_ref_type->Interfaces()) { - // NOTE: mmartin. make correct check later for multiple bounds - assignable = (interface == constraint_type) || assignable; - } + if (type_arg->IsETSUnionType()) { + auto const &constituent_types = type_arg->AsETSUnionType()->ConstituentTypes(); + return std::all_of(constituent_types.begin(), constituent_types.end(), + [this, constraint_type](Type *c_type) { return ValidateTypeArg(constraint_type, c_type); }); } - return assignable; + return checker_->Relation()->IsAssignableTo(type_arg, constraint_type); } void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParameterInstantiation *type_args) @@ -178,7 +145,7 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ArenaVectorGetHashFromTypeArguments(type_arg_types); - auto type_params = type->TypeArguments(); + auto const &type_params = type->TypeArguments(); while (type_arg_types.size() < type_params.size()) { type_arg_types.push_back(type_params.at(type_arg_types.size())); @@ -187,27 +154,24 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ArenaVectorNewSubstitution(); auto *constraints_substitution = checker_->NewSubstitution(); for (size_t ix = 0; ix < type_params.size(); ix++) { - constraints_substitution->emplace(type_params[ix], type_arg_types[ix]); + if (!type_params[ix]->IsETSTypeParameter()) { + continue; + } + ETSChecker::EmplaceSubstituted(constraints_substitution, type_params[ix]->AsETSTypeParameter(), + type_arg_types[ix]); } for (size_t ix = 0; ix < type_params.size(); ix++) { auto *type_param = type_params[ix]; - bool is_compatible_type_arg; - if (type_arg_types[ix]->IsETSUnionType()) { - auto union_constituent_types = type_arg_types[ix]->AsETSUnionType()->ConstituentTypes(); - is_compatible_type_arg = std::all_of(union_constituent_types.begin(), union_constituent_types.end(), - [this, type_param, constraints_substitution](Type *type_arg) { - return checker_->IsCompatibleTypeArgument( - type_param, type_arg, constraints_substitution); - }); - } else { - is_compatible_type_arg = - checker_->IsCompatibleTypeArgument(type_param, type_arg_types[ix], constraints_substitution); + if (!type_param->IsETSTypeParameter()) { + continue; } - if (!is_compatible_type_arg && !checker_->Relation()->NoThrowGenericTypeAlias()) { + if (!checker_->IsCompatibleTypeArgument(type_param->AsETSTypeParameter(), type_arg_types[ix], + constraints_substitution) && + !checker_->Relation()->NoThrowGenericTypeAlias()) { checker_->ThrowTypeError( {"Type ", type_arg_types[ix], " is not assignable to", " type parameter ", type_params[ix]}, pos); } - substitution->emplace(type_params[ix], type_arg_types[ix]); + ETSChecker::EmplaceSubstituted(substitution, type_param->AsETSTypeParameter(), type_arg_types[ix]); } result_ = type->Substitute(checker_->Relation(), substitution)->AsETSObjectType(); diff --git a/ets2panda/checker/ets/typeRelationContext.h b/ets2panda/checker/ets/typeRelationContext.h index bd08c6587..d0148f37d 100644 --- a/ets2panda/checker/ets/typeRelationContext.h +++ b/ets2panda/checker/ets/typeRelationContext.h @@ -139,19 +139,9 @@ public: const lexer::SourcePosition &pos) : checker_(checker) { - ir::TSTypeParameterDeclaration *type_param_decl = nullptr; - - if (type->HasObjectFlag(ETSObjectFlags::TYPE_PARAMETER)) { - type_param_decl = nullptr; - } else if (type->HasObjectFlag(ETSObjectFlags::CLASS)) { - type_param_decl = type->GetDeclNode()->AsClassDefinition()->TypeParams(); - } else if (type->HasObjectFlag(ETSObjectFlags::INTERFACE)) { - type_param_decl = type->GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); - } - if (ValidateTypeArguments(type, type_param_decl, type_args, pos)) { + if (ValidateTypeArguments(type, type_args, pos)) { return; } - InstantiateType(type, type_args); } @@ -171,10 +161,10 @@ public: } private: - bool ValidateTypeArguments(ETSObjectType *type, ir::TSTypeParameterDeclaration *type_param_decl, - ir::TSTypeParameterInstantiation *type_args, const lexer::SourcePosition &pos); + bool ValidateTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *type_args, + const lexer::SourcePosition &pos); - bool ValidateTypeArg(ETSObjectType *constraint_type, ETSObjectType *arg_ref_type); + bool ValidateTypeArg(Type *constraint_type, Type *type_arg); void InstantiateType(ETSObjectType *type, ir::TSTypeParameterInstantiation *type_args); diff --git a/ets2panda/checker/types/ets/etsArrayType.cpp b/ets2panda/checker/types/ets/etsArrayType.cpp index 5c2bdbac3..706fb35ec 100644 --- a/ets2panda/checker/types/ets/etsArrayType.cpp +++ b/ets2panda/checker/types/ets/etsArrayType.cpp @@ -117,6 +117,12 @@ void ETSArrayType::Cast(TypeRelation *const relation, Type *const target) return; } + if (ElementType()->IsETSTypeParameter()) { + // unchecked cast! + relation->Result(true); + return; + } + conversion::Forbidden(relation); return; } @@ -141,8 +147,7 @@ void ETSArrayType::IsSupertypeOf(TypeRelation *const relation, Type *source) if (source->IsETSArrayType()) { auto *const source_elem_type = this->AsETSArrayType()->ElementType(); auto *const target_elem_type = source->AsETSArrayType()->ElementType(); - if (source_elem_type->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT) && - target_elem_type->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT)) { + if (ETSChecker::IsReferenceType(target_elem_type) && ETSChecker::IsReferenceType(source_elem_type)) { source_elem_type->IsSupertypeOf(relation, target_elem_type); } } @@ -159,9 +164,7 @@ Type *ETSArrayType::Substitute(TypeRelation *relation, const Substitution *subst if (substitution == nullptr || substitution->empty()) { return this; } - if (auto found = substitution->find(this); found != substitution->end()) { - return found->second; - } + auto *result_elt = element_->Substitute(relation, substitution); return result_elt == element_ ? this : relation->GetChecker()->AsETSChecker()->CreateETSArrayType(result_elt); } diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index 4674b6fe7..a0a1cfcd9 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -87,16 +87,20 @@ static Signature *ProcessSignatures(TypeRelation *relation, Signature *target, E if (!it->GetSignatureInfo()->type_params.empty()) { auto *substitution = relation->GetChecker()->AsETSChecker()->NewSubstitution(); auto *instantiated_type_params = relation->GetChecker()->AsETSChecker()->NewInstantiatedTypeParamsSet(); + bool res = true; for (size_t ix = 0; ix < target->MinArgCount(); ix++) { - relation->GetChecker()->AsETSChecker()->EnhanceSubstitutionForType( + res &= relation->GetChecker()->AsETSChecker()->EnhanceSubstitutionForType( it->GetSignatureInfo()->type_params, it->GetSignatureInfo()->params[ix]->TsType(), target->GetSignatureInfo()->params[ix]->TsType(), substitution, instantiated_type_params); } if (target->RestVar() != nullptr) { - relation->GetChecker()->AsETSChecker()->EnhanceSubstitutionForType( + res &= relation->GetChecker()->AsETSChecker()->EnhanceSubstitutionForType( it->GetSignatureInfo()->type_params, it->RestVar()->TsType(), target->RestVar()->TsType(), substitution, instantiated_type_params); } + if (!res) { + continue; + } it = it->Substitute(relation, substitution); } diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 07dc03831..6cdf7c434 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -286,7 +286,7 @@ void ETSObjectType::ToString(std::stringstream &ss) const { ss << name_; - if (IsGeneric()) { + if (!type_arguments_.empty()) { auto const type_arguments_size = type_arguments_.size(); ss << compiler::Signatures::GENERIC_BEGIN; type_arguments_[0]->ToString(ss); @@ -321,10 +321,6 @@ void ETSObjectType::IdenticalUptoNullability(TypeRelation *relation, Type *other return; } - if (this_base->HasObjectFlag(ETSObjectFlags::TYPE_PARAMETER) && this_base != other_base) { - return; - } - if (relation->IgnoreTypeParameters() || (this == other)) { relation->Result(true); return; @@ -631,6 +627,11 @@ void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) return; } + if (source->IsETSTypeParameter()) { + source->AsETSTypeParameter()->ConstraintIsSubtypeOf(relation, this); + return; + } + if (!source->IsETSObjectType() || !source->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::CLASS | ETSObjectFlags::INTERFACE | ETSObjectFlags::NULL_TYPE)) { @@ -831,31 +832,8 @@ Type *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *subs return this; } - if (const auto &this_type_in_sub = substitution->find(this); this_type_in_sub != substitution->end()) { - return this_type_in_sub->second; - } - auto *const checker = relation->GetChecker()->AsETSChecker(); auto *base = GetOriginalBaseType(); - if (auto repl = substitution->find(base); repl != substitution->end()) { - auto *repl_type = repl->second; - - /* Any other flags we need to copy? */ - - /* The check this != base is a kludge to distinguish bare type parameter T - with a nullish constraint (like the default Object?) from explicitly nullish T? - */ - if (this != base && ((ContainsNull() && !repl_type->ContainsNull()) || - (ContainsUndefined() && !repl_type->ContainsUndefined()))) { - // this type is explicitly marked as nullish - ASSERT(repl_type->IsETSObjectType() || repl_type->IsETSArrayType() || repl_type->IsETSFunctionType()); - auto nullish_flags = TypeFlag(TypeFlags() & TypeFlag::NULLISH); - auto *new_repl_type = checker->CreateNullishType(repl_type, nullish_flags, checker->Allocator(), relation, - checker->GetGlobalTypesHolder()); - repl_type = new_repl_type; - } - return repl_type; - } ArenaVector new_type_args {checker->Allocator()->Adapter()}; const bool any_change = SubstituteTypeArgs(relation, new_type_args, substitution); @@ -944,4 +922,14 @@ void ETSObjectType::InstantiateProperties() const } } +void ETSObjectType::DebugInfoTypeFromName(std::stringstream &ss, util::StringView asm_name) +{ + ss << compiler::Signatures::CLASS_REF_BEGIN; + auto copied = asm_name.Mutf8(); + std::replace(copied.begin(), copied.end(), *compiler::Signatures::METHOD_SEPARATOR.begin(), + *compiler::Signatures::NAMESPACE_SEPARATOR.begin()); + ss << copied; + ss << compiler::Signatures::MANGLE_SEPARATOR; +} + } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 0500dd6a8..89f49aeb4 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -45,9 +45,8 @@ enum class ETSObjectFlags : uint32_t { INNER = 1U << 15U, DYNAMIC = 1U << 16U, ASYNC_FUNC_RETURN_TYPE = 1U << 17U, - TYPE_PARAMETER = 1U << 18U, - CHECKED_INVOKE_LEGITIMACY = 1U << 19U, - UNDEFINED_TYPE = 1U << 20U, + CHECKED_INVOKE_LEGITIMACY = 1U << 18U, + UNDEFINED_TYPE = 1U << 19U, BUILTIN_STRING = 1U << 23U, BUILTIN_BOOLEAN = 1U << 24U, @@ -492,14 +491,11 @@ public: ss << assembler_name_; } + static void DebugInfoTypeFromName(std::stringstream &ss, util::StringView asm_name); + void ToDebugInfoType(std::stringstream &ss) const override { - ss << compiler::Signatures::CLASS_REF_BEGIN; - auto name = assembler_name_.Mutf8(); - std::replace(name.begin(), name.end(), *compiler::Signatures::METHOD_SEPARATOR.begin(), - *compiler::Signatures::NAMESPACE_SEPARATOR.begin()); - ss << name; - ss << compiler::Signatures::MANGLE_SEPARATOR; + DebugInfoTypeFromName(ss, assembler_name_); } void ToDebugInfoSignatureType(std::stringstream &ss) const diff --git a/ets2panda/checker/types/ets/etsTypeParameter.cpp b/ets2panda/checker/types/ets/etsTypeParameter.cpp index 43edd66d0..d19a6ef11 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsTypeParameter.cpp @@ -14,20 +14,175 @@ */ #include "etsTypeParameter.h" +#include "ir/expressions/identifier.h" +#include "ir/ts/tsTypeParameter.h" +#include "checker/ETSchecker.h" +#include "checker/ets/conversion.h" namespace panda::es2panda::checker { -void ETSTypeParameter::ToString([[maybe_unused]] std::stringstream &ss) const +void ETSTypeParameter::ToString(std::stringstream &ss) const { - UNREACHABLE(); + ss << decl_node_->Name()->Name(); + + if (IsNullish()) { + if (ContainsNull()) { + ss << "|null"; + } + if (ContainsUndefined()) { + ss << "|undefined"; + } + } } void ETSTypeParameter::Identical([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *other) { - UNREACHABLE(); + if ((ContainsNull() != other->ContainsNull()) || (ContainsUndefined() != other->ContainsUndefined())) { + return; + } + + if (other->IsETSTypeParameter() && other->AsETSTypeParameter()->GetOriginal() == GetOriginal()) { + relation->Result(true); + } +} + +bool ETSTypeParameter::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) +{ + return relation->Result(false); } void ETSTypeParameter::AssignmentTarget([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) { - UNREACHABLE(); + if (source->IsETSNullType()) { + relation->Result(ContainsNull()); + return; + } + if (source->IsETSUndefinedType()) { + relation->Result(ContainsUndefined()); + return; + } + + if ((source->ContainsNull() && !ContainsNull()) || (source->ContainsUndefined() && !ContainsUndefined())) { + relation->Result(false); + return; + } + if (source->IsETSTypeParameter() && source->AsETSTypeParameter()->GetOriginal() == GetOriginal()) { + relation->Result(true); + return; + } + + IsSupertypeOf(relation, source); +} + +void ETSTypeParameter::Cast(TypeRelation *relation, Type *target) +{ + if (target->IsSupertypeOf(relation, this), relation->IsTrue()) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + relation->Result(true); + return; + } + + // NOTE(vpukhov): adjust UNCHECKED_CAST flags + if (target->IsETSObjectType()) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + } + relation->Result(relation->InCastingContext()); +} + +void ETSTypeParameter::CastTarget(TypeRelation *relation, Type *source) +{ + if (IsSupertypeOf(relation, source), relation->IsTrue()) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + relation->Result(true); + return; + } + + relation->Result(relation->InCastingContext()); +} + +void ETSTypeParameter::IsSupertypeOf([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) +{ + if (Identical(relation, source), relation->IsTrue()) { + return; + } + + if (source->IsETSTypeParameter()) { + source->AsETSTypeParameter()->ConstraintIsSubtypeOf(relation, this); + return; + } + + relation->Result(false); +} + +Type *ETSTypeParameter::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[maybe_unused]] TypeRelation *relation, + [[maybe_unused]] GlobalTypesHolder *global_types) +{ + auto *const checker = relation->GetChecker()->AsETSChecker(); + + auto *const copied_type = checker->CreateTypeParameter(); + copied_type->AddTypeFlag(TypeFlag::GENERIC); + copied_type->SetDeclNode(GetDeclNode()); + copied_type->SetDefaultType(GetDefaultType()); + copied_type->SetConstraintType(GetConstraintType()); + copied_type->SetVariable(Variable()); + return copied_type; +} + +Type *ETSTypeParameter::Substitute(TypeRelation *relation, const Substitution *substitution) +{ + if (substitution == nullptr || substitution->empty()) { + return this; + } + auto *const checker = relation->GetChecker()->AsETSChecker(); + auto *original = GetOriginal(); + if (auto repl = substitution->find(original); repl != substitution->end()) { + auto *repl_type = repl->second; + /* Any other flags we need to copy? */ + + /* The check this != base is a kludge to distinguish bare type parameter T + with a nullish constraint (like the default Object?) from explicitly nullish T? + */ + if (this != original && ((ContainsNull() && !repl_type->ContainsNull()) || + (ContainsUndefined() && !repl_type->ContainsUndefined()))) { + // this type is explicitly marked as nullish + ASSERT(repl_type->IsETSObjectType() || repl_type->IsETSArrayType() || repl_type->IsETSFunctionType() || + repl_type->IsETSTypeParameter()); + auto nullish_flags = TypeFlag(TypeFlags() & TypeFlag::NULLISH); + auto *new_repl_type = checker->CreateNullishType(repl_type, nullish_flags, checker->Allocator(), relation, + checker->GetGlobalTypesHolder()); + repl_type = new_repl_type; + } + return repl_type; + } + + return this; +} + +Type *ETSTypeParameter::EffectiveConstraint(ETSChecker const *checker) const +{ + return HasConstraint() ? GetConstraintType() : checker->GlobalETSNullishObjectType(); } + +void ETSTypeParameter::ToAssemblerType(std::stringstream &ss) const +{ + if (HasConstraint()) { + GetConstraintType()->ToAssemblerType(ss); + } else { + ss << compiler::Signatures::BUILTIN_OBJECT; + } +} + +void ETSTypeParameter::ToDebugInfoType(std::stringstream &ss) const +{ + if (HasConstraint()) { + GetConstraintType()->ToDebugInfoType(ss); + } else { + ETSObjectType::DebugInfoTypeFromName(ss, compiler::Signatures::BUILTIN_OBJECT); + } +} + +ETSTypeParameter *ETSTypeParameter::GetOriginal() const +{ + return GetDeclNode()->Name()->Variable()->TsType()->AsETSTypeParameter(); +} + } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsTypeParameter.h b/ets2panda/checker/types/ets/etsTypeParameter.h index 1ef6df6e0..d39645a55 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.h +++ b/ets2panda/checker/types/ets/etsTypeParameter.h @@ -17,48 +17,83 @@ #define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_TYPE_PARAMETER_TYPE_H #include "checker/types/type.h" +#include "ir/astNode.h" namespace panda::es2panda::checker { class ETSTypeParameter : public Type { public: explicit ETSTypeParameter() : Type(TypeFlag::ETS_TYPE_PARAMETER) {} - explicit ETSTypeParameter(Type *assembler_type) - : Type(TypeFlag::ETS_TYPE_PARAMETER), assembler_type_(assembler_type) + explicit ETSTypeParameter(Type *default_type, Type *constraint_type) + : Type(TypeFlag::ETS_TYPE_PARAMETER), default_(default_type), constraint_(constraint_type) { } - void SetType(Type *type) + void SetDeclNode(ir::TSTypeParameter *decl) { - type_ = type; + decl_node_ = decl; } - Type *GetType() + ir::TSTypeParameter *GetDeclNode() const { - return type_; + return decl_node_; } - Type *GetAssemblerType() + ETSTypeParameter *GetOriginal() const; + + void SetDefaultType(Type *type) + { + default_ = type; + } + + Type *GetDefaultType() const + { + return default_; + } + + void SetConstraintType(Type *type) { - return assembler_type_; + constraint_ = type; } - Type **GetTypeRef() + Type *GetConstraintType() const { - return &type_; + return constraint_; } - Type **GetAssemblerTypeRef() + bool HasConstraint() const { - return &assembler_type_; + return GetConstraintType() != nullptr; } + Type *EffectiveConstraint(ETSChecker const *checker) const; + void ToString(std::stringstream &ss) const override; void Identical(TypeRelation *relation, Type *other) override; 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; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; + Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *global_types) override; + Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; + + bool ConstraintIsSubtypeOf(TypeRelation *relation, Type *target) + { + if (HasConstraint()) { + target->IsSupertypeOf(relation, GetConstraintType()); + } else { + relation->Result(false); + } + return relation->IsTrue(); + } + + void ToAssemblerType(std::stringstream &ss) const override; + void ToDebugInfoType(std::stringstream &ss) const override; private: - Type *type_ {}; - Type *assembler_type_ {}; + ir::TSTypeParameter *decl_node_ {}; + Type *default_ {}; + Type *constraint_ {}; }; } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index fe46cd934..18d2fcbde 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -42,6 +42,13 @@ void ETSUnionType::ToDebugInfoType(std::stringstream &ss) const lub_type_->ToDebugInfoType(ss); } +ETSUnionType::ETSUnionType(ETSChecker *checker, ArenaVector &&constituent_types) + : Type(TypeFlag::ETS_UNION), constituent_types_(std::move(constituent_types)) +{ + ASSERT(constituent_types_.size() > 1); + lub_type_ = ComputeLUB(checker); +} + bool ETSUnionType::EachTypeRelatedToSomeType(TypeRelation *relation, ETSUnionType *source, ETSUnionType *target) { return std::all_of(source->constituent_types_.begin(), source->constituent_types_.end(), @@ -54,23 +61,19 @@ bool ETSUnionType::TypeRelatedToSomeType(TypeRelation *relation, Type *source, E [relation, source](auto *t) { return relation->IsIdenticalTo(source, t); }); } -void ETSUnionType::SetLeastUpperBoundType(ETSChecker *checker) +Type *ETSUnionType::ComputeLUB(ETSChecker *checker) const { - ASSERT(constituent_types_.size() > 1); - if (lub_type_ == nullptr) { - lub_type_ = constituent_types_.front(); - for (auto *t : constituent_types_) { - if (!t->HasTypeFlag(TypeFlag::ETS_ARRAY_OR_OBJECT)) { - lub_type_ = checker->GetGlobalTypesHolder()->GlobalETSObjectType(); - return; - } - if (t->IsETSObjectType() && t->AsETSObjectType()->SuperType() == nullptr) { - lub_type_ = checker->GetGlobalTypesHolder()->GlobalETSObjectType(); - return; - } - lub_type_ = checker->FindLeastUpperBound(lub_type_, t); + auto lub = constituent_types_.front(); + for (auto *t : constituent_types_) { + if (!checker->IsReferenceType(t)) { + return checker->GetGlobalTypesHolder()->GlobalETSObjectType(); + } + if (t->IsETSObjectType() && t->AsETSObjectType()->SuperType() == nullptr) { + return checker->GetGlobalTypesHolder()->GlobalETSObjectType(); } + lub = checker->FindLeastUpperBound(lub, t); } + return lub; } void ETSUnionType::Identical(TypeRelation *relation, Type *other) @@ -94,8 +97,7 @@ bool ETSUnionType::AssignmentSource(TypeRelation *relation, Type *target) } } - relation->Result(true); - return true; + return relation->Result(true); } void ETSUnionType::AssignmentTarget(TypeRelation *relation, Type *source) @@ -213,17 +215,6 @@ void ETSUnionType::NormalizeTypes(TypeRelation *relation, ArenaVector &c } } -Type *ETSUnionType::HandleUnionType([[maybe_unused]] TypeRelation *relation, ETSUnionType *union_type) -{ - NormalizeTypes(relation, union_type->constituent_types_); - - if (union_type->ConstituentTypes().size() == 1) { - return union_type->ConstituentTypes()[0]; - } - - return union_type; -} - Type *ETSUnionType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *global_types) { ArenaVector copied_constituents(allocator->Adapter()); @@ -234,14 +225,12 @@ Type *ETSUnionType::Instantiate(ArenaAllocator *allocator, TypeRelation *relatio : it->Instantiate(allocator, relation, global_types)); } + ETSUnionType::NormalizeTypes(relation, copied_constituents); if (copied_constituents.size() == 1) { return copied_constituents[0]; } - auto *new_union_type = allocator->New(std::move(copied_constituents)); - - new_union_type->SetLeastUpperBoundType(relation->GetChecker()->AsETSChecker()); - return HandleUnionType(relation, new_union_type); + return allocator->New(relation->GetChecker()->AsETSChecker(), std::move(copied_constituents)); } Type *ETSUnionType::Substitute(TypeRelation *relation, const Substitution *substitution) @@ -259,21 +248,21 @@ void ETSUnionType::Cast(TypeRelation *relation, Type *target) auto *const checker = relation->GetChecker()->AsETSChecker(); auto *const ref_target = target->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE) ? checker->PrimitiveTypeAsETSBuiltinType(target) : target; - auto exact_type = std::find_if(constituent_types_.begin(), constituent_types_.end(), - [this, checker, relation, ref_target](Type *src) { - if (src == ref_target && relation->IsCastableTo(src, ref_target)) { - GetLeastUpperBoundType(checker)->Cast(relation, ref_target); - ASSERT(relation->IsTrue()); - return true; - } - return false; - }); + auto exact_type = + std::find_if(constituent_types_.begin(), constituent_types_.end(), [this, relation, ref_target](Type *src) { + if (src == ref_target && relation->IsCastableTo(src, ref_target)) { + GetLeastUpperBoundType()->Cast(relation, ref_target); + ASSERT(relation->IsTrue()); + return true; + } + return false; + }); if (exact_type != constituent_types_.end()) { return; } for (auto *source : constituent_types_) { if (relation->IsCastableTo(source, ref_target)) { - GetLeastUpperBoundType(checker)->Cast(relation, ref_target); + GetLeastUpperBoundType()->Cast(relation, ref_target); ASSERT(relation->IsTrue()); if (ref_target != target) { source->Cast(relation, target); @@ -294,6 +283,31 @@ void ETSUnionType::Cast(TypeRelation *relation, Type *target) conversion::Forbidden(relation); } +void ETSUnionType::IsSupertypeOf(TypeRelation *relation, Type *source) +{ + relation->Result(false); + + if (source->IsETSUnionType()) { + for (auto const &source_ctype : source->AsETSUnionType()->ConstituentTypes()) { + if (IsSupertypeOf(relation, source_ctype), !relation->IsTrue()) { + return; + } + } + return; + } + + for (auto const &ctype : ConstituentTypes()) { + if (ctype->IsSupertypeOf(relation, source), relation->IsTrue()) { + return; + } + } + + if (source->IsETSTypeParameter()) { + source->AsETSTypeParameter()->ConstraintIsSubtypeOf(relation, this); + return; + } +} + void ETSUnionType::CastTarget(TypeRelation *relation, Type *source) { Type *target_type = FindTypeIsCastableToThis(relation->GetNode(), relation, source); diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index 93091f757..39dc90ec1 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -24,42 +24,14 @@ class GlobalTypesHolder; class ETSUnionType : public Type { public: - explicit ETSUnionType(ArenaAllocator *allocator) - : Type(TypeFlag::ETS_UNION), constituent_types_(allocator->Adapter()) - { - } - - explicit ETSUnionType(ArenaVector &&constituent_types) - : Type(TypeFlag::ETS_UNION), constituent_types_(std::move(constituent_types)) - { - } - - explicit ETSUnionType(ArenaVector &constituent_types) - : Type(TypeFlag::ETS_UNION), constituent_types_(constituent_types) - { - } + // constituent_types must be normalized + explicit ETSUnionType(ETSChecker *checker, ArenaVector &&constituent_types); const ArenaVector &ConstituentTypes() const { return constituent_types_; } - ArenaVector &ConstituentTypes() - { - return constituent_types_; - } - - void AddConstituentType(Type *type, TypeRelation *relation) - { - for (auto *it : constituent_types_) { - if (relation->IsIdenticalTo(it, type)) { - return; - } - } - - constituent_types_.push_back(type); - } - void ToString(std::stringstream &ss) const override; void ToAssemblerType(std::stringstream &ss) const override; void ToDebugInfoType(std::stringstream &ss) const override; @@ -70,21 +42,11 @@ public: Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; + void IsSupertypeOf(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; - void SetLeastUpperBoundType(ETSChecker *checker); - - Type *GetLeastUpperBoundType(ETSChecker *checker) - { - if (lub_type_ == nullptr) { - SetLeastUpperBoundType(checker); - } - ASSERT(lub_type_ != nullptr); - return lub_type_; - } - Type *GetLeastUpperBoundType() const { ASSERT(lub_type_ != nullptr); @@ -97,11 +59,9 @@ public: static void NormalizeTypes(TypeRelation *relation, ArenaVector &constituent_types); - static Type *HandleUnionType(TypeRelation *relation, ETSUnionType *union_type); - std::tuple ResolveConditionExpr() const override { - for (auto tp : ConstituentTypes()) { + for (auto const &tp : ConstituentTypes()) { if (!tp->IsConditionalExprType()) { return {true, false}; } @@ -115,7 +75,9 @@ private: static void LinearizeAndEraseIdentical(TypeRelation *relation, ArenaVector &constituent_types); - ArenaVector constituent_types_; + Type *ComputeLUB(ETSChecker *checker) const; + + ArenaVector const constituent_types_; Type *lub_type_ {nullptr}; }; } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index 50e7839a5..5c6eb9a07 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -346,6 +346,11 @@ Type *GlobalTypesHolder::GlobalETSUndefinedType() return global_types_.at(static_cast(GlobalTypeId::ETS_UNDEFINED)); } +Type *GlobalTypesHolder::GlobalETSNullishObjectType() +{ + return global_types_.at(static_cast(GlobalTypeId::ETS_NULLISH_OBJECT)); +} + Type *GlobalTypesHolder::GlobalWildcardType() { return global_types_.at(static_cast(GlobalTypeId::ETS_WILDCARD)); diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index e84ae6ad3..e0e370b45 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -57,6 +57,7 @@ enum class GlobalTypeId { ETS_OBJECT_BUILTIN, ETS_NULL, ETS_UNDEFINED, + ETS_NULLISH_OBJECT, ETS_WILDCARD, ETS_BOOLEAN_BUILTIN, ETS_BYTE_BUILTIN, @@ -159,6 +160,7 @@ public: Type *GlobalETSObjectType(); Type *GlobalETSNullType(); Type *GlobalETSUndefinedType(); + Type *GlobalETSNullishObjectType(); Type *GlobalWildcardType(); Type *GlobalETSBooleanBuiltinType(); Type *GlobalByteBuiltinType(); diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index 8bb01344d..f04fd009e 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -37,6 +37,7 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub bool any_change = false; SignatureInfo *new_sig_info = allocator->New(allocator); const Substitution *new_substitution = substitution; + if (!signature_info_->type_params.empty()) { auto *new_substitution_seed = checker->CopySubstitution(substitution); for (auto *tparam : signature_info_->type_params) { @@ -44,12 +45,13 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub new_sig_info->type_params.push_back(new_tparam); if (new_tparam != tparam) { any_change = true; - new_substitution_seed->insert({tparam, new_tparam}); + if (tparam->IsETSTypeParameter()) { + new_substitution_seed->insert({tparam->AsETSTypeParameter(), new_tparam}); + } } } new_substitution = new_substitution_seed; } - new_sig_info->min_arg_count = signature_info_->min_arg_count; for (auto *param : signature_info_->params) { @@ -84,12 +86,13 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub if (!any_change) { return this; } - auto *result = allocator->New(new_sig_info, new_return_type, this); + auto *result = allocator->New(new_sig_info, new_return_type); result->func_ = func_; result->flags_ = flags_; result->internal_name_ = internal_name_; result->owner_obj_ = owner_obj_; result->owner_var_ = owner_var_; + return result; } @@ -342,12 +345,4 @@ void Signature::AssignmentTarget(TypeRelation *relation, Signature *source) relation->IsAssignableTo(source->RestVar()->TsType(), signature_info_->rest_var->TsType()); } } - -bool Signature::IsBaseReturnDiff() const -{ - if (base_sig_ == nullptr) { - return false; - } - return ReturnType()->ToAssemblerName().str() != base_sig_->ReturnType()->ToAssemblerName().str(); -} } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/signature.h b/ets2panda/checker/types/signature.h index fdbbeb555..94e7b78c3 100644 --- a/ets2panda/checker/types/signature.h +++ b/ets2panda/checker/types/signature.h @@ -92,8 +92,8 @@ DEFINE_BITOPS(SignatureFlags) class Signature { public: - Signature(SignatureInfo *signature_info, Type *return_type, Signature *base_sig = nullptr) - : signature_info_(signature_info), return_type_(return_type), base_sig_(base_sig) + Signature(SignatureInfo *signature_info, Type *return_type) + : signature_info_(signature_info), return_type_(return_type) { } @@ -224,8 +224,6 @@ public: return (flags_ & flag) != 0U; } - bool IsBaseReturnDiff() const; - bool IsFinal() const noexcept { return HasSignatureFlag(SignatureFlags::FINAL); @@ -263,7 +261,6 @@ private: util::StringView internal_name_ {}; ETSObjectType *owner_obj_ {}; varbinder::Variable *owner_var_ {}; - const Signature *base_sig_ = nullptr; }; } // namespace panda::es2panda::checker diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index 5f1b44af2..3f5185007 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -36,6 +36,7 @@ class ETSDynamicType; class ETSAsyncFuncReturnType; class ETSChecker; class ETSDynamicFunctionType; +class ETSTypeParameter; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define DECLARE_TYPENAMES(typeFlag, typeName) class typeName; @@ -43,7 +44,7 @@ TYPE_MAPPING(DECLARE_TYPENAMES) #undef DECLARE_TYPENAMES class ETSStringType; -using Substitution = ArenaMap; +using Substitution = ArenaMap; class Type { public: diff --git a/ets2panda/checker/types/typeFlag.h b/ets2panda/checker/types/typeFlag.h index cfa698c62..e4a973560 100644 --- a/ets2panda/checker/types/typeFlag.h +++ b/ets2panda/checker/types/typeFlag.h @@ -84,7 +84,7 @@ enum class TypeFlag : uint64_t { ETS_DYNAMIC_TYPE = ETS_OBJECT | ETS_DYNAMIC_FLAG, ETS_DYNAMIC_FUNCTION_TYPE = FUNCTION | ETS_DYNAMIC_FLAG, ETS_TYPE = BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | CHAR | ETS_BOOLEAN | ETS_VOID | ETS_OBJECT | ETS_ARRAY | - WILDCARD | ETS_TYPE_PARAMETER | ETS_ENUM | ETS_STRING_ENUM | ETS_DYNAMIC_TYPE, + WILDCARD | ETS_TYPE_PARAMETER | ETS_ENUM | ETS_STRING_ENUM | ETS_DYNAMIC_TYPE | ETS_UNION, ETS_PRIMITIVE = BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | CHAR | ETS_BOOLEAN | ETS_VOID, ETS_PRIMITIVE_RETURN = BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | CHAR | ETS_BOOLEAN | ETS_ENUM, ETS_ARRAY_INDEX = BYTE | SHORT | INT, diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index 636c4dcdb..4e7cff314 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -268,9 +268,10 @@ public: void RaiseError(const std::string &err_msg, const lexer::SourcePosition &loc) const; void RaiseError(std::initializer_list list, const lexer::SourcePosition &loc) const; - void Result(bool res) + bool Result(bool res) { result_ = res ? RelationResult::TRUE : RelationResult::FALSE; + return res; } void Result(RelationResult res) diff --git a/ets2panda/compiler/base/lreference.cpp b/ets2panda/compiler/base/lreference.cpp index 86deaaf53..b118fdbeb 100644 --- a/ets2panda/compiler/base/lreference.cpp +++ b/ets2panda/compiler/base/lreference.cpp @@ -362,10 +362,6 @@ void ETSLReference::SetValue() const const auto *type = etsg_->Checker()->MaybeBoxedType(member_expr->PropVar(), etsg_->Allocator()); - if (type->IsETSUnionType()) { - type = type->AsETSUnionType()->GetLeastUpperBoundType(); - } - etsg_->StoreProperty(Node(), type, base_reg_, prop_name); } diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index cd7dcdc98..cb19f1672 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -457,7 +457,7 @@ static void CompileNullishCoalescing(compiler::ETSGen *etsg, ir::BinaryExpressio compile_operand(node->Left()); - if (!node->Left()->TsType()->IsNullishOrNullLike()) { + if (!etsg->Checker()->MayHaveNulllikeValue(node->Left()->TsType())) { // fallthrough } else if (node->Left()->TsType()->IsETSNullLike()) { compile_operand(node->Right()); @@ -708,7 +708,8 @@ void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calle } else { etsg->CallThisVirtual(expr, callee_reg, expr->Signature(), expr->Arguments()); } - etsg->SetAccumulatorType(expr->TsType()); + + etsg->GuardUncheckedType(expr, expr->UncheckedType(), expr->OptionalType()); } void ETSCompiler::Compile(const ir::CallExpression *expr) const @@ -848,7 +849,7 @@ static bool CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression * } if (expr->Object()->TsType()->IsETSTupleType() && (expr->GetTupleConvertedType() != nullptr)) { - etsg->EmitCheckedNarrowingReferenceConversion(expr, expr->GetTupleConvertedType()); + etsg->InternalCheckCast(expr, expr->GetTupleConvertedType()); } etsg->ApplyConversion(expr); @@ -872,7 +873,8 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const compiler::RegScope rs(etsg); - auto *const object_type = etsg->Checker()->GetNonNullishType(expr->Object()->TsType()); + auto *const object_type = + checker::ETSChecker::GetApparentType(etsg->Checker()->GetNonNullishType(expr->Object()->TsType())); if (CompileComputed(etsg, expr)) { return; @@ -939,15 +941,15 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const if (expr->PropVar()->TsType()->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { checker::Signature *sig = expr->PropVar()->TsType()->AsETSFunctionType()->FindGetter(); etsg->CallThisVirtual0(expr, obj_reg, sig->InternalName()); - etsg->SetAccumulatorType(expr->TsType()); } else if (object_type->IsETSDynamicType()) { 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); + etsg->LoadUnionProperty(expr, expr->OptionalType(), obj_reg, prop_name); } else { const auto full_name = etsg->FormClassPropReference(object_type->AsETSObjectType(), prop_name); - etsg->LoadProperty(expr, expr->OptionalType(), expr->IsGenericField(), obj_reg, full_name); + etsg->LoadProperty(expr, expr->OptionalType(), obj_reg, full_name); } + etsg->GuardUncheckedType(expr, expr->UncheckedType(), expr->OptionalType()); }; etsg->EmitMaybeOptional(expr, load_property, expr->IsOptional()); @@ -1797,7 +1799,8 @@ void ETSCompiler::Compile(const ir::TSAsExpression *expr) const break; } case checker::TypeFlag::ETS_ARRAY: - case checker::TypeFlag::ETS_OBJECT: { + case checker::TypeFlag::ETS_OBJECT: + case checker::TypeFlag::ETS_TYPE_PARAMETER: { etsg->CastToArrayOrObject(expr, target_type, expr->is_unchecked_cast_); break; } @@ -1945,7 +1948,7 @@ void ETSCompiler::Compile(const ir::TSNonNullExpression *expr) const expr->Expr()->Compile(etsg); - if (!etsg->GetAccumulatorType()->IsNullishOrNullLike()) { + if (!etsg->Checker()->MayHaveNulllikeValue(etsg->GetAccumulatorType())) { return; } diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index a8ab69e01..f450d813c 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -46,6 +46,9 @@ namespace panda::es2panda::compiler { +static constexpr auto TYPE_FLAG_BYTECODE_REF = + checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION | checker::TypeFlag::ETS_TYPE_PARAMETER; + ETSGen::ETSGen(ArenaAllocator *allocator, RegSpiller *spiller, CompilerContext *context, varbinder::FunctionScope *scope, ProgramElement *program_element, AstCompiler *astcompiler) noexcept : CodeGen(allocator, spiller, context, scope, program_element, astcompiler), @@ -74,7 +77,7 @@ void ETSGen::CompileAndCheck(const ir::Expression *expr) // This piece of code is necessary to handle multidimensional tuples. As a tuple is stored as an // array of `Objects`. If we make an array inside of the tuple type, then we won't be able to derefer a // 2 dimensional array, with an array that expects to return `Object` after index access. - EmitCheckedNarrowingReferenceConversion(expr, expr->TsType()); + CheckedReferenceNarrowing(expr, expr->TsType()); } auto const *const acc_type = GetAccumulatorType(); @@ -141,7 +144,7 @@ void ETSGen::StoreAccumulator(const ir::AstNode *const node, const VReg vreg) { const auto *const acc_type = GetAccumulatorType(); - if (acc_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (acc_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { Ra().Emit(node, vreg); } else if (acc_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Ra().Emit(node, vreg); @@ -156,7 +159,7 @@ void ETSGen::LoadAccumulator(const ir::AstNode *node, VReg vreg) { const auto *const vreg_type = GetVRegType(vreg); - if (vreg_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (vreg_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { Ra().Emit(node, vreg); } else if (vreg_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Ra().Emit(node, vreg); @@ -172,7 +175,7 @@ IRNode *ETSGen::AllocMov(const ir::AstNode *const node, const VReg vd, const VRe const auto *const source_type = GetVRegType(vs); auto *const mov = [this, source_type, node, vd, vs]() -> IRNode * { - if (source_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (source_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { return Allocator()->New(node, vd, vs); } if (source_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { @@ -210,7 +213,7 @@ void ETSGen::MoveVreg(const ir::AstNode *const node, const VReg vd, const VReg v { const auto *const source_type = GetVRegType(vs); - if (source_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (source_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { Ra().Emit(node, vd, vs); } else if (source_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Ra().Emit(node, vd, vs); @@ -300,7 +303,7 @@ void ETSGen::LoadVar(const ir::AstNode *node, varbinder::Variable const *const v } case ReferenceKind::FIELD: { const auto full_name = FormClassPropReference(GetVRegType(GetThisReg())->AsETSObjectType(), var->Name()); - LoadProperty(node, var->TsType(), false, GetThisReg(), full_name); + LoadProperty(node, var->TsType(), GetThisReg(), full_name); break; } case ReferenceKind::METHOD: @@ -392,7 +395,7 @@ void ETSGen::StoreStaticOwnProperty(const ir::AstNode *node, const checker::Type void ETSGen::StoreStaticProperty(const ir::AstNode *const node, const checker::Type *prop_type, const util::StringView &full_name) { - if (prop_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (prop_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { Sa().Emit(node, full_name); } else if (prop_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Sa().Emit(node, full_name); @@ -404,7 +407,7 @@ void ETSGen::StoreStaticProperty(const ir::AstNode *const node, const checker::T void ETSGen::LoadStaticProperty(const ir::AstNode *const node, const checker::Type *prop_type, const util::StringView &full_name) { - if (prop_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (prop_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { Sa().Emit(node, full_name); } else if (prop_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Sa().Emit(node, full_name); @@ -423,7 +426,7 @@ void ETSGen::StoreProperty(const ir::AstNode *const node, const checker::Type *p if (node->IsIdentifier() && node->AsIdentifier()->Variable()->HasFlag(varbinder::VariableFlags::BOXED)) { prop_type = Checker()->GlobalBuiltinBoxType(prop_type); } - if (prop_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + if (prop_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { Ra().Emit(node, obj_reg, full_name); } else if (prop_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Ra().Emit(node, obj_reg, full_name); @@ -432,17 +435,14 @@ void ETSGen::StoreProperty(const ir::AstNode *const node, const checker::Type *p } } -void ETSGen::LoadProperty(const ir::AstNode *const node, const checker::Type *prop_type, bool is_generic, - const VReg obj_reg, const util::StringView &full_name) +void ETSGen::LoadProperty(const ir::AstNode *const node, const checker::Type *prop_type, const VReg obj_reg, + const util::StringView &full_name) { if (node->IsIdentifier() && node->AsIdentifier()->Variable()->HasFlag(varbinder::VariableFlags::BOXED)) { prop_type = Checker()->GlobalBuiltinBoxType(prop_type); } - if (prop_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (prop_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { Ra().Emit(node, obj_reg, full_name); - if (is_generic) { - EmitCheckCast(node, prop_type); - } } else if (prop_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Ra().Emit(node, obj_reg, full_name); } else { @@ -463,14 +463,11 @@ void ETSGen::StoreUnionProperty([[maybe_unused]] const ir::AstNode *node, [[mayb } void ETSGen::LoadUnionProperty([[maybe_unused]] const ir::AstNode *const node, - [[maybe_unused]] const checker::Type *prop_type, [[maybe_unused]] bool is_generic, - [[maybe_unused]] const VReg obj_reg, [[maybe_unused]] const util::StringView &prop_name) + [[maybe_unused]] const checker::Type *prop_type, [[maybe_unused]] const VReg obj_reg, + [[maybe_unused]] const util::StringView &prop_name) { #ifdef PANDA_WITH_ETS Ra().Emit(node, obj_reg, prop_name); - if (is_generic) { - EmitCheckCast(node, prop_type); - } SetAccumulatorType(prop_type); #else UNREACHABLE(); @@ -500,7 +497,7 @@ void ETSGen::StorePropertyDynamic(const ir::AstNode *node, const checker::Type * method_name = Signatures::Dynamic::SetPropertyDoubleBuiltin(lang); } else if (prop_type->IsETSStringType()) { method_name = Signatures::Dynamic::SetPropertyStringBuiltin(lang); - } else if (prop_type->IsETSObjectType()) { + } else if (prop_type->IsETSObjectType() || prop_type->IsETSTypeParameter()) { method_name = Signatures::Dynamic::SetPropertyDynamicBuiltin(lang); // NOTE: vpukhov. add non-dynamic builtin if (!prop_type->IsETSDynamicType()) { @@ -549,7 +546,7 @@ void ETSGen::LoadPropertyDynamic(const ir::AstNode *node, const checker::Type *p method_name = Signatures::Dynamic::GetPropertyDoubleBuiltin(lang); } else if (prop_type->IsETSStringType()) { method_name = Signatures::Dynamic::GetPropertyStringBuiltin(lang); - } else if (prop_type->IsETSObjectType()) { + } else if (prop_type->IsETSObjectType() || prop_type->IsETSTypeParameter()) { method_name = Signatures::Dynamic::GetPropertyDynamicBuiltin(lang); type = Checker()->GlobalBuiltinDynamicType(lang); } else { @@ -713,7 +710,7 @@ void ETSGen::LoadDefaultValue([[maybe_unused]] const ir::AstNode *node, [[maybe_ if (type->IsETSUnionType()) { type = Checker()->GetGlobalTypesHolder()->GlobalETSObjectType(); } - if (type->IsETSObjectType() || type->IsETSArrayType()) { + if (type->IsETSObjectType() || type->IsETSArrayType() || type->IsETSTypeParameter()) { LoadAccumulatorNull(node, type); } else if (type->IsETSBooleanType()) { LoadAccumulatorBoolean(node, type->AsETSBooleanType()->GetValue()); @@ -738,7 +735,7 @@ void ETSGen::ReturnAcc(const ir::AstNode *node) { const auto *const acc_type = GetAccumulatorType(); - if (acc_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)) { + if (acc_type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { Sa().Emit(node); } else if (acc_type->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Sa().Emit(node); @@ -754,7 +751,7 @@ void ETSGen::EmitIsInstanceNonNullish([[maybe_unused]] const ir::AstNode *const #ifdef PANDA_WITH_ETS auto const obj_type = GetVRegType(obj_reg); // undefined is implemented as Object instance, so "instanceof Object" must be treated carefully - if (!obj_type->ContainsUndefined() || cls_type != Checker()->GlobalETSObjectType()) { + if (!Checker()->MayHaveUndefinedValue(obj_type) || cls_type != Checker()->GlobalETSObjectType()) { LoadAccumulator(node, obj_reg); Sa().Emit(node, cls_type->AssemblerName()); SetAccumulatorType(Checker()->GlobalETSBooleanType()); @@ -794,7 +791,7 @@ void ETSGen::EmitIsInstance([[maybe_unused]] const ir::AstNode *const node, [[ma return; } - if (!rhs_type->IsNullishOrNullLike()) { + if (!Checker()->MayHaveNulllikeValue(rhs_type)) { EmitIsInstanceNonNullish(node, obj_reg, rhs_type); return; } @@ -805,10 +802,10 @@ void ETSGen::EmitIsInstance([[maybe_unused]] const ir::AstNode *const node, [[ma LoadAccumulator(node, obj_reg); // Iterate union members - if (rhs_type->ContainsNull() || rhs_type->IsETSNullType()) { + if (Checker()->MayHaveNullValue(rhs_type)) { BranchIfNull(node, if_true); } - if (rhs_type->ContainsUndefined() || rhs_type->IsETSUndefinedType()) { + if (Checker()->MayHaveUndefinedValue(rhs_type)) { Sa().Emit(node); BranchIfTrue(node, if_true); LoadAccumulator(node, obj_reg); @@ -828,6 +825,32 @@ void ETSGen::EmitIsInstance([[maybe_unused]] const ir::AstNode *const node, [[ma #endif // PANDA_WITH_ETS } +void ETSGen::InternalCheckCast(const ir::AstNode *node, const es2panda::checker::Type *target) +{ + ASSERT(target->IsETSObjectType() && !target->IsNullishOrNullLike()); + Sa().Emit(node, ToAssemblerType(target)); + SetAccumulatorType(target); +} + +void ETSGen::CheckedReferenceNarrowing(const ir::AstNode *node, const checker::Type *target) +{ + ASSERT(target->HasTypeFlag(TYPE_FLAG_BYTECODE_REF) && !target->IsETSNullLike()); + // NOTE(vpukhov): implement for nulllike and union targets + + Sa().Emit(node, ToAssemblerType(target)); + SetAccumulatorType(target); +} + +void ETSGen::GuardUncheckedType(const ir::AstNode *node, const checker::Type *unchecked, const checker::Type *target) +{ + if (unchecked != nullptr) { + SetAccumulatorType(unchecked); + CheckedReferenceNarrowing(node, target); + } else { + SetAccumulatorType(target); + } +} + bool ETSGen::TryLoadConstantExpression(const ir::Expression *node) { const auto *type = node->TsType(); @@ -900,8 +923,8 @@ void ETSGen::ApplyConversionCast(const ir::AstNode *node, const checker::Type *t break; } case checker::TypeFlag::ETS_ARRAY: - [[fallthrough]]; - case checker::TypeFlag::ETS_OBJECT: { + case checker::TypeFlag::ETS_OBJECT: + case checker::TypeFlag::ETS_TYPE_PARAMETER: { if (GetAccumulatorType() != nullptr && GetAccumulatorType()->IsETSDynamicType()) { CastDynamicToObject(node, target_type); } @@ -926,7 +949,7 @@ void ETSGen::ApplyBoxingConversion(const ir::AstNode *node) void ETSGen::ApplyUnboxingConversion(const ir::AstNode *node) { - if (GetAccumulatorType()->IsNullishOrNullLike()) { // NOTE: vpukhov. should be a CTE + if (Checker()->MayHaveNulllikeValue(GetAccumulatorType())) { // NOTE: vpukhov. should be a CTE EmitNullishGuardian(node); } EmitUnboxingConversion(node); @@ -952,7 +975,7 @@ void ETSGen::ApplyConversion(const ir::AstNode *node, const checker::Type *targe } if (target_type->IsETSUnionType()) { - SetAccumulatorType(target_type->AsETSUnionType()->GetLeastUpperBoundType()); + SetAccumulatorType(target_type); return; } @@ -1000,7 +1023,7 @@ void ETSGen::EmitUnboxingConversion(const ir::AstNode *node) auto emit_unboxed_call = [this, &node](std::string_view signature_flag, const checker::Type *const target_type, const checker::Type *const boxed_type) { if (node->HasAstNodeFlags(ir::AstNodeFlags::CHECKCAST)) { - EmitCheckedNarrowingReferenceConversion(node, boxed_type); + CheckedReferenceNarrowing(node, boxed_type); } Ra().Emit(node, signature_flag, dummy_reg_, 0); @@ -1187,7 +1210,7 @@ void ETSGen::EmitLocalBoxGet(ir::AstNode const *node, checker::Type const *conte break; default: Ra().Emit(node, Signatures::BUILTIN_BOX_GET, dummy_reg_, 0); - EmitCheckCast(node, content_type); + CheckedReferenceNarrowing(node, content_type); break; } SetAccumulatorType(content_type); @@ -1569,7 +1592,7 @@ void ETSGen::CastToInt(const ir::AstNode *node) void ETSGen::CastToArrayOrObject(const ir::AstNode *const node, const checker::Type *const target_type, const bool unchecked) { - ASSERT(GetAccumulatorType()->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION)); + ASSERT(GetAccumulatorType()->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)); const auto *const source_type = GetAccumulatorType(); @@ -1583,12 +1606,17 @@ void ETSGen::CastToArrayOrObject(const ir::AstNode *const node, const checker::T return; } - if (unchecked) { - SetAccumulatorType(target_type); + if (!unchecked) { + CheckedReferenceNarrowing(node, target_type); return; } - EmitCheckedNarrowingReferenceConversion(node, target_type); + if (target_type->IsETSTypeParameter() && target_type->AsETSTypeParameter()->HasConstraint()) { + CheckedReferenceNarrowing(node, target_type->AsETSTypeParameter()->GetConstraintType()); + } else if (target_type->IsETSObjectType()) { + CheckedReferenceNarrowing(node, target_type->AsETSObjectType()->GetConstOriginalBaseType()); + } + SetAccumulatorType(target_type); } void ETSGen::CastDynamicToObject(const ir::AstNode *node, const checker::Type *target_type) @@ -1598,14 +1626,13 @@ void ETSGen::CastDynamicToObject(const ir::AstNode *node, const checker::Type *t return; } - // NOTE: itrubachev. Introduce checker::TypeFlag::LAMBDA_OBJECT and lambda object type itself in es2panda. - // Now lambda object is any class with invoke method, that seems strange + // NOTE(vpukhov): #14626 remove, replace target_type with interface if (target_type->IsLambdaObject()) { VReg dyn_obj_reg = AllocReg(); StoreAccumulator(node, dyn_obj_reg); Ra().Emit(node, target_type->AsETSObjectType()->ConstructSignatures()[0]->InternalName(), dyn_obj_reg, dummy_reg_); - SetAccumulatorType(Checker()->GlobalETSObjectType()); + SetAccumulatorType(target_type); return; } @@ -1619,7 +1646,7 @@ void ETSGen::CastDynamicToObject(const ir::AstNode *node, const checker::Type *t return; } - if (target_type->IsETSArrayType() || target_type->IsETSObjectType()) { + if (target_type->IsETSArrayType() || target_type->IsETSObjectType() || target_type->IsETSTypeParameter()) { auto lang = GetAccumulatorType()->AsETSDynamicType()->Language(); auto method_name = compiler::Signatures::Dynamic::GetObjectBuiltin(lang); @@ -1691,7 +1718,8 @@ void ETSGen::CastToDynamic(const ir::AstNode *node, const checker::ETSDynamicTyp method_name = compiler::Signatures::Dynamic::NewDoubleBuiltin(type->Language()); break; } - case checker::TypeFlag::ETS_OBJECT: { + case checker::TypeFlag::ETS_OBJECT: + case checker::TypeFlag::ETS_TYPE_PARAMETER: { if (GetAccumulatorType()->IsETSStringType()) { method_name = compiler::Signatures::Dynamic::NewStringBuiltin(type->Language()); break; @@ -1793,16 +1821,6 @@ void ETSGen::CastDynamicTo(const ir::AstNode *node, enum checker::TypeFlag type_ SetAccumulatorType(object_type); } -void ETSGen::EmitCheckedNarrowingReferenceConversion(const ir::AstNode *const node, - const checker::Type *const target_type) -{ - ASSERT(target_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT | checker::TypeFlag::ETS_UNION) && - !target_type->IsETSNullLike()); - - Sa().Emit(node, ToCheckCastTypeView(target_type)); - SetAccumulatorType(target_type); -} - void ETSGen::ToBinaryResult(const ir::AstNode *node, Label *if_false) { Label *end = AllocLabel(); @@ -1975,14 +1993,14 @@ void ETSGen::BranchIfNullish([[maybe_unused]] const ir::AstNode *node, [[maybe_u #ifdef PANDA_WITH_ETS auto *const type = GetAccumulatorType(); - if (!type->IsNullishOrNullLike()) { + if (!Checker()->MayHaveNulllikeValue(type)) { return; } if (type->IsETSNullLike()) { Sa().Emit(node, if_nullish); return; } - if (!type->ContainsUndefined()) { + if (!Checker()->MayHaveUndefinedValue(type)) { Sa().Emit(node, if_nullish); return; } @@ -2011,14 +2029,14 @@ void ETSGen::BranchIfNotNullish([[maybe_unused]] const ir::AstNode *node, [[mayb #ifdef PANDA_WITH_ETS auto *const type = GetAccumulatorType(); - if (!type->IsNullishOrNullLike()) { + if (!Checker()->MayHaveNulllikeValue(type)) { Sa().Emit(node, if_not_nullish); return; } if (type->IsETSNullLike()) { return; } - if (!type->ContainsUndefined()) { + if (!Checker()->MayHaveUndefinedValue(type)) { Sa().Emit(node, if_not_nullish); return; } @@ -2048,8 +2066,8 @@ void ETSGen::ConvertToNonNullish(const ir::AstNode *node) { auto const *nullish_type = GetAccumulatorType(); auto const *target_type = Checker()->GetNonNullishType(nullish_type); - if (nullish_type->ContainsUndefined() && target_type != Checker()->GlobalETSObjectType()) { - EmitCheckedNarrowingReferenceConversion(node, target_type); + if (Checker()->MayHaveUndefinedValue(nullish_type) && target_type != Checker()->GlobalETSObjectType()) { + CheckedReferenceNarrowing(node, target_type); } SetAccumulatorType(target_type); } @@ -2057,7 +2075,7 @@ void ETSGen::ConvertToNonNullish(const ir::AstNode *node) void ETSGen::EmitNullishGuardian(const ir::AstNode *node) { auto const *nullish_type = GetAccumulatorType(); - ASSERT(nullish_type->IsNullish()); + ASSERT(Checker()->MayHaveNulllikeValue(nullish_type)); compiler::Label *if_not_nullish = AllocLabel(); BranchIfNotNullish(node, if_not_nullish); @@ -2263,17 +2281,6 @@ void ETSGen::UnaryDollarDollar(const ir::AstNode *node) EmitThrow(node, exception); } -void ETSGen::InsertNeededCheckCast(const checker::Signature *signature, const ir::AstNode *node) -{ - if (signature->IsBaseReturnDiff()) { - EmitCheckCast(node, signature->ReturnType()); - } else if (signature->HasSignatureFlag(checker::SignatureFlags::THIS_RETURN_TYPE)) { - ASSERT(node->IsCallExpression()); - - EmitCheckCast(node, node->AsCallExpression()->TsType()); - } -} - void ETSGen::Update(const ir::AstNode *node, lexer::TokenType op) { switch (op) { @@ -2316,8 +2323,9 @@ void ETSGen::StringBuilderAppend(const ir::AstNode *node, VReg builder) signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_BUILTIN_STRING; } - if (GetAccumulatorType()->IsETSObjectType() && !GetAccumulatorType()->IsETSStringType()) { - if (GetAccumulatorType()->ContainsNull() || GetAccumulatorType()->IsETSNullType()) { + if ((GetAccumulatorType()->IsETSObjectType() || GetAccumulatorType()->IsETSTypeParameter()) && + !GetAccumulatorType()->IsETSStringType()) { + if (Checker()->MayHaveNullValue(GetAccumulatorType())) { Label *ifnull = AllocLabel(); Label *end = AllocLabel(); BranchIfNull(node, ifnull); @@ -2447,10 +2455,6 @@ void ETSGen::LoadArrayElement(const ir::AstNode *node, VReg object_reg) { auto *element_type = GetVRegType(object_reg)->AsETSArrayType()->ElementType(); - if (element_type->IsETSUnionType()) { - element_type = element_type->AsETSUnionType()->GetLeastUpperBoundType(); - } - switch (checker::ETSChecker::ETSType(element_type)) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: { @@ -2486,6 +2490,8 @@ void ETSGen::LoadArrayElement(const ir::AstNode *node, VReg object_reg) } case checker::TypeFlag::ETS_ARRAY: case checker::TypeFlag::ETS_OBJECT: + case checker::TypeFlag::ETS_TYPE_PARAMETER: + case checker::TypeFlag::ETS_UNION: case checker::TypeFlag::ETS_DYNAMIC_TYPE: { Ra().Emit(node, object_reg); break; @@ -2501,9 +2507,6 @@ void ETSGen::LoadArrayElement(const ir::AstNode *node, VReg object_reg) void ETSGen::StoreArrayElement(const ir::AstNode *node, VReg object_reg, VReg index, const checker::Type *element_type) { - if (element_type->IsETSUnionType()) { - element_type = element_type->AsETSUnionType()->GetLeastUpperBoundType(); - } switch (checker::ETSChecker::ETSType(element_type)) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: { @@ -2536,6 +2539,8 @@ void ETSGen::StoreArrayElement(const ir::AstNode *node, VReg object_reg, VReg in } case checker::TypeFlag::ETS_ARRAY: case checker::TypeFlag::ETS_OBJECT: + case checker::TypeFlag::ETS_TYPE_PARAMETER: + case checker::TypeFlag::ETS_UNION: case checker::TypeFlag::ETS_DYNAMIC_TYPE: { Ra().Emit(node, object_reg, index); break; @@ -2639,23 +2644,13 @@ bool ETSGen::ExtendWithFinalizer(ir::AstNode *node, const ir::AstNode *original_ return ExtendWithFinalizer(parent, original_node, prev_finnaly); } -util::StringView ETSGen::ToCheckCastTypeView(const es2panda::checker::Type *type) const +util::StringView ETSGen::ToAssemblerType(const es2panda::checker::Type *type) const { - auto asm_t = type; - if (type->IsETSUnionType()) { - asm_t = type->AsETSUnionType()->GetLeastUpperBoundType(); - } + ASSERT(type->HasTypeFlag(TYPE_FLAG_BYTECODE_REF) && !type->IsETSNullLike()); + std::stringstream ss; - asm_t->ToAssemblerTypeWithRank(ss); + type->ToAssemblerTypeWithRank(ss); return util::UString(ss.str(), Allocator()).View(); } -void ETSGen::EmitCheckCast(const ir::AstNode *node, const es2panda::checker::Type *type) -{ - if (type->IsETSArrayType()) { - return; // Since generic arrays allowed we can't add checkcast for them. - } - Ra().Emit(node, ToCheckCastTypeView(type)); -} - } // namespace panda::es2panda::compiler diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 6e93a1c48..e074af2d7 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -69,7 +69,7 @@ public: void StoreProperty(const ir::AstNode *node, const checker::Type *prop_type, VReg obj_reg, const util::StringView &name); - void LoadProperty(const ir::AstNode *node, const checker::Type *prop_type, bool is_generic, VReg obj_reg, + void LoadProperty(const ir::AstNode *node, const checker::Type *prop_type, 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); @@ -80,7 +80,7 @@ public: 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, + void LoadUnionProperty(const ir::AstNode *node, const checker::Type *prop_type, VReg obj_reg, const util::StringView &prop_name); void LoadUndefinedDynamic(const ir::AstNode *node, Language lang); @@ -225,7 +225,7 @@ public: } Label *if_nullish {nullptr}; Label *end {nullptr}; - if (type->IsNullishOrNullLike()) { + if (Checker()->MayHaveNulllikeValue(type)) { if constexpr (USE_FALSE_LABEL) { BranchIfNullish(node, if_false); } else { @@ -307,7 +307,7 @@ public: { auto *const type = GetAccumulatorType(); - if (!type->IsNullishOrNullLike()) { + if (!Checker()->MayHaveNulllikeValue(type)) { compile(); } else if (type->IsETSNullLike()) { if (is_optional) { @@ -541,9 +541,12 @@ public: void CastToDynamic(const ir::AstNode *node, const checker::ETSDynamicType *type); void CastDynamicTo(const ir::AstNode *node, enum checker::TypeFlag type_flag); void CastToArrayOrObject(const ir::AstNode *node, const checker::Type *target_type, bool unchecked); - void EmitCheckedNarrowingReferenceConversion(const ir::AstNode *node, const checker::Type *target_type); void CastDynamicToObject(const ir::AstNode *node, const checker::Type *target_type); + void InternalCheckCast(const ir::AstNode *node, const checker::Type *target); + void CheckedReferenceNarrowing(const ir::AstNode *node, const checker::Type *target); + void GuardUncheckedType(const ir::AstNode *node, const checker::Type *unchecked, const checker::Type *target); + // Call, Construct void NewArray(const ir::AstNode *node, VReg arr, VReg dim, const checker::Type *arr_type); void NewObject(const ir::AstNode *node, VReg ctor, util::StringView name); @@ -664,11 +667,7 @@ private: void UnaryTilde(const ir::AstNode *node); void UnaryDollarDollar(const ir::AstNode *node); - util::StringView ToCheckCastTypeView(const es2panda::checker::Type *type) const; - void EmitCheckCast(const ir::AstNode *node, const es2panda::checker::Type *type); - - // To avoid verifier error checkcast is needed - void InsertNeededCheckCast(const checker::Signature *signature, const ir::AstNode *node); + util::StringView ToAssemblerType(const es2panda::checker::Type *type) const; template void StoreValueIntoArray(const ir::AstNode *const node, const VReg arr, const VReg index) @@ -759,6 +758,7 @@ private: switch (type_kind) { case checker::TypeFlag::ETS_OBJECT: + case checker::TypeFlag::ETS_TYPE_PARAMETER: case checker::TypeFlag::ETS_DYNAMIC_TYPE: { RegScope rs(this); VReg arg0 = AllocReg(); @@ -969,8 +969,6 @@ private: break; } } - - InsertNeededCheckCast(signature, node); } template @@ -1025,8 +1023,6 @@ private: break; } } - - InsertNeededCheckCast(signature, node); } #undef COMPILE_ARG @@ -1080,8 +1076,6 @@ private: break; } } - - InsertNeededCheckCast(signature, node); } #undef COMPILE_ARG diff --git a/ets2panda/ir/expressions/callExpression.h b/ets2panda/ir/expressions/callExpression.h index 067c7fda4..e95b9ac20 100644 --- a/ets2panda/ir/expressions/callExpression.h +++ b/ets2panda/ir/expressions/callExpression.h @@ -121,6 +121,16 @@ public: type_params_ = type_params; } + [[nodiscard]] checker::Type *UncheckedType() const noexcept + { + return unchecked_type_; + } + + void SetUncheckedType(checker::Type *type) noexcept + { + unchecked_type_ = type; + } + void SetTrailingBlock(ir::BlockStatement *const block) noexcept { trailing_block_ = block; @@ -169,6 +179,7 @@ protected: // for trailing lambda feature in ets ir::BlockStatement *trailing_block_ {}; bool is_trailing_block_in_new_line_ {false}; + checker::Type *unchecked_type_ {}; // NOLINTEND(misc-non-private-member-variables-in-classes) private: diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index 5ad1e8dc0..68cfc53cb 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -201,22 +201,26 @@ checker::Type *MemberExpression::CheckUnionMember(checker::ETSChecker *checker, common_prop_type = member_type; }; for (auto *const type : union_type->ConstituentTypes()) { - if (type->IsETSObjectType()) { - SetObjectType(type->AsETSObjectType()); + auto *const apparent = checker->GetApparentType(type); + if (apparent->IsETSObjectType()) { + SetObjectType(apparent->AsETSObjectType()); add_prop_type(ResolveObjectMember(checker).first); - } else if (type->IsETSEnumType() || base_type->IsETSStringEnumType()) { - add_prop_type(ResolveEnumMember(checker, type).first); + } else if (apparent->IsETSEnumType() || base_type->IsETSStringEnumType()) { + add_prop_type(ResolveEnumMember(checker, apparent).first); } else { UNREACHABLE(); } } - SetObjectType(union_type->GetLeastUpperBoundType(checker)->AsETSObjectType()); + SetObjectType(union_type->GetLeastUpperBoundType()->AsETSObjectType()); return common_prop_type; } -checker::Type *MemberExpression::AdjustOptional(checker::ETSChecker *checker, checker::Type *type) +checker::Type *MemberExpression::AdjustType(checker::ETSChecker *checker, checker::Type *type) { SetOptionalType(type); + if (PropVar() != nullptr) { + unchecked_type_ = checker->GuaranteedTypeForUncheckedPropertyAccess(PropVar()); + } if (IsOptional() && Object()->TsType()->IsNullishOrNullLike()) { checker->Relation()->SetNode(this); type = checker->CreateOptionalResultType(type); @@ -356,12 +360,6 @@ checker::Type *MemberExpression::CheckComputed(checker::ETSChecker *checker, che CheckArrayIndexValue(checker); } - if (property_->IsIdentifier()) { - SetPropVar(property_->AsIdentifier()->Variable()->AsLocalVariable()); - } else if (auto var = property_->Variable(); (var != nullptr) && var->IsLocalVariable()) { - SetPropVar(var->AsLocalVariable()); - } - // NOTE: apply capture conversion on this type if (base_type->IsETSArrayType()) { if (base_type->IsETSTupleType()) { @@ -417,21 +415,4 @@ MemberExpression *MemberExpression::Clone(ArenaAllocator *const allocator, AstNo throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); } -bool MemberExpression::IsGenericField() const -{ - const auto obj_t = object_->TsType(); - if (!obj_t->IsETSObjectType()) { - return false; - } - auto base_class_t = obj_t->AsETSObjectType()->GetBaseType(); - if (base_class_t == nullptr) { - return false; - } - const auto &prop_name = property_->AsIdentifier()->Name(); - auto base_prop = base_class_t->GetProperty(prop_name, checker::PropertySearchFlags::SEARCH_FIELD); - if (base_prop == nullptr || base_prop->TsType() == nullptr) { - return false; - } - return TsType()->ToAssemblerName().str() != base_prop->TsType()->ToAssemblerName().str(); -} } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/expressions/memberExpression.h b/ets2panda/ir/expressions/memberExpression.h index 57305e315..660b71081 100644 --- a/ets2panda/ir/expressions/memberExpression.h +++ b/ets2panda/ir/expressions/memberExpression.h @@ -155,6 +155,11 @@ public: ignore_box_ = true; } + [[nodiscard]] checker::Type *UncheckedType() const noexcept + { + return unchecked_type_; + } + checker::Type *GetTupleConvertedType() const noexcept { return tuple_converted_type_; @@ -203,7 +208,7 @@ private: checker::Type *type) const; std::pair ResolveObjectMember(checker::ETSChecker *checker) const; - checker::Type *AdjustOptional(checker::ETSChecker *checker, checker::Type *type); + checker::Type *AdjustType(checker::ETSChecker *checker, checker::Type *type); checker::Type *CheckComputed(checker::ETSChecker *checker, checker::Type *base_type); checker::Type *CheckUnionMember(checker::ETSChecker *checker, checker::Type *base_type); @@ -212,13 +217,13 @@ private: checker::Type *CheckTupleAccessMethod(checker::ETSChecker *checker, checker::Type *base_type); void LoadRhs(compiler::PandaGen *pg) const; - bool IsGenericField() const; Expression *object_ = nullptr; Expression *property_ = nullptr; MemberExpressionKind kind_; bool computed_; bool ignore_box_ {false}; + checker::Type *unchecked_type_ {}; varbinder::LocalVariable *prop_var_ {}; checker::ETSObjectType *obj_type_ {}; checker::Type *tuple_converted_type_ {}; diff --git a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt index 4769cb130..426576fd8 100644 --- a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt +++ b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt @@ -10900,67 +10900,121 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { + "type": "TSAsExpression", + "expression": { "type": "MemberExpression", "object": { - "type": "ThisExpression", + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 132, + "column": 18 + }, + "end": { + "line": 132, + "column": 22 + } + } + }, + "property": { + "type": "Identifier", + "name": "data", + "decorators": [], + "loc": { + "start": { + "line": 132, + "column": 23 + }, + "end": { + "line": 132, + "column": 27 + } + } + }, + "computed": false, + "optional": false, "loc": { "start": { "line": 132, - "column": 17 + "column": 18 }, "end": { "line": 132, - "column": 21 + "column": 27 } } }, "property": { "type": "Identifier", - "name": "data", + "name": "i", "decorators": [], "loc": { "start": { "line": 132, - "column": 22 + "column": 28 }, "end": { "line": 132, - "column": 26 + "column": 29 } } }, - "computed": false, + "computed": true, "optional": false, "loc": { "start": { "line": 132, - "column": 17 + "column": 18 }, "end": { "line": 132, - "column": 26 + "column": 30 } } }, - "property": { - "type": "Identifier", - "name": "i", - "decorators": [], + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 132, + "column": 34 + }, + "end": { + "line": 132, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 132, + "column": 34 + }, + "end": { + "line": 132, + "column": 41 + } + } + }, "loc": { "start": { "line": 132, - "column": 27 + "column": 34 }, "end": { "line": 132, - "column": 28 + "column": 41 } } }, - "computed": true, - "optional": false, "loc": { "start": { "line": 132, @@ -10968,7 +11022,7 @@ }, "end": { "line": 132, - "column": 29 + "column": 41 } } }, @@ -10979,11 +11033,11 @@ "loc": { "start": { "line": 132, - "column": 30 + "column": 42 }, "end": { "line": 132, - "column": 36 + "column": 48 } } }, @@ -10996,23 +11050,77 @@ }, "end": { "line": 132, - "column": 36 + "column": 48 } } }, "arguments": [ { - "type": "Identifier", - "name": "e", - "decorators": [], + "type": "TSAsExpression", + "expression": { + "type": "Identifier", + "name": "e", + "decorators": [], + "loc": { + "start": { + "line": 132, + "column": 49 + }, + "end": { + "line": 132, + "column": 50 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 132, + "column": 54 + }, + "end": { + "line": 132, + "column": 60 + } + } + }, + "loc": { + "start": { + "line": 132, + "column": 54 + }, + "end": { + "line": 132, + "column": 61 + } + } + }, + "loc": { + "start": { + "line": 132, + "column": 54 + }, + "end": { + "line": 132, + "column": 61 + } + } + }, "loc": { "start": { "line": 132, - "column": 37 + "column": 49 }, "end": { "line": 132, - "column": 38 + "column": 50 } } } @@ -11025,7 +11133,7 @@ }, "end": { "line": 132, - "column": 39 + "column": 61 } } }, @@ -11063,7 +11171,7 @@ "loc": { "start": { "line": 132, - "column": 41 + "column": 63 }, "end": { "line": 134, diff --git a/ets2panda/test/compiler/ets/generic_arrayaslist.ets b/ets2panda/test/compiler/ets/generic_arrayaslist.ets index 120673db7..9c2801195 100644 --- a/ets2panda/test/compiler/ets/generic_arrayaslist.ets +++ b/ets2panda/test/compiler/ets/generic_arrayaslist.ets @@ -129,7 +129,7 @@ class ArrayAsListt implements Listt { assert false: "Not implemented: internal issue with calling equals"; for (let i = 0; i < this.curSize; ++i) { - if (this.data[i].equals(e)) { + if ((this.data[i] as Object).equals(e as Object)) { return true; } } diff --git a/ets2panda/test/compiler/ets/generics_implicit_lambda2-expected.txt b/ets2panda/test/compiler/ets/generics_implicit_lambda2-expected.txt index 642f8dc36..2191f1795 100644 --- a/ets2panda/test/compiler/ets/generics_implicit_lambda2-expected.txt +++ b/ets2panda/test/compiler/ets/generics_implicit_lambda2-expected.txt @@ -1082,4 +1082,4 @@ } } } -TypeError: Type parameter already instantiated with another type [generics_implicit_lambda2.ets:16:17] +TypeError: No matching call signature [generics_implicit_lambda2.ets:19:5] diff --git a/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt b/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt index 7aee39031..7e2cc15cd 100644 --- a/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt +++ b/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt @@ -39,6 +39,47 @@ } } }, + "constraint": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 26 + } + } + }, "loc": { "start": { "line": 16, @@ -46,7 +87,7 @@ }, "end": { "line": 16, - "column": 11 + "column": 26 } } } @@ -58,7 +99,7 @@ }, "end": { "line": 16, - "column": 11 + "column": 26 } } }, @@ -604,7 +645,7 @@ "loc": { "start": { "line": 16, - "column": 12 + "column": 27 }, "end": { "line": 22, diff --git a/ets2panda/test/compiler/ets/generics_instantiation_3.ets b/ets2panda/test/compiler/ets/generics_instantiation_3.ets index 248620d3b..53882858e 100644 --- a/ets2panda/test/compiler/ets/generics_instantiation_3.ets +++ b/ets2panda/test/compiler/ets/generics_instantiation_3.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -class A { +class A { public foo(e: T): void { this.data[2].equals(e); } diff --git a/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt b/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt index 8652bd2ed..03c646f0d 100644 --- a/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt +++ b/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt @@ -528,4 +528,3 @@ } } } -TypeError: Call argument at index 0 is not compatible with the signature's type at that index. [genericDefaultParam_3.ets:20:6] diff --git a/ets2panda/test/runtime/ets/UncheckedCasts.ets b/ets2panda/test/runtime/ets/UncheckedCasts.ets new file mode 100644 index 000000000..f5852a44e --- /dev/null +++ b/ets2panda/test/runtime/ets/UncheckedCasts.ets @@ -0,0 +1,78 @@ +/* + * 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. + */ + +type Nullish = Object | null | undefined; + +class Bad { } +class X { } + +function expect_ccexc(fn: () => void) { + try { + fn(); + assert false; + } catch (e: Exception) { + assert(e instanceof ClassCastException); + } +} + +class G { + erase(x: Nullish): T { return x as T; } +} +function check_G_Object(x: Nullish) { + expect_ccexc(() => { new G().erase(x); }) +} +function check_G_X(x: Nullish) { + expect_ccexc(() => { new G().erase(x); }) +} +function test_substitution() { + //check_G_Object(null); + //check_G_Object(undefined); + //check_G_X(null); + check_G_X(undefined); + check_G_X(new Object()); + check_G_X(new Bad()); +} + +class CG { + pass(x: Nullish) { x as T; } +} +function check_CG_X(x: Nullish) { + expect_ccexc(() => { new CG().pass(x); }) +} +function test_constraint() { + //check_CG_X(null); + check_CG_X(undefined); + check_CG_X(new Object()); + check_CG_X(new Bad()); +} + +class GG { + pass(x: Nullish) { x as G; } +} +function check_GG(x: Nullish) { + expect_ccexc(() => { new GG().pass(x); }) +} +function test_basetype() { + //check_GG(null); + check_GG(undefined); + check_GG(new Object()); +} + +function main() { + // NOTE(vpukhov): add nullability checks, add union param/constraint tests + test_substitution(); + test_constraint(); + test_basetype(); +} diff --git a/ets2panda/test/runtime/ets/UnionConstraint.ets b/ets2panda/test/runtime/ets/UnionConstraint.ets new file mode 100644 index 000000000..9cadb73ac --- /dev/null +++ b/ets2panda/test/runtime/ets/UnionConstraint.ets @@ -0,0 +1,31 @@ +/* + * 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 X { } +function id(x: T) { return x } + +function id_s(x: string) { return id(x) } +function id_sx(x: string | X) { return id(x) } + +function main() { + let x = new X(); + + assert(id(1.1) == 1.1); + assert(id("a") == "a"); + assert(id(x) == x); + + assert(id_s("a") == "a"); + assert(id_sx(x) == x); +} diff --git a/ets2panda/test/runtime/ets/generic-function.ets b/ets2panda/test/runtime/ets/generic-function.ets index 19c2f7c72..1c1469d45 100644 --- a/ets2panda/test/runtime/ets/generic-function.ets +++ b/ets2panda/test/runtime/ets/generic-function.ets @@ -19,7 +19,7 @@ class cls extends Object { } } -function foo(item : T) : String { +function foo(item : T) : String { let str = item.toString(); return str; } diff --git a/ets2panda/test/test-lists/parser/parser-js-ignored.txt b/ets2panda/test/test-lists/parser/parser-js-ignored.txt index 6d530536f..0b48aa71f 100644 --- a/ets2panda/test/test-lists/parser/parser-js-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-js-ignored.txt @@ -66,3 +66,6 @@ parser/ets/null-coalesc-negative.ets # Lambda tests, disabled because crash during compiler parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body_capture_variable.ets + +# Bad test shadows Object with type parameter name #14913 +compiler/ets/override13.ets diff --git a/ets2panda/util/declgenEts2Ts.cpp b/ets2panda/util/declgenEts2Ts.cpp index 0d88da396..2cb69ab4b 100644 --- a/ets2panda/util/declgenEts2Ts.cpp +++ b/ets2panda/util/declgenEts2Ts.cpp @@ -180,6 +180,10 @@ void TSDeclGen::GenTypeNonNullish(const checker::Type *checker_type) GenObjectType(checker_type->AsETSObjectType()); return; } + if (checker_type->IsETSTypeParameter()) { + GenTypeParameterType(checker_type->AsETSTypeParameter()); + return; + } // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define TYPE_CHECKS(typeFlag, typeName) \ @@ -314,6 +318,11 @@ void TSDeclGen::GenObjectType(const checker::ETSObjectType *object_type) } } +void TSDeclGen::GenTypeParameterType(const checker::ETSTypeParameter *type_param) +{ + Out(type_param->GetDeclNode()->Name()->Name()); +} + void TSDeclGen::GenTypeParameters(const ir::TSTypeParameterDeclaration *type_params) { if (type_params != nullptr) { diff --git a/ets2panda/util/declgenEts2Ts.h b/ets2panda/util/declgenEts2Ts.h index 0bed55d82..bd3f36671 100644 --- a/ets2panda/util/declgenEts2Ts.h +++ b/ets2panda/util/declgenEts2Ts.h @@ -50,6 +50,7 @@ private: void GenTypeNonNullish(const checker::Type *checker_type); void GenFunctionType(const checker::ETSFunctionType *function_type, const ir::MethodDefinition *method_def = nullptr); + void GenTypeParameterType(const checker::ETSTypeParameter *type_param); void GenObjectType(const checker::ETSObjectType *object_type); void GenEnumType(const checker::ETSEnumType *enum_type); -- Gitee