From 0568453a310b42b194e4cdad6c0d523661ed78a5 Mon Sep 17 00:00:00 2001 From: Boglarka Haag Date: Thu, 11 Jul 2024 09:18:50 +0200 Subject: [PATCH 01/15] Segfault on inheriting generated getter-setter Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IABOAY Reason: Segmentation fault occured when we tried to inherit from a class which implemented an interface with properties without implenting the getter-setters explicitly. Description: The generated getter-setters didn't changed the declaration's node from class property to the new method definition. Test scenarios (new, modified, affected functions): infer_igetter_setter_implementation_1.ets infer_igetter_setter_implementation_2.ets Signed-off-by: Haag Boglarka --- ets2panda/checker/ets/helpers.cpp | 20 ++++----- ets2panda/checker/ets/object.cpp | 4 +- ...herited_getter_setter_implementation_1.ets | 31 +++++++++++++ ...herited_getter_setter_implementation_2.ets | 43 +++++++++++++++++++ 4 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 ets2panda/test/runtime/ets/inherited_getter_setter_implementation_1.ets create mode 100644 ets2panda/test/runtime/ets/inherited_getter_setter_implementation_2.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 6fde4aa632..76fe1a2e97 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2247,8 +2247,6 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); - auto flags = ir::ModifierFlags::PUBLIC; - ArenaVector params(checker->Allocator()->Adapter()); ArenaVector stmts(checker->Allocator()->Adapter()); checker->GenerateGetterSetterBody(stmts, params, field, paramScope, isSetter); @@ -2262,7 +2260,7 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty auto *func = checker->AllocNode( checker->Allocator(), ir::ScriptFunction::ScriptFunctionData {body, ir::FunctionSignature(nullptr, std::move(params), returnTypeAnn), - funcFlags, flags, true}); + funcFlags, ir::ModifierFlags::PUBLIC, true}); if (!isSetter) { func->AddFlag(ir::ScriptFunctionFlags::HAS_RETURN); @@ -2272,20 +2270,20 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty body->SetScope(functionScope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *methodIdent = property->Key()->AsIdentifier()->Clone(checker->Allocator(), nullptr); - auto *decl = checker->Allocator()->New( - checker->Allocator(), property->Key()->AsIdentifier()->Name(), - property->Key()->AsIdentifier()->Variable()->Declaration()->Node()); - auto *var = checker->Allocator()->New(decl, varbinder::VariableFlags::VAR); - var->AddFlag(varbinder::VariableFlags::METHOD); - - methodIdent->SetVariable(var); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *funcExpr = checker->AllocNode(func); funcExpr->SetRange(func->Range()); func->AddFlag(ir::ScriptFunctionFlags::METHOD); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *method = checker->AllocNode(ir::MethodDefinitionKind::METHOD, methodIdent, funcExpr, - flags, checker->Allocator(), false); + ir::ModifierFlags::PUBLIC, checker->Allocator(), false); + + auto *decl = checker->Allocator()->New(checker->Allocator(), + property->Key()->AsIdentifier()->Name(), method); + auto *var = checker->Allocator()->New(decl, varbinder::VariableFlags::VAR); + var->AddFlag(varbinder::VariableFlags::METHOD); + + methodIdent->SetVariable(var); method->Id()->SetMutator(); method->SetRange(field->Range()); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index a9b6d01793..20b2cc2b85 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -999,7 +999,9 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) } auto newStatus = checker::CheckerStatus::IN_CLASS; - classType->SetEnclosingType(Context().ContainingClass()); + if (Context().ContainingClass() != classType) { + classType->SetEnclosingType(Context().ContainingClass()); + } if (classDef->IsInner()) { newStatus |= CheckerStatus::INNER_CLASS; diff --git a/ets2panda/test/runtime/ets/inherited_getter_setter_implementation_1.ets b/ets2panda/test/runtime/ets/inherited_getter_setter_implementation_1.ets new file mode 100644 index 0000000000..28636bc4db --- /dev/null +++ b/ets2panda/test/runtime/ets/inherited_getter_setter_implementation_1.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface I { + a: int +} + +class A implements I { + a: int; +} + +class B extends A {} + +function main() { + let b = new B(); + b.a = 1; + let c: int = b.a; + assert c == 1; +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/inherited_getter_setter_implementation_2.ets b/ets2panda/test/runtime/ets/inherited_getter_setter_implementation_2.ets new file mode 100644 index 0000000000..8102ad95a3 --- /dev/null +++ b/ets2panda/test/runtime/ets/inherited_getter_setter_implementation_2.ets @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface I { + readonly a: boolean +} + +class A implements I { + a: boolean + b : boolean + constructor() { + this.a = false + this.b = false + } + + foo() { + this.b = true + } +} + +class B extends A { + constructor() { + super() + this.a = true + } +} + +function main() { + let b = new B() + assert(b.a) +} \ No newline at end of file -- Gitee From 15b49e9f0d311026604eb7b2650bef10937883e8 Mon Sep 17 00:00:00 2001 From: Boglarka Haag Date: Fri, 12 Jul 2024 16:13:03 +0200 Subject: [PATCH 02/15] [ArkTs frontend] Cannot use external overload Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IACL1W Reason: Runtime error occurs when an overload is external. Description: External overloads were searched under wrong name. Test scenarios (new, modified, affected functions): import_external_overload/* Change-Id: I2c38939f2a21eb08fc9efa1144be2e270ecc81a5 Signed-off-by: Haag Boglarka --- ets2panda/varbinder/ETSBinder.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 44a4f609b1..22e9d5b6de 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -55,6 +55,7 @@ #include "ir/module/importDeclaration.h" #include "ir/module/importSpecifier.h" #include "ir/expressions/literals/stringLiteral.h" +#include "mem/arena_allocator.h" #include "util/helpers.h" #include "util/ustring.h" #include "checker/types/type.h" @@ -458,21 +459,24 @@ static const util::StringView &GetPackageName(varbinder::Variable *var) return scope->Node()->AsETSScript()->Program()->ModuleName(); } -void AddOverloadFlag(bool isStdLib, varbinder::Variable *var, varbinder::Variable *variable) +void AddOverloadFlag(ArenaAllocator *allocator, bool isStdLib, varbinder::Variable *importedVar, + varbinder::Variable *variable) { auto *const currentNode = variable->Declaration()->Node()->AsMethodDefinition(); - auto *const method = var->Declaration()->Node()->AsMethodDefinition(); + auto *const method = importedVar->Declaration()->Node()->AsMethodDefinition(); // Necessary because stdlib and escompat handled as same package, it can be removed after fixing package handling - if (isStdLib && (GetPackageName(var) != GetPackageName(variable))) { + if (isStdLib && (GetPackageName(importedVar) != GetPackageName(variable))) { return; } if (!method->Overloads().empty() && !method->HasOverload(currentNode)) { method->AddOverload(currentNode); - currentNode->Function()->Id()->SetVariable(var); + currentNode->Function()->Id()->SetVariable(importedVar); currentNode->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD); currentNode->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD); + util::UString newInternalName(currentNode->Function()->Scope()->Name(), allocator); + currentNode->Function()->Scope()->BindInternalName(newInternalName.View()); return; } @@ -481,6 +485,8 @@ void AddOverloadFlag(bool isStdLib, varbinder::Variable *var, varbinder::Variabl method->Function()->Id()->SetVariable(variable); method->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD); method->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD); + util::UString newInternalName(method->Function()->Scope()->Name(), allocator); + method->Function()->Scope()->BindInternalName(newInternalName.View()); } } @@ -504,7 +510,7 @@ void ETSBinder::ImportAllForeignBindings(ir::AstNode *const specifier, if (variable != nullptr && var != variable && variable->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { bool isStdLib = util::Helpers::IsStdLib(Program()); - AddOverloadFlag(isStdLib, var, variable); + AddOverloadFlag(Allocator(), isStdLib, var, variable); continue; } if (variable != nullptr && var != variable) { @@ -756,7 +762,7 @@ bool ETSBinder::AddImportSpecifiersToTopBindings(ir::AstNode *const specifier, if (variable != nullptr && var != variable) { if (variable->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { bool isStdLib = util::Helpers::IsStdLib(Program()); - AddOverloadFlag(isStdLib, var, variable); + AddOverloadFlag(Allocator(), isStdLib, var, variable); return true; } ThrowError(importPath->Start(), RedeclarationErrorMessageAssembler(var, variable, localName)); @@ -958,7 +964,8 @@ void ETSBinder::BuildFunctionName(const ir::ScriptFunction *func) const std::stringstream ss; ASSERT(func->IsArrow() || !funcScope->Name().Empty()); - ss << funcScope->Name() << compiler::Signatures::METHOD_SEPARATOR; + ss << (func->IsExternalOverload() ? funcScope->InternalName() : funcScope->Name()) + << compiler::Signatures::METHOD_SEPARATOR; const auto *signature = func->Signature(); @@ -1080,7 +1087,7 @@ bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable bool isStdLib = util::Helpers::IsStdLib(Program()); if (variable != nullptr && var != variable) { if (variable->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { - AddOverloadFlag(isStdLib, var, variable); + AddOverloadFlag(Allocator(), isStdLib, var, variable); return true; } @@ -1092,7 +1099,7 @@ bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable return true; } if (insRes.first->second->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { - AddOverloadFlag(isStdLib, var, insRes.first->second); + AddOverloadFlag(Allocator(), isStdLib, var, insRes.first->second); return true; } -- Gitee From ffc7aa48e5b0eb1e6a074f870b0a5727b1e9c37a Mon Sep 17 00:00:00 2001 From: Torok Gergo Date: Wed, 10 Jul 2024 11:32:56 +0200 Subject: [PATCH 03/15] Removing recursive import tests Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IAC1OM Reason: Parser test runner cannot evaluate recursive import tests Description: Removed recursive import tests from parser Signed-off-by: Gergo Torok --- .../case_0/foo2__module-expected.txt | 424 ------------- .../recursive_import/case_0/foo2__module.ets | 21 - .../case_0/main__foo1_as__module-expected.txt | 583 ------------------ .../case_0/main__foo1_as__module.ets | 26 - .../foo2__module-expected.txt | 424 ------------- .../foo2__module.ets | 21 - .../main__foo1-expected.txt | 1 - .../main__foo1.ets | 26 - .../foo2__module-expected.txt | 354 ----------- .../foo2__module.ets | 21 - .../foo3__module-expected.txt | 397 ------------ .../foo3__module.ets | 22 - .../main__foo1_as__module-expected.txt | 567 ----------------- .../main__foo1_as__module.ets | 26 - .../foo2__module-expected.txt | 354 ----------- .../foo2__module.ets | 21 - .../foo3__module-expected.txt | 397 ------------ .../foo3__module.ets | 22 - .../main__foo1-expected.txt | 1 - .../main__foo1.ets | 26 - .../foo2-expected.txt | 1 - .../foo2.ets | 21 - .../foo3__module-expected.txt | 397 ------------ .../foo3__module.ets | 22 - .../main__foo1_as__module-expected.txt | 567 ----------------- .../main__foo1_as__module.ets | 26 - .../foo2__module-expected.txt | 534 ---------------- .../foo2__module.ets | 24 - .../foo3__module-expected.txt | 453 -------------- .../foo3__module.ets | 21 - .../main__foo1-expected.txt | 376 ----------- .../main__foo1.ets | 20 - .../test-lists/parser/parser-ets-ignored.txt | 16 - 33 files changed, 6212 deletions(-) delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_0/foo2__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_0/foo2__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_0/main__foo1_as__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_0/main__foo1_as__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/foo2__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/foo2__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/main__foo1-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/main__foo1.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo2__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo2__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/main__foo1-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/main__foo1.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo2-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo2.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo3__module-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo3__module.ets delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/main__foo1-expected.txt delete mode 100644 ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/main__foo1.ets diff --git a/ets2panda/test/parser/ets/recursive_import/case_0/foo2__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_0/foo2__module-expected.txt deleted file mode 100644 index 0066ab9929..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_0/foo2__module-expected.txt +++ /dev/null @@ -1,424 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./main__foo1_as__module", - "loc": { - "start": { - "line": 16, - "column": 17 - }, - "end": { - "line": 16, - "column": 42 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - }, - "imported": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 42 - } - } - }, - { - "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": "foo", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 20 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 20 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [ - { - "type": "ETSParameterExpression", - "name": { - "type": "Identifier", - "name": "a", - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 24 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 24 - }, - "end": { - "line": 18, - "column": 26 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 24 - }, - "end": { - "line": 18, - "column": 26 - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 21 - }, - "end": { - "line": 18, - "column": 26 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 21 - }, - "end": { - "line": 18, - "column": 26 - } - } - } - ], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 28 - }, - "end": { - "line": 18, - "column": 31 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo", - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 25 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 26 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 27 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 20, - "column": 12 - }, - "end": { - "line": 20, - "column": 13 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 14 - } - } - } - ], - "loc": { - "start": { - "line": 18, - "column": 32 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 20 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 20 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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/recursive_import/case_0/foo2__module.ets b/ets2panda/test/parser/ets/recursive_import/case_0/foo2__module.ets deleted file mode 100644 index 0ab31c2b36..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_0/foo2__module.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {A} from "./main__foo1_as__module" - -export function foo(a: A): int { - console.log("in foo"); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_0/main__foo1_as__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_0/main__foo1_as__module-expected.txt deleted file mode 100644 index 72b4c78e71..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_0/main__foo1_as__module-expected.txt +++ /dev/null @@ -1,583 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo2__module", - "loc": { - "start": { - "line": 16, - "column": 19 - }, - "end": { - "line": 16, - "column": 35 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 12 - } - } - }, - "imported": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 12 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 12 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 35 - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 14 - }, - "end": { - "line": 18, - "column": 15 - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 6 - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 8 - }, - "end": { - "line": 19, - "column": 11 - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 11 - } - } - }, - { - "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": 18, - "column": 16 - }, - "end": { - "line": 20, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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": "main", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 10 - }, - "end": { - "line": 23, - "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": 23, - "column": 10 - }, - "end": { - "line": 23, - "column": 14 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 19 - }, - "end": { - "line": 23, - "column": 23 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "a", - "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": 17 - }, - "end": { - "line": 24, - "column": 18 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 17 - }, - "end": { - "line": 24, - "column": 19 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 17 - }, - "end": { - "line": 24, - "column": 19 - } - } - }, - "arguments": [], - "loc": { - "start": { - "line": 24, - "column": 13 - }, - "end": { - "line": 24, - "column": 21 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 9 - }, - "end": { - "line": 24, - "column": 21 - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 24, - "column": 5 - }, - "end": { - "line": 24, - "column": 21 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 8 - } - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 9 - }, - "end": { - "line": 25, - "column": 10 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 11 - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 12 - } - } - } - ], - "loc": { - "start": { - "line": 23, - "column": 24 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 14 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 14 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 1 - }, - "end": { - "line": 26, - "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": 27, - "column": 1 - } - } -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_0/main__foo1_as__module.ets b/ets2panda/test/parser/ets/recursive_import/case_0/main__foo1_as__module.ets deleted file mode 100644 index 0ac6ceee06..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_0/main__foo1_as__module.ets +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo} from "./foo2__module" - -export class A { - a: int; -} - - -function main() : void { - let a = new A(); - foo(a); -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/foo2__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/foo2__module-expected.txt deleted file mode 100644 index b505646cc5..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/foo2__module-expected.txt +++ /dev/null @@ -1,424 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./main__foo1", - "loc": { - "start": { - "line": 16, - "column": 17 - }, - "end": { - "line": 16, - "column": 31 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - }, - "imported": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - } - ], - "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": "foo", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 20 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 20 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [ - { - "type": "ETSParameterExpression", - "name": { - "type": "Identifier", - "name": "a", - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 24 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 24 - }, - "end": { - "line": 18, - "column": 26 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 24 - }, - "end": { - "line": 18, - "column": 26 - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 21 - }, - "end": { - "line": 18, - "column": 26 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 21 - }, - "end": { - "line": 18, - "column": 26 - } - } - } - ], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 28 - }, - "end": { - "line": 18, - "column": 31 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo", - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 25 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 26 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 27 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 20, - "column": 12 - }, - "end": { - "line": 20, - "column": 13 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 14 - } - } - } - ], - "loc": { - "start": { - "line": 18, - "column": 32 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 20 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 20 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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/recursive_import/case_1_fail_not_called_w_module/foo2__module.ets b/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/foo2__module.ets deleted file mode 100644 index 0885357093..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/foo2__module.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {A} from "./main__foo1" - -export function foo(a: A): int { - console.log("in foo"); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/main__foo1-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/main__foo1-expected.txt deleted file mode 100644 index a8f80a6368..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/main__foo1-expected.txt +++ /dev/null @@ -1 +0,0 @@ -SyntaxError: Please compile `main__foo1.ets` with `--ets-module` option. It is being imported by another file. [foo2__module.ets:16:17] diff --git a/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/main__foo1.ets b/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/main__foo1.ets deleted file mode 100644 index 0ac6ceee06..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_1_fail_not_called_w_module/main__foo1.ets +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo} from "./foo2__module" - -export class A { - a: int; -} - - -function main() : void { - let a = new A(); - foo(a); -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo2__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo2__module-expected.txt deleted file mode 100644 index 2302fb5558..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo2__module-expected.txt +++ /dev/null @@ -1,354 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./main__foo1_as__module", - "loc": { - "start": { - "line": 16, - "column": 17 - }, - "end": { - "line": 16, - "column": 42 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - }, - "imported": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 42 - } - } - }, - { - "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": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 29 - }, - "end": { - "line": 18, - "column": 32 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo_in_2", - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 30 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 31 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 32 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 20, - "column": 12 - }, - "end": { - "line": 20, - "column": 13 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 14 - } - } - } - ], - "loc": { - "start": { - "line": 18, - "column": 33 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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/recursive_import/case_2_3-sources-in-circle/foo2__module.ets b/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo2__module.ets deleted file mode 100644 index cb9236d125..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo2__module.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {A} from "./main__foo1_as__module" - -export function foo_in_2(): int { - console.log("in foo_in_2"); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module-expected.txt deleted file mode 100644 index b0338509f0..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module-expected.txt +++ /dev/null @@ -1,397 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo2__module", - "loc": { - "start": { - "line": 16, - "column": 24 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "imported": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - { - "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": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 29 - }, - "end": { - "line": 18, - "column": 32 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo_in_3", - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 30 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 31 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 32 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 13 - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 15 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 16 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "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": 18, - "column": 33 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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/parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module.ets b/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module.ets deleted file mode 100644 index e3f5710b25..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module.ets +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo_in_2} from "./foo2__module" - -export function foo_in_3(): int { - console.log("in foo_in_3"); - foo_in_2(); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module-expected.txt deleted file mode 100644 index 5ad8284910..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module-expected.txt +++ /dev/null @@ -1,567 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo3__module", - "loc": { - "start": { - "line": 16, - "column": 24 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "imported": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 14 - }, - "end": { - "line": 18, - "column": 15 - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 6 - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 8 - }, - "end": { - "line": 19, - "column": 11 - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 11 - } - } - }, - { - "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": 18, - "column": 16 - }, - "end": { - "line": 20, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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": "main", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 10 - }, - "end": { - "line": 23, - "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": 23, - "column": 10 - }, - "end": { - "line": 23, - "column": 14 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 19 - }, - "end": { - "line": 23, - "column": 23 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "a", - "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": 17 - }, - "end": { - "line": 24, - "column": 18 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 17 - }, - "end": { - "line": 24, - "column": 19 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 17 - }, - "end": { - "line": 24, - "column": 19 - } - } - }, - "arguments": [], - "loc": { - "start": { - "line": 24, - "column": 13 - }, - "end": { - "line": 24, - "column": 21 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 9 - }, - "end": { - "line": 24, - "column": 21 - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 24, - "column": 5 - }, - "end": { - "line": 24, - "column": 21 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 13 - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 15 - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 16 - } - } - } - ], - "loc": { - "start": { - "line": 23, - "column": 24 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 14 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 14 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 1 - }, - "end": { - "line": 26, - "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": 27, - "column": 1 - } - } -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module.ets b/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module.ets deleted file mode 100644 index 45f20acd8f..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module.ets +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo_in_3} from "./foo3__module" - -export class A { - a: int; -} - - -function main() : void { - let a = new A(); - foo_in_3(); -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module-expected.txt deleted file mode 100644 index bcd5f0a97e..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module-expected.txt +++ /dev/null @@ -1,354 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./main__foo1", - "loc": { - "start": { - "line": 16, - "column": 17 - }, - "end": { - "line": 16, - "column": 31 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - }, - "imported": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 10 - } - } - } - ], - "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": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 29 - }, - "end": { - "line": 18, - "column": 32 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo_in_2", - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 30 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 31 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 32 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 20, - "column": 12 - }, - "end": { - "line": 20, - "column": 13 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 14 - } - } - } - ], - "loc": { - "start": { - "line": 18, - "column": 33 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module.ets b/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module.ets deleted file mode 100644 index 99a8034055..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {A} from "./main__foo1" - -export function foo_in_2(): int { - console.log("in foo_in_2"); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module-expected.txt deleted file mode 100644 index b0338509f0..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module-expected.txt +++ /dev/null @@ -1,397 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo2__module", - "loc": { - "start": { - "line": 16, - "column": 24 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "imported": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - { - "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": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 29 - }, - "end": { - "line": 18, - "column": 32 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo_in_3", - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 30 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 31 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 32 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 13 - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 15 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 16 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "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": 18, - "column": 33 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module.ets b/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module.ets deleted file mode 100644 index e3f5710b25..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module.ets +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo_in_2} from "./foo2__module" - -export function foo_in_3(): int { - console.log("in foo_in_3"); - foo_in_2(); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/main__foo1-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/main__foo1-expected.txt deleted file mode 100644 index a8f80a6368..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/main__foo1-expected.txt +++ /dev/null @@ -1 +0,0 @@ -SyntaxError: Please compile `main__foo1.ets` with `--ets-module` option. It is being imported by another file. [foo2__module.ets:16:17] diff --git a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/main__foo1.ets b/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/main__foo1.ets deleted file mode 100644 index 45f20acd8f..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/main__foo1.ets +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo_in_3} from "./foo3__module" - -export class A { - a: int; -} - - -function main() : void { - let a = new A(); - foo_in_3(); -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo2-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo2-expected.txt deleted file mode 100644 index c8d3996963..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo2-expected.txt +++ /dev/null @@ -1 +0,0 @@ -SyntaxError: Please compile `foo2.ets` with `--ets-module` option. It is being imported by another file. [foo3__module.ets:16:24] diff --git a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo2.ets b/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo2.ets deleted file mode 100644 index cb9236d125..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo2.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {A} from "./main__foo1_as__module" - -export function foo_in_2(): int { - console.log("in foo_in_2"); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module-expected.txt deleted file mode 100644 index 2400c82d6f..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module-expected.txt +++ /dev/null @@ -1,397 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo2", - "loc": { - "start": { - "line": 16, - "column": 24 - }, - "end": { - "line": 16, - "column": 32 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "imported": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 32 - } - } - }, - { - "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": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 25 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 29 - }, - "end": { - "line": 18, - "column": 32 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo_in_3", - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 30 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 31 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 32 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 13 - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 15 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 16 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "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": 18, - "column": 33 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 25 - }, - "end": { - "line": 22, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module.ets b/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module.ets deleted file mode 100644 index cb13fab47c..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module.ets +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo_in_2} from "./foo2" - -export function foo_in_3(): int { - console.log("in foo_in_3"); - foo_in_2(); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module-expected.txt deleted file mode 100644 index 5ad8284910..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module-expected.txt +++ /dev/null @@ -1,567 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo3__module", - "loc": { - "start": { - "line": 16, - "column": 24 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "imported": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 14 - }, - "end": { - "line": 18, - "column": 15 - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 6 - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 8 - }, - "end": { - "line": 19, - "column": 11 - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 11 - } - } - }, - { - "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": 18, - "column": 16 - }, - "end": { - "line": 20, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "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": "main", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 10 - }, - "end": { - "line": 23, - "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": 23, - "column": 10 - }, - "end": { - "line": 23, - "column": 14 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 19 - }, - "end": { - "line": 23, - "column": 23 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "a", - "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": 17 - }, - "end": { - "line": 24, - "column": 18 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 17 - }, - "end": { - "line": 24, - "column": 19 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 17 - }, - "end": { - "line": 24, - "column": 19 - } - } - }, - "arguments": [], - "loc": { - "start": { - "line": 24, - "column": 13 - }, - "end": { - "line": 24, - "column": 21 - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 9 - }, - "end": { - "line": 24, - "column": 21 - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 24, - "column": 5 - }, - "end": { - "line": 24, - "column": 21 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 13 - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 15 - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 5 - }, - "end": { - "line": 25, - "column": 16 - } - } - } - ], - "loc": { - "start": { - "line": 23, - "column": 24 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 14 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 14 - }, - "end": { - "line": 26, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 1 - }, - "end": { - "line": 26, - "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": 27, - "column": 1 - } - } -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module.ets b/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module.ets deleted file mode 100644 index 45f20acd8f..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module.ets +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo_in_3} from "./foo3__module" - -export class A { - a: int; -} - - -function main() : void { - let a = new A(); - foo_in_3(); -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module-expected.txt deleted file mode 100644 index 1fcd9da6ef..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module-expected.txt +++ /dev/null @@ -1,534 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo3__module", - "loc": { - "start": { - "line": 16, - "column": 24 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "imported": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 14 - }, - "end": { - "line": 18, - "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": 18, - "column": 18 - }, - "end": { - "line": 18, - "column": 18 - } - } - } - ], - "loc": { - "start": { - "line": 18, - "column": 16 - }, - "end": { - "line": 18, - "column": 18 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 8 - }, - "end": { - "line": 18, - "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": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 17 - }, - "end": { - "line": 20, - "column": 25 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 17 - }, - "end": { - "line": 20, - "column": 25 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 29 - }, - "end": { - "line": 20, - "column": 32 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 5 - }, - "end": { - "line": 21, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 13 - }, - "end": { - "line": 21, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 21, - "column": 5 - }, - "end": { - "line": 21, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo_in_2", - "loc": { - "start": { - "line": 21, - "column": 17 - }, - "end": { - "line": 21, - "column": 30 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 21, - "column": 5 - }, - "end": { - "line": 21, - "column": 31 - } - } - }, - "loc": { - "start": { - "line": 21, - "column": 5 - }, - "end": { - "line": 21, - "column": 32 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 5 - }, - "end": { - "line": 22, - "column": 13 - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 22, - "column": 5 - }, - "end": { - "line": 22, - "column": 15 - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 5 - }, - "end": { - "line": 22, - "column": 16 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 23, - "column": 12 - }, - "end": { - "line": 23, - "column": 13 - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 5 - }, - "end": { - "line": 23, - "column": 14 - } - } - } - ], - "loc": { - "start": { - "line": 20, - "column": 33 - }, - "end": { - "line": 24, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 25 - }, - "end": { - "line": 24, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 25 - }, - "end": { - "line": 24, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 8 - }, - "end": { - "line": 24, - "column": 2 - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 25, - "column": 1 - } - } -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module.ets b/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module.ets deleted file mode 100644 index d9d2023fdf..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module.ets +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo_in_3} from "./foo3__module" - -export class A {} - -export function foo_in_2(): int { - console.log("in foo_in_2"); - foo_in_3(); - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo3__module-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo3__module-expected.txt deleted file mode 100644 index 97d461121e..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo3__module-expected.txt +++ /dev/null @@ -1,453 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo2__module", - "loc": { - "start": { - "line": 15, - "column": 17 - }, - "end": { - "line": 15, - "column": 33 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 15, - "column": 9 - }, - "end": { - "line": 15, - "column": 10 - } - } - }, - "imported": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 15, - "column": 9 - }, - "end": { - "line": 15, - "column": 10 - } - } - }, - "loc": { - "start": { - "line": 15, - "column": 9 - }, - "end": { - "line": 15, - "column": 10 - } - } - } - ], - "loc": { - "start": { - "line": 15, - "column": 1 - }, - "end": { - "line": 15, - "column": 33 - } - } - }, - { - "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": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 17 - }, - "end": { - "line": 17, - "column": 25 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo_in_3", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 17 - }, - "end": { - "line": 17, - "column": 25 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 29 - }, - "end": { - "line": 17, - "column": 32 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9 - }, - "end": { - "line": 18, - "column": 10 - } - } - }, - "init": { - "type": "ETSNewClassInstanceExpression", - "typeReference": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "A", - "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 - } - } - }, - "arguments": [], - "loc": { - "start": { - "line": 18, - "column": 13 - }, - "end": { - "line": 18, - "column": 21 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 9 - }, - "end": { - "line": 18, - "column": 21 - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 18, - "column": 5 - }, - "end": { - "line": 18, - "column": 21 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "console", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "property": { - "type": "Identifier", - "name": "log", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "in foo_in_3", - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 30 - } - } - } - ], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 31 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 31 - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 20, - "column": 12 - }, - "end": { - "line": 20, - "column": 13 - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 5 - }, - "end": { - "line": 20, - "column": 14 - } - } - } - ], - "loc": { - "start": { - "line": 17, - "column": 33 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 25 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 25 - }, - "end": { - "line": 21, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 8 - }, - "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/recursive_import/case_5_main-is-not-part-of-circle/foo3__module.ets b/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo3__module.ets deleted file mode 100644 index 615dd74a9b..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo3__module.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import {A} from "./foo2__module" - -export function foo_in_3(): int { - let a = new A(); - console.log("in foo_in_3") - return 0; -} diff --git a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/main__foo1-expected.txt b/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/main__foo1-expected.txt deleted file mode 100644 index 8910b1506d..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/main__foo1-expected.txt +++ /dev/null @@ -1,376 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ImportDeclaration", - "source": { - "type": "StringLiteral", - "value": "./foo2__module", - "loc": { - "start": { - "line": 16, - "column": 24 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - "specifiers": [ - { - "type": "ImportSpecifier", - "local": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "imported": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 9 - }, - "end": { - "line": 16, - "column": 17 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 40 - } - } - }, - { - "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": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 19 - }, - "end": { - "line": 18, - "column": 23 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo_in_2", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 13 - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 15 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5 - }, - "end": { - "line": 19, - "column": 16 - } - } - } - ], - "loc": { - "start": { - "line": 18, - "column": 24 - }, - "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/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/main__foo1.ets b/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/main__foo1.ets deleted file mode 100644 index 9fef5aeb84..0000000000 --- a/ets2panda/test/parser/ets/recursive_import/case_5_main-is-not-part-of-circle/main__foo1.ets +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {foo_in_2} from "./foo2__module" - -function main() : void { - foo_in_2(); -} diff --git a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt index ebf4d5bc1d..1caaa4f69c 100644 --- a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt @@ -32,22 +32,6 @@ compiler/ets/lambdaWithLocalClassAccess.ets # Skipped until #16329 is done. It is not properly checked and does not cause a CTE when using namespace import with alias. parser/ets/re_export/import_5.ets -# Some tests within recursive import folder should run with `--ets-module` flag. These files has "__module" in their -# name. Tests below are ignored because they should result in the ats provided in their -expected.txt. Currently they -# result in an error message due to not compiling with `--ets-module` flag. -parser/ets/recursive_import/case_0/foo2__module.ets -parser/ets/recursive_import/case_0/main__foo1_as__module.ets -parser/ets/recursive_import/case_1_fail_not_called_w_module/foo2__module.ets -parser/ets/recursive_import/case_2_3-sources-in-circle/foo2__module.ets -parser/ets/recursive_import/case_2_3-sources-in-circle/foo3__module.ets -parser/ets/recursive_import/case_2_3-sources-in-circle/main__foo1_as__module.ets -parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo2__module.ets -parser/ets/recursive_import/case_3_3-sources-in-circle-fail-no-ets-module-compile/foo3__module.ets -parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/foo3__module.ets -parser/ets/recursive_import/case_4_3-sources-in-circle_no-ets-module-compile_2/main__foo1_as__module.ets -parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo2__module.ets -parser/ets/recursive_import/case_5_main-is-not-part-of-circle/foo3__module.ets - # No conversion from enum to Object compiler/ets/lambda_infer_type/lambda_infer_type_retrun_enum.ets -- Gitee From d2a8d915326b130bab9d8cef33553a112edc4bf5 Mon Sep 17 00:00:00 2001 From: Konstantin Kuznetsov Date: Fri, 21 Jun 2024 18:02:42 +0300 Subject: [PATCH 04/15] Split AST verifier Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IA71S1 Testing: refactoring only, no code changes. Runned all tests suites Signed-off-by: Konstantin Kuznetsov Signed-off-by: Maxim Logaev --- ets2panda/BUILD.gn | 19 +- ets2panda/CMakeLists.txt | 19 +- ets2panda/ast_verifier/ASTVerifier.cpp | 97 ++ .../core => ast_verifier}/ASTVerifier.h | 54 +- .../ast_verifier/arithmeticOperationValid.cpp | 74 + .../ast_verifier/arithmeticOperationValid.h | 34 + ets2panda/ast_verifier/checkContext.cpp | 37 + ets2panda/ast_verifier/checkContext.h | 91 ++ .../ast_verifier/everyChildHasValidParent.cpp | 50 + .../ast_verifier/everyChildHasValidParent.h | 31 + .../ast_verifier/everyChildInParentRange.cpp | 44 + .../ast_verifier/everyChildInParentRange.h | 31 + .../forLoopCorrectlyInitialized.cpp | 101 ++ .../forLoopCorrectlyInitialized.h | 36 + ets2panda/ast_verifier/helpers.cpp | 331 ++++ ets2panda/ast_verifier/helpers.h | 62 + .../ast_verifier/identifierHasVariable.cpp | 136 ++ .../ast_verifier/identifierHasVariable.h | 37 + .../ast_verifier/importExportAccessValid.cpp | 139 ++ .../ast_verifier/importExportAccessValid.h | 42 + .../ast_verifier/modifierAccessValid.cpp | 68 + ets2panda/ast_verifier/modifierAccessValid.h | 35 + ets2panda/ast_verifier/nodeHasParent.cpp | 38 + ets2panda/ast_verifier/nodeHasParent.h | 31 + ets2panda/ast_verifier/nodeHasSourceRange.cpp | 31 + ets2panda/ast_verifier/nodeHasSourceRange.h | 31 + ets2panda/ast_verifier/nodeHasType.cpp | 87 + ets2panda/ast_verifier/nodeHasType.h | 34 + .../referenceTypeAnnotationIsNull.cpp | 34 + .../referenceTypeAnnotationIsNull.h | 31 + .../sequenceExpressionHasLastType.cpp | 43 + .../sequenceExpressionHasLastType.h | 33 + .../variableHasEnclosingScope.cpp | 155 ++ .../ast_verifier/variableHasEnclosingScope.h | 38 + ets2panda/ast_verifier/variableHasScope.cpp | 165 ++ ets2panda/ast_verifier/variableHasScope.h | 41 + .../variableNameIdentifierNameSame.cpp | 60 + .../variableNameIdentifierNameSame.h | 31 + ets2panda/compiler/core/ASTVerifier.cpp | 1443 ----------------- ets2panda/compiler/core/compilerImpl.cpp | 2 +- .../lowering/ets/expressionLambdaLowering.cpp | 1 - .../ets/interfacePropertyDeclarations.cpp | 1 - .../compiler/lowering/ets/promiseVoid.cpp | 1 - .../compiler/lowering/ets/tupleLowering.cpp | 1 - .../compiler/lowering/ets/unionLowering.cpp | 1 - ets2panda/compiler/lowering/phase.cpp | 1 - ets2panda/compiler/lowering/plugin_phase.h | 1 - .../test/unit/public/ast_verifier_test.h | 2 +- 48 files changed, 2399 insertions(+), 1506 deletions(-) create mode 100644 ets2panda/ast_verifier/ASTVerifier.cpp rename ets2panda/{compiler/core => ast_verifier}/ASTVerifier.h (76%) create mode 100644 ets2panda/ast_verifier/arithmeticOperationValid.cpp create mode 100644 ets2panda/ast_verifier/arithmeticOperationValid.h create mode 100644 ets2panda/ast_verifier/checkContext.cpp create mode 100644 ets2panda/ast_verifier/checkContext.h create mode 100644 ets2panda/ast_verifier/everyChildHasValidParent.cpp create mode 100644 ets2panda/ast_verifier/everyChildHasValidParent.h create mode 100644 ets2panda/ast_verifier/everyChildInParentRange.cpp create mode 100644 ets2panda/ast_verifier/everyChildInParentRange.h create mode 100644 ets2panda/ast_verifier/forLoopCorrectlyInitialized.cpp create mode 100644 ets2panda/ast_verifier/forLoopCorrectlyInitialized.h create mode 100644 ets2panda/ast_verifier/helpers.cpp create mode 100644 ets2panda/ast_verifier/helpers.h create mode 100644 ets2panda/ast_verifier/identifierHasVariable.cpp create mode 100644 ets2panda/ast_verifier/identifierHasVariable.h create mode 100644 ets2panda/ast_verifier/importExportAccessValid.cpp create mode 100644 ets2panda/ast_verifier/importExportAccessValid.h create mode 100644 ets2panda/ast_verifier/modifierAccessValid.cpp create mode 100644 ets2panda/ast_verifier/modifierAccessValid.h create mode 100644 ets2panda/ast_verifier/nodeHasParent.cpp create mode 100644 ets2panda/ast_verifier/nodeHasParent.h create mode 100644 ets2panda/ast_verifier/nodeHasSourceRange.cpp create mode 100644 ets2panda/ast_verifier/nodeHasSourceRange.h create mode 100644 ets2panda/ast_verifier/nodeHasType.cpp create mode 100644 ets2panda/ast_verifier/nodeHasType.h create mode 100644 ets2panda/ast_verifier/referenceTypeAnnotationIsNull.cpp create mode 100644 ets2panda/ast_verifier/referenceTypeAnnotationIsNull.h create mode 100644 ets2panda/ast_verifier/sequenceExpressionHasLastType.cpp create mode 100644 ets2panda/ast_verifier/sequenceExpressionHasLastType.h create mode 100644 ets2panda/ast_verifier/variableHasEnclosingScope.cpp create mode 100644 ets2panda/ast_verifier/variableHasEnclosingScope.h create mode 100644 ets2panda/ast_verifier/variableHasScope.cpp create mode 100644 ets2panda/ast_verifier/variableHasScope.h create mode 100644 ets2panda/ast_verifier/variableNameIdentifierNameSame.cpp create mode 100644 ets2panda/ast_verifier/variableNameIdentifierNameSame.h delete mode 100644 ets2panda/compiler/core/ASTVerifier.cpp diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 14a3b74899..d99ca53e9a 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -27,6 +27,24 @@ config("libes2panda_public_config") { } libes2panda_sources = [ + "ast_verifier/ASTVerifier.cpp", + "ast_verifier/arithmeticOperationValid.cpp", + "ast_verifier/checkContext.cpp", + "ast_verifier/everyChildHasValidParent.cpp", + "ast_verifier/everyChildInParentRange.cpp", + "ast_verifier/forLoopCorrectlyInitialized.cpp", + "ast_verifier/helpers.cpp", + "ast_verifier/identifierHasVariable.cpp", + "ast_verifier/importExportAccessValid.cpp", + "ast_verifier/modifierAccessValid.cpp", + "ast_verifier/nodeHasParent.cpp", + "ast_verifier/nodeHasSourceRange.cpp", + "ast_verifier/nodeHasType.cpp", + "ast_verifier/referenceTypeAnnotationIsNull.cpp", + "ast_verifier/sequenceExpressionHasLastType.cpp", + "ast_verifier/variableHasEnclosingScope.cpp", + "ast_verifier/variableHasScope.cpp", + "ast_verifier/variableNameIdentifierNameSame.cpp", "checker/ASchecker.cpp", "checker/ETSAnalyzer.cpp", "checker/ETSAnalyzerHelpers.cpp", @@ -137,7 +155,6 @@ libes2panda_sources = [ "compiler/base/literals.cpp", "compiler/base/lreference.cpp", "compiler/base/optionalChain.cpp", - "compiler/core/ASTVerifier.cpp", "compiler/core/ETSCompiler.cpp", "compiler/core/ETSGen.cpp", "compiler/core/ETSemitter.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 270899a6b5..8f442846c8 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -110,6 +110,24 @@ panda_gen( ) set(ES2PANDA_LIB_SRC + ast_verifier/ASTVerifier.cpp + ast_verifier/arithmeticOperationValid.cpp + ast_verifier/checkContext.cpp + ast_verifier/everyChildHasValidParent.cpp + ast_verifier/everyChildInParentRange.cpp + ast_verifier/helpers.cpp + ast_verifier/identifierHasVariable.cpp + ast_verifier/importExportAccessValid.cpp + ast_verifier/nodeHasParent.cpp + ast_verifier/nodeHasSourceRange.cpp + ast_verifier/nodeHasType.cpp + ast_verifier/referenceTypeAnnotationIsNull.cpp + ast_verifier/forLoopCorrectlyInitialized.cpp + ast_verifier/modifierAccessValid.cpp + ast_verifier/sequenceExpressionHasLastType.cpp + ast_verifier/variableHasEnclosingScope.cpp + ast_verifier/variableHasScope.cpp + ast_verifier/variableNameIdentifierNameSame.cpp es2panda.cpp varbinder/ASBinder.cpp varbinder/TSBinder.cpp @@ -130,7 +148,6 @@ set(ES2PANDA_LIB_SRC compiler/base/literals.cpp compiler/base/lreference.cpp compiler/base/optionalChain.cpp - compiler/core/ASTVerifier.cpp compiler/core/codeGen.cpp compiler/core/compileJob.cpp compiler/core/compileQueue.cpp diff --git a/ets2panda/ast_verifier/ASTVerifier.cpp b/ets2panda/ast_verifier/ASTVerifier.cpp new file mode 100644 index 0000000000..ce6ccc5991 --- /dev/null +++ b/ets2panda/ast_verifier/ASTVerifier.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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 "ASTVerifier.h" +#include "ast_verifier/helpers.h" +#include "ast_verifier/sequenceExpressionHasLastType.h" +#include "ast_verifier/checkContext.h" +#include "ast_verifier/everyChildHasValidParent.h" +#include "ast_verifier/everyChildInParentRange.h" +#include "ast_verifier/identifierHasVariable.h" +#include "ast_verifier/nodeHasParent.h" +#include "ast_verifier/nodeHasSourceRange.h" +#include "ast_verifier/nodeHasType.h" +#include "ast_verifier/referenceTypeAnnotationIsNull.h" +#include "ast_verifier/variableHasScope.h" +#include "ast_verifier/variableHasEnclosingScope.h" +#include "ast_verifier/forLoopCorrectlyInitialized.h" +#include "ast_verifier/modifierAccessValid.h" +#include "ast_verifier/importExportAccessValid.h" +#include "ast_verifier/arithmeticOperationValid.h" +#include "ast_verifier/variableNameIdentifierNameSame.h" + +namespace ark::es2panda::compiler::ast_verifier { + +ASTVerifier::ASTVerifier(ArenaAllocator *allocator) +{ + AddInvariant(allocator, "NodeHasParent"); + AddInvariant(allocator, "NodeHasSourceRange"); + AddInvariant(allocator, "NodeHasType"); + AddInvariant(allocator, "IdentifierHasVariable"); + AddInvariant(allocator, "VariableHasScope"); + AddInvariant(allocator, "EveryChildHasValidParent"); + AddInvariant(allocator, "EveryChildInParentRange"); + AddInvariant(allocator, "VariableHasEnclosingScope"); + AddInvariant(allocator, "ForLoopCorrectlyInitialized"); + AddInvariant(allocator, "ModifierAccessValid"); + AddInvariant(allocator, "ImportExportAccessValid"); + AddInvariant(allocator, "ArithmeticOperationValid"); + AddInvariant(allocator, "SequenceExpressionHasLastType"); + AddInvariant(allocator, "ReferenceTypeAnnotationIsNull"); + AddInvariant(allocator, "VariableNameIdentifierNameSame"); +} + +Messages ASTVerifier::VerifyFull(const ir::AstNode *ast) +{ + auto recursiveChecks = InvariantNameSet {}; + std::copy_if(invariantsNames_.begin(), invariantsNames_.end(), + std::inserter(recursiveChecks, recursiveChecks.end()), + [](const std::string &s) { return s.find(RECURSIVE_SUFFIX) != s.npos; }); + return Verify(ast, recursiveChecks); +} + +Messages ASTVerifier::Verify(const ir::AstNode *ast, const InvariantNameSet &invariantSet) +{ + CheckContext ctx {}; + const auto containsInvariants = + std::includes(invariantsNames_.begin(), invariantsNames_.end(), invariantSet.begin(), invariantSet.end()); + if (!containsInvariants) { + auto invalidInvariants = InvariantNameSet {}; + for (const auto &invariant : invariantSet) { + if (invariantsNames_.find(invariant) == invariantsNames_.end()) { + invalidInvariants.insert(invariant); + } + } + for (const auto &invariant : invalidInvariants) { + ctx.AddCheckMessage(std::string {"Invariant was not found: "} + invariant, *ast, lexer::SourcePosition {}); + } + } + + for (const auto &name : invariantSet) { + if (const auto &found = invariantsChecks_.find(name); found != invariantsChecks_.end()) { + if (ast == nullptr) { + continue; + } + + auto invariant = found->second; + ctx.SetCheckName(name.data()); + invariant(ctx, ast); + } + } + + return ctx.GetMessages(); +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/compiler/core/ASTVerifier.h b/ets2panda/ast_verifier/ASTVerifier.h similarity index 76% rename from ets2panda/compiler/core/ASTVerifier.h rename to ets2panda/ast_verifier/ASTVerifier.h index 31f586b538..cc24e60c0f 100644 --- a/ets2panda/compiler/core/ASTVerifier.h +++ b/ets2panda/ast_verifier/ASTVerifier.h @@ -22,68 +22,18 @@ #include #include +#include "ast_verifier/checkContext.h" + #include "ir/astNode.h" #include "ir/statements/blockStatement.h" #include "lexer/token/sourceLocation.h" #include "parser/program/program.h" #include "util/ustring.h" #include "utils/arena_containers.h" -#include "utils/json_builder.h" #include "varbinder/variable.h" namespace ark::es2panda::compiler::ast_verifier { -enum class CheckSeverity { ERROR, WARNING, UNKNOWN }; -inline std::string CheckSeverityString(CheckSeverity value) -{ - switch (value) { - case CheckSeverity::ERROR: - return "error"; - case CheckSeverity::WARNING: - return "warning"; - default: - UNREACHABLE(); - } -} - -class CheckMessage { -public: - explicit CheckMessage(util::StringView name, util::StringView cause, util::StringView message, size_t line) - : invariantName_ {name}, cause_ {cause}, message_ {message}, line_ {line} - { - } - - std::string Invariant() const - { - return invariantName_; - } - - std::function DumpJSON(CheckSeverity severity, const std::string &sourceName, - const std::string &phaseName) const - { - return [sourceName, phaseName, severity, this](JsonObjectBuilder &body) { - body.AddProperty("severity", CheckSeverityString(severity)); - body.AddProperty("invariant", invariantName_); - body.AddProperty("cause", cause_); - body.AddProperty("ast", message_); - body.AddProperty("line", line_ + 1); - body.AddProperty("source", sourceName); - body.AddProperty("phase", phaseName); - }; - } - -private: - std::string invariantName_; - std::string cause_; - std::string message_; - size_t line_; -}; -using Messages = std::vector; - -enum class CheckDecision { CORRECT, INCORRECT }; -enum class CheckAction { CONTINUE, SKIP_SUBTREE }; -using CheckResult = std::tuple; -class CheckContext; using InvariantCheck = std::function; using Invariants = std::map; diff --git a/ets2panda/ast_verifier/arithmeticOperationValid.cpp b/ets2panda/ast_verifier/arithmeticOperationValid.cpp new file mode 100644 index 0000000000..9e6ec2ff9d --- /dev/null +++ b/ets2panda/ast_verifier/arithmeticOperationValid.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "arithmeticOperationValid.h" +#include "ir/expressions/binaryExpression.h" +#include "ir/base/classDefinition.h" +#include "ir/ts/tsInterfaceDeclaration.h" +#include "ir/ts/tsEnumDeclaration.h" +#include "ir/ts/tsInterfaceBody.h" +#include "helpers.h" + +namespace ark::es2panda::compiler::ast_verifier { + +[[nodiscard]] CheckResult ArithmeticOperationValid::operator()([[maybe_unused]] CheckContext &ctx, + const ir::AstNode *ast) +{ + if (auto [decision, action] = CheckCompound(ctx, ast); action == CheckAction::SKIP_SUBTREE) { + return {decision, action}; + } + if (!ast->IsBinaryExpression() || !ast->AsBinaryExpression()->IsArithmetic()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + if ((ast->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_PLUS || + ast->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_PLUS_EQUAL) && + (IsStringType(ast->AsBinaryExpression()->Left()) || IsStringType(ast->AsBinaryExpression()->Right()))) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); + bool isBitwise = ast->AsBinaryExpression()->IsBitwise(); + ast->Iterate([&result, &ctx, &isBitwise](ir::AstNode *child) { + if (!IsValidTypeForBinaryOp(child, isBitwise)) { + ctx.AddCheckMessage("Not a numeric type", *child, child->Start()); + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + }); + return result; +} + +CheckResult ArithmeticOperationValid::CheckCompound(CheckContext &ctx, const ir::AstNode *ast) +{ + if (ast->IsTSInterfaceDeclaration()) { + for (const auto &member : ast->AsTSInterfaceDeclaration()->Body()->Body()) { + [[maybe_unused]] auto _ = (*this)(ctx, member); + } + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + if (ast->IsTSEnumDeclaration()) { + for (const auto &member : ast->AsTSEnumDeclaration()->Members()) { + [[maybe_unused]] auto _ = (*this)(ctx, member); + } + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + if (ast->IsClassDefinition()) { + for (const auto &member : ast->AsClassDefinition()->Body()) { + [[maybe_unused]] auto _ = (*this)(ctx, member); + } + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/arithmeticOperationValid.h b/ets2panda/ast_verifier/arithmeticOperationValid.h new file mode 100644 index 0000000000..82c27a501b --- /dev/null +++ b/ets2panda/ast_verifier/arithmeticOperationValid.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_ARITHMETICOPERATIONVALID_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_ARITHMETICOPERATIONVALID_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class ArithmeticOperationValid { +public: + explicit ArithmeticOperationValid([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + +private: + CheckResult CheckCompound(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_ARITHMETICOPERATIONVALID_H diff --git a/ets2panda/ast_verifier/checkContext.cpp b/ets2panda/ast_verifier/checkContext.cpp new file mode 100644 index 0000000000..b022e14cd9 --- /dev/null +++ b/ets2panda/ast_verifier/checkContext.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +void CheckContext::AddCheckMessage(const std::string &cause, const ir::AstNode &node, const lexer::SourcePosition &from) +{ + const auto loc = from.line; + const auto &&dump = node.DumpJSON(); + messages_.emplace_back(checkName_, cause.data(), dump.data(), loc); +} + +void CheckContext::SetCheckName(util::StringView checkName) +{ + checkName_ = checkName; +} + +Messages CheckContext::GetMessages() +{ + return messages_; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/checkContext.h b/ets2panda/ast_verifier/checkContext.h new file mode 100644 index 0000000000..d384018a8d --- /dev/null +++ b/ets2panda/ast_verifier/checkContext.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONTEXT_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONTEXT_H + +#include "ir/astNode.h" +#include "utils/json_builder.h" + +namespace ark::es2panda::compiler::ast_verifier { + +enum class CheckDecision { CORRECT, INCORRECT }; +enum class CheckAction { CONTINUE, SKIP_SUBTREE }; +using CheckResult = std::tuple; + +enum class CheckSeverity { ERROR, WARNING, UNKNOWN }; +inline std::string CheckSeverityString(CheckSeverity value) +{ + switch (value) { + case CheckSeverity::ERROR: + return "error"; + case CheckSeverity::WARNING: + return "warning"; + default: + UNREACHABLE(); + } +} + +class CheckMessage { +public: + explicit CheckMessage(util::StringView name, util::StringView cause, util::StringView message, size_t line) + : invariantName_ {name}, cause_ {cause}, message_ {message}, line_ {line} + { + } + + std::string Invariant() const + { + return invariantName_; + } + + std::function DumpJSON(CheckSeverity severity, const std::string &sourceName, + const std::string &phaseName) const + { + return [sourceName, phaseName, severity, this](JsonObjectBuilder &body) { + body.AddProperty("severity", CheckSeverityString(severity)); + body.AddProperty("invariant", invariantName_); + body.AddProperty("cause", cause_); + body.AddProperty("ast", message_); + body.AddProperty("line", line_ + 1); + body.AddProperty("source", sourceName); + body.AddProperty("phase", phaseName); + }; + } + +private: + std::string invariantName_; + std::string cause_; + std::string message_; + size_t line_; +}; + +using Messages = std::vector; + +class CheckContext { +public: + explicit CheckContext() : checkName_ {"Invalid"} {} + + void AddCheckMessage(const std::string &cause, const ir::AstNode &node, const lexer::SourcePosition &from); + void SetCheckName(util::StringView checkName); + Messages GetMessages(); + +private: + Messages messages_; + util::StringView checkName_; +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONTEXT_H diff --git a/ets2panda/ast_verifier/everyChildHasValidParent.cpp b/ets2panda/ast_verifier/everyChildHasValidParent.cpp new file mode 100644 index 0000000000..5f31b0fad4 --- /dev/null +++ b/ets2panda/ast_verifier/everyChildHasValidParent.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "everyChildHasValidParent.h" + +namespace ark::es2panda::compiler::ast_verifier { + +CheckResult EveryChildHasValidParent::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); + if (ast->IsETSScript()) { + return result; + } + + ast->Iterate([&](const ir::AstNode *node) { + if (ir::AstNode const *parent = node->Parent(); ast != parent) { + // NOTE: Temporary suppress. + // Should be removed after special lowering for lambda-functions will be implemented: #14376 + if ((ast->IsScriptFunction() || ast->IsETSFunctionType()) && parent != nullptr && + parent->IsScriptFunction()) { + return; + } + + // NOTE: Temporary suppress. + // Should be removed after new ENUMs support will be implemented: #14443 + if (ast->IsClassDeclaration() && parent != nullptr && parent->IsETSNewClassInstanceExpression()) { + return; + } + + ctx.AddCheckMessage("INCORRECT_PARENT_REF", *node, node->Start()); + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + }); + + return result; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/everyChildHasValidParent.h b/ets2panda/ast_verifier/everyChildHasValidParent.h new file mode 100644 index 0000000000..4634ed8e16 --- /dev/null +++ b/ets2panda/ast_verifier/everyChildHasValidParent.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDHASVALIDPARENT_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDHASVALIDPARENT_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class EveryChildHasValidParent { +public: + explicit EveryChildHasValidParent([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDHASVALIDPARENT_H diff --git a/ets2panda/ast_verifier/everyChildInParentRange.cpp b/ets2panda/ast_verifier/everyChildInParentRange.cpp new file mode 100644 index 0000000000..62032aef1d --- /dev/null +++ b/ets2panda/ast_verifier/everyChildInParentRange.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "everyChildInParentRange.h" + +namespace ark::es2panda::compiler::ast_verifier { + +CheckResult EveryChildInParentRange::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); + if (ast->Parent() == nullptr) { + return result; + } + ast->Iterate([&](const ir::AstNode *node) { + if (ast != node->Parent()) { + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + if (ast->Start().line > node->Start().line || ast->End().line < node->End().line) { + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + if (ast->Start().line == node->Start().line && ast->Start().index > node->Start().index) { + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + if (ast->End().line == node->End().line && ast->End().index < node->End().index) { + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + ctx.AddCheckMessage("INCORRECT_CHILD_RANGE", *node, node->Start()); + }); + return result; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/everyChildInParentRange.h b/ets2panda/ast_verifier/everyChildInParentRange.h new file mode 100644 index 0000000000..d3142a2b8f --- /dev/null +++ b/ets2panda/ast_verifier/everyChildInParentRange.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDINPARENTRANGE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDINPARENTRANGE_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class EveryChildInParentRange { +public: + explicit EveryChildInParentRange([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDINPARENTRANGE_H diff --git a/ets2panda/ast_verifier/forLoopCorrectlyInitialized.cpp b/ets2panda/ast_verifier/forLoopCorrectlyInitialized.cpp new file mode 100644 index 0000000000..22de67ef84 --- /dev/null +++ b/ets2panda/ast_verifier/forLoopCorrectlyInitialized.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "forLoopCorrectlyInitialized.h" +#include "ir/statements/forInStatement.h" +#include "ir/statements/forOfStatement.h" +#include "ir/statements/forUpdateStatement.h" + +namespace ark::es2panda::compiler::ast_verifier { + +[[nodiscard]] CheckResult ForLoopCorrectlyInitialized::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + if (ast->IsForInStatement()) { + return HandleForInStatement(ctx, ast); + } + + if (ast->IsForOfStatement()) { + return HandleForOfStatement(ctx, ast); + } + + if (ast->IsForUpdateStatement()) { + return HandleForUpdateStatement(ctx, ast); + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +[[nodiscard]] CheckResult ForLoopCorrectlyInitialized::HandleForInStatement(CheckContext &ctx, const ir::AstNode *ast) +{ + auto const *left = ast->AsForInStatement()->Left(); + if (left == nullptr) { + ctx.AddCheckMessage("NULL FOR-IN-LEFT", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + + if (!left->IsIdentifier() && !left->IsVariableDeclaration()) { + ctx.AddCheckMessage("INCORRECT FOR-IN-LEFT", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +[[nodiscard]] CheckResult ForLoopCorrectlyInitialized::HandleForOfStatement(CheckContext &ctx, const ir::AstNode *ast) +{ + auto const *left = ast->AsForOfStatement()->Left(); + if (left == nullptr) { + ctx.AddCheckMessage("NULL FOR-OF-LEFT", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + + if (!left->IsIdentifier() && !left->IsVariableDeclaration()) { + ctx.AddCheckMessage("INCORRECT FOR-OF-LEFT", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +[[nodiscard]] CheckResult ForLoopCorrectlyInitialized::HandleForUpdateStatement(CheckContext &ctx, + const ir::AstNode *ast) +{ + // The most important part of for-loop is the test. + // But it also can be null. Then there must be break;(return) in the body. + auto const *test = ast->AsForUpdateStatement()->Test(); + if (test == nullptr) { + auto const *body = ast->AsForUpdateStatement()->Body(); + if (body == nullptr) { + ctx.AddCheckMessage("NULL FOR-TEST AND FOR-BODY", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + bool hasExit = body->IsBreakStatement() || body->IsReturnStatement(); + body->IterateRecursively( + [&hasExit](ir::AstNode *child) { hasExit |= child->IsBreakStatement() || child->IsReturnStatement(); }); + if (!hasExit) { + // an infinite loop + ctx.AddCheckMessage("NULL FOR-TEST AND FOR-BODY doesn't exit", *ast, ast->Start()); + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + if (!test->IsExpression()) { + ctx.AddCheckMessage("NULL FOR VAR", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/forLoopCorrectlyInitialized.h b/ets2panda/ast_verifier/forLoopCorrectlyInitialized.h new file mode 100644 index 0000000000..63151eef6d --- /dev/null +++ b/ets2panda/ast_verifier/forLoopCorrectlyInitialized.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_FORLOOPCORRECTLYINITIALIZED_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_FORLOOPCORRECTLYINITIALIZED_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class ForLoopCorrectlyInitialized { +public: + explicit ForLoopCorrectlyInitialized([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + +private: + [[nodiscard]] CheckResult HandleForInStatement(CheckContext &ctx, const ir::AstNode *ast); + [[nodiscard]] CheckResult HandleForOfStatement(CheckContext &ctx, const ir::AstNode *ast); + [[nodiscard]] CheckResult HandleForUpdateStatement(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_FORLOOPCORRECTLYINITIALIZED_H diff --git a/ets2panda/ast_verifier/helpers.cpp b/ets2panda/ast_verifier/helpers.cpp new file mode 100644 index 0000000000..d46449d304 --- /dev/null +++ b/ets2panda/ast_verifier/helpers.cpp @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "helpers.h" + +#include "checker/types/typeFlag.h" +#include "checker/types/type.h" +#include "checker/types/ets/etsObjectType.h" +#include "ir/statements/blockStatement.h" +#include "ir/ets/etsScript.h" +#include "parser/program/program.h" +#include "ir/expressions/memberExpression.h" +#include "ir/expressions/callExpression.h" + +namespace ark::es2panda::compiler::ast_verifier { + +bool IsImportLike(const ir::AstNode *ast) +{ + return (ast->IsETSImportDeclaration() || ast->IsETSReExportDeclaration() || ast->IsImportExpression() || + ast->IsImportSpecifier() || ast->IsImportDefaultSpecifier() || ast->IsImportNamespaceSpecifier()); +} + +bool IsExportLike(const ir::AstNode *ast) +{ + return (ast->IsExportDefaultDeclaration() || ast->IsExportSpecifier() || ast->IsExportAllDeclaration() || + ast->IsExportNamedDeclaration() || ast->IsETSReExportDeclaration()); +} + +bool IsBooleanType(const ir::AstNode *ast) +{ + if (ast == nullptr) { + return false; + } + + if (!ast->IsTyped()) { + return false; + } + + auto typedAst = static_cast(ast); + + if (typedAst->TsType() == nullptr) { + return false; + } + + if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && + ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { + return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); + } + + return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) || + typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BOOLEAN_LIKE); +} + +bool IsValidTypeForBinaryOp(const ir::AstNode *ast, bool isBitwise) +{ + if (ast == nullptr) { + std::cout << __LINE__ << std::endl; + return false; + } + + if (!ast->IsTyped()) { + std::cout << __LINE__ << std::endl; + return false; + } + + auto typedAst = static_cast(ast); + + if (typedAst->TsType() == nullptr) { + // std::cout << typedAst + std::cout << __LINE__ << std::endl; + return false; + } + + if (IsBooleanType(ast)) { + return isBitwise; + } + + if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && + typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BIGINT)) { + return true; + } + + if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && + ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { + return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE) && + !typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); + } + + return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || + typedAst->TsType()->HasTypeFlag(checker::TypeFlag::NUMBER_LITERAL) || + typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BIGINT) || + typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL); +} + +bool IsStringType(const ir::AstNode *ast) +{ + if (ast == nullptr) { + return false; + } + + if (!ast->IsTyped()) { + return false; + } + + auto typedAst = static_cast(ast); + + if (typedAst->TsType() == nullptr) { + return false; + } + + if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { + return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::STRING) || + typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_STRING); + } + + return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::STRING_LIKE); +} + +bool IsVisibleInternalNode(const ir::AstNode *ast, const ir::AstNode *objTypeDeclNode) +{ + // NOTE(orlovskymaxim) This relies on the fact, that GetTopStatement has no bugs, that is not the case for now + if (!ast->GetTopStatement()->IsETSScript()) { + return false; + } + auto *currentTopStatement = (static_cast(ast->GetTopStatement())); + auto *currentProgram = currentTopStatement->Program(); + if (currentProgram == nullptr) { + return false; + } + util::StringView moduleNameCurrent = currentProgram->ModuleName(); + // NOTE(orlovskymaxim) This relies on the fact, that GetTopStatement has no bugs, that is not the case for now + if (!objTypeDeclNode->GetTopStatement()->IsETSScript()) { + return false; + } + auto *objectTopStatement = (static_cast(objTypeDeclNode->GetTopStatement())); + auto *objectProgram = objectTopStatement->Program(); + if (objectProgram == nullptr) { + return false; + } + util::StringView moduleNameObject = objectProgram->ModuleName(); + return currentTopStatement == objectTopStatement || moduleNameCurrent == moduleNameObject; +} + +const checker::Type *GetClassDefinitionType(const ir::AstNode *ast) +{ + const ir::AstNode *tmpNode = ast; + while (tmpNode->Parent() != nullptr && !tmpNode->IsClassDefinition()) { + tmpNode = tmpNode->Parent(); + } + if (!tmpNode->IsClassDefinition()) { + return nullptr; + } + auto *classDefinition = tmpNode->AsClassDefinition(); + return classDefinition->TsType(); +} + +const checker::Type *GetTSInterfaceDeclarationType(const ir::AstNode *ast) +{ + const ir::AstNode *tmpNode = ast; + while (tmpNode->Parent() != nullptr && !tmpNode->IsTSInterfaceDeclaration()) { + tmpNode = tmpNode->Parent(); + } + if (!tmpNode->IsTSInterfaceDeclaration()) { + return nullptr; + } + auto *tsInterfaceDeclaration = tmpNode->AsTSInterfaceDeclaration(); + return tsInterfaceDeclaration->TsType(); +} + +bool ValidateMethodAccessForClass(const ir::AstNode *ast, const ir::AstNode *ownerSignDeclNode, + checker::Signature *signature, const ir::AstNode *memberObjTypeDeclNode) +{ + // Check if the method is used where it is declared + if (IsContainedIn(ast, ownerSignDeclNode)) { + return true; + } + if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE)) { + return false; + } + if (signature->HasSignatureFlag(checker::SignatureFlags::PROTECTED)) { + // Check if the method is inherited and is used in class in which it is inherited + auto *classDefinitionType = GetClassDefinitionType(ast); + if (classDefinitionType == nullptr || !classDefinitionType->IsETSObjectType()) { + return false; + } + auto *classObjectType = classDefinitionType->AsETSObjectType(); + return classObjectType->IsDescendantOf(signature->Owner()); + } + if (signature->HasSignatureFlag(checker::SignatureFlags::INTERNAL)) { + return IsVisibleInternalNode(ast, memberObjTypeDeclNode); + } + return true; +} + +bool ValidateMethodAccessForTSInterface(const ir::AstNode *ast, const ir::AstNode *ownerSignDeclNode, + checker::Signature *signature, const ir::AstNode *memberObjTypeDeclNode) +{ + // Check if the method is used where it is declared + if (IsContainedIn(ast, ownerSignDeclNode)) { + return true; + } + if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE)) { + return false; + } + if (signature->HasSignatureFlag(checker::SignatureFlags::PROTECTED)) { + // Check if the method is inherited and is used in class in which it is inherited + auto *tsInterfaceDeclarationType = GetTSInterfaceDeclarationType(ast); + if (tsInterfaceDeclarationType == nullptr || !tsInterfaceDeclarationType->IsETSObjectType()) { + return false; + } + auto *tsInterfaceObjectType = tsInterfaceDeclarationType->AsETSObjectType(); + return tsInterfaceObjectType->IsDescendantOf(signature->Owner()); + } + if (signature->HasSignatureFlag(checker::SignatureFlags::INTERNAL)) { + return IsVisibleInternalNode(ast, memberObjTypeDeclNode); + } + return true; +} + +bool ValidatePropertyAccessForClass(const ir::AstNode *ast, const ir::AstNode *propVarDeclNode, + const ir::AstNode *propVarDeclNodeParent, const varbinder::LocalVariable *propVar, + const ir::AstNode *objTypeDeclNode) +{ + // Check if the variable is used where it is declared + if (IsContainedIn(ast, propVarDeclNodeParent)) { + return true; + } + if (propVarDeclNode->IsPrivate()) { + return false; + } + if (propVarDeclNode->IsProtected()) { + auto *classDefinitionType = GetClassDefinitionType(ast); + if (classDefinitionType == nullptr || !classDefinitionType->IsETSObjectType()) { + return false; + } + auto *classObjectType = classDefinitionType->AsETSObjectType(); + return classObjectType->IsPropertyOfAscendant(propVar); + } + if (propVarDeclNode->IsInternal()) { + return IsVisibleInternalNode(ast, objTypeDeclNode); + } + return true; +} + +bool ValidateVariableAccess(const varbinder::LocalVariable *propVar, const ir::MemberExpression *ast) +{ + const auto *propVarDecl = propVar->Declaration(); + if (propVarDecl == nullptr) { + return false; + } + const auto *propVarDeclNode = propVarDecl->Node(); + if (propVarDeclNode == nullptr) { + return false; + } + auto *objType = ast->ObjType(); + if (objType == nullptr) { + return false; + } + const auto *objTypeDeclNode = objType->GetDeclNode(); + if (objTypeDeclNode == nullptr) { + return false; + } + if (objTypeDeclNode->Parent() != nullptr && objTypeDeclNode->Parent()->IsImportNamespaceSpecifier()) { + return true; + } + const auto *propVarDeclNodeParent = propVarDeclNode->Parent(); + if (propVarDeclNodeParent == nullptr) { + return false; + } + if (propVarDeclNodeParent->IsClassDefinition() && objTypeDeclNode->IsClassDefinition()) { + return ValidatePropertyAccessForClass(ast, propVarDeclNode, propVarDeclNodeParent, propVar, objTypeDeclNode); + } + return false; +} + +bool ValidateMethodAccess(const ir::MemberExpression *memberExpression, const ir::CallExpression *ast) +{ + auto *memberObjType = memberExpression->ObjType(); + if (memberObjType == nullptr) { + return false; + } + if (memberObjType->HasObjectFlag(checker::ETSObjectFlags::RESOLVED_SUPER) && + memberObjType->SuperType() != nullptr && + memberObjType->SuperType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE | + checker::ETSObjectFlags::GLOBAL)) { + return true; + } + const auto *memberObjTypeDeclNode = memberObjType->GetDeclNode(); + if (memberObjTypeDeclNode == nullptr) { + return false; + } + if (memberObjTypeDeclNode->Parent() != nullptr && memberObjTypeDeclNode->Parent()->IsImportNamespaceSpecifier()) { + return true; + } + auto *signature = ast->Signature(); + if (signature == nullptr) { + return false; + } + auto *ownerSign = signature->Owner(); + if (ownerSign == nullptr) { + return false; + } + auto *ownerSignDeclNode = ownerSign->GetDeclNode(); + if (ownerSignDeclNode == nullptr) { + return false; + } + if (!ownerSignDeclNode->IsClassDefinition() && !ownerSignDeclNode->IsTSInterfaceDeclaration()) { + return false; + } + bool ret = false; + if (memberObjTypeDeclNode->IsClassDefinition()) { + ret = ValidateMethodAccessForClass(ast, ownerSignDeclNode, signature, memberObjTypeDeclNode); + } else if (memberObjTypeDeclNode->IsTSInterfaceDeclaration()) { + ret = ValidateMethodAccessForTSInterface(ast, ownerSignDeclNode, signature, memberObjTypeDeclNode); + } + return ret; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/helpers.h b/ets2panda/ast_verifier/helpers.h new file mode 100644 index 0000000000..5537259ab9 --- /dev/null +++ b/ets2panda/ast_verifier/helpers.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_HELPERS_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_HELPERS_H + +#include "ir/astNode.h" +#include "checker/types/signature.h" + +namespace ark::es2panda::compiler::ast_verifier { + +bool IsImportLike(const ir::AstNode *ast); +bool IsExportLike(const ir::AstNode *ast); +bool IsBooleanType(const ir::AstNode *ast); +bool IsValidTypeForBinaryOp(const ir::AstNode *ast, bool isBitwise); +bool IsStringType(const ir::AstNode *ast); +bool IsVisibleInternalNode(const ir::AstNode *ast, const ir::AstNode *objTypeDeclNode); +const checker::Type *GetClassDefinitionType(const ir::AstNode *ast); +const checker::Type *GetTSInterfaceDeclarationType(const ir::AstNode *ast); +bool ValidateMethodAccessForClass(const ir::AstNode *ast, const ir::AstNode *ownerSignDeclNode, + checker::Signature *signature, const ir::AstNode *memberObjTypeDeclNode); +bool ValidateMethodAccessForTSInterface(const ir::AstNode *ast, const ir::AstNode *ownerSignDeclNode, + checker::Signature *signature, const ir::AstNode *memberObjTypeDeclNode); +bool ValidatePropertyAccessForClass(const ir::AstNode *ast, const ir::AstNode *propVarDeclNode, + const ir::AstNode *propVarDeclNodeParent, const varbinder::LocalVariable *propVar, + const ir::AstNode *objTypeDeclNode); +bool ValidateVariableAccess(const varbinder::LocalVariable *propVar, const ir::MemberExpression *ast); +bool ValidateMethodAccess(const ir::MemberExpression *memberExpression, const ir::CallExpression *ast); + +template +bool IsContainedIn(const T *child, const T *parent) +{ + if (child == nullptr || parent == nullptr) { + return false; + } + + std::unordered_set savedNodes; + while (child != nullptr && child != parent) { + savedNodes.emplace(child); + child = child->Parent(); + if (savedNodes.find(child) != savedNodes.end()) { + return false; + } + } + return child == parent; +} + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_HELPERS_H diff --git a/ets2panda/ast_verifier/identifierHasVariable.cpp b/ets2panda/ast_verifier/identifierHasVariable.cpp new file mode 100644 index 0000000000..881c39dde3 --- /dev/null +++ b/ets2panda/ast_verifier/identifierHasVariable.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "helpers.h" +#include "identifierHasVariable.h" +#include "ir/base/scriptFunction.h" +#include "ir/expressions/memberExpression.h" +#include "ir/ts/tsEnumDeclaration.h" +#include "ir/typeNode.h" + +namespace ark::es2panda::compiler::ast_verifier { + +CheckResult IdentifierHasVariable::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + if (!ast->IsIdentifier()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + if (ast->AsIdentifier()->Variable() != nullptr) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + const auto *id = ast->AsIdentifier(); + if (CheckAstExceptions(id)) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + // Another function with exceptions to reduce function size + if (CheckMoreAstExceptions(id)) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + ctx.AddCheckMessage("NULL_VARIABLE", *id, id->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; +} + +bool IdentifierHasVariable::CheckMoreAstExceptions(const ir::Identifier *ast) const +{ + // NOTE(kkonkuznetsov): skip async functions + auto parent = ast->Parent(); + while (parent != nullptr) { + if (parent->IsScriptFunction()) { + auto script = parent->AsScriptFunction(); + if (script->IsAsyncFunc()) { + return true; + } + + break; + } + + parent = parent->Parent(); + } + + // NOTE(kkonkuznetsov): skip reexport declarations + if (ast->Parent() != nullptr && ast->Parent()->Parent() != nullptr) { + parent = ast->Parent()->Parent(); + if (parent->IsETSReExportDeclaration()) { + return true; + } + } + + // NOTE(kkonkuznetsov): object expressions + parent = ast->Parent(); + while (parent != nullptr) { + if (parent->IsObjectExpression()) { + return true; + } + + parent = parent->Parent(); + } + + // NOTE(kkonkuznetsov): lambdas + if (ast->Name().Utf8().find("lambda$invoke$") == 0) { + return true; + } + + // NOTE(kkonkuznetsov): some identifiers have empty names + if (ast->Name().Empty()) { + return true; + } + + // NOTE(mmartin): find a better solution to handle utility type resolution + if (ast->Name().Is(Signatures::PARTIAL_TYPE_NAME) || ast->Name().Is(Signatures::REQUIRED_TYPE_NAME) || + ast->Name().Is(Signatures::READONLY_TYPE_NAME)) { + return true; + } + + return false; +} + +bool IdentifierHasVariable::CheckAstExceptions(const ir::Identifier *ast) const +{ + // NOTE(kkonkuznetsov): skip enums + if (ast->Parent()->IsMemberExpression() && + (ast->Parent()->AsMemberExpression()->Object()->TsType() == nullptr || + ast->Parent()->AsMemberExpression()->Object()->TsType()->IsETSEnumType() || + ast->Parent()->AsMemberExpression()->Object()->TsType()->IsETSStringEnumType())) { + return true; + } + + // NOTE(kkonkuznetsov): skip length property + if (ast->Parent()->IsMemberExpression() && ast->Name().Is("length")) { + return true; + } + + // NOTE(kkonkuznetsov): skip anonymous class id + if (ast->Parent()->Parent() != nullptr && ast->Parent()->Parent()->IsETSNewClassInstanceExpression()) { + return true; + } + + // NOTE(kkonkuznetsov): skip package declarations + auto parent = ast->Parent(); + while (parent != nullptr) { + if (parent->IsETSPackageDeclaration()) { + return true; + } + + parent = parent->Parent(); + } + + return false; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/identifierHasVariable.h b/ets2panda/ast_verifier/identifierHasVariable.h new file mode 100644 index 0000000000..ddef8d1b77 --- /dev/null +++ b/ets2panda/ast_verifier/identifierHasVariable.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_IDENTIFIERHASVARIABLE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_IDENTIFIERHASVARIABLE_H + +#include "checkContext.h" + +#include "ir/expressions/identifier.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class IdentifierHasVariable { +public: + explicit IdentifierHasVariable([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + +private: + bool CheckMoreAstExceptions(const ir::Identifier *ast) const; + bool CheckAstExceptions(const ir::Identifier *ast) const; +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_IDENTIFIERHASVARIABLE_H diff --git a/ets2panda/ast_verifier/importExportAccessValid.cpp b/ets2panda/ast_verifier/importExportAccessValid.cpp new file mode 100644 index 0000000000..f2c43e5051 --- /dev/null +++ b/ets2panda/ast_verifier/importExportAccessValid.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "importExportAccessValid.h" +#include "helpers.h" +#include "ir/expressions/callExpression.h" +#include "checker/types/ets/etsObjectType.h" +#include "ir/module/importSpecifier.h" +#include "ir/module/importNamespaceSpecifier.h" +#include "ir/module/importDefaultSpecifier.h" +#include "ir/expressions/identifier.h" +#include "ir/ets/etsImportDeclaration.h" +#include "checker/types/signature.h" + +namespace ark::es2panda::compiler::ast_verifier { + +[[nodiscard]] CheckResult ImportExportAccessValid::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + std::unordered_set importedVariables {}; + if (ast->IsETSImportDeclaration()) { + const auto importDecl = ast->AsETSImportDeclaration()->Specifiers(); + const auto name = [](ir::AstNode *const specifier) { + if (specifier->IsImportNamespaceSpecifier()) { + return specifier->AsImportNamespaceSpecifier()->Local()->Name(); + } + if (specifier->IsImportSpecifier()) { + return specifier->AsImportSpecifier()->Local()->Name(); + } + return specifier->AsImportDefaultSpecifier()->Local()->Name(); + }; + for (const auto import : importDecl) { + importedVariables.emplace(name(import)); + } + } + if (ast->IsCallExpression()) { + const auto *callExpr = ast->AsCallExpression(); + const auto *callee = callExpr->Callee(); + if (callee != nullptr && callee->IsIdentifier() && + !HandleImportExportIdentifier(importedVariables, callee->AsIdentifier(), callExpr)) { + ctx.AddCheckMessage("PROPERTY_NOT_VISIBLE_HERE(NOT_EXPORTED)", *callee, callee->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + } + if (ast->IsIdentifier() && !HandleImportExportIdentifier(importedVariables, ast->AsIdentifier(), nullptr)) { + ctx.AddCheckMessage("PROPERTY_NOT_VISIBLE_HERE(NOT_EXPORTED)", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +bool ImportExportAccessValid::ValidateExport(const varbinder::Variable *var) +{ + const auto *decl = var->Declaration(); + if (decl == nullptr) { + return false; + } + const auto *node = decl->Node(); + if (node == nullptr) { + return false; + } + return node->IsExported() || node->IsExportedType(); +} + +bool ImportExportAccessValid::InvariantImportExportMethod(const std::unordered_set &importedVariables, + const varbinder::Variable *varCallee, + const ir::AstNode *callExpr, util::StringView name) +{ + auto *signature = callExpr->AsCallExpression()->Signature(); + if (signature->Owner() == nullptr) { + // NOTE(vpukhov): Add a synthetic owner for dynamic signatures + ASSERT(callExpr->AsCallExpression()->Callee()->TsType()->HasTypeFlag(checker::TypeFlag::ETS_DYNAMIC_FLAG)); + return true; + } + + if (signature != nullptr && varCallee->Declaration() != nullptr && varCallee->Declaration()->Node() != nullptr && + !IsContainedIn(varCallee->Declaration()->Node(), signature->Owner()->GetDeclNode()) && + varCallee->Declaration()->Node() != signature->Owner()->GetDeclNode()) { + if (importedVariables.find(name.Mutf8()) != importedVariables.end() || + importedVariables.find("") != importedVariables.end()) { + return ValidateExport(varCallee); + } + return false; + } + return true; +} + +bool ImportExportAccessValid::InvariantImportExportVariable(const std::unordered_set &importedVariables, + const varbinder::Variable *var, const ir::Identifier *ident, + util::StringView name) +{ + if (!var->HasFlag(varbinder::VariableFlags::LOCAL) && !var->HasFlag(varbinder::VariableFlags::VAR) && + var->HasFlag(varbinder::VariableFlags::INITIALIZED) && var->Declaration() != nullptr && + var->Declaration()->Node() != nullptr && !var->Declaration()->Node()->IsMethodDefinition() && + !var->Declaration()->Node()->IsClassProperty()) { + auto varParent = var->Declaration()->Node()->Parent(); + if (varParent != nullptr && !IsContainedIn(ident->Parent(), varParent) && ident->Parent() != varParent) { + if (var->GetScope() != nullptr && var->GetScope()->Parent() != nullptr && + var->GetScope()->Parent()->IsGlobalScope() && + ident->GetTopStatement() == varParent->GetTopStatement()) { + return true; + } + if (importedVariables.find(name.Mutf8()) != importedVariables.end() || + importedVariables.find("") != importedVariables.end()) { + return ValidateExport(var); + } + return false; + } + } + return true; +} + +bool ImportExportAccessValid::HandleImportExportIdentifier(std::unordered_set &importedVariables, + const ir::Identifier *ident, const ir::AstNode *callExpr) +{ + if (ident->IsReference()) { + const auto *var = ident->Variable(); + if (var != nullptr) { + if (var->HasFlag(varbinder::VariableFlags::METHOD) && callExpr != nullptr) { + return InvariantImportExportMethod(importedVariables, var, callExpr, ident->Name()); + } + return InvariantImportExportVariable(importedVariables, var, ident, ident->Name()); + } + } + return true; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/importExportAccessValid.h b/ets2panda/ast_verifier/importExportAccessValid.h new file mode 100644 index 0000000000..558ff0bcfe --- /dev/null +++ b/ets2panda/ast_verifier/importExportAccessValid.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_IMPORTEXPORTACCESSVALID_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_IMPORTEXPORTACCESSVALID_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class ImportExportAccessValid { +public: + explicit ImportExportAccessValid([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + +private: + bool ValidateExport(const varbinder::Variable *var); + bool InvariantImportExportMethod(const std::unordered_set &importedVariables, + const varbinder::Variable *varCallee, const ir::AstNode *callExpr, + util::StringView name); + bool InvariantImportExportVariable(const std::unordered_set &importedVariables, + const varbinder::Variable *var, const ir::Identifier *ident, + util::StringView name); + bool HandleImportExportIdentifier(std::unordered_set &importedVariables, const ir::Identifier *ident, + const ir::AstNode *callExpr); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_IMPORTEXPORTACCESSVALID_H diff --git a/ets2panda/ast_verifier/modifierAccessValid.cpp b/ets2panda/ast_verifier/modifierAccessValid.cpp new file mode 100644 index 0000000000..2b91bc5661 --- /dev/null +++ b/ets2panda/ast_verifier/modifierAccessValid.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modifierAccessValid.h" +#include "helpers.h" +#include "varbinder/variableFlags.h" +#include "ir/expressions/memberExpression.h" +#include "ir/expressions/callExpression.h" + +namespace ark::es2panda::compiler::ast_verifier { + +[[nodiscard]] CheckResult ModifierAccessValid::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + if (auto [decision, action] = HandleMethodExpression(ctx, ast); decision == CheckDecision::INCORRECT) { + return {decision, action}; + } + if (auto [decision, action] = HandleCallExpression(ctx, ast); decision == CheckDecision::INCORRECT) { + return {decision, action}; + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +CheckResult ModifierAccessValid::HandleMethodExpression(CheckContext &ctx, const ir::AstNode *ast) +{ + if (!ast->IsMemberExpression()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + const auto *propVar = ast->AsMemberExpression()->PropVar(); + if (propVar != nullptr && propVar->HasFlag(varbinder::VariableFlags::PROPERTY) && + !ValidateVariableAccess(propVar, ast->AsMemberExpression())) { + ctx.AddCheckMessage("PROPERTY_NOT_VISIBLE_HERE", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +CheckResult ModifierAccessValid::HandleCallExpression(CheckContext &ctx, const ir::AstNode *ast) +{ + if (!ast->IsCallExpression()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + const auto *callExpr = ast->AsCallExpression(); + const auto *callee = callExpr->Callee(); + if (callee != nullptr && callee->IsMemberExpression()) { + const auto *calleeMember = callee->AsMemberExpression(); + const auto *propVarCallee = calleeMember->PropVar(); + if (propVarCallee != nullptr && propVarCallee->HasFlag(varbinder::VariableFlags::METHOD) && + !ValidateMethodAccess(calleeMember, ast->AsCallExpression())) { + ctx.AddCheckMessage("PROPERTY_NOT_VISIBLE_HERE", *callee, callee->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/modifierAccessValid.h b/ets2panda/ast_verifier/modifierAccessValid.h new file mode 100644 index 0000000000..dbe24bfea0 --- /dev/null +++ b/ets2panda/ast_verifier/modifierAccessValid.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_MODIFIERACCESSVALID_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_MODIFIERACCESSVALID_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class ModifierAccessValid { +public: + explicit ModifierAccessValid([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + +private: + CheckResult HandleMethodExpression(CheckContext &ctx, const ir::AstNode *ast); + CheckResult HandleCallExpression(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_MODIFIERACCESSVALID_H diff --git a/ets2panda/ast_verifier/nodeHasParent.cpp b/ets2panda/ast_verifier/nodeHasParent.cpp new file mode 100644 index 0000000000..94a78985d8 --- /dev/null +++ b/ets2panda/ast_verifier/nodeHasParent.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nodeHasParent.h" + +#include "ir/statements/blockStatement.h" + +namespace ark::es2panda::compiler::ast_verifier { + +CheckResult NodeHasParent::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + const auto isEtsScript = ast->IsETSScript() || (ast->IsBlockStatement() && ast->AsBlockStatement()->IsProgram()); + const auto hasParent = ast->Parent() != nullptr; + if (!isEtsScript && !hasParent) { + ctx.AddCheckMessage("NULL_PARENT", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + + if (ast->IsProgram()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/nodeHasParent.h b/ets2panda/ast_verifier/nodeHasParent.h new file mode 100644 index 0000000000..852feb7187 --- /dev/null +++ b/ets2panda/ast_verifier/nodeHasParent.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASPARENT_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASPARENT_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class NodeHasParent { +public: + explicit NodeHasParent([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASPARENT_H diff --git a/ets2panda/ast_verifier/nodeHasSourceRange.cpp b/ets2panda/ast_verifier/nodeHasSourceRange.cpp new file mode 100644 index 0000000000..f6bee31d65 --- /dev/null +++ b/ets2panda/ast_verifier/nodeHasSourceRange.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nodeHasSourceRange.h" + +namespace ark::es2panda::compiler::ast_verifier { + +CheckResult NodeHasSourceRange::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + const auto hasRange = + ast->Start().line != 0 || ast->Start().index != 0 || ast->End().line != 0 || ast->End().index != 0; + if (!hasRange) { + ctx.AddCheckMessage("NULL_RANGE", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/nodeHasSourceRange.h b/ets2panda/ast_verifier/nodeHasSourceRange.h new file mode 100644 index 0000000000..d5fe280ee0 --- /dev/null +++ b/ets2panda/ast_verifier/nodeHasSourceRange.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASSOURCERANGE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASSOURCERANGE_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class NodeHasSourceRange { +public: + explicit NodeHasSourceRange([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASSOURCERANGE_H diff --git a/ets2panda/ast_verifier/nodeHasType.cpp b/ets2panda/ast_verifier/nodeHasType.cpp new file mode 100644 index 0000000000..d6f7c0e534 --- /dev/null +++ b/ets2panda/ast_verifier/nodeHasType.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "helpers.h" +#include "nodeHasType.h" +#include "ir/base/classDefinition.h" +#include "ir/expressions/identifier.h" +#include "ir/ts/tsEnumDeclaration.h" +#include "ir/ts/tsInterfaceBody.h" +#include "ir/ts/tsInterfaceDeclaration.h" + +namespace ark::es2panda::compiler::ast_verifier { + +CheckResult NodeHasType::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + // NOTE(orlovskymaxim) In TS some ETS constructs are expressions (i.e. class/interface definition) + // Because ETS uses some AST classes from TS this introduces semantical problem + // Solution for now - manually filter expressions that are statements in ETS + if (ast->IsETSPackageDeclaration()) { + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + if (IsImportLike(ast)) { + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + if (IsExportLike(ast)) { + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + + if (ast->IsTSTypeAliasDeclaration()) { + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + if (auto [decision, action] = CheckCompound(ctx, ast); action == CheckAction::SKIP_SUBTREE) { + return {decision, action}; + } + + if (ast->IsTyped() && ast->IsExpression()) { + if (ast->IsClassDefinition() && ast->AsClassDefinition()->Ident()->Name() == "ETSGLOBAL") { + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + if (ast->IsIdentifier() && ast->AsIdentifier()->Name() == "") { + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + const auto *typed = static_cast(ast); + if (typed->TsType() == nullptr) { + ctx.AddCheckMessage("NULL_TS_TYPE", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +CheckResult NodeHasType::CheckCompound(CheckContext &ctx, const ir::AstNode *ast) +{ + if (ast->IsTSInterfaceDeclaration()) { + for (const auto &member : ast->AsTSInterfaceDeclaration()->Body()->Body()) { + [[maybe_unused]] auto _ = (*this)(ctx, member); + } + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + if (ast->IsTSEnumDeclaration()) { + for (const auto &member : ast->AsTSEnumDeclaration()->Members()) { + [[maybe_unused]] auto _ = (*this)(ctx, member); + } + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + if (ast->IsClassDefinition()) { + for (const auto &member : ast->AsClassDefinition()->Body()) { + [[maybe_unused]] auto _ = (*this)(ctx, member); + } + return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/nodeHasType.h b/ets2panda/ast_verifier/nodeHasType.h new file mode 100644 index 0000000000..2d7427372e --- /dev/null +++ b/ets2panda/ast_verifier/nodeHasType.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASTYPE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASTYPE_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class NodeHasType { +public: + explicit NodeHasType([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + +private: + CheckResult CheckCompound(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASTYPE_H diff --git a/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.cpp b/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.cpp new file mode 100644 index 0000000000..5770b83e92 --- /dev/null +++ b/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "referenceTypeAnnotationIsNull.h" + +#include "ir/expressions/identifier.h" + +namespace ark::es2panda::compiler::ast_verifier { + +CheckResult ReferenceTypeAnnotationIsNull::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); + if (ast->IsIdentifier()) { + if (ast->AsIdentifier()->IsReference() && ast->AsIdentifier()->TypeAnnotation() != nullptr) { + ctx.AddCheckMessage("TYPE_ANNOTATION_NOT_NULLPTR", *ast, ast->Start()); + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + } + return result; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.h b/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.h new file mode 100644 index 0000000000..0be6c7ef2b --- /dev/null +++ b/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_REFERENCETYPEANNOTATIONISNULL_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_REFERENCETYPEANNOTATIONISNULL_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class ReferenceTypeAnnotationIsNull { +public: + explicit ReferenceTypeAnnotationIsNull([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_REFERENCETYPEANNOTATIONISNULL_H diff --git a/ets2panda/ast_verifier/sequenceExpressionHasLastType.cpp b/ets2panda/ast_verifier/sequenceExpressionHasLastType.cpp new file mode 100644 index 0000000000..28fc77836e --- /dev/null +++ b/ets2panda/ast_verifier/sequenceExpressionHasLastType.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sequenceExpressionHasLastType.h" +#include "ir/expressions/sequenceExpression.h" + +namespace ark::es2panda::compiler::ast_verifier { + +[[nodiscard]] CheckResult SequenceExpressionHasLastType::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + if (!ast->IsSequenceExpression()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + const auto *expr = ast->AsSequenceExpression(); + const auto *last = expr->Sequence().back(); + if (expr->TsType() == nullptr) { + ctx.AddCheckMessage("Sequence expression type is null", *expr, expr->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + if (last->TsType() == nullptr) { + ctx.AddCheckMessage("Sequence expression last type is null", *last, last->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + if (expr->TsType() != last->TsType()) { + ctx.AddCheckMessage("Sequence expression type and last expression type are not the same", *expr, expr->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/sequenceExpressionHasLastType.h b/ets2panda/ast_verifier/sequenceExpressionHasLastType.h new file mode 100644 index 0000000000..64087b3ac1 --- /dev/null +++ b/ets2panda/ast_verifier/sequenceExpressionHasLastType.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_SEQUENCEEXPRESSIONHASLASTTYPE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_SEQUENCEEXPRESSIONHASLASTTYPE_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class SequenceExpressionHasLastType { +public: + explicit SequenceExpressionHasLastType([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + +private: +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_SEQUENCEEXPRESSIONHASLASTTYPE_H diff --git a/ets2panda/ast_verifier/variableHasEnclosingScope.cpp b/ets2panda/ast_verifier/variableHasEnclosingScope.cpp new file mode 100644 index 0000000000..d7319b279f --- /dev/null +++ b/ets2panda/ast_verifier/variableHasEnclosingScope.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "variableHasEnclosingScope.h" +#include "variableHasScope.h" +#include "helpers.h" +#include "ir/expressions/functionExpression.h" +#include "ir/base/scriptFunction.h" +#include "ir/expressions/identifier.h" +#include "ir/typeNode.h" + +namespace ark::es2panda::compiler::ast_verifier { + +[[nodiscard]] CheckResult VariableHasEnclosingScope::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + const auto maybeVar = VariableHasScope::GetLocalScopeVariable(allocator_, ctx, ast); + if (!maybeVar) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + const auto var = *maybeVar; + const auto scope = var->GetScope(); + if (scope == nullptr) { + // already checked + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + const auto encloseScope = scope->EnclosingVariableScope(); + if (encloseScope == nullptr) { + ctx.AddCheckMessage("NO_ENCLOSING_VAR_SCOPE", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + const auto node = scope->Node(); + auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); + if (!IsContainedIn(ast, node)) { + if (CheckCatchClause(ast, node)) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + if (CheckScopeNodeExceptions(node)) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + if (CheckAstExceptions(ast)) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + ctx.AddCheckMessage("VARIABLE_NOT_ENCLOSE_SCOPE", *ast, ast->Start()); + } + + if (!IsContainedIn(scope, encloseScope)) { + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + ctx.AddCheckMessage("VARIABLE_NOT_ENCLOSE_SCOPE", *ast, ast->Start()); + } + + return result; +} + +bool VariableHasEnclosingScope::CheckCatchClause(const ir::AstNode *ast, const ir::AstNode *node) const +{ + if (node == nullptr) { + return false; + } + + // Check that ast node is contained within node parent for Catch Clause: + // Catch Clause { + // Catch Body { + // AST that we need to check + // } + // Param (Scope Node) { + // } + // } + if (node->Parent() != nullptr && node->Parent()->IsCatchClause()) { + return IsContainedIn(ast, node->Parent()); + } + + return false; +} + +bool VariableHasEnclosingScope::CheckScopeNodeExceptions(const ir::AstNode *node) const +{ + if (node == nullptr) { + return false; + } + + // NOTE(kkonkuznetsov): lambdas + auto parent = node->Parent(); + while (parent != nullptr) { + if (parent->IsFunctionExpression()) { + auto script = parent->AsFunctionExpression()->Function(); + if (script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { + return true; + } + + break; + } + + parent = parent->Parent(); + } + + return false; +} + +bool VariableHasEnclosingScope::CheckAstExceptions(const ir::AstNode *ast) const +{ + // NOTE(kkonkuznetsov): skip parameter expression inside arrow function expression + auto parent = ast->Parent(); + while (parent != nullptr) { + if (parent->IsETSParameterExpression()) { + return true; + } + + parent = parent->Parent(); + } + + if (ast->Parent()->IsLabelledStatement()) { + // Labels are attached to loop scopes, + // however label identifier is outside of loop. + // Example: + // + // loop: for (let i = 0; i < 10; i++) { + // } + return true; + } + + // NOTE(kkonkuznetsov): skip lambdas + parent = ast->Parent(); + while (parent != nullptr) { + if (parent->IsFunctionExpression()) { + auto script = parent->AsFunctionExpression()->Function(); + if (script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { + return true; + } + + break; + } + + parent = parent->Parent(); + } + + return false; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/variableHasEnclosingScope.h b/ets2panda/ast_verifier/variableHasEnclosingScope.h new file mode 100644 index 0000000000..cce4c2e2f7 --- /dev/null +++ b/ets2panda/ast_verifier/variableHasEnclosingScope.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASENCLOSINGSCOPE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASENCLOSINGSCOPE_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class VariableHasEnclosingScope { +public: + explicit VariableHasEnclosingScope(ArenaAllocator &allocator) : allocator_ {allocator} {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + +private: + bool CheckCatchClause(const ir::AstNode *ast, const ir::AstNode *node) const; + bool CheckScopeNodeExceptions(const ir::AstNode *node) const; + bool CheckAstExceptions(const ir::AstNode *ast) const; + + ArenaAllocator &allocator_; +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASENCLOSINGSCOPE_H diff --git a/ets2panda/ast_verifier/variableHasScope.cpp b/ets2panda/ast_verifier/variableHasScope.cpp new file mode 100644 index 0000000000..e19c94bf1f --- /dev/null +++ b/ets2panda/ast_verifier/variableHasScope.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "helpers.h" +#include "identifierHasVariable.h" +#include "variableHasScope.h" +#include "ir/base/scriptFunction.h" +#include "ir/ts/tsEnumDeclaration.h" +#include "ir/typeNode.h" + +namespace ark::es2panda::compiler::ast_verifier { + +CheckResult VariableHasScope::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + if (!ast->IsIdentifier()) { + // Check invariant of Identifier only + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + // NOTE(kkonkuznetsov): lambdas + if (ast->AsIdentifier()->Name().Utf8().find("lambda$invoke$") == 0) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + // we will check invariant for only local variables of identifiers + if (const auto maybeVar = GetLocalScopeVariable(allocator_, ctx, ast); maybeVar.has_value()) { + const auto var = *maybeVar; + const auto scope = var->GetScope(); + if (scope == nullptr) { + ctx.AddCheckMessage("NULL_SCOPE_LOCAL_VAR", *ast, ast->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + + auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); + if (!ScopeEncloseVariable(ctx, var)) { + result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; + } + + return result; + } + + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; +} + +std::optional VariableHasScope::GetLocalScopeVariable(ArenaAllocator &allocator, + CheckContext &ctx, + const ir::AstNode *ast) +{ + if (!ast->IsIdentifier()) { + return std::nullopt; + } + + auto invariantHasVariable = IdentifierHasVariable {allocator}; + const auto variable = ast->AsIdentifier()->Variable(); + const auto [decision, action] = invariantHasVariable(ctx, ast); + + if (variable == nullptr) { + // NOTE(kkonkuznetsov): variable should not be null + // but currently some identifiers do not have variables, + // see exceptions in IdentifierHasVariable check + return std::nullopt; + } + + if (decision == CheckDecision::CORRECT && variable->IsLocalVariable()) { + const auto localVar = variable->AsLocalVariable(); + if (localVar->HasFlag(varbinder::VariableFlags::LOCAL)) { + return localVar; + } + } + + return std::nullopt; +} + +bool VariableHasScope::ScopeEncloseVariable(CheckContext &ctx, const varbinder::LocalVariable *var) +{ + ASSERT(var); + + const auto scope = var->GetScope(); + if (scope == nullptr || var->Declaration() == nullptr) { + return true; + } + + const auto node = var->Declaration()->Node(); + if (node == nullptr) { + return true; + } + + const auto varStart = node->Start(); + bool isOk = true; + if (scope->Bindings().count(var->Name()) == 0) { + ctx.AddCheckMessage("SCOPE_DO_NOT_ENCLOSE_LOCAL_VAR", *node, varStart); + isOk = false; + } + + const auto scopeNode = scope->Node(); + const auto varNode = node; + bool skip = CheckAstExceptions(varNode); + + if (!IsContainedIn(varNode, scopeNode) || scopeNode == nullptr) { + if (!skip) { + ctx.AddCheckMessage("SCOPE_NODE_DONT_DOMINATE_VAR_NODE", *node, varStart); + isOk = false; + } + } + + const auto &decls = scope->Decls(); + const auto declDominate = std::count(decls.begin(), decls.end(), var->Declaration()); + if (declDominate == 0) { + if (!skip) { + ctx.AddCheckMessage("SCOPE_DECL_DONT_DOMINATE_VAR_DECL", *node, varStart); + isOk = false; + } + } + + return isOk; +} + +bool VariableHasScope::CheckAstExceptions(const ir::AstNode *ast) +{ + // NOTE(kkonkuznetsov): in some cases with lambdas scope node is null + if (ast->Parent() != nullptr && ast->Parent()->IsETSFunctionType()) { + return true; + } + + if (ast->IsLabelledStatement()) { + // Labels are attached to loop scopes, + // however label identifier is outside of loop. + // Example: + // + // loop: for (let i = 0; i < 10; i++) { + // } + return true; + } + + // NOTE(kkonkuznetsov): lambdas + auto parent = ast->Parent(); + while (parent != nullptr) { + if (parent->IsScriptFunction()) { + auto script = parent->AsScriptFunction(); + if (script->Id() != nullptr && script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { + return true; + } + + break; + } + + parent = parent->Parent(); + } + + return false; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/variableHasScope.h b/ets2panda/ast_verifier/variableHasScope.h new file mode 100644 index 0000000000..52cc7a91cd --- /dev/null +++ b/ets2panda/ast_verifier/variableHasScope.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASSCOPE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASSCOPE_H + +#include "checkContext.h" + +#include "varbinder/varbinder.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class VariableHasScope { +public: + explicit VariableHasScope(ArenaAllocator &allocator) : allocator_ {allocator} {} + + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); + static std::optional GetLocalScopeVariable(ArenaAllocator &allocator, CheckContext &ctx, + const ir::AstNode *ast); + bool ScopeEncloseVariable(CheckContext &ctx, const varbinder::LocalVariable *var); + +private: + ArenaAllocator &allocator_; + bool CheckAstExceptions(const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASSCOPE_H diff --git a/ets2panda/ast_verifier/variableNameIdentifierNameSame.cpp b/ets2panda/ast_verifier/variableNameIdentifierNameSame.cpp new file mode 100644 index 0000000000..f2bb9f7d5f --- /dev/null +++ b/ets2panda/ast_verifier/variableNameIdentifierNameSame.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "variableNameIdentifierNameSame.h" +#include "ir/expressions/identifier.h" +#include "ir/ets/etsImportDeclaration.h" + +namespace ark::es2panda::compiler::ast_verifier { + +[[nodiscard]] CheckResult VariableNameIdentifierNameSame::operator()(CheckContext &ctx, const ir::AstNode *ast) +{ + if (!ast->IsIdentifier()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + const auto *id = ast->AsIdentifier(); + const auto variable = ast->AsIdentifier()->Variable(); + if (variable == nullptr || variable->Declaration() == nullptr || variable->Declaration()->Node() == nullptr) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + const auto variableNode = variable->Declaration()->Node(); + // NOTE(psaykerone): skip because, this exceptions need to be fixed in checker and lowering + if (variableNode->IsExported() || variableNode->IsExportedType() || variableNode->IsDefaultExported() || + id->Name().Utf8().find("field") == 0 || variable->Name().Utf8().find("field") == 0) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + if (id->Name() == variable->Name()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + // For dynamic imports imported identifier name does not match variable name + // Example: + // import { A as AA } from "dynamic_js_import_tests" + // Variable name will be AA + // But imported identifier name is A + auto parent = ast->Parent(); + while (parent != nullptr) { + if (parent->IsETSImportDeclaration() && parent->AsETSImportDeclaration()->IsPureDynamic()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + } + + parent = parent->Parent(); + } + + ctx.AddCheckMessage("IDENTIFIER_NAME_DIFFERENCE", *id, id->Start()); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; +} + +} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/variableNameIdentifierNameSame.h b/ets2panda/ast_verifier/variableNameIdentifierNameSame.h new file mode 100644 index 0000000000..3fec3eb3f1 --- /dev/null +++ b/ets2panda/ast_verifier/variableNameIdentifierNameSame.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLENAMEIDENTIFIERNAMESAME_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLENAMEIDENTIFIERNAMESAME_H + +#include "checkContext.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class VariableNameIdentifierNameSame { +public: + explicit VariableNameIdentifierNameSame([[maybe_unused]] ArenaAllocator &allocator) {} + [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLENAMEIDENTIFIERNAMESAME_H diff --git a/ets2panda/compiler/core/ASTVerifier.cpp b/ets2panda/compiler/core/ASTVerifier.cpp deleted file mode 100644 index ebb27993e3..0000000000 --- a/ets2panda/compiler/core/ASTVerifier.cpp +++ /dev/null @@ -1,1443 +0,0 @@ -/* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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 "ASTVerifier.h" - -#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" -#include "ir/ets/etsClassLiteral.h" -#include "ir/ets/etsFunctionType.h" -#include "ir/ets/etsNewClassInstanceExpression.h" -#include "ir/ets/etsParameterExpression.h" -#include "ir/ets/etsTypeReference.h" -#include "ir/ets/etsTypeReferencePart.h" -#include "ir/ets/etsImportDeclaration.h" -#include "ir/ets/etsScript.h" -#include "ir/expressions/sequenceExpression.h" -#include "ir/module/importSpecifier.h" -#include "ir/module/importNamespaceSpecifier.h" -#include "ir/module/importDefaultSpecifier.h" -#include "ir/expressions/callExpression.h" -#include "ir/expressions/binaryExpression.h" -#include "ir/expressions/functionExpression.h" -#include "ir/expressions/identifier.h" -#include "ir/expressions/literals/numberLiteral.h" -#include "ir/expressions/literals/stringLiteral.h" -#include "ir/expressions/memberExpression.h" -#include "ir/statements/blockStatement.h" -#include "ir/statements/forInStatement.h" -#include "ir/statements/forOfStatement.h" -#include "ir/statements/forUpdateStatement.h" -#include "ir/statements/variableDeclaration.h" -#include "ir/statements/variableDeclarator.h" -#include "ir/statements/classDeclaration.h" -#include "ir/statements/expressionStatement.h" -#include "ir/statements/throwStatement.h" -#include "ir/statements/tryStatement.h" -#include "ir/ts/tsClassImplements.h" -#include "ir/ts/tsEnumDeclaration.h" -#include "ir/ts/tsInterfaceBody.h" -#include "ir/ts/tsTypeParameter.h" -#include "ir/ts/tsTypeParameterDeclaration.h" -#include "ir/ts/tsTypeParameterInstantiation.h" -#include "lexer/token/tokenType.h" -#include "util/ustring.h" -#include "utils/arena_containers.h" -#include "varbinder/scope.h" - -#include -#include - -namespace ark::es2panda::compiler::ast_verifier { -class CheckContext { -public: - explicit CheckContext() : checkName_ {"Invalid"} {} - - void AddCheckMessage(const std::string &cause, const ir::AstNode &node, const lexer::SourcePosition &from) - { - const auto loc = from.line; - const auto &&dump = node.DumpJSON(); - messages_.emplace_back(checkName_, cause.data(), dump.data(), loc); - } - - void SetCheckName(util::StringView checkName) - { - checkName_ = checkName; - } - - Messages GetMessages() - { - return messages_; - } - -private: - Messages messages_; - util::StringView checkName_; -}; - -static bool IsBooleanType(const ir::AstNode *ast) -{ - if (ast == nullptr) { - return false; - } - - if (!ast->IsTyped()) { - return false; - } - - auto typedAst = static_cast(ast); - - if (typedAst->TsType() == nullptr) { - return false; - } - - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && - ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { - return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); - } - - return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) || - typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BOOLEAN_LIKE); -} - -bool IsImportLike(const ir::AstNode *ast) -{ - return (ast->IsETSImportDeclaration() || ast->IsETSReExportDeclaration() || ast->IsImportExpression() || - ast->IsImportSpecifier() || ast->IsImportDefaultSpecifier() || ast->IsImportNamespaceSpecifier()); -} - -bool IsExportLike(const ir::AstNode *ast) -{ - return (ast->IsExportDefaultDeclaration() || ast->IsExportSpecifier() || ast->IsExportAllDeclaration() || - ast->IsExportNamedDeclaration() || ast->IsETSReExportDeclaration()); -} - -static bool IsValidTypeForBinaryOp(const ir::AstNode *ast, bool isBitwise) -{ - if (ast == nullptr) { - std::cout << __LINE__ << std::endl; - return false; - } - - if (!ast->IsTyped()) { - std::cout << __LINE__ << std::endl; - return false; - } - - auto typedAst = static_cast(ast); - - if (typedAst->TsType() == nullptr) { - // std::cout << typedAst - std::cout << __LINE__ << std::endl; - return false; - } - - if (IsBooleanType(ast)) { - return isBitwise; - } - - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && - typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BIGINT)) { - return true; - } - - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && - ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { - return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE) && - !typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); - } - - return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - typedAst->TsType()->HasTypeFlag(checker::TypeFlag::NUMBER_LITERAL) || - typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BIGINT) || - typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL); -} - -static bool IsStringType(const ir::AstNode *ast) -{ - if (ast == nullptr) { - return false; - } - - if (!ast->IsTyped()) { - return false; - } - - auto typedAst = static_cast(ast); - - if (typedAst->TsType() == nullptr) { - return false; - } - - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { - return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::STRING) || - typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_STRING); - } - - return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::STRING_LIKE); -} - -template -static bool IsContainedIn(const T *child, const T *parent) -{ - if (child == nullptr || parent == nullptr) { - return false; - } - - std::unordered_set savedNodes; - while (child != nullptr && child != parent) { - savedNodes.emplace(child); - child = child->Parent(); - if (savedNodes.find(child) != savedNodes.end()) { - return false; - } - } - return child == parent; -} -bool IsVisibleInternalNode(const ir::AstNode *ast, const ir::AstNode *objTypeDeclNode) -{ - // NOTE(orlovskymaxim) This relies on the fact, that GetTopStatement has no bugs, that is not the case for now - if (!ast->GetTopStatement()->IsETSScript()) { - return false; - } - auto *currentTopStatement = (static_cast(ast->GetTopStatement())); - auto *currentProgram = currentTopStatement->Program(); - if (currentProgram == nullptr) { - return false; - } - util::StringView moduleNameCurrent = currentProgram->ModuleName(); - // NOTE(orlovskymaxim) This relies on the fact, that GetTopStatement has no bugs, that is not the case for now - if (!objTypeDeclNode->GetTopStatement()->IsETSScript()) { - return false; - } - auto *objectTopStatement = (static_cast(objTypeDeclNode->GetTopStatement())); - auto *objectProgram = objectTopStatement->Program(); - if (objectProgram == nullptr) { - return false; - } - util::StringView moduleNameObject = objectProgram->ModuleName(); - return currentTopStatement == objectTopStatement || moduleNameCurrent == moduleNameObject; -} - -static const checker::Type *GetClassDefinitionType(const ir::AstNode *ast) -{ - const ir::AstNode *tmpNode = ast; - while (tmpNode->Parent() != nullptr && !tmpNode->IsClassDefinition()) { - tmpNode = tmpNode->Parent(); - } - if (!tmpNode->IsClassDefinition()) { - return nullptr; - } - auto *classDefinition = tmpNode->AsClassDefinition(); - return classDefinition->TsType(); -} - -static const checker::Type *GetTSInterfaceDeclarationType(const ir::AstNode *ast) -{ - const ir::AstNode *tmpNode = ast; - while (tmpNode->Parent() != nullptr && !tmpNode->IsTSInterfaceDeclaration()) { - tmpNode = tmpNode->Parent(); - } - if (!tmpNode->IsTSInterfaceDeclaration()) { - return nullptr; - } - auto *tsInterfaceDeclaration = tmpNode->AsTSInterfaceDeclaration(); - return tsInterfaceDeclaration->TsType(); -} - -static bool ValidateMethodAccessForClass(const ir::AstNode *ast, const ir::AstNode *ownerSignDeclNode, - checker::Signature *signature, const ir::AstNode *memberObjTypeDeclNode) -{ - // Check if the method is used where it is declared - if (IsContainedIn(ast, ownerSignDeclNode)) { - return true; - } - if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE)) { - return false; - } - if (signature->HasSignatureFlag(checker::SignatureFlags::PROTECTED)) { - // Check if the method is inherited and is used in class in which it is inherited - auto *classDefinitionType = GetClassDefinitionType(ast); - if (classDefinitionType == nullptr || !classDefinitionType->IsETSObjectType()) { - return false; - } - auto *classObjectType = classDefinitionType->AsETSObjectType(); - return classObjectType->IsDescendantOf(signature->Owner()); - } - if (signature->HasSignatureFlag(checker::SignatureFlags::INTERNAL)) { - return IsVisibleInternalNode(ast, memberObjTypeDeclNode); - } - return true; -} - -static bool ValidateMethodAccessForTSInterface(const ir::AstNode *ast, const ir::AstNode *ownerSignDeclNode, - checker::Signature *signature, const ir::AstNode *memberObjTypeDeclNode) -{ - // Check if the method is used where it is declared - if (IsContainedIn(ast, ownerSignDeclNode)) { - return true; - } - if (signature->HasSignatureFlag(checker::SignatureFlags::PRIVATE)) { - return false; - } - if (signature->HasSignatureFlag(checker::SignatureFlags::PROTECTED)) { - // Check if the method is inherited and is used in class in which it is inherited - auto *tsInterfaceDeclarationType = GetTSInterfaceDeclarationType(ast); - if (tsInterfaceDeclarationType == nullptr || !tsInterfaceDeclarationType->IsETSObjectType()) { - return false; - } - auto *tsInterfaceObjectType = tsInterfaceDeclarationType->AsETSObjectType(); - return tsInterfaceObjectType->IsDescendantOf(signature->Owner()); - } - if (signature->HasSignatureFlag(checker::SignatureFlags::INTERNAL)) { - return IsVisibleInternalNode(ast, memberObjTypeDeclNode); - } - return true; -} - -static bool ValidatePropertyAccessForClass(const ir::AstNode *ast, const ir::AstNode *propVarDeclNode, - const ir::AstNode *propVarDeclNodeParent, - const varbinder::LocalVariable *propVar, const ir::AstNode *objTypeDeclNode) -{ - // Check if the variable is used where it is declared - if (IsContainedIn(ast, propVarDeclNodeParent)) { - return true; - } - if (propVarDeclNode->IsPrivate()) { - return false; - } - if (propVarDeclNode->IsProtected()) { - auto *classDefinitionType = GetClassDefinitionType(ast); - if (classDefinitionType == nullptr || !classDefinitionType->IsETSObjectType()) { - return false; - } - auto *classObjectType = classDefinitionType->AsETSObjectType(); - return classObjectType->IsPropertyOfAscendant(propVar); - } - if (propVarDeclNode->IsInternal()) { - return IsVisibleInternalNode(ast, objTypeDeclNode); - } - return true; -} - -static bool ValidateVariableAccess(const varbinder::LocalVariable *propVar, const ir::MemberExpression *ast) -{ - const auto *propVarDecl = propVar->Declaration(); - if (propVarDecl == nullptr) { - return false; - } - const auto *propVarDeclNode = propVarDecl->Node(); - if (propVarDeclNode == nullptr) { - return false; - } - auto *objType = ast->ObjType(); - if (objType == nullptr) { - return false; - } - const auto *objTypeDeclNode = objType->GetDeclNode(); - if (objTypeDeclNode == nullptr) { - return false; - } - if (objTypeDeclNode->Parent() != nullptr && objTypeDeclNode->Parent()->IsImportNamespaceSpecifier()) { - return true; - } - const auto *propVarDeclNodeParent = propVarDeclNode->Parent(); - if (propVarDeclNodeParent == nullptr) { - return false; - } - if (propVarDeclNodeParent->IsClassDefinition() && objTypeDeclNode->IsClassDefinition()) { - return ValidatePropertyAccessForClass(ast, propVarDeclNode, propVarDeclNodeParent, propVar, objTypeDeclNode); - } - return false; -} - -static bool ValidateMethodAccess(const ir::MemberExpression *memberExpression, const ir::CallExpression *ast) -{ - auto *memberObjType = memberExpression->ObjType(); - if (memberObjType == nullptr) { - return false; - } - if (memberObjType->HasObjectFlag(checker::ETSObjectFlags::RESOLVED_SUPER) && - memberObjType->SuperType() != nullptr && - memberObjType->SuperType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE | - checker::ETSObjectFlags::GLOBAL)) { - return true; - } - const auto *memberObjTypeDeclNode = memberObjType->GetDeclNode(); - if (memberObjTypeDeclNode == nullptr) { - return false; - } - if (memberObjTypeDeclNode->Parent() != nullptr && memberObjTypeDeclNode->Parent()->IsImportNamespaceSpecifier()) { - return true; - } - auto *signature = ast->Signature(); - if (signature == nullptr) { - return false; - } - auto *ownerSign = signature->Owner(); - if (ownerSign == nullptr) { - return false; - } - auto *ownerSignDeclNode = ownerSign->GetDeclNode(); - if (ownerSignDeclNode == nullptr) { - return false; - } - if (!ownerSignDeclNode->IsClassDefinition() && !ownerSignDeclNode->IsTSInterfaceDeclaration()) { - return false; - } - bool ret = false; - if (memberObjTypeDeclNode->IsClassDefinition()) { - ret = ValidateMethodAccessForClass(ast, ownerSignDeclNode, signature, memberObjTypeDeclNode); - } else if (memberObjTypeDeclNode->IsTSInterfaceDeclaration()) { - ret = ValidateMethodAccessForTSInterface(ast, ownerSignDeclNode, signature, memberObjTypeDeclNode); - } - return ret; -} - -class VariableNameIdentifierNameSame { -public: - explicit VariableNameIdentifierNameSame([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - if (!ast->IsIdentifier()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - const auto *id = ast->AsIdentifier(); - const auto variable = ast->AsIdentifier()->Variable(); - if (variable == nullptr || variable->Declaration() == nullptr || variable->Declaration()->Node() == nullptr) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - const auto variableNode = variable->Declaration()->Node(); - // NOTE(psaykerone): skip because, this exceptions need to be fixed in checker and lowering - if (variableNode->IsExported() || variableNode->IsExportedType() || variableNode->IsDefaultExported() || - id->Name().Utf8().find("field") == 0 || variable->Name().Utf8().find("field") == 0) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - if (id->Name() == variable->Name()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - // For dynamic imports imported identifier name does not match variable name - // Example: - // import { A as AA } from "dynamic_js_import_tests" - // Variable name will be AA - // But imported identifier name is A - auto parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsETSImportDeclaration() && parent->AsETSImportDeclaration()->IsPureDynamic()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - parent = parent->Parent(); - } - - ctx.AddCheckMessage("IDENTIFIER_NAME_DIFFERENCE", *id, id->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } -}; - -class NodeHasParent { -public: - explicit NodeHasParent([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - const auto isEtsScript = - ast->IsETSScript() || (ast->IsBlockStatement() && ast->AsBlockStatement()->IsProgram()); - const auto hasParent = ast->Parent() != nullptr; - if (!isEtsScript && !hasParent) { - ctx.AddCheckMessage("NULL_PARENT", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - if (ast->IsProgram()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } -}; - -class ReferenceTypeAnnotationIsNull { -public: - explicit ReferenceTypeAnnotationIsNull([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); - if (ast->IsIdentifier()) { - if (ast->AsIdentifier()->IsReference() && ast->AsIdentifier()->TypeAnnotation() != nullptr) { - ctx.AddCheckMessage("TYPE_ANNOTATION_NOT_NULLPTR", *ast, ast->Start()); - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - } - return result; - } -}; - -class NodeHasSourceRange { -public: - explicit NodeHasSourceRange([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - const auto hasRange = - ast->Start().line != 0 || ast->Start().index != 0 || ast->End().line != 0 || ast->End().index != 0; - if (!hasRange) { - ctx.AddCheckMessage("NULL_RANGE", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } -}; - -class IdentifierHasVariable { -public: - explicit IdentifierHasVariable([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - if (!ast->IsIdentifier()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - if (ast->AsIdentifier()->Variable() != nullptr) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - const auto *id = ast->AsIdentifier(); - if (CheckAstExceptions(id)) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - // Another function with exceptions to reduce function size - if (CheckMoreAstExceptions(id)) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - ctx.AddCheckMessage("NULL_VARIABLE", *id, id->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - -private: - bool CheckMoreAstExceptions(const ir::Identifier *ast) const - { - // NOTE(kkonkuznetsov): skip async functions - auto parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsScriptFunction()) { - auto script = parent->AsScriptFunction(); - if (script->IsAsyncFunc()) { - return true; - } - - break; - } - - parent = parent->Parent(); - } - - // NOTE(kkonkuznetsov): skip reexport declarations - if (ast->Parent() != nullptr && ast->Parent()->Parent() != nullptr) { - parent = ast->Parent()->Parent(); - if (parent->IsETSReExportDeclaration()) { - return true; - } - } - - // NOTE(kkonkuznetsov): object expressions - parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsObjectExpression()) { - return true; - } - - parent = parent->Parent(); - } - - // NOTE(kkonkuznetsov): lambdas - if (ast->Name().Utf8().find("lambda$invoke$") == 0) { - return true; - } - - // NOTE(kkonkuznetsov): some identifiers have empty names - if (ast->Name().Empty()) { - return true; - } - - // NOTE(mmartin): find a better solution to handle utility type resolution - if (ast->Name().Is(Signatures::PARTIAL_TYPE_NAME) || ast->Name().Is(Signatures::REQUIRED_TYPE_NAME) || - ast->Name().Is(Signatures::READONLY_TYPE_NAME)) { - return true; - } - - return false; - } - - bool CheckAstExceptions(const ir::Identifier *ast) const - { - // NOTE(kkonkuznetsov): skip enums - if (ast->Parent()->IsMemberExpression() && - (ast->Parent()->AsMemberExpression()->Object()->TsType() == nullptr || - ast->Parent()->AsMemberExpression()->Object()->TsType()->IsETSEnumType() || - ast->Parent()->AsMemberExpression()->Object()->TsType()->IsETSStringEnumType())) { - return true; - } - - // NOTE(kkonkuznetsov): skip length property - if (ast->Parent()->IsMemberExpression() && ast->Name().Is("length")) { - return true; - } - - // NOTE(kkonkuznetsov): skip anonymous class id - if (ast->Parent()->Parent() != nullptr && ast->Parent()->Parent()->IsETSNewClassInstanceExpression()) { - return true; - } - - // NOTE(kkonkuznetsov): skip package declarations - auto parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsETSPackageDeclaration()) { - return true; - } - - parent = parent->Parent(); - } - - return false; - } -}; - -class NodeHasType { -public: - explicit NodeHasType([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - // NOTE(orlovskymaxim) In TS some ETS constructs are expressions (i.e. class/interface definition) - // Because ETS uses some AST classes from TS this introduces semantical problem - // Solution for now - manually filter expressions that are statements in ETS - if (ast->IsETSPackageDeclaration()) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (IsImportLike(ast)) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (IsExportLike(ast)) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - - if (ast->IsTSTypeAliasDeclaration()) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (auto [decision, action] = CheckCompound(ctx, ast); action == CheckAction::SKIP_SUBTREE) { - return {decision, action}; - } - - if (ast->IsTyped() && ast->IsExpression()) { - if (ast->IsClassDefinition() && ast->AsClassDefinition()->Ident()->Name() == "ETSGLOBAL") { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (ast->IsIdentifier() && ast->AsIdentifier()->Name() == "") { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - const auto *typed = static_cast(ast); - if (typed->TsType() == nullptr) { - ctx.AddCheckMessage("NULL_TS_TYPE", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - -private: - CheckResult CheckCompound(CheckContext &ctx, const ir::AstNode *ast) - { - if (ast->IsTSInterfaceDeclaration()) { - for (const auto &member : ast->AsTSInterfaceDeclaration()->Body()->Body()) { - [[maybe_unused]] auto _ = (*this)(ctx, member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (ast->IsTSEnumDeclaration()) { - for (const auto &member : ast->AsTSEnumDeclaration()->Members()) { - [[maybe_unused]] auto _ = (*this)(ctx, member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (ast->IsClassDefinition()) { - for (const auto &member : ast->AsClassDefinition()->Body()) { - [[maybe_unused]] auto _ = (*this)(ctx, member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } -}; - -class VariableHasScope { -public: - explicit VariableHasScope(ArenaAllocator &allocator) : allocator_ {allocator} {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - if (!ast->IsIdentifier()) { - // Check invariant of Identifier only - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - // NOTE(kkonkuznetsov): lambdas - if (ast->AsIdentifier()->Name().Utf8().find("lambda$invoke$") == 0) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - // we will check invariant for only local variables of identifiers - if (const auto maybeVar = GetLocalScopeVariable(allocator_, ctx, ast); maybeVar.has_value()) { - const auto var = *maybeVar; - const auto scope = var->GetScope(); - if (scope == nullptr) { - ctx.AddCheckMessage("NULL_SCOPE_LOCAL_VAR", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); - if (!ScopeEncloseVariable(ctx, var)) { - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - return result; - } - - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - static std::optional GetLocalScopeVariable(ArenaAllocator &allocator, CheckContext &ctx, - const ir::AstNode *ast) - { - if (!ast->IsIdentifier()) { - return std::nullopt; - } - - auto invariantHasVariable = IdentifierHasVariable {allocator}; - const auto variable = ast->AsIdentifier()->Variable(); - const auto [decision, action] = invariantHasVariable(ctx, ast); - - if (variable == nullptr) { - // NOTE(kkonkuznetsov): variable should not be null - // but currently some identifiers do not have variables, - // see exceptions in IdentifierHasVariable check - return std::nullopt; - } - - if (decision == CheckDecision::CORRECT && variable->IsLocalVariable()) { - const auto localVar = variable->AsLocalVariable(); - if (localVar->HasFlag(varbinder::VariableFlags::LOCAL)) { - return localVar; - } - } - - return std::nullopt; - } - - bool ScopeEncloseVariable(CheckContext &ctx, const varbinder::LocalVariable *var) - { - ASSERT(var); - - const auto scope = var->GetScope(); - if (scope == nullptr || var->Declaration() == nullptr) { - return true; - } - - const auto node = var->Declaration()->Node(); - if (node == nullptr) { - return true; - } - - const auto varStart = node->Start(); - bool isOk = true; - if (scope->Bindings().count(var->Name()) == 0) { - ctx.AddCheckMessage("SCOPE_DO_NOT_ENCLOSE_LOCAL_VAR", *node, varStart); - isOk = false; - } - - const auto scopeNode = scope->Node(); - const auto varNode = node; - bool skip = CheckAstExceptions(varNode); - - if (!IsContainedIn(varNode, scopeNode) || scopeNode == nullptr) { - if (!skip) { - ctx.AddCheckMessage("SCOPE_NODE_DONT_DOMINATE_VAR_NODE", *node, varStart); - isOk = false; - } - } - - const auto &decls = scope->Decls(); - const auto declDominate = std::count(decls.begin(), decls.end(), var->Declaration()); - if (declDominate == 0) { - if (!skip) { - ctx.AddCheckMessage("SCOPE_DECL_DONT_DOMINATE_VAR_DECL", *node, varStart); - isOk = false; - } - } - - return isOk; - } - -private: - ArenaAllocator &allocator_; - - bool CheckAstExceptions(const ir::AstNode *ast) - { - // NOTE(kkonkuznetsov): in some cases with lambdas scope node is null - if (ast->Parent() != nullptr && ast->Parent()->IsETSFunctionType()) { - return true; - } - - if (ast->IsLabelledStatement()) { - // Labels are attached to loop scopes, - // however label identifier is outside of loop. - // Example: - // - // loop: for (let i = 0; i < 10; i++) { - // } - return true; - } - - // NOTE(kkonkuznetsov): lambdas - auto parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsScriptFunction()) { - auto script = parent->AsScriptFunction(); - if (script->Id() != nullptr && script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { - return true; - } - - break; - } - - parent = parent->Parent(); - } - - return false; - } -}; - -class EveryChildInParentRange { -public: - explicit EveryChildInParentRange([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); - if (ast->Parent() == nullptr) { - return result; - } - ast->Iterate([&](const ir::AstNode *node) { - if (ast != node->Parent()) { - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - if (ast->Start().line > node->Start().line || ast->End().line < node->End().line) { - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - if (ast->Start().line == node->Start().line && ast->Start().index > node->Start().index) { - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - if (ast->End().line == node->End().line && ast->End().index < node->End().index) { - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - ctx.AddCheckMessage("INCORRECT_CHILD_RANGE", *node, node->Start()); - }); - return result; - } - -private: -}; - -class EveryChildHasValidParent { -public: - explicit EveryChildHasValidParent([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); - if (ast->IsETSScript()) { - return result; - } - - ast->Iterate([&](const ir::AstNode *node) { - if (ir::AstNode const *parent = node->Parent(); ast != parent) { - // NOTE: Temporary suppress. - // Should be removed after special lowering for lambda-functions will be implemented: #14376 - if ((ast->IsScriptFunction() || ast->IsETSFunctionType()) && parent != nullptr && - parent->IsScriptFunction()) { - return; - } - - // NOTE: Temporary suppress. - // Should be removed after new ENUMs support will be implemented: #14443 - if (ast->IsClassDeclaration() && parent != nullptr && parent->IsETSNewClassInstanceExpression()) { - return; - } - - ctx.AddCheckMessage("INCORRECT_PARENT_REF", *node, node->Start()); - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - }); - - return result; - } - -private: -}; - -class VariableHasEnclosingScope { -public: - explicit VariableHasEnclosingScope(ArenaAllocator &allocator) : allocator_ {allocator} {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - const auto maybeVar = VariableHasScope::GetLocalScopeVariable(allocator_, ctx, ast); - if (!maybeVar) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - const auto var = *maybeVar; - const auto scope = var->GetScope(); - if (scope == nullptr) { - // already checked - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - const auto encloseScope = scope->EnclosingVariableScope(); - if (encloseScope == nullptr) { - ctx.AddCheckMessage("NO_ENCLOSING_VAR_SCOPE", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - const auto node = scope->Node(); - auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); - if (!IsContainedIn(ast, node)) { - if (CheckCatchClause(ast, node)) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - if (CheckScopeNodeExceptions(node)) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - if (CheckAstExceptions(ast)) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - ctx.AddCheckMessage("VARIABLE_NOT_ENCLOSE_SCOPE", *ast, ast->Start()); - } - - if (!IsContainedIn(scope, encloseScope)) { - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - ctx.AddCheckMessage("VARIABLE_NOT_ENCLOSE_SCOPE", *ast, ast->Start()); - } - - return result; - } - -private: - ArenaAllocator &allocator_; - - bool CheckCatchClause(const ir::AstNode *ast, const ir::AstNode *node) const - { - if (node == nullptr) { - return false; - } - - // Check that ast node is contained within node parent for Catch Clause: - // Catch Clause { - // Catch Body { - // AST that we need to check - // } - // Param (Scope Node) { - // } - // } - if (node->Parent() != nullptr && node->Parent()->IsCatchClause()) { - return IsContainedIn(ast, node->Parent()); - } - - return false; - } - - bool CheckScopeNodeExceptions(const ir::AstNode *node) const - { - if (node == nullptr) { - return false; - } - - // NOTE(kkonkuznetsov): lambdas - auto parent = node->Parent(); - while (parent != nullptr) { - if (parent->IsFunctionExpression()) { - auto script = parent->AsFunctionExpression()->Function(); - if (script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { - return true; - } - - break; - } - - parent = parent->Parent(); - } - - return false; - } - - bool CheckAstExceptions(const ir::AstNode *ast) const - { - // NOTE(kkonkuznetsov): skip parameter expression inside arrow function expression - auto parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsETSParameterExpression()) { - return true; - } - - parent = parent->Parent(); - } - - if (ast->Parent()->IsLabelledStatement()) { - // Labels are attached to loop scopes, - // however label identifier is outside of loop. - // Example: - // - // loop: for (let i = 0; i < 10; i++) { - // } - return true; - } - - // NOTE(kkonkuznetsov): skip lambdas - parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsFunctionExpression()) { - auto script = parent->AsFunctionExpression()->Function(); - if (script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { - return true; - } - - break; - } - - parent = parent->Parent(); - } - - return false; - } -}; - -class SequenceExpressionHasLastType { -public: - explicit SequenceExpressionHasLastType([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - if (!ast->IsSequenceExpression()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - const auto *expr = ast->AsSequenceExpression(); - const auto *last = expr->Sequence().back(); - if (expr->TsType() == nullptr) { - ctx.AddCheckMessage("Sequence expression type is null", *expr, expr->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - if (last->TsType() == nullptr) { - ctx.AddCheckMessage("Sequence expression last type is null", *last, last->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - if (expr->TsType() != last->TsType()) { - ctx.AddCheckMessage("Sequence expression type and last expression type are not the same", *expr, - expr->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - -private: -}; - -class ForLoopCorrectlyInitialized { -public: - explicit ForLoopCorrectlyInitialized([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - if (ast->IsForInStatement()) { - return HandleForInStatement(ctx, ast); - } - - if (ast->IsForOfStatement()) { - return HandleForOfStatement(ctx, ast); - } - - if (ast->IsForUpdateStatement()) { - return HandleForUpdateStatement(ctx, ast); - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - -private: - [[nodiscard]] CheckResult HandleForInStatement(CheckContext &ctx, const ir::AstNode *ast) - { - auto const *left = ast->AsForInStatement()->Left(); - if (left == nullptr) { - ctx.AddCheckMessage("NULL FOR-IN-LEFT", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - if (!left->IsIdentifier() && !left->IsVariableDeclaration()) { - ctx.AddCheckMessage("INCORRECT FOR-IN-LEFT", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - [[nodiscard]] CheckResult HandleForOfStatement(CheckContext &ctx, const ir::AstNode *ast) - { - auto const *left = ast->AsForOfStatement()->Left(); - if (left == nullptr) { - ctx.AddCheckMessage("NULL FOR-OF-LEFT", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - if (!left->IsIdentifier() && !left->IsVariableDeclaration()) { - ctx.AddCheckMessage("INCORRECT FOR-OF-LEFT", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - [[nodiscard]] CheckResult HandleForUpdateStatement(CheckContext &ctx, const ir::AstNode *ast) - { - // The most important part of for-loop is the test. - // But it also can be null. Then there must be break;(return) in the body. - auto const *test = ast->AsForUpdateStatement()->Test(); - if (test == nullptr) { - auto const *body = ast->AsForUpdateStatement()->Body(); - if (body == nullptr) { - ctx.AddCheckMessage("NULL FOR-TEST AND FOR-BODY", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - bool hasExit = body->IsBreakStatement() || body->IsReturnStatement(); - body->IterateRecursively( - [&hasExit](ir::AstNode *child) { hasExit |= child->IsBreakStatement() || child->IsReturnStatement(); }); - if (!hasExit) { - // an infinite loop - ctx.AddCheckMessage("NULL FOR-TEST AND FOR-BODY doesn't exit", *ast, ast->Start()); - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - if (!test->IsExpression()) { - ctx.AddCheckMessage("NULL FOR VAR", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } -}; - -class ModifierAccessValid { -public: - explicit ModifierAccessValid([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - if (auto [decision, action] = HandleMethodExpression(ctx, ast); decision == CheckDecision::INCORRECT) { - return {decision, action}; - } - if (auto [decision, action] = HandleCallExpression(ctx, ast); decision == CheckDecision::INCORRECT) { - return {decision, action}; - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - -private: - CheckResult HandleMethodExpression(CheckContext &ctx, const ir::AstNode *ast) - { - if (!ast->IsMemberExpression()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - const auto *propVar = ast->AsMemberExpression()->PropVar(); - if (propVar != nullptr && propVar->HasFlag(varbinder::VariableFlags::PROPERTY) && - !ValidateVariableAccess(propVar, ast->AsMemberExpression())) { - ctx.AddCheckMessage("PROPERTY_NOT_VISIBLE_HERE", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - CheckResult HandleCallExpression(CheckContext &ctx, const ir::AstNode *ast) - { - if (!ast->IsCallExpression()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - const auto *callExpr = ast->AsCallExpression(); - const auto *callee = callExpr->Callee(); - if (callee != nullptr && callee->IsMemberExpression()) { - const auto *calleeMember = callee->AsMemberExpression(); - const auto *propVarCallee = calleeMember->PropVar(); - if (propVarCallee != nullptr && propVarCallee->HasFlag(varbinder::VariableFlags::METHOD) && - !ValidateMethodAccess(calleeMember, ast->AsCallExpression())) { - ctx.AddCheckMessage("PROPERTY_NOT_VISIBLE_HERE", *callee, callee->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } -}; - -class ImportExportAccessValid { -public: - explicit ImportExportAccessValid([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()(CheckContext &ctx, const ir::AstNode *ast) - { - std::unordered_set importedVariables {}; - if (ast->IsETSImportDeclaration()) { - const auto importDecl = ast->AsETSImportDeclaration()->Specifiers(); - const auto name = [](ir::AstNode *const specifier) { - if (specifier->IsImportNamespaceSpecifier()) { - return specifier->AsImportNamespaceSpecifier()->Local()->Name(); - } - if (specifier->IsImportSpecifier()) { - return specifier->AsImportSpecifier()->Local()->Name(); - } - return specifier->AsImportDefaultSpecifier()->Local()->Name(); - }; - for (const auto import : importDecl) { - importedVariables.emplace(name(import)); - } - } - if (ast->IsCallExpression()) { - const auto *callExpr = ast->AsCallExpression(); - const auto *callee = callExpr->Callee(); - if (callee != nullptr && callee->IsIdentifier() && - !HandleImportExportIdentifier(importedVariables, callee->AsIdentifier(), callExpr)) { - ctx.AddCheckMessage("PROPERTY_NOT_VISIBLE_HERE(NOT_EXPORTED)", *callee, callee->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - } - if (ast->IsIdentifier() && !HandleImportExportIdentifier(importedVariables, ast->AsIdentifier(), nullptr)) { - ctx.AddCheckMessage("PROPERTY_NOT_VISIBLE_HERE(NOT_EXPORTED)", *ast, ast->Start()); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - -private: - bool ValidateExport(const varbinder::Variable *var) - { - const auto *decl = var->Declaration(); - if (decl == nullptr) { - return false; - } - const auto *node = decl->Node(); - if (node == nullptr) { - return false; - } - return node->IsExported() || node->IsExportedType(); - } - - bool InvariantImportExportMethod(const std::unordered_set &importedVariables, - const varbinder::Variable *varCallee, const ir::AstNode *callExpr, - util::StringView name) - { - auto *signature = callExpr->AsCallExpression()->Signature(); - if (signature->Owner() == nullptr) { - // NOTE(vpukhov): Add a synthetic owner for dynamic signatures - ASSERT(callExpr->AsCallExpression()->Callee()->TsType()->HasTypeFlag(checker::TypeFlag::ETS_DYNAMIC_FLAG)); - return true; - } - - if (signature != nullptr && varCallee->Declaration() != nullptr && - varCallee->Declaration()->Node() != nullptr && - !IsContainedIn(varCallee->Declaration()->Node(), signature->Owner()->GetDeclNode()) && - varCallee->Declaration()->Node() != signature->Owner()->GetDeclNode()) { - if (importedVariables.find(name.Mutf8()) != importedVariables.end() || - importedVariables.find("") != importedVariables.end()) { - return ValidateExport(varCallee); - } - return false; - } - return true; - } - - bool InvariantImportExportVariable(const std::unordered_set &importedVariables, - const varbinder::Variable *var, const ir::Identifier *ident, - util::StringView name) - { - if (!var->HasFlag(varbinder::VariableFlags::LOCAL) && !var->HasFlag(varbinder::VariableFlags::VAR) && - var->HasFlag(varbinder::VariableFlags::INITIALIZED) && var->Declaration() != nullptr && - var->Declaration()->Node() != nullptr && !var->Declaration()->Node()->IsMethodDefinition() && - !var->Declaration()->Node()->IsClassProperty()) { - auto varParent = var->Declaration()->Node()->Parent(); - if (varParent != nullptr && !IsContainedIn(ident->Parent(), varParent) && ident->Parent() != varParent) { - if (var->GetScope() != nullptr && var->GetScope()->Parent() != nullptr && - var->GetScope()->Parent()->IsGlobalScope() && - ident->GetTopStatement() == varParent->GetTopStatement()) { - return true; - } - if (importedVariables.find(name.Mutf8()) != importedVariables.end() || - importedVariables.find("") != importedVariables.end()) { - return ValidateExport(var); - } - return false; - } - } - return true; - } - - bool HandleImportExportIdentifier(std::unordered_set &importedVariables, const ir::Identifier *ident, - const ir::AstNode *callExpr) - { - if (ident->IsReference()) { - const auto *var = ident->Variable(); - if (var != nullptr) { - if (var->HasFlag(varbinder::VariableFlags::METHOD) && callExpr != nullptr) { - return InvariantImportExportMethod(importedVariables, var, callExpr, ident->Name()); - } - return InvariantImportExportVariable(importedVariables, var, ident, ident->Name()); - } - } - return true; - } -}; - -class ArithmeticOperationValid { -public: - explicit ArithmeticOperationValid([[maybe_unused]] ArenaAllocator &allocator) {} - - [[nodiscard]] CheckResult operator()([[maybe_unused]] CheckContext &ctx, const ir::AstNode *ast) - { - if (auto [decision, action] = CheckCompound(ctx, ast); action == CheckAction::SKIP_SUBTREE) { - return {decision, action}; - } - if (!ast->IsBinaryExpression() || !ast->AsBinaryExpression()->IsArithmetic()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - if ((ast->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_PLUS || - ast->AsBinaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_PLUS_EQUAL) && - (IsStringType(ast->AsBinaryExpression()->Left()) || IsStringType(ast->AsBinaryExpression()->Right()))) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - auto result = std::make_tuple(CheckDecision::CORRECT, CheckAction::CONTINUE); - bool isBitwise = ast->AsBinaryExpression()->IsBitwise(); - ast->Iterate([&result, &ctx, &isBitwise](ir::AstNode *child) { - if (!IsValidTypeForBinaryOp(child, isBitwise)) { - ctx.AddCheckMessage("Not a numeric type", *child, child->Start()); - result = {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - }); - return result; - } - -private: - CheckResult CheckCompound(CheckContext &ctx, const ir::AstNode *ast) - { - if (ast->IsTSInterfaceDeclaration()) { - for (const auto &member : ast->AsTSInterfaceDeclaration()->Body()->Body()) { - [[maybe_unused]] auto _ = (*this)(ctx, member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (ast->IsTSEnumDeclaration()) { - for (const auto &member : ast->AsTSEnumDeclaration()->Members()) { - [[maybe_unused]] auto _ = (*this)(ctx, member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (ast->IsClassDefinition()) { - for (const auto &member : ast->AsClassDefinition()->Body()) { - [[maybe_unused]] auto _ = (*this)(ctx, member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } -}; - -ASTVerifier::ASTVerifier(ArenaAllocator *allocator) -{ - AddInvariant(allocator, "NodeHasParent"); - AddInvariant(allocator, "NodeHasSourceRange"); - AddInvariant(allocator, "NodeHasType"); - AddInvariant(allocator, "IdentifierHasVariable"); - AddInvariant(allocator, "VariableHasScope"); - AddInvariant(allocator, "EveryChildHasValidParent"); - AddInvariant(allocator, "EveryChildInParentRange"); - AddInvariant(allocator, "VariableHasEnclosingScope"); - AddInvariant(allocator, "ForLoopCorrectlyInitialized"); - AddInvariant(allocator, "ModifierAccessValid"); - AddInvariant(allocator, "ImportExportAccessValid"); - AddInvariant(allocator, "ArithmeticOperationValid"); - AddInvariant(allocator, "SequenceExpressionHasLastType"); - AddInvariant(allocator, "ReferenceTypeAnnotationIsNull"); - AddInvariant(allocator, "VariableNameIdentifierNameSame"); -} - -Messages ASTVerifier::VerifyFull(const ir::AstNode *ast) -{ - auto recursiveChecks = InvariantNameSet {}; - std::copy_if(invariantsNames_.begin(), invariantsNames_.end(), - std::inserter(recursiveChecks, recursiveChecks.end()), - [](const std::string &s) { return s.find(RECURSIVE_SUFFIX) != s.npos; }); - return Verify(ast, recursiveChecks); -} - -Messages ASTVerifier::Verify(const ir::AstNode *ast, const InvariantNameSet &invariantSet) -{ - CheckContext ctx {}; - const auto containsInvariants = - std::includes(invariantsNames_.begin(), invariantsNames_.end(), invariantSet.begin(), invariantSet.end()); - if (!containsInvariants) { - auto invalidInvariants = InvariantNameSet {}; - for (const auto &invariant : invariantSet) { - if (invariantsNames_.find(invariant) == invariantsNames_.end()) { - invalidInvariants.insert(invariant); - } - } - for (const auto &invariant : invalidInvariants) { - ctx.AddCheckMessage(std::string {"Invariant was not found: "} + invariant, *ast, lexer::SourcePosition {}); - } - } - - for (const auto &name : invariantSet) { - if (const auto &found = invariantsChecks_.find(name); found != invariantsChecks_.end()) { - if (ast == nullptr) { - continue; - } - - auto invariant = found->second; - ctx.SetCheckName(name.data()); - invariant(ctx, ast); - } - } - - return ctx.GetMessages(); -} - -} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index 65ee766630..609343e911 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -15,7 +15,7 @@ #include "compilerImpl.h" -#include "compiler/core/ASTVerifier.h" +#include "ast_verifier/ASTVerifier.h" #include "es2panda.h" #include "checker/ETSAnalyzer.h" #include "checker/TSAnalyzer.h" diff --git a/ets2panda/compiler/lowering/ets/expressionLambdaLowering.cpp b/ets2panda/compiler/lowering/ets/expressionLambdaLowering.cpp index 72d9e98a7f..73cea7ae19 100644 --- a/ets2panda/compiler/lowering/ets/expressionLambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/expressionLambdaLowering.cpp @@ -15,7 +15,6 @@ #include "expressionLambdaLowering.h" #include "checker/ETSchecker.h" -#include "compiler/core/ASTVerifier.h" namespace ark::es2panda::compiler { static ir::AstNode *ConvertExpression(checker::ETSChecker *const checker, ir::ArrowFunctionExpression *const arrow) diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index 5a8f89886d..33fc10fd3a 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -17,7 +17,6 @@ #include "checker/ETSchecker.h" #include "checker/types/type.h" -#include "compiler/core/ASTVerifier.h" #include "compiler/lowering/util.h" #include "ir/astNode.h" #include "ir/expression.h" diff --git a/ets2panda/compiler/lowering/ets/promiseVoid.cpp b/ets2panda/compiler/lowering/ets/promiseVoid.cpp index 3ad58325fc..30de0dbe7a 100644 --- a/ets2panda/compiler/lowering/ets/promiseVoid.cpp +++ b/ets2panda/compiler/lowering/ets/promiseVoid.cpp @@ -16,7 +16,6 @@ #include "promiseVoid.h" #include "checker/ETSchecker.h" #include "checker/checker.h" -#include "compiler/core/ASTVerifier.h" #include "generated/signatures.h" #include "ir/base/scriptFunction.h" #include "ir/ets/etsTypeReference.h" diff --git a/ets2panda/compiler/lowering/ets/tupleLowering.cpp b/ets2panda/compiler/lowering/ets/tupleLowering.cpp index 984f66b1d5..2cae029c73 100644 --- a/ets2panda/compiler/lowering/ets/tupleLowering.cpp +++ b/ets2panda/compiler/lowering/ets/tupleLowering.cpp @@ -17,7 +17,6 @@ #include "checker/ETSchecker.h" #include "checker/types/ets/etsTupleType.h" -#include "compiler/core/ASTVerifier.h" #include "compiler/lowering/util.h" #include "ir/expressions/assignmentExpression.h" #include "ir/expressions/identifier.h" diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index a95619817c..03b0ac0f37 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -14,7 +14,6 @@ */ #include "unionLowering.h" -#include "compiler/core/ASTVerifier.h" #include "varbinder/variableFlags.h" #include "varbinder/ETSBinder.h" #include "checker/ETSchecker.h" diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 99fb42aae5..105d994a0c 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -15,7 +15,6 @@ #include "phase.h" #include "checker/checker.h" -#include "compiler/core/ASTVerifier.h" #include "ets/ambientLowering.h" #include "ets/defaultParameterLowering.h" #include "lexer/token/sourceLocation.h" diff --git a/ets2panda/compiler/lowering/plugin_phase.h b/ets2panda/compiler/lowering/plugin_phase.h index e842251949..9616d5e212 100644 --- a/ets2panda/compiler/lowering/plugin_phase.h +++ b/ets2panda/compiler/lowering/plugin_phase.h @@ -16,7 +16,6 @@ #ifndef ES2PANDA_COMPILER_PLUGIN_PHASE_H #define ES2PANDA_COMPILER_PLUGIN_PHASE_H -#include "compiler/core/ASTVerifier.h" #include "compiler/lowering/phase.h" #include "util/plugin.h" diff --git a/ets2panda/test/unit/public/ast_verifier_test.h b/ets2panda/test/unit/public/ast_verifier_test.h index 8fe3fb3e63..c7e08c897a 100644 --- a/ets2panda/test/unit/public/ast_verifier_test.h +++ b/ets2panda/test/unit/public/ast_verifier_test.h @@ -16,7 +16,7 @@ #ifndef TEST_UNIT_PUBLIC_AST_VERIFIER_TEST_H #define TEST_UNIT_PUBLIC_AST_VERIFIER_TEST_H -#include "compiler/core/ASTVerifier.h" +#include "ast_verifier/ASTVerifier.h" #include "test/utils/panda_executable_path_getter.h" #include -- Gitee From f2289778344f125204478f5e6976153b47e8d843 Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Mon, 15 Jul 2024 11:29:10 +0800 Subject: [PATCH 05/15] Fix segfault in union type and trailing lambda Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IACYRN?from=project-issue Descrpition:Before setting the parent node of a node, we first need to determine whether the node is not `nullptr`. Tests: ninja tests passed bash ets_testrunner.sh --cts -r -rt passed Signed-off-by: xuxinjie4 --- ets2panda/ir/base/scriptFunction.cpp | 4 ++- .../ets/union_type_and_trailing_lambda.ets | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/runtime/ets/union_type_and_trailing_lambda.ets diff --git a/ets2panda/ir/base/scriptFunction.cpp b/ets2panda/ir/base/scriptFunction.cpp index 818f0c08d6..4f3eb479d2 100644 --- a/ets2panda/ir/base/scriptFunction.cpp +++ b/ets2panda/ir/base/scriptFunction.cpp @@ -120,7 +120,9 @@ void ScriptFunction::Iterate(const NodeTraverser &cb) const void ScriptFunction::SetReturnTypeAnnotation(TypeNode *node) noexcept { irSignature_.SetReturnType(node); - node->SetParent(this); + if (node != nullptr) { + node->SetParent(this); + } } void ScriptFunction::Dump(ir::AstDumper *dumper) const diff --git a/ets2panda/test/runtime/ets/union_type_and_trailing_lambda.ets b/ets2panda/test/runtime/ets/union_type_and_trailing_lambda.ets new file mode 100644 index 0000000000..2519ec0c2a --- /dev/null +++ b/ets2panda/test/runtime/ets/union_type_and_trailing_lambda.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{} + +function no_param(fn: A | () => void) { + if (fn instanceof A){ + assert false:"false" + } else { + fn() + } +} + +let a: int = 5 + +function main(): void{ + no_param() { + assert a==5 + } +} \ No newline at end of file -- Gitee From 3d48a6dc71252fbda29ef09bcbde3c9fa2ba810f Mon Sep 17 00:00:00 2001 From: Igor Sharonov Date: Mon, 1 Jul 2024 13:22:55 +0300 Subject: [PATCH 06/15] Fix constant double to byte conversion Testing: Extend narrowing cast from constant tests Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IA8AIO Change-Id: I828c782eefe104bed3a36c18ca87d1efbd440561 Signed-off-by: Igor Sharonov --- ets2panda/checker/ets/narrowingConverter.h | 20 ++++---------------- ets2panda/test/runtime/ets/CastPrimitive.ets | 11 +++++++++++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/ets2panda/checker/ets/narrowingConverter.h b/ets2panda/checker/ets/narrowingConverter.h index 111d84dcd6..690e756fa9 100644 --- a/ets2panda/checker/ets/narrowingConverter.h +++ b/ets2panda/checker/ets/narrowingConverter.h @@ -103,21 +103,6 @@ private: } } - template - int CalculateIntValue(SType value) - { - if (std::isinf(value)) { - if (std::signbit(value)) { - return std::numeric_limits::min(); - } - return std::numeric_limits::max(); - } - if (std::isnan(value)) { - return 0; - } - return static_cast(value); - } - template To CastFloatingPointToIntOrLong(From value) { @@ -153,7 +138,10 @@ private: case TypeFlag::BYTE: case TypeFlag::CHAR: case TypeFlag::SHORT: { - return CalculateIntValue(value); + if (source->HasTypeFlag(checker::TypeFlag::DOUBLE) || source->HasTypeFlag(checker::TypeFlag::FLOAT)) { + return static_cast(CastFloatingPointToIntOrLong(value)); + } + return static_cast(value); } case TypeFlag::INT: case TypeFlag::LONG: { diff --git a/ets2panda/test/runtime/ets/CastPrimitive.ets b/ets2panda/test/runtime/ets/CastPrimitive.ets index fd7a6a5631..4a20f359e7 100644 --- a/ets2panda/test/runtime/ets/CastPrimitive.ets +++ b/ets2panda/test/runtime/ets/CastPrimitive.ets @@ -81,5 +81,16 @@ function main(): void { i = false; assert i as boolean == false; + assert 4294967296.0 as byte == -1; + assert 4294967296.0 as char == c'\uFFFF'; + assert 4294967296.0 as short == -1; + assert 4294967296.0 as int == Int.MAX_VALUE; + assert 4294967296.0 as long == 4294967296; + assert -4294967296.0 as byte == 0; + assert -4294967296.0 as char == c'\u0000'; + assert -4294967296.0 as short == 0; + assert -4294967296.0 as int == Int.MIN_VALUE; + assert -4294967296.0 as long == -4294967296; + return; } -- Gitee From 791383f8232cb555cd4ad3881baf41eeb6bd3aa0 Mon Sep 17 00:00:00 2001 From: Otto Eotvos Date: Tue, 9 Jul 2024 15:06:20 +0200 Subject: [PATCH 07/15] Implement selective export directive with alias Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IA7DWJ Implemented selective export with alias support for exportable program elements. Added checks for clashing names and double export attempts on the same item. Testing: all required pre-merge tests have passed. The result is available in the GGWatcher. Also fixes internal issue #16804 Change-Id: I2fa3479366dadd7bb0f1d7a1f17e17cfde9369c7 Signed-off-by: Otto Eotvos --- ets2panda/checker/ETSAnalyzer.cpp | 8 +- ets2panda/checker/ETSchecker.h | 1 + ets2panda/checker/ets/helpers.cpp | 18 +- ets2panda/checker/types/ets/etsObjectType.h | 13 + .../topLevelStmts/globalDeclTransformer.cpp | 10 + .../ets/topLevelStmts/importExportDecls.cpp | 83 +- .../ets/topLevelStmts/importExportDecls.h | 6 + ets2panda/ir/astNode.cpp | 23 +- ets2panda/ir/astNode.h | 20 +- .../re-export_with_alias/export-expected.txt | 850 ++++++++++++ .../re-export_with_alias/export.ets | 26 + .../import_aliased_re-export-expected.txt | 822 ++++++++++++ .../import_aliased_re-export.ets | 25 + .../re-export_with_alias-expected.txt | 366 ++++++ .../re-export_with_alias.ets | 17 + .../import_function_wrong_name-expected.txt | 226 ++++ .../import_function_wrong_name.ets | 16 + .../import_interface-expected.txt | 652 ++++++++++ .../import_interface.ets | 20 + .../import_interface_wrong_name-expected.txt | 226 ++++ .../import_interface_wrong_name.ets | 16 + .../import_selective_exported-expected.txt | 1140 ++++++++++++++++ .../import_selective_exported.ets | 29 + ...pace_import_wrong_access_name-expected.txt | 550 ++++++++ .../namespace_import_wrong_access_name.ets | 18 + .../selective_export-expected.txt | 1157 +++++++++++++++++ .../selective_export.ets | 38 + ...ive_export_clashing_exports_1-expected.txt | 1 + .../selective_export_clashing_exports_1.ets | 20 + ...ive_export_clashing_exports_2-expected.txt | 1 + .../selective_export_clashing_exports_2.ets | 20 + ...ive_export_clashing_exports_3-expected.txt | 1 + .../selective_export_clashing_exports_3.ets | 22 + ...ive_export_clashing_exports_4-expected.txt | 1 + .../selective_export_clashing_exports_4.ets | 22 + .../selective_export_function-expected.txt | 260 ++++ .../selective_export_function.ets | 20 + .../selective_export_interface-expected.txt | 239 ++++ .../selective_export_interface.ets | 22 + .../selective_export_with_alias-expected.txt | 461 +++++++ .../selective_export_with_alias.ets | 22 + ...selective_import_with_alias_1-expected.txt | 417 ++++++ .../selective_import_with_alias_1.ets | 18 + ...selective_import_with_alias_2-expected.txt | 417 ++++++ .../selective_import_with_alias_2.ets | 18 + .../type/import_type_1-expected.txt | 2 +- .../ets/import_tests/type/type_3-expected.txt | 2 +- .../selective_export_bad-expected.txt | 2 +- ets2panda/varbinder/ETSBinder.cpp | 77 +- ets2panda/varbinder/ETSBinder.h | 61 +- 50 files changed, 8412 insertions(+), 90 deletions(-) create mode 100644 ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1.ets create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2-expected.txt create mode 100644 ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 3c2b0b35f5..0d60abdcc5 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2658,10 +2658,14 @@ checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const // clang-format off auto searchName = importDecl->IsETSImportDeclaration() - ? checker->VarBinder()->AsETSBinder()->GetExportSelectiveAliasValue( + ? checker->VarBinder()->AsETSBinder()->FindNameInAliasMap( importDecl->AsETSImportDeclaration()->ResolvedSource()->Str(), expr->Right()->Name()) : expr->Right()->Name(); // clang-format on + // NOTE (oeotvos) This should be done differently in the follow-up patch. + if (searchName.Empty()) { + searchName = expr->Right()->Name(); + } varbinder::Variable *prop = baseType->AsETSObjectType()->GetProperty(searchName, checker::PropertySearchFlags::SEARCH_DECL); @@ -2669,7 +2673,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const checker->ThrowTypeError({"'", expr->Right()->Name(), "' type does not exist."}, expr->Right()->Start()); } - if (expr->Right()->Name().Is(searchName.Mutf8()) && prop->Declaration()->Node()->HasAliasExport()) { + if (expr->Right()->Name().Is(searchName.Mutf8()) && prop->Declaration()->Node()->HasExportAlias()) { checker->ThrowTypeError({"Cannot find imported element '", searchName, "' exported with alias"}, expr->Right()->Start()); } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 51bd4b1f22..c7f744dc90 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -461,6 +461,7 @@ public: template void BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleObjType, ir::ETSImportDeclaration *importDecl, const varbinder::Scope::VariableMap &bindings); + util::StringView FindPropNameForNamespaceImport(const util::StringView &originalName); void SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjType, const util::StringView &importPath, ir::ETSImportDeclaration *importDecl = nullptr); void SetrModuleObjectTsType(ir::Identifier *local, checker::ETSObjectType *moduleObjType); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 76fe1a2e97..cc0c8eab64 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1243,11 +1243,27 @@ void ETSChecker::BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleO if (!aliasedName.Empty()) { moduleObjType->AddReExportAlias(var->Declaration()->Name(), aliasedName); } - moduleObjType->AddProperty(var->AsLocalVariable()); + moduleObjType->AddProperty(var->AsLocalVariable(), + FindPropNameForNamespaceImport(var->AsLocalVariable()->Name())); } } } +util::StringView ETSChecker::FindPropNameForNamespaceImport(const util::StringView &originalName) +{ + if (auto relatedMapItem = + VarBinder()->AsETSBinder()->GetSelectiveExportAliasMultimap().find(Program()->SourceFilePath()); + relatedMapItem != VarBinder()->AsETSBinder()->GetSelectiveExportAliasMultimap().end()) { + if (auto result = std::find_if(relatedMapItem->second.begin(), relatedMapItem->second.end(), + [originalName](const auto &item) { return item.second == originalName; }); + result != relatedMapItem->second.end()) { + return result->first; + } + } + + return originalName; +} + void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjType, const util::StringView &importPath, ir::ETSImportDeclaration *importDecl) { diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index e78d1c94e5..3861d5eaec 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -337,6 +337,19 @@ public: propertiesInstantiated_ = true; } + template + void AddProperty(varbinder::LocalVariable *prop, util::StringView localName) const + { + util::StringView nameToAccess = prop->Name(); + + if (!localName.Empty()) { + nameToAccess = localName; + } + + properties_[static_cast(TYPE)].emplace(nameToAccess, prop); + propertiesInstantiated_ = true; + } + template void RemoveProperty(varbinder::LocalVariable *prop) { diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp index 07c9233710..a19c606ce5 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp @@ -53,6 +53,11 @@ void GlobalDeclTransformer::VisitFunctionDeclaration(ir::FunctionDeclaration *fu allocator_, methodKind, funcDecl->Function()->Id()->Clone(allocator_, nullptr), funcExpr, funcDecl->Function()->Modifiers(), allocator_, false); method->SetRange(funcDecl->Range()); + + if (funcDecl->Function()->IsExported() && funcDecl->Function()->HasExportAlias()) { + method->AddAstNodeFlags(ir::AstNodeFlags::HAS_EXPORT_ALIAS); + } + result_.classProperties.emplace_back(method); } @@ -66,6 +71,11 @@ void GlobalDeclTransformer::VisitVariableDeclaration(ir::VariableDeclaration *va declarator->Init(), typeAnn, varDecl->Modifiers(), allocator_, false); field->SetRange(declarator->Range()); + + if (varDecl->IsExported() && varDecl->HasExportAlias()) { + field->AddAstNodeFlags(ir::AstNodeFlags::HAS_EXPORT_ALIAS); + } + result_.classProperties.emplace_back(field); if (auto stmt = InitTopLevelProperty(field); stmt != nullptr) { result_.initStatements.emplace_back(stmt); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp index 177b7577b8..344b652f48 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp @@ -35,35 +35,95 @@ void ImportExportDecls::HandleGlobalStmts(const ArenaVector & exportedTypes_.clear(); for (auto stmt : program->Ast()->Statements()) { stmt->Accept(this); + if (stmt->IsExportNamedDeclaration()) { + PopulateAliasMap(stmt->AsExportNamedDeclaration(), program->SourceFilePath()); + } } for (auto const &[exportName, startLoc] : exportNameMap_) { const bool isType = exportedTypes_.find(exportName) != exportedTypes_.end(); - if ((fieldMap_.count(exportName) == 0 && !isType)) { + util::StringView originalName = varbinder_->FindNameInAliasMap(program->SourceFilePath(), exportName); + + ASSERT(!originalName.Empty()); + + if (fieldMap_.find(originalName) == fieldMap_.end() && !isType) { util::ErrorHandler::ThrowSyntaxError( - program, "Cannot find name '" + exportName.Mutf8() + "' to export.", startLoc); + varbinder_->Program(), "Cannot find name '" + originalName.Mutf8() + "' to export", startLoc); } if (!isType) { - auto field = fieldMap_[exportName]; - field->AddModifier(ir::ModifierFlags::EXPORT); + HandleSelectiveExportWithAlias(originalName, exportName, startLoc); + } + } + } +} + +void ImportExportDecls::PopulateAliasMap(const ir::ExportNamedDeclaration *decl, const util::StringView &path) +{ + for (auto spec : decl->Specifiers()) { + if (!varbinder_->AddSelectiveExportAlias(path, spec->Local()->Name(), spec->Exported()->Name())) { + util::ErrorHandler::ThrowSyntaxError(varbinder_->Program(), + "The given name '" + spec->Local()->Name().Mutf8() + + "' is already used in another export", + spec->Start()); + } + } +} + +void ImportExportDecls::HandleSelectiveExportWithAlias(util::StringView originalFieldName, util::StringView exportName, + lexer::SourcePosition startLoc) +{ + ir::AstNode *field = fieldMap_.find(originalFieldName)->second; + if ((field->Modifiers() & ir::ModifierFlags::EXPORTED) != 0) { + // Note (oeotvos) Needs to be discussed, whether we would like to allow exporting the same program + // element using its original name and also an alias, like: export {test_func, test_func as foo}. + util::ErrorHandler::ThrowSyntaxError( + varbinder_->Program(), "Cannot export '" + originalFieldName.Mutf8() + "', it was already exported", + startLoc); + } + + field->AddModifier(ir::ModifierFlags::EXPORT); + + if (exportName != originalFieldName) { + if (auto declItem = fieldMap_.find(exportName); declItem != fieldMap_.end()) { + // Checking for the alias might be unnecessary, because explicit exports cannot + // have an alias yet. + if (((declItem->second->Modifiers() & ir::ModifierFlags::EXPORTED) != 0) && + !declItem->second->HasExportAlias()) { + util::ErrorHandler::ThrowSyntaxError( + varbinder_->Program(), + "The given name '" + exportName.Mutf8() + "' is already used in another export", startLoc); } } + field->AddAstNodeFlags(ir::AstNodeFlags::HAS_EXPORT_ALIAS); } } void ImportExportDecls::VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) { - auto id = funcDecl->Function()->Id(); - fieldMap_.emplace(id->Name(), funcDecl->Function()); + fieldMap_.emplace(funcDecl->Function()->Id()->Name(), funcDecl->Function()); } void ImportExportDecls::VisitVariableDeclaration(ir::VariableDeclaration *varDecl) { for (const auto &decl : varDecl->Declarators()) { - auto id = decl->Id()->AsIdentifier(); - fieldMap_.emplace(id->Name(), varDecl); + fieldMap_.emplace(decl->Id()->AsIdentifier()->Name(), varDecl); } } +void ImportExportDecls::VisitClassDeclaration(ir::ClassDeclaration *classDecl) +{ + fieldMap_.emplace(classDecl->Definition()->Ident()->Name(), classDecl); +} + +void ImportExportDecls::VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAliasDecl) +{ + fieldMap_.emplace(typeAliasDecl->Id()->Name(), typeAliasDecl); +} + +void ImportExportDecls::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDecl) +{ + fieldMap_.emplace(interfaceDecl->Id()->Name(), interfaceDecl); +} + void ImportExportDecls::VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) { for (auto spec : exportDecl->Specifiers()) { @@ -72,9 +132,9 @@ void ImportExportDecls::VisitExportNamedDeclaration(ir::ExportNamedDeclaration * exportedTypes_.insert(local->Name()); } if (!exportNameMap_.emplace(local->Name(), local->Start()).second) { - util::ErrorHandler::ThrowSyntaxError(varbinder_->Program(), - "Cannot redeclare exported variable '" + local->Name().Mutf8() + "'", - local->Start()); + util::ErrorHandler::ThrowSyntaxError( + varbinder_->Program(), + "The given name '" + local->Name().Mutf8() + "' is already used in another export", local->Start()); } } } @@ -162,7 +222,6 @@ void ImportExportDecls::VerifyType(ir::Statement *stmt, parser::Program *program HandleSimpleType(exportedTypes, exportedStatements, stmt, name, program, spec->Local()->Start()); if (!name.Is(nameFind.Mutf8())) { element->second->AddAstNodeFlags(ir::AstNodeFlags::HAS_EXPORT_ALIAS); - varbinder_->AddExportSelectiveAlias(program->SourceFilePath(), name, nameFind); HandleSimpleType(exportedTypes, exportedStatements, stmt, nameFind, program, spec->Local()->Start()); } } diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h index 0101c9d24a..40cf60ca06 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h @@ -65,11 +65,17 @@ public: lexer::SourcePosition pos); void VerifySingleExportDefault(const ArenaVector &programs); + void HandleSelectiveExportWithAlias(util::StringView originalFieldName, util::StringView exportName, + lexer::SourcePosition startLoc); + void PopulateAliasMap(const ir::ExportNamedDeclaration *decl, const util::StringView &path); private: void VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) override; void VisitVariableDeclaration(ir::VariableDeclaration *varDecl) override; void VisitExportNamedDeclaration(ir::ExportNamedDeclaration *exportDecl) override; + void VisitClassDeclaration(ir::ClassDeclaration *classDecl) override; + void VisitTSTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAliasDecl) override; + void VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDecl) override; private: varbinder::ETSBinder *varbinder_ {nullptr}; diff --git a/ets2panda/ir/astNode.cpp b/ets2panda/ir/astNode.cpp index 84a8c67fd7..1d4717a9a5 100644 --- a/ets2panda/ir/astNode.cpp +++ b/ets2panda/ir/astNode.cpp @@ -27,9 +27,28 @@ AstNode::AstNode(AstNode const &other) variable_ = other.variable_; } flags_ = other.flags_; + astNodeFlags_ = other.astNodeFlags_; // boxing_unboxing_flags_ {}; leave default value! } +[[nodiscard]] bool AstNode::IsExported() const noexcept +{ + if (UNLIKELY(IsClassDefinition())) { + return parent_->IsExported(); + } + + return (flags_ & ModifierFlags::EXPORT) != 0; +} + +[[nodiscard]] bool AstNode::IsDefaultExported() const noexcept +{ + if (UNLIKELY(IsClassDefinition())) { + return parent_->IsDefaultExported(); + } + + return (flags_ & ModifierFlags::DEFAULT_EXPORT) != 0; +} + [[nodiscard]] bool AstNode::IsExportedType() const noexcept { if (UNLIKELY(IsClassDefinition())) { @@ -39,10 +58,10 @@ AstNode::AstNode(AstNode const &other) return (flags_ & ModifierFlags::EXPORT_TYPE) != 0; } -[[nodiscard]] bool AstNode::HasAliasExport() const noexcept +[[nodiscard]] bool AstNode::HasExportAlias() const noexcept { if (UNLIKELY(IsClassDefinition())) { - return parent_->HasAliasExport(); + return parent_->HasExportAlias(); } return (astNodeFlags_ & AstNodeFlags::HAS_EXPORT_ALIAS) != 0; diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index afe1186b28..70e78ffd92 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -369,23 +369,9 @@ public: return (flags_ & ModifierFlags::INTERNAL) != 0; } - [[nodiscard]] bool IsExported() const noexcept - { - if (UNLIKELY(IsClassDefinition())) { - return parent_->IsExported(); - } - - return (flags_ & ModifierFlags::EXPORT) != 0; - } + [[nodiscard]] bool IsExported() const noexcept; - [[nodiscard]] bool IsDefaultExported() const noexcept - { - if (UNLIKELY(IsClassDefinition())) { - return parent_->IsDefaultExported(); - } - - return (flags_ & ModifierFlags::DEFAULT_EXPORT) != 0; - } + [[nodiscard]] bool IsDefaultExported() const noexcept; [[nodiscard]] bool IsExportedType() const noexcept; @@ -429,7 +415,7 @@ public: return flags_; } - [[nodiscard]] bool HasAliasExport() const noexcept; + [[nodiscard]] bool HasExportAlias() const noexcept; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define DECLARE_FLAG_OPERATIONS(flag_type, member_name) \ diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export-expected.txt b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export-expected.txt new file mode 100644 index 0000000000..ba5b85b120 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export-expected.txt @@ -0,0 +1,850 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 22, + "column": 23 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "test_method", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 16 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "test_method", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 16 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 23, + "column": 20 + }, + "end": { + "line": 23, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 16 + } + } + }, + "property": { + "type": "Identifier", + "name": "print", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 17 + }, + "end": { + "line": 24, + "column": 22 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 22 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "test_method +", + "loc": { + "start": { + "line": 24, + "column": 23 + }, + "end": { + "line": 24, + "column": 38 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 25, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 25, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 25, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 25, + "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": 26, + "column": 2 + }, + "end": { + "line": 26, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 24 + }, + "end": { + "line": 26, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8 + }, + "end": { + "line": 26, + "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": "main", + "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": "main", + "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": "_$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": 16, + "column": 12 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "right": { + "type": "StringLiteral", + "value": "Hello_world", + "loc": { + "start": { + "line": 16, + "column": 31 + }, + "end": { + "line": 16, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 12 + }, + "end": { + "line": 16, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 12 + }, + "end": { + "line": 16, + "column": 44 + } + } + } + ], + "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": "test_var", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 12 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 12 + }, + "end": { + "line": 16, + "column": 44 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 18, + "column": 30 + }, + "end": { + "line": 18, + "column": 37 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "BooleanLiteral", + "value": true, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 38 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 20, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 27, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export.ets b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export.ets new file mode 100644 index 0000000000..c96a7fff86 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export let test_var: String = "Hello_world"; + +export function test_func(): boolean { + return true; +} + +export class TestClass { + test_method(): void { + console.print("test_method\n"); + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export-expected.txt b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export-expected.txt new file mode 100644 index 0000000000..42f22b34bd --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export-expected.txt @@ -0,0 +1,822 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./re-export_with_alias", + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 51 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "aliased_var", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "imported": { + "type": "Identifier", + "name": "aliased_var", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 20 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 52 + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./re-export_with_alias", + "loc": { + "start": { + "line": 17, + "column": 42 + }, + "end": { + "line": 17, + "column": 66 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "aliased_func", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "imported": { + "type": "Identifier", + "name": "aliased_func", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "AliasedClass", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 35 + } + } + }, + "imported": { + "type": "Identifier", + "name": "AliasedClass", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 35 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 67 + } + } + }, + { + "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": "ETSPrimitiveType", + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 12 + } + } + }, + "property": { + "type": "Identifier", + "name": "print", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "arguments": [ + { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Identifier", + "name": "aliased_var", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 30 + } + } + }, + "right": { + "type": "StringLiteral", + "value": " +", + "loc": { + "start": { + "line": 20, + "column": 33 + }, + "end": { + "line": 20, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 19 + }, + "end": { + "line": 20, + "column": 37 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 39 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "aliased_func", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 17 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 20 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "tmp_var", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "AliasedClass", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 32 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 16 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "AliasedClass", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 37 + }, + "end": { + "line": 23, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 37 + }, + "end": { + "line": 23, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 37 + }, + "end": { + "line": 23, + "column": 50 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 23, + "column": 33 + }, + "end": { + "line": 23, + "column": 52 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 52 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 52 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "tmp_var", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 12 + } + } + }, + "property": { + "type": "Identifier", + "name": "test_method", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 24, + "column": 24 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 24 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 25, + "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": 26, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export.ets b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export.ets new file mode 100644 index 0000000000..64474c21a5 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {aliased_var} from "./re-export_with_alias"; +import {aliased_func, AliasedClass} from "./re-export_with_alias"; + +function main(): void { + console.print(aliased_var + "\n"); + aliased_func(); + + let tmp_var: AliasedClass = new AliasedClass(); + tmp_var.test_method(); +} diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias-expected.txt b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias-expected.txt new file mode 100644 index 0000000000..ead73637e2 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias-expected.txt @@ -0,0 +1,366 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ETSReExportDeclaration", + "ets_import_declarations": { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./export", + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 49 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "aliased_var", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 32 + } + } + }, + "imported": { + "type": "Identifier", + "name": "test_var", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 32 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ETSReExportDeclaration", + "ets_import_declarations": { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./export", + "loc": { + "start": { + "line": 17, + "column": 68 + }, + "end": { + "line": 17, + "column": 78 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "aliased_func", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, + "imported": { + "type": "Identifier", + "name": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "AliasedClass", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 49 + }, + "end": { + "line": 17, + "column": 61 + } + } + }, + "imported": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 36 + }, + "end": { + "line": 17, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 36 + }, + "end": { + "line": 17, + "column": 61 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 79 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "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": 18, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias.ets b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias.ets new file mode 100644 index 0000000000..af54db5b08 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias.ets @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {test_var as aliased_var} from "./export"; +export {test_func as aliased_func, TestClass as AliasedClass} from "./export"; diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name-expected.txt new file mode 100644 index 0000000000..df4e5b55a0 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name-expected.txt @@ -0,0 +1,226 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./selective_export_function", + "loc": { + "start": { + "line": 16, + "column": 25 + }, + "end": { + "line": 16, + "column": 54 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 18 + } + } + }, + "imported": { + "type": "Identifier", + "name": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 54 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "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 + } + } +} +SyntaxError: Cannot find imported element 'test_func' [import_function_wrong_name.ets:16:9] diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name.ets new file mode 100644 index 0000000000..437a704787 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {test_func} from "./selective_export_function" diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface-expected.txt new file mode 100644 index 0000000000..1033b9a35c --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface-expected.txt @@ -0,0 +1,652 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./selective_export_interface", + "loc": { + "start": { + "line": 16, + "column": 45 + }, + "end": { + "line": 16, + "column": 75 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "TestInterface", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "imported": { + "type": "Identifier", + "name": "TestInterface", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "AliasInterface", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "imported": { + "type": "Identifier", + "name": "AliasInterface", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 76 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "superClass": null, + "implements": [ + { + "type": "TSClassImplements", + "expression": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "TestInterface", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 41 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 43 + } + } + } + ], + "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": 18, + "column": 44 + }, + "end": { + "line": 18, + "column": 44 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 42 + }, + "end": { + "line": 18, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 44 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "TestClassToo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "superClass": null, + "implements": [ + { + "type": "TSClassImplements", + "expression": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "AliasInterface", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 31 + }, + "end": { + "line": 20, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 31 + }, + "end": { + "line": 20, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 31 + }, + "end": { + "line": 20, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 31 + }, + "end": { + "line": 20, + "column": 47 + } + } + } + ], + "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": 48 + }, + "end": { + "line": 20, + "column": 48 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 46 + }, + "end": { + "line": 20, + "column": 48 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 48 + } + } + }, + { + "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/import_tests/selective_export_tests/import_interface.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface.ets new file mode 100644 index 0000000000..44fe863572 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {TestInterface, AliasInterface} from "./selective_export_interface"; + +class TestClass implements TestInterface {} + +class TestClassToo implements AliasInterface {} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name-expected.txt new file mode 100644 index 0000000000..b211d7d101 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name-expected.txt @@ -0,0 +1,226 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./selective_export_interface", + "loc": { + "start": { + "line": 16, + "column": 32 + }, + "end": { + "line": 16, + "column": 62 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "InterfaceToAlias", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "imported": { + "type": "Identifier", + "name": "InterfaceToAlias", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 25 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 63 + } + } + }, + { + "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 + } + } +} +SyntaxError: Cannot find imported element 'InterfaceToAlias' [import_interface_wrong_name.ets:16:9] diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name.ets new file mode 100644 index 0000000000..74ec5fdf90 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {InterfaceToAlias} from "./selective_export_interface"; diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported-expected.txt new file mode 100644 index 0000000000..eb89d99fb4 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported-expected.txt @@ -0,0 +1,1140 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./selective_export", + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 42 + } + } + }, + "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": 42 + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./selective_export", + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 40 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "func", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "imported": { + "type": "Identifier", + "name": "func", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 41 + } + } + }, + { + "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": "ETSPrimitiveType", + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "func", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 9 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 12 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 12 + } + } + }, + "property": { + "type": "Identifier", + "name": "print", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 13 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 18 + } + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "property": { + "type": "Identifier", + "name": "msg", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 23 + }, + "end": { + "line": 21, + "column": 26 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 21, + "column": 26 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 28 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "test_var", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 22 + } + } + }, + "right": { + "type": "Identifier", + "name": "tc", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 23 + }, + "end": { + "line": 23, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 32 + }, + "end": { + "line": 23, + "column": 35 + } + } + }, + "right": { + "type": "Identifier", + "name": "tc", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 36 + }, + "end": { + "line": 23, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 32 + }, + "end": { + "line": 23, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 32 + }, + "end": { + "line": 23, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 32 + }, + "end": { + "line": 23, + "column": 39 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 23, + "column": 28 + }, + "end": { + "line": 23, + "column": 41 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 41 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 41 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 12 + } + } + }, + "property": { + "type": "Identifier", + "name": "print", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 24, + "column": 18 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 18 + } + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "test_var", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 19 + }, + "end": { + "line": 24, + "column": 27 + } + } + }, + "property": { + "type": "Identifier", + "name": "test_member", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 28 + }, + "end": { + "line": 24, + "column": 39 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 19 + }, + "end": { + "line": 24, + "column": 39 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 41 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "test_var", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 13 + } + } + }, + "property": { + "type": "Identifier", + "name": "test_method", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 14 + }, + "end": { + "line": 25, + "column": 25 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 25 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 28 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "alias_var", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 9 + }, + "end": { + "line": 27, + "column": 18 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 28 + } + } + }, + "right": { + "type": "Identifier", + "name": "aliased", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 29 + }, + "end": { + "line": 27, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 25 + }, + "end": { + "line": 27, + "column": 37 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 27, + "column": 21 + }, + "end": { + "line": 27, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 9 + }, + "end": { + "line": 27, + "column": 39 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 39 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "alias_var", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 5 + }, + "end": { + "line": 28, + "column": 14 + } + } + }, + "property": { + "type": "Identifier", + "name": "alias_class_method", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 15 + }, + "end": { + "line": 28, + "column": 33 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 28, + "column": 5 + }, + "end": { + "line": 28, + "column": 33 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 28, + "column": 5 + }, + "end": { + "line": 28, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 5 + }, + "end": { + "line": 28, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 23 + }, + "end": { + "line": 29, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 29, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 29, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 29, + "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": 30, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported.ets new file mode 100644 index 0000000000..ce33368cbb --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported.ets @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as all from "./selective_export" +import {func} from "./selective_export"; + +function main(): void { + func(); + console.print(all.msg); + + let test_var: all.tc = new all.tc(); + console.print(test_var.test_member); + test_var.test_method(); + + let alias_var = new all.aliased(); + alias_var.alias_class_method(); +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name-expected.txt new file mode 100644 index 0000000000..40b19ef50f --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name-expected.txt @@ -0,0 +1,550 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./selective_export", + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 42 + } + } + }, + "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": 42 + } + } + }, + { + "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": "main", + "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": "main", + "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": "_$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": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "right": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "right": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 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": "test_var", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "value": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "all", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "right": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 20 + }, + "end": { + "line": 18, + "column": 34 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 18, + "column": 16 + }, + "end": { + "line": 18, + "column": 36 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 19, + "column": 1 + } + } +} +TypeError: Cannot find imported element 'TestClass' exported with alias [namespace_import_wrong_access_name.ets:18:24] diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets new file mode 100644 index 0000000000..de48420948 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as all from "./selective_export" + +let test_var = new all.TestClass(); diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export-expected.txt new file mode 100644 index 0000000000..203d3feaac --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export-expected.txt @@ -0,0 +1,1157 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 7 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "test_member", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 16 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "test_member", + "loc": { + "start": { + "line": 21, + "column": 19 + }, + "end": { + "line": 21, + "column": 32 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 32 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "test_method", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 16 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "test_method", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 16 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 23, + "column": 20 + }, + "end": { + "line": 23, + "column": 24 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 23, + "column": 25 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 16 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 27 + } + } + }, + { + "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": 20, + "column": 17 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "AliasClass", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 26, + "column": 17 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "alias_class_method", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 23 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "alias_class_method", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 23 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 27, + "column": 27 + }, + "end": { + "line": 27, + "column": 31 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 16 + } + } + }, + "property": { + "type": "Identifier", + "name": "print", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 17 + }, + "end": { + "line": 28, + "column": 22 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 22 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "alias_class_method", + "loc": { + "start": { + "line": 28, + "column": 23 + }, + "end": { + "line": 28, + "column": 43 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 45 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 32 + }, + "end": { + "line": 29, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 23 + }, + "end": { + "line": 29, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 23 + }, + "end": { + "line": 29, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 29, + "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": 30, + "column": 2 + }, + "end": { + "line": 30, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 18 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "aliased", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 6 + }, + "end": { + "line": 32, + "column": 13 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "AliasClass", + "decorators": [], + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 32, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 32, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 32, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 27 + } + } + }, + { + "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": "main", + "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": "main", + "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": "_$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": "msg", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "right": { + "type": "StringLiteral", + "value": "hello", + "loc": { + "start": { + "line": 18, + "column": 11 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "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": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 27 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 16, + "column": 28 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "msg", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "hello", + "loc": { + "start": { + "line": 18, + "column": 11 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 39, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export.ets new file mode 100644 index 0000000000..0e0fe091a6 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function test_func(): void {} + +let msg = "hello"; + +class TestClass { + test_member = "test_member"; + + test_method(): void {} +} + +class AliasClass { + alias_class_method(): void { + console.print("alias_class_method"); + } +} + +type aliased = AliasClass; + +export { + test_func as func, msg, + TestClass as tc, + aliased +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1-expected.txt new file mode 100644 index 0000000000..d05d1b06c9 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1-expected.txt @@ -0,0 +1 @@ +SyntaxError: Cannot export 'foo', it was already exported [selective_export_clashing_exports_1.ets:19:10] diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1.ets new file mode 100644 index 0000000000..a6e150c959 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function foo(): void {} + +export { + foo as bar +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2-expected.txt new file mode 100644 index 0000000000..9316033646 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2-expected.txt @@ -0,0 +1 @@ +SyntaxError: Cannot export 'foo', it was already exported [selective_export_clashing_exports_2.ets:19:10] diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets new file mode 100644 index 0000000000..3fb34fc5e7 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default function foo(): void {} + +export { + foo as bar +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3-expected.txt new file mode 100644 index 0000000000..c331c37006 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3-expected.txt @@ -0,0 +1 @@ +SyntaxError: The given name 'foo' is already used in another export [selective_export_clashing_exports_3.ets:21:10] diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets new file mode 100644 index 0000000000..d0d9d29353 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function foo(): void {} + +let msg = "hello"; + +export { + msg as foo +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4-expected.txt new file mode 100644 index 0000000000..68a8c0bb97 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4-expected.txt @@ -0,0 +1 @@ +SyntaxError: The given name 'foo' is already used in another export [selective_export_clashing_exports_4.ets:21:10] diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets new file mode 100644 index 0000000000..7b8b5f7b45 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default function foo(): void {} + +let msg = "hello"; + +export { + msg as foo +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function-expected.txt new file mode 100644 index 0000000000..16124914e4 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function-expected.txt @@ -0,0 +1,260 @@ +{ + "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": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "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": "test_func", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 27 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 16, + "column": 28 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 30 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function.ets new file mode 100644 index 0000000000..b2843f7bb2 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function test_func(): void {} + +export { + test_func as func +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface-expected.txt new file mode 100644 index 0000000000..d42e05e3b2 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface-expected.txt @@ -0,0 +1,239 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [], + "loc": { + "start": { + "line": 16, + "column": 25 + }, + "end": { + "line": 16, + "column": 27 + } + } + }, + "id": { + "type": "Identifier", + "name": "TestInterface", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 17, + "column": 10 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [], + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "id": { + "type": "Identifier", + "name": "InterfaceToAlias", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 19, + "column": 7 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "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/import_tests/selective_export_tests/selective_export_interface.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface.ets new file mode 100644 index 0000000000..1ffcec9e6f --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface TestInterface {} +interface InterfaceToAlias {} + +export { + TestInterface, + InterfaceToAlias as AliasInterface +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias-expected.txt new file mode 100644 index 0000000000..cc8fc2edbb --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias-expected.txt @@ -0,0 +1,461 @@ +{ + "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": "main", + "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": "main", + "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": "_$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": "msg", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "right": { + "type": "StringLiteral", + "value": "hello", + "loc": { + "start": { + "line": 18, + "column": 11 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "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": 21 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 24 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "msg", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "hello", + "loc": { + "start": { + "line": 18, + "column": 11 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 18 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 23, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias.ets new file mode 100644 index 0000000000..11af1b7dc4 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo(): void {} + +let msg = "hello"; + +export { + msg as foo +} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1-expected.txt new file mode 100644 index 0000000000..0df208ec17 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1-expected.txt @@ -0,0 +1,417 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./selective_export_interface", + "loc": { + "start": { + "line": 16, + "column": 51 + }, + "end": { + "line": 16, + "column": 81 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "NotAliasInterface", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 27 + }, + "end": { + "line": 16, + "column": 44 + } + } + }, + "imported": { + "type": "Identifier", + "name": "AliasInterface", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 44 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 81 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "superClass": null, + "implements": [ + { + "type": "TSClassImplements", + "expression": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "NotAliasInterface", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 47 + } + } + } + ], + "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": 18, + "column": 48 + }, + "end": { + "line": 18, + "column": 48 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 46 + }, + "end": { + "line": 18, + "column": 48 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 48 + } + } + }, + { + "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/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1.ets new file mode 100644 index 0000000000..34ef91370e --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AliasInterface as NotAliasInterface} from "./selective_export_interface" + +class TestClass implements NotAliasInterface {} diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2-expected.txt new file mode 100644 index 0000000000..c1f9019854 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2-expected.txt @@ -0,0 +1,417 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./selective_export_interface", + "loc": { + "start": { + "line": 16, + "column": 47 + }, + "end": { + "line": 16, + "column": 77 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "InterfaceAlias", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 26 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "imported": { + "type": "Identifier", + "name": "TestInterface", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 40 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 77 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "TestClass", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "superClass": null, + "implements": [ + { + "type": "TSClassImplements", + "expression": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "InterfaceAlias", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 44 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 44 + } + } + } + ], + "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": 18, + "column": 45 + }, + "end": { + "line": 18, + "column": 45 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 43 + }, + "end": { + "line": 18, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 45 + } + } + }, + { + "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/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2.ets b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2.ets new file mode 100644 index 0000000000..5ccc9bb6f6 --- /dev/null +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {TestInterface as InterfaceAlias} from "./selective_export_interface" + +class TestClass implements InterfaceAlias {} diff --git a/ets2panda/test/parser/ets/import_tests/type/import_type_1-expected.txt b/ets2panda/test/parser/ets/import_tests/type/import_type_1-expected.txt index 7f69fd8ec8..56d9621b75 100644 --- a/ets2panda/test/parser/ets/import_tests/type/import_type_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/type/import_type_1-expected.txt @@ -300,4 +300,4 @@ } } } -SyntaxError: Cannot find imported element 'A' exported with alias [import_type_1.ets:16:9] +SyntaxError: Cannot find imported element 'A' [import_type_1.ets:16:9] diff --git a/ets2panda/test/parser/ets/import_tests/type/type_3-expected.txt b/ets2panda/test/parser/ets/import_tests/type/type_3-expected.txt index 1b2be19512..fe95110d99 100644 --- a/ets2panda/test/parser/ets/import_tests/type/type_3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/type/type_3-expected.txt @@ -1 +1 @@ -SyntaxError: Cannot redeclare exported variable 'foo' [type_3.ets:20:27] +SyntaxError: The given name 'foo' is already used in another export [type_3.ets:20:27] 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 index 840f7dbccf..57211e023a 100644 --- a/ets2panda/test/parser/ets/selective_export/selective_export_bad-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/selective_export_bad-expected.txt @@ -1 +1 @@ -SyntaxError: Cannot find name 'foo' to export. [selective_export_bad.ets:16:10] +SyntaxError: Cannot find name 'foo' to export [selective_export_bad.ets:16:10] diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 22e9d5b6de..1568d1bcb6 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -575,71 +575,33 @@ bool ETSBinder::AddImportNamespaceSpecifiersToTopBindings(ir::AstNode *const spe return true; } -void ETSBinder::AddExportSelectiveAlias(const util::StringView &path, const util::StringView &key, - const util::StringView &value) -{ - auto it = selectiveExportsWithAlias_.find(path); - if (it == selectiveExportsWithAlias_.end()) { - AliasesByExportedNames aliasesByExportedNames(Allocator()->Adapter()); - aliasesByExportedNames.insert({key, value}); - selectiveExportsWithAlias_.insert({path, aliasesByExportedNames}); - return; - } - it->second.insert({key, value}); -} - -util::StringView ETSBinder::GetExportSelectiveAliasValue(util::StringView const &path, - util::StringView const &key) const -{ - if (auto alias = selectiveExportsWithAlias_.find(path); selectiveExportsWithAlias_.end() != alias) { - auto ret = alias->second.find(key); - if (alias->second.end() != ret) { - return ret->second; - } - } - return key; -} - Variable *ETSBinder::FindImportSpecifiersVariable(const util::StringView &imported, const varbinder::Scope::VariableMap &globalBindings, const ArenaVector &recordRes) { - auto const checkVar = [this, &imported](const util::StringView &searchImported, - varbinder::Variable *foundVariable) { - if (imported.Is(searchImported.Mutf8()) && foundVariable->Declaration()->Node()->HasAliasExport()) { - ThrowError(foundVariable->Declaration()->Node()->Start(), - "Cannot find imported element '" + imported.Mutf8() + "' exported with alias"); - } - - return foundVariable; - }; - - util::StringView searchImported = GetExportSelectiveAliasValue(recordRes.front()->SourceFilePath(), imported); - auto foundVar = globalBindings.find(searchImported); + auto foundVar = globalBindings.find(imported); if (foundVar == globalBindings.end()) { const auto &staticMethodBindings = recordRes.front()->GlobalClassScope()->StaticMethodScope()->Bindings(); - foundVar = staticMethodBindings.find(searchImported); + foundVar = staticMethodBindings.find(imported); if (foundVar != staticMethodBindings.end()) { - return checkVar(searchImported, foundVar->second); + return foundVar->second; } bool found = false; for (auto res : recordRes) { - searchImported = GetExportSelectiveAliasValue(res->SourceFilePath(), imported); const auto &staticFieldBindings = res->GlobalClassScope()->StaticFieldScope()->Bindings(); - foundVar = staticFieldBindings.find(searchImported); + foundVar = staticFieldBindings.find(imported); if (foundVar != staticFieldBindings.end()) { found = true; foundVar->second->AsLocalVariable()->AddFlag(VariableFlags::INITIALIZED); break; } } - if (!found) { return nullptr; } } - return checkVar(searchImported, foundVar->second); + return foundVar->second; } ir::ETSImportDeclaration *ETSBinder::FindImportDeclInReExports(const ir::ETSImportDeclaration *const import, @@ -740,7 +702,12 @@ bool ETSBinder::AddImportSpecifiersToTopBindings(ir::AstNode *const specifier, } } - auto *const var = FindImportSpecifiersVariable(imported, globalBindings, recordRes); + util::StringView nameToSearchFor = FindNameInAliasMap(import->ResolvedSource()->Str(), imported); + if (nameToSearchFor.Empty()) { + nameToSearchFor = imported; + } + + auto *const var = FindImportSpecifiersVariable(nameToSearchFor, globalBindings, recordRes); importSpecifier->Imported()->SetVariable(var); importSpecifier->Local()->SetVariable(var); @@ -753,11 +720,28 @@ bool ETSBinder::AddImportSpecifiersToTopBindings(ir::AstNode *const specifier, return true; } - ThrowError(importPath->Start(), "Cannot find imported element " + imported.Mutf8()); + ThrowError(importPath->Start(), "Cannot find imported element '" + imported.Mutf8() + "'"); } ValidateImportVariable(var, import, imported, importPath); + if (CheckForRedeclarationError(localName, var, importPath)) { + return true; + } + + // The first part of the condition will be true, if something was given an alias when exported, but we try + // to import it using its original name. + if (nameToSearchFor == imported && var->Declaration()->Node()->HasExportAlias()) { + ThrowError(specifier->Start(), "Cannot find imported element '" + imported.Mutf8() + "'"); + } + + InsertForeignBinding(specifier, import, localName, var); + return true; +} + +bool ETSBinder::CheckForRedeclarationError(const util::StringView &localName, Variable *const var, + const ir::StringLiteral *const importPath) +{ auto variable = Program()->GlobalClassScope()->FindLocal(localName, ResolveBindingOptions::ALL); if (variable != nullptr && var != variable) { if (variable->Declaration()->IsFunctionDecl() && var->Declaration()->IsFunctionDecl()) { @@ -768,8 +752,7 @@ bool ETSBinder::AddImportSpecifiersToTopBindings(ir::AstNode *const specifier, ThrowError(importPath->Start(), RedeclarationErrorMessageAssembler(var, variable, localName)); } - InsertForeignBinding(specifier, import, localName, var); - return true; + return false; } varbinder::Variable *ETSBinder::FindStaticBinding(const ArenaVector &recordRes, diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 82627e4e21..06481ca46c 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -20,11 +20,12 @@ #include "varbinder/recordTable.h" #include "ir/ets/etsImportDeclaration.h" #include "ir/ets/etsReExportDeclaration.h" +#include "ir/expressions/identifier.h" +#include "ir/module/importSpecifier.h" #include "parser/program/program.h" #include "util/importPathManager.h" namespace ark::es2panda::varbinder { - using AliasesByExportedNames = ArenaMap; using ModulesToExportedNamesWithAliases = ArenaMap; @@ -48,7 +49,7 @@ public: reExportImports_(Allocator()->Adapter()), dynamicImportVars_(Allocator()->Adapter()), importSpecifiers_(Allocator()->Adapter()), - selectiveExportsWithAlias_(Allocator()->Adapter()) + selectiveExportAliasMultimap_(Allocator()->Adapter()) { InitImplicitThisParam(); } @@ -223,9 +224,57 @@ public: void ResolveReferencesForScopeWithContext(ir::AstNode *node, Scope *scope); - void AddExportSelectiveAlias(const util::StringView &path, const util::StringView &key, - const util::StringView &value); - util::StringView GetExportSelectiveAliasValue(util::StringView const &path, util::StringView const &key) const; + bool CheckForRedeclarationError(const util::StringView &localName, Variable *const var, + const ir::StringLiteral *const importPath); + + bool AddSelectiveExportAlias(util::StringView const &path, util::StringView const &key, + util::StringView const &value) + { + if (auto foundMap = selectiveExportAliasMultimap_.find(path); foundMap != selectiveExportAliasMultimap_.end()) { + return foundMap->second.insert({key, value}).second; + } + + ArenaMap map(Allocator()->Adapter()); + bool insertResult = map.insert({key, value}).second; + selectiveExportAliasMultimap_.insert({path, map}); + return insertResult; + } + + [[nodiscard]] const ModulesToExportedNamesWithAliases &GetSelectiveExportAliasMultimap() const noexcept + { + return selectiveExportAliasMultimap_; + } + + util::StringView FindNameInAliasMap(const util::StringView &pathAsKey, const util::StringView &aliasName) + { + if (auto relatedMap = selectiveExportAliasMultimap_.find(pathAsKey); + relatedMap != selectiveExportAliasMultimap_.end()) { + if (auto item = relatedMap->second.find(aliasName); item != relatedMap->second.end()) { + return item->second; + } + } + + return ""; + } + + util::StringView FindLocalNameForImport(const ir::ImportSpecifier *const importSpecifier, + util::StringView &imported, const ir::StringLiteral *const importPath) + { + if (importSpecifier->Local() != nullptr) { + auto checkImportPathAndName = [&importPath, &imported](const auto &savedSpecifier) { + return importPath->Str() != savedSpecifier.first && imported == savedSpecifier.second; + }; + if (!std::any_of(importSpecifiers_.begin(), importSpecifiers_.end(), checkImportPathAndName)) { + TopScope()->EraseBinding(imported); + } + + importSpecifiers_.emplace_back(importPath->Str(), imported); + + return importSpecifier->Local()->Name(); + } + + return imported; + } private: void BuildClassDefinitionImpl(ir::ClassDefinition *classDef); @@ -250,7 +299,7 @@ private: ir::Identifier *thisParam_ {}; ArenaVector> importSpecifiers_; ir::AstNode *defaultExport_ {}; - ModulesToExportedNamesWithAliases selectiveExportsWithAlias_; + ModulesToExportedNamesWithAliases selectiveExportAliasMultimap_; friend class RecordTableContext; }; -- Gitee From b53662a329bba5177a368189cdb6169d67197b89 Mon Sep 17 00:00:00 2001 From: Tamas Toth Date: Mon, 8 Jul 2024 09:34:15 +0200 Subject: [PATCH 08/15] [ETS] Fix imported enum with star Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IABD5D Fixes #17932 internal issue Signed-off-by: Tamas Toth Change-Id: Icdf042f31ebaa3962e50e80dc4c70755401d6aa8 --- ets2panda/checker/ets/helpers.cpp | 3 + .../ets/import_tests/enum/export-expected.txt | 2888 +++++++++++++++++ .../parser/ets/import_tests/enum/export.ets | 21 + .../ets/import_tests/enum/import-expected.txt | 527 +++ .../parser/ets/import_tests/enum/import.ets | 18 + 5 files changed, 3457 insertions(+) create mode 100644 ets2panda/test/parser/ets/import_tests/enum/export-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/enum/export.ets create mode 100644 ets2panda/test/parser/ets/import_tests/enum/import-expected.txt create mode 100644 ets2panda/test/parser/ets/import_tests/enum/import.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index cc0c8eab64..bb8e070bf7 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1281,6 +1281,9 @@ void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjT BindingsModuleObjectAddProperty( moduleObjType, importDecl, programList.front()->GlobalClassScope()->StaticMethodScope()->Bindings()); + BindingsModuleObjectAddProperty( + moduleObjType, importDecl, programList.front()->GlobalClassScope()->StaticDeclScope()->Bindings()); + BindingsModuleObjectAddProperty( moduleObjType, importDecl, programList.front()->GlobalClassScope()->InstanceDeclScope()->Bindings()); diff --git a/ets2panda/test/parser/ets/import_tests/enum/export-expected.txt b/ets2panda/test/parser/ets/import_tests/enum/export-expected.txt new file mode 100644 index 0000000000..a347b88f41 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/enum/export-expected.txt @@ -0,0 +1,2888 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ETSPackageDeclaration", + "name": { + "type": "Identifier", + "name": "xml", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 18, + "column": 7 + } + } + }, + { + "type": "TSEnumDeclaration", + "id": { + "type": "Identifier", + "name": "EventType", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "members": [ + { + "type": "TSEnumMember", + "id": { + "type": "Identifier", + "name": "START_DOCUMENT", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 19 + } + } + }, + "initializer": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 19, + "column": 21 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 22 + } + } + }, + { + "type": "TSEnumMember", + "id": { + "type": "Identifier", + "name": "END_DOCUMENT", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 17 + } + } + }, + "initializer": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 20, + "column": 20 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 21 + } + } + } + ], + "const": false, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "#EventType#NamesArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "value": { + "type": "ArrayExpression", + "elements": [ + { + "type": "StringLiteral", + "value": "START_DOCUMENT", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "StringLiteral", + "value": "END_DOCUMENT", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "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": 1, + "column": 1 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "#EventType#getName", + "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": "#EventType#getName", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "ordinal", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EventType", + "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 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "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 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "#EventType#NamesArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "TSAsExpression", + "expression": { + "type": "Identifier", + "name": "ordinal", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": true, + "optional": false, + "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": 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": "#EventType#valueOf", + "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": "#EventType#valueOf", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "name", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "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 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EventType", + "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 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ForUpdateStatement", + "init": { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "#EventType#NamesArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "Identifier", + "name": "length", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "body": { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "operator": "==", + "left": { + "type": "Identifier", + "name": "name", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "#EventType#NamesArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "consequent": { + "type": "ReturnStatement", + "argument": { + "type": "TSAsExpression", + "expression": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EventType", + "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": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ThrowStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Exception", + "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 + } + } + }, + "arguments": [ + { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "StringLiteral", + "value": "No enum constant EventType.", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "right": { + "type": "Identifier", + "name": "name", + "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": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + "throwMarker": "throws", + "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": "#EventType#ValuesArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "value": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "#EventType#getValue", + "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": "#EventType#getValue", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "e", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EventType", + "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 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "#EventType#ValuesArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "TSAsExpression", + "expression": { + "type": "Identifier", + "name": "e", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": true, + "optional": false, + "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": 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": "#EventType#StringValuesArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "value": { + "type": "ArrayExpression", + "elements": [ + { + "type": "StringLiteral", + "value": "0", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "StringLiteral", + "value": "1", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "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": 1, + "column": 1 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "#EventType#toString", + "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": "#EventType#toString", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "ordinal", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EventType", + "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 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "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 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "#EventType#StringValuesArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "TSAsExpression", + "expression": { + "type": "Identifier", + "name": "ordinal", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": true, + "optional": false, + "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": 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": "#EventType#ItemsArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "value": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "EventType", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "Identifier", + "name": "START_DOCUMENT", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "EventType", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "Identifier", + "name": "END_DOCUMENT", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EventType", + "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": 1, + "column": 1 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "#EventType#values", + "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": "#EventType#values", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "TSArrayType", + "elementType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EventType", + "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": 1, + "column": 1 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "#EventType#ItemsArray", + "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": 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": "#EventType#fromInt", + "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": "#EventType#fromInt", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "ordinal", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "EventType", + "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 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "ordinal", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "#EventType#ItemsArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "Identifier", + "name": "length", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "consequent": { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "#EventType#ItemsArray", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "property": { + "type": "Identifier", + "name": "ordinal", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "alternate": null, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "ThrowStatement", + "argument": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Exception", + "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 + } + } + }, + "arguments": [ + { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "StringLiteral", + "value": "No enum constant in EventType with ordinal value ", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "right": { + "type": "Identifier", + "name": "ordinal", + "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": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + "throwMarker": "throws", + "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": 22, + "column": 1 + } + } +} diff --git a/ets2panda/test/parser/ets/import_tests/enum/export.ets b/ets2panda/test/parser/ets/import_tests/enum/export.ets new file mode 100644 index 0000000000..678522a9ad --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/enum/export.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package xml + +export enum EventType { + START_DOCUMENT =0, + END_DOCUMENT = 1, +}; diff --git a/ets2panda/test/parser/ets/import_tests/enum/import-expected.txt b/ets2panda/test/parser/ets/import_tests/enum/import-expected.txt new file mode 100644 index 0000000000..9ae9b0527d --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/enum/import-expected.txt @@ -0,0 +1,527 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./export", + "loc": { + "start": { + "line": 16, + "column": 20 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "specifiers": [ + { + "type": "ImportNamespaceSpecifier", + "local": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 8 + }, + "end": { + "line": 16, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + { + "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": "main", + "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": "main", + "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": "_$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": "event", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 10 + } + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 27 + } + } + }, + "property": { + "type": "Identifier", + "name": "EventType", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 37 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 37 + } + } + }, + "property": { + "type": "Identifier", + "name": "END_DOCUMENT", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 38 + }, + "end": { + "line": 18, + "column": 50 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 26 + }, + "end": { + "line": 18, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 50 + } + } + } + ], + "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": "event", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 10 + } + } + }, + "accessibility": "public", + "static": true, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "right": { + "type": "Identifier", + "name": "EventType", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "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 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 50 + } + } + } + ], + "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_tests/enum/import.ets b/ets2panda/test/parser/ets/import_tests/enum/import.ets new file mode 100644 index 0000000000..32287a3740 --- /dev/null +++ b/ets2panda/test/parser/ets/import_tests/enum/import.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as x from "./export" + +let event: x.EventType = x.EventType.END_DOCUMENT; -- Gitee From 59a19f32ed103dd9f060eef09ee6202fe9bab61f Mon Sep 17 00:00:00 2001 From: Konstantin Kuznetsov Date: Mon, 1 Jul 2024 18:08:53 +0300 Subject: [PATCH 09/15] Remove lambdas exceptions from ast-verifier Many warnings were resolved after lambdas refactoring. Issue: I9T8YV, I9T90B, I91NHG Testing: new unit tests for ast-verifier Signed-off-by: Konstantin Kuznetsov --- .../ast_verifier/identifierHasVariable.cpp | 5 -- .../variableHasEnclosingScope.cpp | 61 ++------------ ets2panda/ast_verifier/variableHasScope.cpp | 25 ++---- ..._verifier_identifier_has_variable_test.cpp | 82 +++++++++++++++++++ ...fier_variable_has_enclosing_scope_test.cpp | 55 +++++++++++++ .../ast_verifier_variable_has_scope_test.cpp | 29 +++++++ 6 files changed, 178 insertions(+), 79 deletions(-) diff --git a/ets2panda/ast_verifier/identifierHasVariable.cpp b/ets2panda/ast_verifier/identifierHasVariable.cpp index 881c39dde3..472087ee85 100644 --- a/ets2panda/ast_verifier/identifierHasVariable.cpp +++ b/ets2panda/ast_verifier/identifierHasVariable.cpp @@ -81,11 +81,6 @@ bool IdentifierHasVariable::CheckMoreAstExceptions(const ir::Identifier *ast) co parent = parent->Parent(); } - // NOTE(kkonkuznetsov): lambdas - if (ast->Name().Utf8().find("lambda$invoke$") == 0) { - return true; - } - // NOTE(kkonkuznetsov): some identifiers have empty names if (ast->Name().Empty()) { return true; diff --git a/ets2panda/ast_verifier/variableHasEnclosingScope.cpp b/ets2panda/ast_verifier/variableHasEnclosingScope.cpp index d7319b279f..98e963e16c 100644 --- a/ets2panda/ast_verifier/variableHasEnclosingScope.cpp +++ b/ets2panda/ast_verifier/variableHasEnclosingScope.cpp @@ -47,10 +47,6 @@ namespace ark::es2panda::compiler::ast_verifier { return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } - if (CheckScopeNodeExceptions(node)) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - if (CheckAstExceptions(ast)) { return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } @@ -88,30 +84,6 @@ bool VariableHasEnclosingScope::CheckCatchClause(const ir::AstNode *ast, const i return false; } -bool VariableHasEnclosingScope::CheckScopeNodeExceptions(const ir::AstNode *node) const -{ - if (node == nullptr) { - return false; - } - - // NOTE(kkonkuznetsov): lambdas - auto parent = node->Parent(); - while (parent != nullptr) { - if (parent->IsFunctionExpression()) { - auto script = parent->AsFunctionExpression()->Function(); - if (script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { - return true; - } - - break; - } - - parent = parent->Parent(); - } - - return false; -} - bool VariableHasEnclosingScope::CheckAstExceptions(const ir::AstNode *ast) const { // NOTE(kkonkuznetsov): skip parameter expression inside arrow function expression @@ -124,32 +96,13 @@ bool VariableHasEnclosingScope::CheckAstExceptions(const ir::AstNode *ast) const parent = parent->Parent(); } - if (ast->Parent()->IsLabelledStatement()) { - // Labels are attached to loop scopes, - // however label identifier is outside of loop. - // Example: - // - // loop: for (let i = 0; i < 10; i++) { - // } - return true; - } - - // NOTE(kkonkuznetsov): skip lambdas - parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsFunctionExpression()) { - auto script = parent->AsFunctionExpression()->Function(); - if (script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { - return true; - } - - break; - } - - parent = parent->Parent(); - } - - return false; + // Labels are attached to loop scopes, + // however label identifier is outside of loop. + // Example: + // + // loop: for (let i = 0; i < 10; i++) { + // } + return (ast->Parent()->IsLabelledStatement()); } } // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/variableHasScope.cpp b/ets2panda/ast_verifier/variableHasScope.cpp index e19c94bf1f..3048d91260 100644 --- a/ets2panda/ast_verifier/variableHasScope.cpp +++ b/ets2panda/ast_verifier/variableHasScope.cpp @@ -29,11 +29,6 @@ CheckResult VariableHasScope::operator()(CheckContext &ctx, const ir::AstNode *a return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } - // NOTE(kkonkuznetsov): lambdas - if (ast->AsIdentifier()->Name().Utf8().find("lambda$invoke$") == 0) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - // we will check invariant for only local variables of identifiers if (const auto maybeVar = GetLocalScopeVariable(allocator_, ctx, ast); maybeVar.has_value()) { const auto var = *maybeVar; @@ -129,6 +124,11 @@ bool VariableHasScope::ScopeEncloseVariable(CheckContext &ctx, const varbinder:: bool VariableHasScope::CheckAstExceptions(const ir::AstNode *ast) { + // NODE(kkonkuznetsov): scope warnings with async lambdas + if (ast->IsETSParameterExpression()) { + return true; + } + // NOTE(kkonkuznetsov): in some cases with lambdas scope node is null if (ast->Parent() != nullptr && ast->Parent()->IsETSFunctionType()) { return true; @@ -144,21 +144,6 @@ bool VariableHasScope::CheckAstExceptions(const ir::AstNode *ast) return true; } - // NOTE(kkonkuznetsov): lambdas - auto parent = ast->Parent(); - while (parent != nullptr) { - if (parent->IsScriptFunction()) { - auto script = parent->AsScriptFunction(); - if (script->Id() != nullptr && script->Id()->Name().Utf8().find("lambda$invoke$") == 0) { - return true; - } - - break; - } - - parent = parent->Parent(); - } - return false; } diff --git a/ets2panda/test/unit/public/ast_verifier_identifier_has_variable_test.cpp b/ets2panda/test/unit/public/ast_verifier_identifier_has_variable_test.cpp index c87478a1b2..c37dcb678d 100644 --- a/ets2panda/test/unit/public/ast_verifier_identifier_has_variable_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_identifier_has_variable_test.cpp @@ -134,3 +134,85 @@ TEST_F(ASTVerifierTest, TSQualifiedName) impl_->DestroyContext(ctx); } + +TEST_F(ASTVerifierTest, ParametersInArrowFunctionExpression) +{ + ASTVerifier verifier {Allocator()}; + + char const *text = R"( + let b = 1; + let f = (p: double) => b + p; + function main () { + assert f(42) == 43 + } + )"; + + 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))); + + InvariantNameSet checks; + checks.insert("IdentifierHasVariableForAll"); + const auto &messages = verifier.Verify(ast, checks); + ASSERT_EQ(messages.size(), 0); + + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, Lambdas) +{ + ASTVerifier verifier {Allocator()}; + + char const *text = R"( + type asyncLambda = () => Promise; + + async function asyncFunc(): Promise { + return true; + } + + function callAsyncLambda(): void { + let is_call_async_lambda: boolean = false; + + let async_lambda: asyncLambda = async (): Promise => { + await asyncFunc(); + is_call_async_lambda = true; + }; + } + + type I2v = (i: int) => void; + type T1 = (lambda: (arg: int) => int, arg: int) => int; + type T2 = (c: int) => int; + + const F1: I2v = (counter: int) => { + let funcWithLambda: T1 = (lambda: (arg: int) => int, arg: int) => { + return lambda(arg); + }; + + let it: T2 = (c: int): int => { + return c; + }; + + while (counter > 0) counter = funcWithLambda(it, counter); + }; + + function main() { + F1(44); + return 0; + } + )"; + + 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))); + + InvariantNameSet checks; + checks.insert("IdentifierHasVariableForAll"); + const auto &messages = verifier.Verify(ast, checks); + ASSERT_EQ(messages.size(), 0); + + impl_->DestroyContext(ctx); +} \ No newline at end of file diff --git a/ets2panda/test/unit/public/ast_verifier_variable_has_enclosing_scope_test.cpp b/ets2panda/test/unit/public/ast_verifier_variable_has_enclosing_scope_test.cpp index c917286ef9..6514ef3d03 100644 --- a/ets2panda/test/unit/public/ast_verifier_variable_has_enclosing_scope_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_variable_has_enclosing_scope_test.cpp @@ -52,3 +52,58 @@ TEST_F(ASTVerifierTest, CatchClause) impl_->DestroyContext(ctx); } + +TEST_F(ASTVerifierTest, LambdasHaveCorrectScope) +{ + ASTVerifier verifier {Allocator()}; + + char const *text = R"( + type BenchmarkFunc = () => void; + + function main() { + const arr: number[] = [1, 2, 3, 4]; + const ITERATE_FUNC: BenchmarkFunc = () => { + const length = arr.length; + }; + } + )"; + + 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))); + + InvariantNameSet checks; + checks.insert("VariableHasEnclosingScopeForAll"); + const auto &messages = verifier.Verify(ast, checks); + ASSERT_EQ(messages.size(), 0); + + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, ParametersInArrowFunctionExpression) +{ + ASTVerifier verifier {Allocator()}; + + char const *text = R"( + let b = 1; + let f = (p: double) => b + p; + function main () { + assert f(42) == 43 + } + )"; + + 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))); + + InvariantNameSet checks; + checks.insert("VariableHasEnclosingScopeForAll"); + const auto &messages = verifier.Verify(ast, checks); + ASSERT_EQ(messages.size(), 0); + + impl_->DestroyContext(ctx); +} diff --git a/ets2panda/test/unit/public/ast_verifier_variable_has_scope_test.cpp b/ets2panda/test/unit/public/ast_verifier_variable_has_scope_test.cpp index 8844fddb8d..111aeedc87 100644 --- a/ets2panda/test/unit/public/ast_verifier_variable_has_scope_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_variable_has_scope_test.cpp @@ -91,3 +91,32 @@ TEST_F(ASTVerifierTest, TestUnions) impl_->DestroyContext(ctx); } + +TEST_F(ASTVerifierTest, LambdasHaveCorrectScope) +{ + ASTVerifier verifier {Allocator()}; + + char const *text = R"( + type BenchmarkFunc = () => void; + + function main() { + const arr: number[] = [1, 2, 3, 4]; + const ITERATE_FUNC: BenchmarkFunc = () => { + const length = arr.length; + }; + } + )"; + + 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))); + + InvariantNameSet checks; + checks.insert("VariableHasScopeForAll"); + const auto &messages = verifier.Verify(ast, checks); + ASSERT_EQ(messages.size(), 0); + + impl_->DestroyContext(ctx); +} -- Gitee From aae2db961bfe5cf8af82dcf15bb8d584e9a4dd3a Mon Sep 17 00:00:00 2001 From: Konstantin Kuznetsov Date: Mon, 8 Jul 2024 13:36:51 +0300 Subject: [PATCH 10/15] Fix incorrect parent reference Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IAA1O7 Testing: added new unit test for AST verifier Signed-off-by: Konstantin Kuznetsov --- .../ast_verifier/everyChildHasValidParent.cpp | 7 -- ets2panda/checker/ets/helpers.cpp | 2 +- ets2panda/ir/ts/tsThisType.cpp | 15 ++++ ets2panda/ir/ts/tsThisType.h | 1 + ets2panda/test/unit/public/CMakeLists.txt | 4 + ...fier_every_child_has_valid_parent_test.cpp | 74 +++++++++++++++++++ 6 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 ets2panda/test/unit/public/ast_verifier_every_child_has_valid_parent_test.cpp diff --git a/ets2panda/ast_verifier/everyChildHasValidParent.cpp b/ets2panda/ast_verifier/everyChildHasValidParent.cpp index 5f31b0fad4..1d93a3ff51 100644 --- a/ets2panda/ast_verifier/everyChildHasValidParent.cpp +++ b/ets2panda/ast_verifier/everyChildHasValidParent.cpp @@ -26,13 +26,6 @@ CheckResult EveryChildHasValidParent::operator()(CheckContext &ctx, const ir::As ast->Iterate([&](const ir::AstNode *node) { if (ir::AstNode const *parent = node->Parent(); ast != parent) { - // NOTE: Temporary suppress. - // Should be removed after special lowering for lambda-functions will be implemented: #14376 - if ((ast->IsScriptFunction() || ast->IsETSFunctionType()) && parent != nullptr && - parent->IsScriptFunction()) { - return; - } - // NOTE: Temporary suppress. // Should be removed after new ENUMs support will be implemented: #14443 if (ast->IsClassDeclaration() && parent != nullptr && parent->IsETSNewClassInstanceExpression()) { diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index bb8e070bf7..f67dcfac21 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2128,7 +2128,7 @@ void ETSChecker::InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunction } } if (lambda->ReturnTypeAnnotation() == nullptr) { - lambda->SetReturnTypeAnnotation(calleeType->ReturnType()); + lambda->SetReturnTypeAnnotation(calleeType->ReturnType()->Clone(Allocator(), lambda)); } } diff --git a/ets2panda/ir/ts/tsThisType.cpp b/ets2panda/ir/ts/tsThisType.cpp index d317d7253c..02f90d8077 100644 --- a/ets2panda/ir/ts/tsThisType.cpp +++ b/ets2panda/ir/ts/tsThisType.cpp @@ -68,4 +68,19 @@ checker::Type *TSThisType::GetType([[maybe_unused]] checker::ETSChecker *checker { return checker->Context().ContainingClass(); } + +TSThisType *TSThisType::Clone(ArenaAllocator *const allocator, AstNode *const parent) +{ + if (auto *const clone = allocator->New(); clone != nullptr) { + if (parent != nullptr) { + clone->SetParent(parent); + } + + clone->SetRange(Range()); + return clone; + } + + throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR); +} + } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ts/tsThisType.h b/ets2panda/ir/ts/tsThisType.h index 23b24d26dc..5ce3170b27 100644 --- a/ets2panda/ir/ts/tsThisType.h +++ b/ets2panda/ir/ts/tsThisType.h @@ -33,6 +33,7 @@ public: 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; + TSThisType *Clone(ArenaAllocator *allocator, AstNode *parent) override; void Accept(ASTVisitorT *v) override { diff --git a/ets2panda/test/unit/public/CMakeLists.txt b/ets2panda/test/unit/public/CMakeLists.txt index c871308ffb..7a246ecca0 100644 --- a/ets2panda/test/unit/public/CMakeLists.txt +++ b/ets2panda/test/unit/public/CMakeLists.txt @@ -59,6 +59,10 @@ ets2panda_add_gtest(ast_verifier_variable_has_scope_test CPP_SOURCES ast_verifier_variable_has_scope_test.cpp ) +ets2panda_add_gtest(ast_verifier_every_child_has_valid_parent_test + CPP_SOURCES ast_verifier_every_child_has_valid_parent_test.cpp +) + panda_add_library(e2p_test_plugin SHARED e2p_test_plugin.c) panda_target_include_directories(e2p_test_plugin PRIVATE "${ES2PANDA_PATH}") panda_target_link_libraries(e2p_test_plugin es2panda-public) diff --git a/ets2panda/test/unit/public/ast_verifier_every_child_has_valid_parent_test.cpp b/ets2panda/test/unit/public/ast_verifier_every_child_has_valid_parent_test.cpp new file mode 100644 index 0000000000..85b3c736a8 --- /dev/null +++ b/ets2panda/test/unit/public/ast_verifier_every_child_has_valid_parent_test.cpp @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ast_verifier_test.h" +#include "checker/ETSchecker.h" +#include "ir/expressions/identifier.h" +#include "ir/astNode.h" +#include "parser/ETSparser.h" + +#include + +using ark::es2panda::compiler::ast_verifier::ASTVerifier; +using ark::es2panda::compiler::ast_verifier::InvariantNameSet; +using ark::es2panda::ir::AstNode; + +TEST_F(ASTVerifierTest, ReturnTypeInLambda) +{ + ASTVerifier verifier {Allocator()}; + char const *text = R"( + function main(): void { + let x: () => void = ()=> {} + } + )"; + + 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))); + + InvariantNameSet checks; + checks.insert("EveryChildHasValidParentForAll"); + const auto &messages = verifier.Verify(ast, checks); + ASSERT_EQ(messages.size(), 0); + + impl_->DestroyContext(ctx); +} + +TEST_F(ASTVerifierTest, TSThisType) +{ + ASTVerifier verifier {Allocator()}; + char const *text = R"( + class A { + foo(a?: Number): this { return this; } + } + + function main () {} + )"; + + 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))); + + InvariantNameSet checks; + checks.insert("EveryChildHasValidParentForAll"); + const auto &messages = verifier.Verify(ast, checks); + ASSERT_EQ(messages.size(), 0); + + impl_->DestroyContext(ctx); +} -- Gitee From f18e89489b254ae6652cc8714a98dd1684b661e4 Mon Sep 17 00:00:00 2001 From: Sergey Khil Date: Fri, 12 Jul 2024 17:30:25 +0300 Subject: [PATCH 11/15] Property dump and fix print of properties Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IACOEA Signed-off-by: Sergey Khil --- ets2panda/ir/base/classProperty.cpp | 5 +++++ ets2panda/ir/ets/etsParameterExpression.cpp | 7 ++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ets2panda/ir/base/classProperty.cpp b/ets2panda/ir/base/classProperty.cpp index 7a07160d7b..a2217e79f9 100644 --- a/ets2panda/ir/base/classProperty.cpp +++ b/ets2panda/ir/base/classProperty.cpp @@ -110,6 +110,10 @@ void ClassProperty::Dump(ir::SrcDumper *dumper) const key_->Dump(dumper); } + if (IsOptionalDeclaration()) { + dumper->Add("?"); + } + if (typeAnnotation_ != nullptr) { dumper->Add(": "); typeAnnotation_->Dump(dumper); @@ -121,6 +125,7 @@ void ClassProperty::Dump(ir::SrcDumper *dumper) const } dumper->Add(";"); + dumper->Endl(); } void ClassProperty::Compile(compiler::PandaGen *pg) const diff --git a/ets2panda/ir/ets/etsParameterExpression.cpp b/ets2panda/ir/ets/etsParameterExpression.cpp index 4b15f70473..df9262725b 100644 --- a/ets2panda/ir/ets/etsParameterExpression.cpp +++ b/ets2panda/ir/ets/etsParameterExpression.cpp @@ -168,11 +168,8 @@ void ETSParameterExpression::Dump(ir::SrcDumper *const dumper) const } } if (initializer_ != nullptr) { - ASSERT(initializer_->IsNumberLiteral()); - if (initializer_->AsNumberLiteral()->Str().Length() > 0) { - dumper->Add(" = "); - initializer_->Dump(dumper); - } + dumper->Add(" = "); + initializer_->Dump(dumper); } } } -- Gitee From 479f6be0814aa47a57f54b6a6e44f3bd4d253cbd Mon Sep 17 00:00:00 2001 From: cheezzario Date: Tue, 16 Jul 2024 12:42:23 +0300 Subject: [PATCH 12/15] [ArkTS][StdLib] Drop Object.equals Description: Drop Object.equals() Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/IACL01 Testing: All required pre-merge tests passed. Results are available in the ggwatcher Signed-off-by: cheezzario --- .../ets/generic_arrayaslist-expected.txt | 207 ++++-------------- .../test/compiler/ets/generic_arrayaslist.ets | 2 +- .../ets/generics_instantiation_3-expected.txt | 98 +++------ .../compiler/ets/generics_instantiation_3.ets | 2 +- ets2panda/test/runtime/ets/array-object.ets | 1 - .../runtime/ets/nullishTypeCodesamples.ets | 2 +- 6 files changed, 78 insertions(+), 234 deletions(-) diff --git a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt index f5d342c34e..4ca9a1c366 100644 --- a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt +++ b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt @@ -10870,231 +10870,108 @@ "test": { "type": "CallExpression", "callee": { - "type": "MemberExpression", - "object": { - "type": "TSAsExpression", - "expression": { + "type": "Identifier", + "name": "__runtimeEquals", + "decorators": [], + "loc": { + "start": { + "line": 132, + "column": 17 + }, + "end": { + "line": 132, + "column": 32 + } + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { "type": "MemberExpression", "object": { - "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, + "type": "ThisExpression", "loc": { "start": { "line": 132, - "column": 18 + "column": 33 }, "end": { "line": 132, - "column": 27 + "column": 37 } } }, "property": { "type": "Identifier", - "name": "i", + "name": "data", "decorators": [], "loc": { "start": { "line": 132, - "column": 28 + "column": 38 }, "end": { "line": 132, - "column": 29 + "column": 42 } } }, - "computed": true, + "computed": false, "optional": false, "loc": { "start": { "line": 132, - "column": 18 + "column": 33 }, "end": { "line": 132, - "column": 30 + "column": 42 } } }, - "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 - } - } - }, + "property": { + "type": "Identifier", + "name": "i", + "decorators": [], "loc": { "start": { "line": 132, - "column": 34 + "column": 43 }, "end": { "line": 132, - "column": 41 + "column": 44 } } }, + "computed": true, + "optional": false, "loc": { "start": { "line": 132, - "column": 17 + "column": 33 }, "end": { "line": 132, - "column": 41 + "column": 45 } } }, - "property": { + { "type": "Identifier", - "name": "equals", + "name": "e", "decorators": [], "loc": { "start": { "line": 132, - "column": 42 + "column": 47 }, "end": { "line": 132, "column": 48 } } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 132, - "column": 17 - }, - "end": { - "line": 132, - "column": 48 - } - } - }, - "arguments": [ - { - "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": 49 - }, - "end": { - "line": 132, - "column": 50 - } - } } ], "optional": false, @@ -11105,7 +10982,7 @@ }, "end": { "line": 132, - "column": 61 + "column": 49 } } }, @@ -11143,7 +11020,7 @@ "loc": { "start": { "line": 132, - "column": 63 + "column": 51 }, "end": { "line": 134, diff --git a/ets2panda/test/compiler/ets/generic_arrayaslist.ets b/ets2panda/test/compiler/ets/generic_arrayaslist.ets index 4a08b5c2c4..33e480c871 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] as Object).equals(e as Object)) { + if (__runtimeEquals(this.data[i], e)) { return true; } } diff --git a/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt b/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt index 757b511447..94e90ddeb9 100644 --- a/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt +++ b/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt @@ -240,43 +240,14 @@ { "type": "ExpressionStatement", "expression": { - "type": "CallExpression", - "callee": { + "type": "BinaryExpression", + "operator": "==", + "left": { "type": "MemberExpression", "object": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "ThisExpression", - "loc": { - "start": { - "line": 18, - "column": 9 - }, - "end": { - "line": 18, - "column": 13 - } - } - }, - "property": { - "type": "Identifier", - "name": "data", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 14 - }, - "end": { - "line": 18, - "column": 18 - } - } - }, - "computed": false, - "optional": false, + "type": "ThisExpression", "loc": { "start": { "line": 18, @@ -284,25 +255,26 @@ }, "end": { "line": 18, - "column": 18 + "column": 13 } } }, "property": { - "type": "NumberLiteral", - "value": 2, + "type": "Identifier", + "name": "data", + "decorators": [], "loc": { "start": { "line": 18, - "column": 19 + "column": 14 }, "end": { "line": 18, - "column": 20 + "column": 18 } } }, - "computed": true, + "computed": false, "optional": false, "loc": { "start": { @@ -311,26 +283,25 @@ }, "end": { "line": 18, - "column": 21 + "column": 18 } } }, "property": { - "type": "Identifier", - "name": "equals", - "decorators": [], + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 18, - "column": 22 + "column": 19 }, "end": { "line": 18, - "column": 28 + "column": 20 } } }, - "computed": false, + "computed": true, "optional": false, "loc": { "start": { @@ -339,28 +310,25 @@ }, "end": { "line": 18, - "column": 28 + "column": 21 } } }, - "arguments": [ - { - "type": "Identifier", - "name": "e", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 29 - }, - "end": { - "line": 18, - "column": 30 - } + "right": { + "type": "Identifier", + "name": "e", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 26 } } - ], - "optional": false, + }, "loc": { "start": { "line": 18, @@ -368,7 +336,7 @@ }, "end": { "line": 18, - "column": 31 + "column": 26 } } }, @@ -379,7 +347,7 @@ }, "end": { "line": 18, - "column": 32 + "column": 27 } } } diff --git a/ets2panda/test/compiler/ets/generics_instantiation_3.ets b/ets2panda/test/compiler/ets/generics_instantiation_3.ets index 6a6fe0e309..eefe579d47 100644 --- a/ets2panda/test/compiler/ets/generics_instantiation_3.ets +++ b/ets2panda/test/compiler/ets/generics_instantiation_3.ets @@ -15,7 +15,7 @@ class A { public foo(e: T): void { - this.data[2].equals(e); + this.data[2] == e; } private data: T[]; diff --git a/ets2panda/test/runtime/ets/array-object.ets b/ets2panda/test/runtime/ets/array-object.ets index 916e01520f..c7caaf99e0 100644 --- a/ets2panda/test/runtime/ets/array-object.ets +++ b/ets2panda/test/runtime/ets/array-object.ets @@ -37,7 +37,6 @@ function main(): void { assert(arr1 == object_array); assert(arr1 == object); assert(arr1 != arr2); - assert(object.equals(arr1 as Object) == true); // Cannot cast type 'int[]' to 'Object[]' // let object_array2: Object[] = arr2 as Object[]; diff --git a/ets2panda/test/runtime/ets/nullishTypeCodesamples.ets b/ets2panda/test/runtime/ets/nullishTypeCodesamples.ets index 4d78ff9fdb..2b42d7b9ad 100644 --- a/ets2panda/test/runtime/ets/nullishTypeCodesamples.ets +++ b/ets2panda/test/runtime/ets/nullishTypeCodesamples.ets @@ -19,7 +19,7 @@ class A { this.indices = new number[2][2]; } - public override equals(other: Object | null | undefined): boolean { + public equals(other: Object | null | undefined): boolean { for (let i = 0; i < this.indices!.length; ++i) { let num: number[] = this.indices![i]; num[0]; -- Gitee From 43c9636f065864324ad7c48dc4c753aec391ed69 Mon Sep 17 00:00:00 2001 From: Igor Sharonov Date: Tue, 16 Jul 2024 13:03:42 +0300 Subject: [PATCH 13/15] Fix const string to char lambda test Issue: internal #18121 Change-Id: I3169b3d80bb00ef5a8e6da7ee1d68a5b1e2d7a13 Signed-off-by: Igor Sharonov --- ets2panda/compiler/lowering/phase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 105d994a0c..72060ad4f8 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -121,6 +121,7 @@ std::vector GetETSPhaseList() &g_pluginsAfterCheck, &g_bigintLowering, &g_opAssignmentLowering, + &g_constStringToCharLowering, &g_boxingForLocals, &g_lambdaConversionPhase, &g_recordLowering, @@ -132,7 +133,6 @@ std::vector GetETSPhaseList() &g_localClassLowering, &g_objectLiteralLowering, &g_stringConstructorLowering, - &g_constStringToCharLowering, &g_stringComparisonLowering, &g_partialExportClassGen, &g_pluginsAfterLowerings, -- Gitee From 4b83f987d6320b32bcc3ed279462b88e3718903d Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Mon, 15 Jul 2024 14:48:14 +0800 Subject: [PATCH 14/15] Deleted ValidateTypeArg fucntion Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IAD1F8?from=project-issue Description:After issue #15026 is merged, validateTypeArg will be unuseed at all. So just simply delete this funciton.\ Tests: ninja tests passed bash ets_testrunner.sh --cts -r -rt passed Signed-off-by: xuxinjie4 --- ets2panda/checker/ets/typeRelationContext.cpp | 18 ------------------ ets2panda/checker/ets/typeRelationContext.h | 2 -- 2 files changed, 20 deletions(-) diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index bd0834d6fe..557db5e37a 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -60,24 +60,6 @@ bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSType return false; } -bool InstantiationContext::ValidateTypeArg(Type *constraintType, Type *typeArg) -{ - // NOTE: #14993 enforce IsETSReferenceType - if (typeArg->IsWildcardType()) { - return true; - } - - if (typeArg->IsETSVoidType() && constraintType->IsETSUnionType()) { - for (auto const it : constraintType->AsETSUnionType()->ConstituentTypes()) { - if (it->IsETSUndefinedType() || it->IsETSVoidType()) { - return true; - } - } - } - - return checker_->Relation()->IsAssignableTo(typeArg, constraintType); -} - void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParameterInstantiation *typeArgs) { ArenaVector typeArgTypes(checker_->Allocator()->Adapter()); diff --git a/ets2panda/checker/ets/typeRelationContext.h b/ets2panda/checker/ets/typeRelationContext.h index 8924087a3c..a48e8e5423 100644 --- a/ets2panda/checker/ets/typeRelationContext.h +++ b/ets2panda/checker/ets/typeRelationContext.h @@ -193,8 +193,6 @@ private: bool ValidateTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *typeArgs, const lexer::SourcePosition &pos); - bool ValidateTypeArg(Type *constraintType, Type *typeArg); - void InstantiateType(ETSObjectType *type, ir::TSTypeParameterInstantiation *typeArgs); void InstantiateType(ETSObjectType *type, ArenaVector &&typeArgTypes, const lexer::SourcePosition &pos); -- Gitee From c95e444bef65cdfaf34bcac29993df8296371102 Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Tue, 25 Jun 2024 14:58:51 +0300 Subject: [PATCH 15/15] Error logger and TypeError type Signed-off-by: Georgy Bronnikov --- ets2panda/BUILD.gn | 1 + ets2panda/CMakeLists.txt | 1 + ets2panda/checker/ETSchecker.cpp | 7 +- ets2panda/checker/ETSchecker.h | 2 + ets2panda/checker/checker.cpp | 16 +- ets2panda/checker/checker.h | 8 + ets2panda/checker/ets/object.cpp | 1 - ets2panda/checker/types/ets/etsObjectType.cpp | 5 +- ets2panda/checker/types/globalTypesHolder.cpp | 9 + ets2panda/checker/types/globalTypesHolder.h | 4 + ets2panda/checker/types/type.cpp | 11 ++ ets2panda/checker/types/type.h | 8 + ets2panda/checker/types/typeError.h | 42 +++++ ets2panda/checker/types/typeFlag.h | 36 ++-- ets2panda/checker/types/typeMapping.h | 3 +- ets2panda/compiler/core/ETSCompiler.cpp | 3 + ets2panda/ir/astNode.h | 75 -------- ets2panda/ir/base/classElement.h | 1 + ets2panda/ir/base/tsSignatureDeclaration.h | 2 +- ets2panda/ir/expression.h | 1 + ets2panda/ir/statement.h | 38 ---- ets2panda/ir/ts/tsTypeAliasDeclaration.h | 1 + ets2panda/ir/typed.h | 164 ++++++++++++++++++ ets2panda/util/errorLogger.cpp | 27 +++ ets2panda/util/errorLogger.h | 45 +++++ ets2panda/varbinder/variable.cpp | 2 + ets2panda/varbinder/variable.h | 14 +- 27 files changed, 389 insertions(+), 138 deletions(-) create mode 100644 ets2panda/checker/types/typeError.h create mode 100644 ets2panda/ir/typed.h create mode 100644 ets2panda/util/errorLogger.cpp create mode 100644 ets2panda/util/errorLogger.h diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index d99ca53e9a..bc32b04b0e 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -418,6 +418,7 @@ libes2panda_sources = [ "util/arktsconfig.cpp", "util/bitset.cpp", "util/errorHandler.cpp", + "util/errorLogger.cpp", "util/helpers.cpp", "util/importPathManager.cpp", "util/path.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 8f442846c8..b561b4ab8d 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -511,6 +511,7 @@ set(ES2PANDA_LIB_SRC util/arktsconfig.cpp util/bitset.cpp util/errorHandler.cpp + util/errorLogger.cpp util/helpers.cpp util/importPathManager.cpp util/path.cpp diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 8556428fab..81799ff7b6 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -185,7 +185,7 @@ bool ETSChecker::StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, CheckWarnings(Program(), options); } - return true; + return !ErrorLogger()->IsAnyError(); } void ETSChecker::CheckProgram(parser::Program *program, bool runAnalysis) @@ -430,6 +430,11 @@ const GlobalArraySignatureMap &ETSChecker::GlobalArrayTypes() const return globalArraySignatures_; } +Type *ETSChecker::GlobalTypeError() const +{ + return GetGlobalTypesHolder()->GlobalTypeError(); +} + void ETSChecker::HandleUpdatedCallExpressionNode(ir::CallExpression *callExpr) { VarBinder()->AsETSBinder()->HandleCustomNodes(callExpr); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index c7f744dc90..c9659d6790 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -133,6 +133,8 @@ public: GlobalArraySignatureMap &GlobalArrayTypes(); const GlobalArraySignatureMap &GlobalArrayTypes() const; + Type *GlobalTypeError() 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; diff --git a/ets2panda/checker/checker.cpp b/ets2panda/checker/checker.cpp index 74e8235f7d..74ece2958a 100644 --- a/ets2panda/checker/checker.cpp +++ b/ets2panda/checker/checker.cpp @@ -37,7 +37,8 @@ Checker::Checker() : allocator_(SpaceType::SPACE_TYPE_COMPILER, nullptr, true), context_(this, CheckerStatus::NO_OPTS), globalTypes_(allocator_.New(&allocator_)), - relation_(allocator_.New(this)) + relation_(allocator_.New(this)), + errorLogger_(allocator_.New(&allocator_)) { } @@ -88,6 +89,19 @@ void Checker::ThrowTypeError(std::string_view message, const lexer::SourcePositi throw Error {ErrorType::TYPE, program_->SourceFilePath().Utf8(), message, loc.line, loc.col}; } +void Checker::LogTypeError(std::initializer_list list, const lexer::SourcePosition &pos) +{ + LogTypeError(FormatMsg(list), pos); +} + +void Checker::LogTypeError(std::string_view message, const lexer::SourcePosition &pos) +{ + lexer::LineIndex index(program_->SourceCode()); + lexer::SourceLocation loc = index.GetLocation(pos); + + errorLogger_->Log(Error {ErrorType::TYPE, program_->SourceFilePath().Utf8(), message, loc.line, loc.col}); +} + void Checker::Warning(const std::string_view message, const lexer::SourcePosition &pos) const { lexer::LineIndex index(program_->SourceCode()); diff --git a/ets2panda/checker/checker.h b/ets2panda/checker/checker.h index ca422d8428..d51de1d6ab 100644 --- a/ets2panda/checker/checker.h +++ b/ets2panda/checker/checker.h @@ -20,6 +20,7 @@ #include "checker/checkerContext.h" #include "checker/SemanticAnalyzer.h" +#include "util/errorLogger.h" namespace ark::es2panda::parser { class Program; @@ -166,6 +167,8 @@ public: [[noreturn]] void ThrowTypeError(std::string_view message, const lexer::SourcePosition &pos); [[noreturn]] void ThrowTypeError(std::initializer_list list, const lexer::SourcePosition &pos); + void LogTypeError(std::string_view message, const lexer::SourcePosition &pos); + void LogTypeError(std::initializer_list list, const lexer::SourcePosition &pos); void Warning(std::string_view message, const lexer::SourcePosition &pos) const; void ReportWarning(std::initializer_list list, const lexer::SourcePosition &pos); @@ -199,6 +202,10 @@ protected: void Initialize(varbinder::VarBinder *varbinder); parser::Program *Program() const; void SetProgram(parser::Program *program); + util::ErrorLogger *ErrorLogger() + { + return errorLogger_; + } private: ArenaAllocator allocator_; @@ -209,6 +216,7 @@ private: varbinder::VarBinder *varbinder_ {}; parser::Program *program_ {}; varbinder::Scope *scope_ {}; + util::ErrorLogger *errorLogger_ {}; RelationHolder identicalResults_ {{}, RelationType::IDENTICAL}; RelationHolder assignableResults_ {{}, RelationType::ASSIGNABLE}; diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 20b2cc2b85..6c4ab8a13a 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -584,7 +584,6 @@ void ETSChecker::CreateFunctionTypesFromAbstracts(const std::vector } auto *created = CreateETSFunctionType(it); - created->AddTypeFlag(TypeFlag::SYNTHETIC); target->push_back(created); } } diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index cb96ccd8be..b8ecc6249e 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -157,7 +157,6 @@ varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(co varbinder::LocalVariable *res = allocator_->New(varbinder::VariableFlags::SYNTHETIC | varbinder::VariableFlags::METHOD); ETSFunctionType *funcType = CreateETSFunctionType(name); - funcType->AddTypeFlag(TypeFlag::SYNTHETIC); varbinder::LocalVariable *functionalInterface = CollectSignaturesForSyntheticType(funcType, name, flags); @@ -183,6 +182,10 @@ varbinder::LocalVariable *ETSObjectType::CollectSignaturesForSyntheticType(ETSFu const util::StringView &name, PropertySearchFlags flags) const { + if (funcType == nullptr) { + return nullptr; + } + auto const addSignature = [funcType, flags](varbinder::LocalVariable *found) -> void { for (auto *it : found->TsType()->AsETSFunctionType()->CallSignatures()) { if (((flags & PropertySearchFlags::IGNORE_ABSTRACT) != 0) && diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index afb9eb0ece..40d1a5f636 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -15,6 +15,7 @@ #include "globalTypesHolder.h" +#include "checker/types/typeError.h" #include "checker/types/ts/numberType.h" #include "checker/types/ts/anyType.h" #include "checker/types/ts/stringType.h" @@ -95,6 +96,7 @@ GlobalTypesHolder::GlobalTypesHolder(ArenaAllocator *allocator) : builtinNameMap globalTypes_[static_cast(GlobalTypeId::ETS_NULL)] = allocator->New(); globalTypes_[static_cast(GlobalTypeId::ETS_UNDEFINED)] = allocator->New(); globalTypes_[static_cast(GlobalTypeId::ETS_WILDCARD)] = allocator->New(); + globalTypes_[static_cast(GlobalTypeId::TYPE_ERROR)] = allocator->New(); builtinNameMappings_.emplace("Boolean", GlobalTypeId::ETS_BOOLEAN_BUILTIN); builtinNameMappings_.emplace("Byte", GlobalTypeId::ETS_BYTE_BUILTIN); @@ -149,6 +151,8 @@ GlobalTypesHolder::GlobalTypesHolder(ArenaAllocator *allocator) : builtinNameMap builtinNameMappings_.emplace("RegExp", GlobalTypeId::ETS_REGEXP_BUILTIN); builtinNameMappings_.emplace("Set", GlobalTypeId::ETS_SET_BUILTIN); + builtinNameMappings_.emplace("TYPE ERROR", GlobalTypeId::TYPE_ERROR); + // ETS functional types for (size_t id = static_cast(GlobalTypeId::ETS_FUNCTION0_CLASS), nargs = 0; id < static_cast(GlobalTypeId::ETS_FUNCTIONN_CLASS); id++, nargs++) { @@ -630,6 +634,11 @@ Type *GlobalTypesHolder::GlobalFunctionBuiltinType(size_t nargs) return globalTypes_.at(static_cast(GlobalTypeId::ETS_FUNCTION0_CLASS) + nargs); } +Type *GlobalTypesHolder::GlobalTypeError() +{ + return globalTypes_.at(static_cast(GlobalTypeId::TYPE_ERROR)); +} + void GlobalTypesHolder::InitializeBuiltin(const util::StringView name, Type *type) { const auto typeId = builtinNameMappings_.find(name); diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index 6e899448c1..f0c291d38d 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -131,6 +131,8 @@ enum class GlobalTypeId : std::size_t { ETS_FUNCTION16_CLASS, ETS_FUNCTIONN_CLASS, + TYPE_ERROR, + COUNT, }; @@ -243,6 +245,8 @@ public: Type *GlobalJSRuntimeBuiltinType(); Type *GlobalJSValueBuiltinType(); + Type *GlobalTypeError(); + void InitializeBuiltin(util::StringView name, Type *type); using Holder = std::array(GlobalTypeId::COUNT)>; diff --git a/ets2panda/checker/types/type.cpp b/ets2panda/checker/types/type.cpp index 3d443396d4..a0aab5954d 100644 --- a/ets2panda/checker/types/type.cpp +++ b/ets2panda/checker/types/type.cpp @@ -167,4 +167,15 @@ std::uint32_t Type::GetPrecedence(Type const *type) noexcept } return 0U; } + +bool IsTypeError(Type const *tp) +{ + return tp != nullptr && tp->IsTypeError(); +} + +void ThrowEmptyError() +{ + throw Error(ErrorType::TYPE, "", ""); +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index a1e21b1e22..697ffc100d 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -274,6 +274,14 @@ protected: uint64_t id_; // NOLINTEND(misc-non-private-member-variables-in-classes) }; + +// NOLINTBEGIN(readability-redundant-declaration) +// To avoid including type.h from variable.h, astNode.h +bool IsTypeError(Type const *tp); +// Use this in order to avoid crashes where TypeError is not expected +[[noreturn]] void ThrowEmptyError(); +// NOLINTEND(readability-redundant-declaration) + } // namespace ark::es2panda::checker #endif /* TYPESCRIPT_TYPES_TYPE_H */ diff --git a/ets2panda/checker/types/typeError.h b/ets2panda/checker/types/typeError.h new file mode 100644 index 0000000000..8969747c0d --- /dev/null +++ b/ets2panda/checker/types/typeError.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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_CHECKER_TYPES_ERROR_TYPE_ERROR_H +#define ES2PANDA_CHECKER_TYPES_ERROR_TYPE_ERROR_H + +#include "es2panda.h" +#include "checker/types/type.h" + +namespace ark::es2panda::checker { + +class TypeError : public Type { +public: + explicit TypeError() : Type(TypeFlag::TYPE_ERROR) {} + + void AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) override + { + // Don't spread the error + relation->Result(RelationResult::TRUE); + } + + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override + { + ss << "*TYPE_ERROR*"; + } +}; + +} // namespace ark::es2panda::checker + +#endif diff --git a/ets2panda/checker/types/typeFlag.h b/ets2panda/checker/types/typeFlag.h index 59a66bfaf3..413d17915a 100644 --- a/ets2panda/checker/types/typeFlag.h +++ b/ets2panda/checker/types/typeFlag.h @@ -71,24 +71,24 @@ enum class TypeFlag : uint64_t { ETS_VOID = 1ULL << 43ULL, // ETS void type ETS_OBJECT = 1ULL << 44ULL, // ETS class or interface type ETS_ARRAY = 1ULL << 45ULL, // ETS array type - SYNTHETIC = 1ULL << 46ULL, // synthetic type created by the checker for specific checks - WILDCARD = 1ULL << 47ULL, // new A() - ETS_TYPE_PARAMETER = 1ULL << 48ULL, // ETS type parameter - ETS_TYPE_REFERENCE = 1ULL << 49ULL, // ETS type reference - GENERIC = 1ULL << 50ULL, // ETS Generic - ETS_ENUM = 1ULL << 51ULL, // ETS Enum - ETS_STRING_ENUM = 1ULL << 52ULL, // ETS string-type Enumeration - ETS_DYNAMIC_FLAG = 1ULL << 53ULL, // ETS Dynamic flag - GETTER = 1ULL << 54ULL, // ETS Getter - SETTER = 1ULL << 55ULL, // ETS Setter - ETS_EXTENSION_FUNC_HELPER = 1ULL << 56ULL, // ETS Extension Function Helper - ETS_UNION = 1ULL << 57ULL, // ETS union - ETS_TUPLE = 1ULL << 58ULL, // ETS tuple type - ETS_NULL = 1ULL << 59ULL, // ETS null - ETS_UNDEFINED = 1ULL << 60ULL, // ETS undefined - ETS_NONNULLISH = 1ULL << 61ULL, // ETS nonnullish type parameter - ETS_READONLY = 1ULL << 62ULL, // ETS readonly type parameter - ETS_REQUIRED_TYPE_PARAMETER = 1ULL << 63ULL, // ETS Required type parameter + WILDCARD = 1ULL << 46ULL, // new A() + ETS_TYPE_PARAMETER = 1ULL << 47ULL, // ETS type parameter + ETS_TYPE_REFERENCE = 1ULL << 48ULL, // ETS type reference + GENERIC = 1ULL << 49ULL, // ETS Generic + ETS_ENUM = 1ULL << 50ULL, // ETS Enum + ETS_STRING_ENUM = 1ULL << 51ULL, // ETS string-type Enumeration + ETS_DYNAMIC_FLAG = 1ULL << 52ULL, // ETS Dynamic flag + GETTER = 1ULL << 53ULL, // ETS Getter + SETTER = 1ULL << 54ULL, // ETS Setter + ETS_EXTENSION_FUNC_HELPER = 1ULL << 55ULL, // ETS Extension Function Helper + ETS_UNION = 1ULL << 56ULL, // ETS union + ETS_TUPLE = 1ULL << 57ULL, // ETS tuple type + ETS_NULL = 1ULL << 58ULL, // ETS null + ETS_UNDEFINED = 1ULL << 59ULL, // ETS undefined + ETS_NONNULLISH = 1ULL << 60ULL, // ETS nonnullish type parameter + ETS_READONLY = 1ULL << 61ULL, // ETS readonly type parameter + ETS_REQUIRED_TYPE_PARAMETER = 1ULL << 62ULL, // ETS Required type parameter + TYPE_ERROR = 1ULL << 63ULL, // type error 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 | diff --git a/ets2panda/checker/types/typeMapping.h b/ets2panda/checker/types/typeMapping.h index 653fc40c15..b3c116db4d 100644 --- a/ets2panda/checker/types/typeMapping.h +++ b/ets2panda/checker/types/typeMapping.h @@ -64,7 +64,8 @@ _(TypeFlag::ETS_ENUM, ETSEnumType) \ _(TypeFlag::ETS_STRING_ENUM, ETSStringEnumType) \ _(TypeFlag::ETS_EXTENSION_FUNC_HELPER, ETSExtensionFuncHelperType) \ - _(TypeFlag::ETS_TUPLE, ETSTupleType) + _(TypeFlag::ETS_TUPLE, ETSTupleType) \ + _(TypeFlag::TYPE_ERROR, TypeError) #define OBJECT_TYPE_MAPPING(_) \ _(ObjectType::ObjectTypeKind::FUNCTION, FunctionType) \ diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 42ab4ece20..75c2256bc6 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -799,6 +799,9 @@ bool ETSCompiler::IsSucceedCompilationProxyMemberExpr(const ir::CallExpression * ETSGen *etsg = GetETSGen(); auto *const calleeObject = expr->callee_->AsMemberExpression()->Object(); auto const *const enumInterface = [calleeType = calleeObject->TsType()]() -> checker::ETSEnumInterface const * { + if (calleeType == nullptr) { + return nullptr; + } if (calleeType->IsETSEnumType()) { return calleeType->AsETSEnumType(); } diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index 70e78ffd92..157c0d9947 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -524,46 +524,6 @@ private: void SetOriginalNode(AstNode *originalNode); }; -template -class Typed : public T { -public: - Typed() = delete; - ~Typed() override = default; - - NO_COPY_OPERATOR(Typed); - NO_MOVE_SEMANTIC(Typed); - - [[nodiscard]] checker::Type *TsType() noexcept - { - return tsType_; - } - - [[nodiscard]] const checker::Type *TsType() const noexcept - { - return tsType_; - } - - void SetTsType(checker::Type *tsType) noexcept - { - tsType_ = tsType; - } - - bool IsTyped() const override - { - return true; - } - -protected: - explicit Typed(AstNodeType const type) : T(type) {} - explicit Typed(AstNodeType const type, ModifierFlags const flags) : T(type, flags) {} - - // NOTE: when cloning node its type is not copied but removed empty so that it can be re-checked further. - Typed(Typed const &other) : T(static_cast(other)) {} - -private: - checker::Type *tsType_ {}; -}; - template class Annotated : public T { public: @@ -597,40 +557,5 @@ private: TypeNode *typeAnnotation_ {}; }; -class TypedAstNode : public Typed { -public: - TypedAstNode() = delete; - ~TypedAstNode() override = default; - - NO_COPY_OPERATOR(TypedAstNode); - NO_MOVE_SEMANTIC(TypedAstNode); - -protected: - explicit TypedAstNode(AstNodeType const type) : Typed(type) {} - explicit TypedAstNode(AstNodeType const type, ModifierFlags const flags) : Typed(type, flags) {} - - TypedAstNode(TypedAstNode const &other) : Typed(static_cast const &>(other)) {} -}; - -class AnnotatedAstNode : public Annotated { -public: - AnnotatedAstNode() = delete; - ~AnnotatedAstNode() override = default; - - NO_COPY_OPERATOR(AnnotatedAstNode); - NO_MOVE_SEMANTIC(AnnotatedAstNode); - -protected: - explicit AnnotatedAstNode(AstNodeType const type, TypeNode *const typeAnnotation) - : Annotated(type, typeAnnotation) - { - } - explicit AnnotatedAstNode(AstNodeType const type) : Annotated(type) {} - explicit AnnotatedAstNode(AstNodeType const type, ModifierFlags const flags) : Annotated(type, flags) {} - - AnnotatedAstNode(AnnotatedAstNode const &other) : Annotated(static_cast const &>(other)) - { - } -}; } // namespace ark::es2panda::ir #endif diff --git a/ets2panda/ir/base/classElement.h b/ets2panda/ir/base/classElement.h index 8ef3b02dd7..cc70613431 100644 --- a/ets2panda/ir/base/classElement.h +++ b/ets2panda/ir/base/classElement.h @@ -17,6 +17,7 @@ #define ES2PANDA_PARSER_INCLUDE_AST_CLASS_ELEMENT_H #include "ir/statement.h" +#include "ir/typed.h" namespace ark::es2panda::ir { class Expression; diff --git a/ets2panda/ir/base/tsSignatureDeclaration.h b/ets2panda/ir/base/tsSignatureDeclaration.h index 8524c7516e..1ff286cc19 100644 --- a/ets2panda/ir/base/tsSignatureDeclaration.h +++ b/ets2panda/ir/base/tsSignatureDeclaration.h @@ -18,7 +18,7 @@ #include "ir/astNode.h" #include "ir/base/scriptFunctionSignature.h" -#include "ir/statement.h" +#include "ir/typed.h" namespace ark::es2panda::checker { class TSAnalyzer; diff --git a/ets2panda/ir/expression.h b/ets2panda/ir/expression.h index 9e982324c4..4ab79d03be 100644 --- a/ets2panda/ir/expression.h +++ b/ets2panda/ir/expression.h @@ -17,6 +17,7 @@ #define ES2PANDA_IR_EXPRESSION_H #include "ir/astNode.h" +#include "ir/typed.h" namespace ark::es2panda::ir { class Literal; diff --git a/ets2panda/ir/statement.h b/ets2panda/ir/statement.h index 398e28ea23..e4304eba19 100644 --- a/ets2panda/ir/statement.h +++ b/ets2panda/ir/statement.h @@ -42,44 +42,6 @@ protected: Statement(Statement const &other) : AstNode(static_cast(other)) {} }; -class TypedStatement : public Typed { -public: - TypedStatement() = delete; - ~TypedStatement() override = default; - - NO_COPY_OPERATOR(TypedStatement); - NO_MOVE_SEMANTIC(TypedStatement); - -protected: - explicit TypedStatement(AstNodeType type) : Typed(type) {}; - explicit TypedStatement(AstNodeType type, ModifierFlags flags) : Typed(type, flags) {}; - - TypedStatement(TypedStatement const &other) : Typed(static_cast const &>(other)) {} - - inline static checker::Type *const CHECKED = reinterpret_cast(0x01); -}; - -class AnnotatedStatement : public Annotated { -public: - AnnotatedStatement() = delete; - ~AnnotatedStatement() override = default; - - NO_COPY_OPERATOR(AnnotatedStatement); - NO_MOVE_SEMANTIC(AnnotatedStatement); - -protected: - explicit AnnotatedStatement(AstNodeType type, TypeNode *typeAnnotation) : Annotated(type, typeAnnotation) - { - } - - explicit AnnotatedStatement(AstNodeType type) : Annotated(type) {} - explicit AnnotatedStatement(AstNodeType type, ModifierFlags flags) : Annotated(type, flags) {} - - AnnotatedStatement(AnnotatedStatement const &other) - : Annotated(static_cast const &>(other)) - { - } -}; } // namespace ark::es2panda::ir #endif diff --git a/ets2panda/ir/ts/tsTypeAliasDeclaration.h b/ets2panda/ir/ts/tsTypeAliasDeclaration.h index f00e94e3f1..ba80fb5e4e 100644 --- a/ets2panda/ir/ts/tsTypeAliasDeclaration.h +++ b/ets2panda/ir/ts/tsTypeAliasDeclaration.h @@ -17,6 +17,7 @@ #define ES2PANDA_IR_TS_TYPE_ALIAS_DECLARATION_H #include "ir/statement.h" +#include "ir/typed.h" namespace ark::es2panda::varbinder { class Variable; diff --git a/ets2panda/ir/typed.h b/ets2panda/ir/typed.h new file mode 100644 index 0000000000..7bf9428a21 --- /dev/null +++ b/ets2panda/ir/typed.h @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_IR_TYPED_H +#define ES2PANDA_IR_TYPED_H + +#include "ir/astNode.h" +#include "ir/statement.h" + +namespace ark::es2panda::checker { +// NOLINTBEGIN(readability-redundant-declaration) +bool IsTypeError(Type const *tp); +[[noreturn]] void ThrowEmptyError(); +// NOLINTEND(readability-redundant-declaration) +} // namespace ark::es2panda::checker + +namespace ark::es2panda::ir { + +template +class Typed : public T { +public: + Typed() = delete; + ~Typed() override = default; + + NO_COPY_OPERATOR(Typed); + NO_MOVE_SEMANTIC(Typed); + + [[nodiscard]] checker::Type const *TsType() const + { + if (UNLIKELY(IsTypeError(tsType_))) { + checker::ThrowEmptyError(); + } + return tsType_; + } + + [[nodiscard]] checker::Type const *TsTypeOrError() const noexcept + { + return tsType_; + } + + [[nodiscard]] checker::Type *TsType() + { + if (UNLIKELY(IsTypeError(tsType_))) { + checker::ThrowEmptyError(); + } + return tsType_; + } + + [[nodiscard]] checker::Type *TsTypeOrError() noexcept + { + return tsType_; + } + + void SetTsType(checker::Type *tsType) noexcept + { + tsType_ = tsType; + } + + bool IsTyped() const override + { + return true; + } + +protected: + explicit Typed(AstNodeType const type) : T(type) {} + explicit Typed(AstNodeType const type, ModifierFlags const flags) : T(type, flags) {} + + // NOTE: when cloning node its type is not copied but removed empty so that it can be re-checked further. + Typed(Typed const &other) : T(static_cast(other)) {} + +private: + checker::Type *tsType_ {}; +}; + +class TypedAstNode : public Typed { +public: + TypedAstNode() = delete; + ~TypedAstNode() override = default; + + NO_COPY_OPERATOR(TypedAstNode); + NO_MOVE_SEMANTIC(TypedAstNode); + +protected: + explicit TypedAstNode(AstNodeType const type) : Typed(type) {} + explicit TypedAstNode(AstNodeType const type, ModifierFlags const flags) : Typed(type, flags) {} + + TypedAstNode(TypedAstNode const &other) : Typed(static_cast const &>(other)) {} +}; + +class AnnotatedAstNode : public Annotated { +public: + AnnotatedAstNode() = delete; + ~AnnotatedAstNode() override = default; + + NO_COPY_OPERATOR(AnnotatedAstNode); + NO_MOVE_SEMANTIC(AnnotatedAstNode); + +protected: + explicit AnnotatedAstNode(AstNodeType const type, TypeNode *const typeAnnotation) + : Annotated(type, typeAnnotation) + { + } + explicit AnnotatedAstNode(AstNodeType const type) : Annotated(type) {} + explicit AnnotatedAstNode(AstNodeType const type, ModifierFlags const flags) : Annotated(type, flags) {} + + AnnotatedAstNode(AnnotatedAstNode const &other) : Annotated(static_cast const &>(other)) + { + } +}; + +class TypedStatement : public Typed { +public: + TypedStatement() = delete; + ~TypedStatement() override = default; + + NO_COPY_OPERATOR(TypedStatement); + NO_MOVE_SEMANTIC(TypedStatement); + +protected: + explicit TypedStatement(AstNodeType type) : Typed(type) {}; + explicit TypedStatement(AstNodeType type, ModifierFlags flags) : Typed(type, flags) {}; + + TypedStatement(TypedStatement const &other) : Typed(static_cast const &>(other)) {} + + inline static checker::Type *const CHECKED = reinterpret_cast(0x01); +}; + +class AnnotatedStatement : public Annotated { +public: + AnnotatedStatement() = delete; + ~AnnotatedStatement() override = default; + + NO_COPY_OPERATOR(AnnotatedStatement); + NO_MOVE_SEMANTIC(AnnotatedStatement); + +protected: + explicit AnnotatedStatement(AstNodeType type, TypeNode *typeAnnotation) : Annotated(type, typeAnnotation) + { + } + + explicit AnnotatedStatement(AstNodeType type) : Annotated(type) {} + explicit AnnotatedStatement(AstNodeType type, ModifierFlags flags) : Annotated(type, flags) {} + + AnnotatedStatement(AnnotatedStatement const &other) + : Annotated(static_cast const &>(other)) + { + } +}; + +} // namespace ark::es2panda::ir + +#endif diff --git a/ets2panda/util/errorLogger.cpp b/ets2panda/util/errorLogger.cpp new file mode 100644 index 0000000000..6940c3eb21 --- /dev/null +++ b/ets2panda/util/errorLogger.cpp @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "errorLogger.h" + +namespace ark::es2panda::util { + +void ErrorLogger::Log(Error &&error, std::ostream &stream) +{ + stream << error.TypeString() << ": " << error.Message() << " [" << error.File() << ":" << error.Line() << ":" + << error.Col() << "]" << std::endl; + log_.push_back(std::move(error)); +} + +} // namespace ark::es2panda::util diff --git a/ets2panda/util/errorLogger.h b/ets2panda/util/errorLogger.h new file mode 100644 index 0000000000..74f9427345 --- /dev/null +++ b/ets2panda/util/errorLogger.h @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_UTIL_ERROR_LOGGER_H +#define ES2PANDA_UTIL_ERROR_LOGGER_H + +#include "es2panda.h" + +namespace ark::es2panda::util { + +class ErrorLogger { +public: + explicit ErrorLogger(ArenaAllocator *allocator) : log_(allocator->Adapter()) {} + + ArenaVector const &Log() const + { + return log_; + } + + bool IsAnyError() + { + return !log_.empty(); + } + + void Log(Error &&error, std::ostream &ostream = std::cerr); + +private: + ArenaVector log_; +}; + +} // namespace ark::es2panda::util + +#endif diff --git a/ets2panda/varbinder/variable.cpp b/ets2panda/varbinder/variable.cpp index d845860a74..6768c7b88a 100644 --- a/ets2panda/varbinder/variable.cpp +++ b/ets2panda/varbinder/variable.cpp @@ -15,11 +15,13 @@ #include "variable.h" +#include "checker/types/type.h" #include "varbinder/scope.h" #include namespace ark::es2panda::varbinder { + LocalVariable::LocalVariable(Decl *decl, VariableFlags flags) : Variable(decl, flags) { if (decl->IsConstDecl() || decl->IsReadonlyDecl()) { diff --git a/ets2panda/varbinder/variable.h b/ets2panda/varbinder/variable.h index ce9600fb3d..ff89914371 100644 --- a/ets2panda/varbinder/variable.h +++ b/ets2panda/varbinder/variable.h @@ -27,6 +27,10 @@ namespace ark::es2panda::checker { class Type; enum class PropertyType; +// NOLINTBEGIN(readability-redundant-declaration) +bool IsTypeError(Type const *tp); +[[noreturn]] void ThrowEmptyError(); +// NOLINTEND(readability-redundant-declaration) } // namespace ark::es2panda::checker namespace ark::es2panda::varbinder { @@ -81,7 +85,15 @@ public: return flags_; } - [[nodiscard]] checker::Type *TsType() const noexcept + [[nodiscard]] checker::Type *TsType() const + { + if (UNLIKELY(IsTypeError(tsType_))) { + checker::ThrowEmptyError(); + } + return tsType_; + } + + [[nodiscard]] checker::Type *TsTypeOrError() const noexcept { return tsType_; } -- Gitee