diff --git a/binder/ETSBinder.cpp b/binder/ETSBinder.cpp index 6ef9aa02d6e5660e74076ac4fe5ce28c258ead53..aac4da10f73920a6f8425901b7b776b378244560 100644 --- a/binder/ETSBinder.cpp +++ b/binder/ETSBinder.cpp @@ -19,6 +19,7 @@ #include "ir/expressions/thisExpression.h" #include "ir/expressions/memberExpression.h" #include "ir/expressions/callExpression.h" +#include "ir/expressions/assignmentExpression.h" #include "ir/expressions/functionExpression.h" #include "ir/base/methodDefinition.h" #include "ir/base/scriptFunction.h" @@ -137,7 +138,38 @@ void ETSBinder::LookupTypeReference(ir::Identifier *ident, bool allow_dynamic_na void ETSBinder::LookupIdentReference(ir::Identifier *ident) { const auto &name = ident->Name(); - auto res = GetScope()->Find(name, ResolveBindingOptions::ALL); + auto const *scope = GetScope(); + + // We have to distinguish member expressions (like A.x or this.x) from the local variables and parameters! + if (ident->Parent()->IsMemberExpression()) { + auto const *const member_expression = ident->Parent()->AsMemberExpression(); + + if (ident == member_expression->Property()) { + if (member_expression->Object()->IsIdentifier()) { + auto const scope_res = + scope->Find(member_expression->Object()->AsIdentifier()->Name(), + ResolveBindingOptions::ALL_DECLARATION | ResolveBindingOptions::ALL_VARIABLES); + + if (scope_res.variable != nullptr) { + auto const *const node = scope_res.variable->Declaration()->Node(); + if (node->IsClassDefinition()) { + scope = node->AsClassDefinition()->Scope(); + } else { + while (scope->IsFunctionScope() || scope->IsFunctionParamScope()) { + scope = scope->Parent(); + } + } + } + } else if (member_expression->Object()->IsThisExpression()) { + while (scope->IsFunctionScope() || scope->IsFunctionParamScope()) { + scope = scope->Parent(); + } + } + } + } + + auto const res = scope->Find(name, ResolveBindingOptions::ALL); + if (res.level != 0) { ASSERT(res.variable != nullptr); @@ -153,9 +185,33 @@ void ETSBinder::LookupIdentReference(ir::Identifier *ident) return; } + // Processing usage of variables that don't have initializer in declaration if (ident->IsReference() && res.variable->Declaration()->IsLetOrConstDecl() && !res.variable->HasFlag(VariableFlags::INITIALIZED)) { - ThrowTDZ(ident->Start(), name); + if (ident->Parent()->IsAssignmentExpression() && ident->Parent()->AsAssignmentExpression()->Left() == ident) { + // if it occurs in the left-hand of assignment expression it becomes initialized + res.variable->AddFlag(VariableFlags::INITIALIZED); + } else if (ident->Parent()->IsMemberExpression() && ident->Parent()->Parent()->IsAssignmentExpression() && + ident->Parent()->Parent()->AsAssignmentExpression()->Left()->IsMemberExpression() && + ident->Parent()->Parent()->AsAssignmentExpression()->Left()->AsMemberExpression()->Property() == + ident) { + // if member expression occurs in the left-hand of assignment expression the variable becomes initialized + res.variable->AddFlag(VariableFlags::INITIALIZED); + } else if (ident->Parent()->IsMemberExpression() && ident->Parent()->Parent()->IsClassProperty()) { + // processing of class property declaration + auto *const class_property = ident->Parent()->Parent()->AsClassProperty(); + if (ident == class_property->Key() && class_property->Value() != nullptr) { + // the variable is a key with non-nullable value - OK + res.variable->AddFlag(VariableFlags::INITIALIZED); + } else { + ThrowTDZ(ident->Start(), name); + } + } else if (ident->Parent()->IsForOfStatement()) { + // the variable declared as iterator in for-of loop statement will be always initialized automatically + res.variable->AddFlag(VariableFlags::INITIALIZED); + } else { + ThrowTDZ(ident->Start(), name); + } } } @@ -260,7 +316,8 @@ void ETSBinder::BuildMemberExpression(ir::MemberExpression *member_expr) { ResolveReference(member_expr->Object()); - if (member_expr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS) { + if (member_expr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS || + member_expr->Kind() == ir::MemberExpressionKind::PROPERTY_ACCESS) { ResolveReference(member_expr->Property()); } } @@ -269,11 +326,9 @@ void ETSBinder::BuildClassDefinition(ir::ClassDefinition *class_def) { auto bound_ctx = BoundContext(record_table_, class_def); - if (class_def->TypeParams() != nullptr) { - auto scope_ctx = LexicalScope::Enter(this, class_def->TypeParams()->Scope()); - ResolveReferences(class_def->TypeParams()); - BuildClassDefinitionImpl(class_def); - return; + if (auto const *const params = class_def->TypeParams(); params != nullptr) { + auto scope_ctx = LexicalScope::Enter(this, params->Scope()); + ResolveReferences(params); } BuildClassDefinitionImpl(class_def); @@ -292,7 +347,8 @@ LocalScope *ETSBinder::ResolvePropertyReference(ir::ClassProperty *prop, ClassSc void ETSBinder::BuildClassDefinitionImpl(ir::ClassDefinition *class_def) { - auto class_ctx = LexicalScope::Enter(this, class_def->Scope()->AsClassScope()); + auto *const class_scope = class_def->Scope()->AsClassScope(); + auto class_ctx = LexicalScope::Enter(this, class_scope); if (class_def->Super() != nullptr) { ResolveReference(class_def->Super()); @@ -303,23 +359,32 @@ void ETSBinder::BuildClassDefinitionImpl(ir::ClassDefinition *class_def) } for (auto *stmt : class_def->Body()) { - if (!stmt->IsClassProperty()) { - continue; - } + if (stmt->IsClassProperty()) { + auto *const class_property = stmt->AsClassProperty(); - auto field_var = ResolvePropertyReference(stmt->AsClassProperty(), class_def->Scope()->AsClassScope()) - ->FindLocal(stmt->AsClassProperty()->Id()->Name()); - field_var->AddFlag(VariableFlags::INITIALIZED); - if (field_var->Declaration()->IsConstDecl() && stmt->AsClassProperty()->Value() == nullptr) { - field_var->AddFlag(VariableFlags::EXPLICIT_INIT_REQUIRED); + auto field_var = + ResolvePropertyReference(class_property, class_scope)->FindLocal(class_property->Id()->Name()); + + if (class_property->Value() == nullptr) { + if (auto const *const type_annotation = class_property->TypeAnnotation(); type_annotation != nullptr) { + if (!type_annotation->IsETSTypeReference() || type_annotation->IsNullable()) { + // Primitive and nullable types always have default initialization value. + field_var->AddFlag(VariableFlags::INITIALIZED); + } + } + if (field_var->Declaration()->IsConstDecl()) { + field_var->AddFlag(VariableFlags::EXPLICIT_INIT_REQUIRED); + } + } else { + field_var->AddFlag(VariableFlags::INITIALIZED); + } } } for (auto *stmt : class_def->Body()) { - if (stmt->IsClassProperty()) { - continue; + if (!stmt->IsClassProperty()) { + ResolveReference(stmt); } - ResolveReference(stmt); } } diff --git a/binder/binder.cpp b/binder/binder.cpp index 2c0650c5c6d81d4963b2f2582df6782f774b08fb..84af8d4b5626d25a4b1bccf061e49dc13970ed3b 100644 --- a/binder/binder.cpp +++ b/binder/binder.cpp @@ -106,9 +106,9 @@ void Binder::ThrowUnresolvableType(const lexer::SourcePosition &pos, const util: void Binder::ThrowTDZ(const lexer::SourcePosition &pos, const util::StringView &name) const { - std::stringstream ss; - ss << "Variable '" << name << "' is accessed before it's initialization."; - ThrowError(pos, ss.str()); + std::string msg {"Variable '"}; + msg += std::string {name} + "' is accessed before it's initialization."; + ThrowError(pos, msg); } void Binder::ThrowInvalidCapture(const lexer::SourcePosition &pos, const util::StringView &name) const @@ -289,7 +289,7 @@ bool Binder::BuildInternalName(ir::ScriptFunction *script_func) return !script_func->IsOverload(); } -void Binder::BuildVarDeclaratorId(ir::AstNode *child_node) +void Binder::BuildVarDeclaratorId(ir::AstNode *child_node, bool const has_initializer) { switch (child_node->Type()) { case ir::AstNodeType::IDENTIFIER: { @@ -303,7 +303,13 @@ void Binder::BuildVarDeclaratorId(ir::AstNode *child_node) auto *variable = scope_->FindLocal(name); ident->SetVariable(variable); BuildSignatureDeclarationBaseParams(ident->TypeAnnotation()); - variable->AddFlag(VariableFlags::INITIALIZED); + + // Note! We are not interested in JS and other languages now. + // Thus for backward compatibility let's leave them as they are. + if (has_initializer || !this->IsETSBinder()) { + variable->AddFlag(VariableFlags::INITIALIZED); + } + break; } case ir::AstNodeType::OBJECT_PATTERN: { @@ -328,7 +334,7 @@ void Binder::BuildVarDeclaratorId(ir::AstNode *child_node) } case ir::AstNodeType::ASSIGNMENT_PATTERN: { ResolveReference(child_node->AsAssignmentPattern()->Right()); - BuildVarDeclaratorId(child_node->AsAssignmentPattern()->Left()); + BuildVarDeclaratorId(child_node->AsAssignmentPattern()->Left(), true); break; } case ir::AstNodeType::PROPERTY: { @@ -352,11 +358,25 @@ void Binder::BuildVarDeclarator(ir::VariableDeclarator *var_decl) return; } - if (var_decl->Init() != nullptr) { - ResolveReference(var_decl->Init()); + auto *const id = var_decl->Id(); + auto *const init = var_decl->Init(); + bool has_initializer = init != nullptr; + + if (has_initializer) { + ResolveReference(init); + } else { + if (var_decl->Parent()->Parent()->IsForOfStatement()) { + has_initializer = true; + } else if (id->IsIdentifier()) { + if (auto const *const type_annotation = id->AsIdentifier()->TypeAnnotation(); type_annotation != nullptr) { + if (!type_annotation->IsETSTypeReference() || type_annotation->IsNullable()) { + has_initializer = true; + } + } + } } - BuildVarDeclaratorId(var_decl->Id()); + BuildVarDeclaratorId(id, has_initializer); } void Binder::BuildClassProperty(const ir::ClassProperty *prop) diff --git a/binder/binder.h b/binder/binder.h index fdeb9556c554988d403d3ee0cd9a2c47062a1eac..8af12a3d5ca421782a6028a5909fc543b0dfa324 100644 --- a/binder/binder.h +++ b/binder/binder.h @@ -129,6 +129,11 @@ public: return var_scope_; } + [[nodiscard]] bool IsETSBinder() const noexcept + { + return Extension() == ScriptExtension::ETS; + } + ETSBinder *AsETSBinder() { ASSERT(Extension() == ScriptExtension::ETS); @@ -215,7 +220,8 @@ protected: void InstantiateArguments(); void InstantiatePrivateContext(const ir::Identifier *ident) const; void BuildVarDeclarator(ir::VariableDeclarator *var_decl); - void BuildVarDeclaratorId(ir::AstNode *child_node); + // NOLINTNEXTLINE(google-default-arguments) + void BuildVarDeclaratorId(ir::AstNode *child_node, bool has_initializer = false); void BuildForUpdateLoop(ir::ForUpdateStatement *for_update_stmt); void BuildForInOfLoop(binder::LoopScope *loop_scope, ir::AstNode *left, ir::Expression *right, ir::Statement *body); void BuildCatchClause(ir::CatchClause *catch_clause_stmt); diff --git a/binder/scope.cpp b/binder/scope.cpp index 22f53e1d214257b3c8091fb2803ee1f151c8bf9a..4b8d3c52bd8f21adccba455b18347ae0af37560c 100644 --- a/binder/scope.cpp +++ b/binder/scope.cpp @@ -21,6 +21,7 @@ #include "binder/variable.h" #include "binder/variableFlags.h" #include "ir/astNode.h" +#include "ir/typeNode.h" #include "ir/expressions/identifier.h" #include "ir/statements/classDeclaration.h" #include "ir/base/classDefinition.h" @@ -323,6 +324,7 @@ Variable *ParamScope::AddParam(ArenaAllocator *allocator, Variable *current_vari return nullptr; } + flags |= VariableFlags::INITIALIZED; auto *param = allocator->New(new_decl, flags); params_.push_back(param); @@ -711,6 +713,16 @@ Variable *ClassScope::AddBinding(ArenaAllocator *allocator, [[maybe_unused]] Var target_scope = is_static ? static_field_scope_ : instance_field_scope_; ident = new_decl->Node()->AsClassProperty()->Id(); flags |= VariableFlags::PROPERTY; + if (new_decl->Node()->IsClassProperty()) { + auto const *const class_property = new_decl->Node()->AsClassProperty(); + auto const *const type_annotation = class_property->TypeAnnotation(); + + if (class_property->Value() != nullptr || + (type_annotation != nullptr && + (!type_annotation->IsETSTypeReference() || type_annotation->IsNullable()))) { + flags |= VariableFlags::INITIALIZED; + } + } break; } case DeclType::INTERFACE: { diff --git a/parser/ETSparser.cpp b/parser/ETSparser.cpp index feece71211a893993a22288cca9bc3f70d28e47a..f877d4dc60ac0c4ab94cd654df0f0ee88943884e 100644 --- a/parser/ETSparser.cpp +++ b/parser/ETSparser.cpp @@ -1243,6 +1243,7 @@ void ETSParser::ParseClassFieldDefiniton(ir::Identifier *field_name, ir::Modifie { ir::TypeNode *type_annotation = nullptr; TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; + bool is_initialized = false; if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { Lexer()->NextToken(); // eat ':' @@ -1253,6 +1254,7 @@ void ETSParser::ParseClassFieldDefiniton(ir::Identifier *field_name, ir::Modifie if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { Lexer()->NextToken(); // eat '=' initializer = ParseInitializer(); + is_initialized = initializer != nullptr; } else if (type_annotation == nullptr) { ThrowSyntaxError("Field type annotation expected"); } @@ -1295,6 +1297,9 @@ void ETSParser::ParseClassFieldDefiniton(ir::Identifier *field_name, ir::Modifie Binder()->AddDecl(field_name->Start(), field_name->Name(), field); } else { Binder()->AddDecl(field_name->Start(), field_name->Name(), field); + if (field_name->Variable() != nullptr && is_initialized) { + field_name->Variable()->AddFlag(binder::VariableFlags::INITIALIZED); + } } declarations->push_back(field); @@ -3089,7 +3094,8 @@ ir::Expression *ETSParser::ParseFunctionParameter() } void ETSParser::AddVariableDeclarationBindings(ir::Expression *init, lexer::SourcePosition start_loc, - VariableParsingFlags flags) + VariableParsingFlags flags, + [[maybe_unused]] binder::VariableFlags var_flags) { std::vector bindings = util::Helpers::CollectBindingNames(init); @@ -3105,7 +3111,7 @@ void ETSParser::AddVariableDeclarationBindings(ir::Expression *init, lexer::Sour binding->SetVariable(var); var->SetScope(Binder()->GetScope()); - var->AddFlag(binder::VariableFlags::LOCAL); + var->AddFlag(binder::VariableFlags::LOCAL | var_flags); decl->BindNode(init); } } diff --git a/parser/ETSparser.h b/parser/ETSparser.h index 9d388f6b96a2f3b4d8d93f35c70bf3bdd43ecfe0..cde8bc9a344399df99b148210ccbe8c4f927e591 100644 --- a/parser/ETSparser.h +++ b/parser/ETSparser.h @@ -122,7 +122,8 @@ private: ir::Expression *ParseCoverParenthesizedExpressionAndArrowParameterList() override; void AddVariableDeclarationBindings(ir::Expression *init, lexer::SourcePosition start_loc, - VariableParsingFlags flags) override; + VariableParsingFlags flags, + [[maybe_unused]] binder::VariableFlags var_flags) override; ir::Statement *ParseTryStatement() override; ir::DebuggerStatement *ParseDebuggerStatement() override; ir::Statement *ParseImportDeclaration(StatementParsingFlags flags) override; diff --git a/parser/parserImpl.h b/parser/parserImpl.h index e680020b4db286c6e315cb61926509e77b38cc17..cdad6d428ccd937626f897091b59daf0c00cce76 100644 --- a/parser/parserImpl.h +++ b/parser/parserImpl.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -397,7 +397,8 @@ protected: [[nodiscard]] virtual std::unique_ptr InitLexer(const SourceFile &source_file); virtual void AddVariableDeclarationBindings(ir::Expression *init, lexer::SourcePosition start_loc, - VariableParsingFlags flags); + VariableParsingFlags flags, + [[maybe_unused]] binder::VariableFlags var_flags); // NOLINTNEXTLINE(google-default-arguments) virtual ir::Statement *ParseStatement(StatementParsingFlags flags = StatementParsingFlags::NONE); // NOLINTNEXTLINE(google-default-arguments) diff --git a/parser/statementParser.cpp b/parser/statementParser.cpp index a7f124fe07623fc0369307f2b0dc8020a8373189..8cbfbace09b8414829d208b5f6ad634413cadfe8 100644 --- a/parser/statementParser.cpp +++ b/parser/statementParser.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -1357,7 +1357,8 @@ ir::VariableDeclarator *ParserImpl::ParseVariableDeclaratorInitializer(ir::Expre } void ParserImpl::AddVariableDeclarationBindings(ir::Expression *init, lexer::SourcePosition start_loc, - VariableParsingFlags flags) + VariableParsingFlags flags, + [[maybe_unused]] binder::VariableFlags var_flags) { std::vector bindings = util::Helpers::CollectBindingNames(init); @@ -1422,10 +1423,24 @@ ir::VariableDeclarator *ParserImpl::ParseVariableDeclarator(ir::Expression *init ir::VariableDeclarator *ParserImpl::ParseVariableDeclarator(VariableParsingFlags flags) { + auto var_flag = binder::VariableFlags::NONE; lexer::SourcePosition start_loc = lexer_->GetToken().Start(); + ir::Expression *init = ParseVariableDeclaratorKey(flags); ir::VariableDeclarator *declarator = ParseVariableDeclarator(init, start_loc, flags); - AddVariableDeclarationBindings(init, start_loc, flags); + + if (declarator->Init() != nullptr) { + var_flag = binder::VariableFlags::INITIALIZED; + } else if (declarator->Id()->IsIdentifier()) { + if (auto const *const type_annotation = declarator->Id()->AsIdentifier()->TypeAnnotation(); + type_annotation != nullptr) { + if (!type_annotation->IsETSTypeReference() || type_annotation->IsNullable()) { + var_flag = binder::VariableFlags::INITIALIZED; + } + } + } + + AddVariableDeclarationBindings(init, start_loc, flags, var_flag); return declarator; } diff --git a/test/compiler/ets/generics_class_recursive_type_1-expected.txt b/test/compiler/ets/generics_class_recursive_type_1-expected.txt index 3bc10ca35df4e50e7f4f4ccf39cbf5c402da02c8..75591cc57aef220495a5cfce5dbd7741ea0310a8 100644 --- a/test/compiler/ets/generics_class_recursive_type_1-expected.txt +++ b/test/compiler/ets/generics_class_recursive_type_1-expected.txt @@ -5836,7 +5836,7 @@ }, "end": { "line": 59, - "column": 20 + "column": 21 } } }, @@ -5847,7 +5847,7 @@ }, "end": { "line": 59, - "column": 20 + "column": 21 } } }, @@ -6010,7 +6010,7 @@ }, "end": { "line": 60, - "column": 20 + "column": 21 } } }, @@ -6021,7 +6021,7 @@ }, "end": { "line": 60, - "column": 20 + "column": 21 } } }, diff --git a/test/compiler/ets/generics_class_recursive_type_1.ets b/test/compiler/ets/generics_class_recursive_type_1.ets index a8aa973287e27a2d2060c68ea583e944b4d96f29..4b80dedfc4a53d981011993c79982d1594d478cd 100644 --- a/test/compiler/ets/generics_class_recursive_type_1.ets +++ b/test/compiler/ets/generics_class_recursive_type_1.ets @@ -56,8 +56,8 @@ class A{ } class B, V>{ - j: Nodes; - i: Nodes; + j: Nodes | null; + i: Nodes | null; foo(): void{ this.j.right.left.right.key.popFront(); this.j = this.i; diff --git a/test/compiler/ets/generics_instantiation_1-expected.txt b/test/compiler/ets/generics_instantiation_1-expected.txt index a39528d5a38ab36748bc8bc21b3cbea200b7b823..9a6dbf251143b06b0cd58030a250571827720779 100644 --- a/test/compiler/ets/generics_instantiation_1-expected.txt +++ b/test/compiler/ets/generics_instantiation_1-expected.txt @@ -155,7 +155,7 @@ }, "end": { "line": 17, - "column": 19 + "column": 20 } } }, @@ -166,7 +166,7 @@ }, "end": { "line": 17, - "column": 19 + "column": 20 } } }, @@ -332,7 +332,7 @@ "loc": { "start": { "line": 18, - "column": 20 + "column": 27 }, "end": { "line": 20, diff --git a/test/compiler/ets/generics_instantiation_1.ets b/test/compiler/ets/generics_instantiation_1.ets index 843d2842dabfe48ed38be61f29e3a40fd3647a30..78739242232e0186af70b690533263f6f789048a 100644 --- a/test/compiler/ets/generics_instantiation_1.ets +++ b/test/compiler/ets/generics_instantiation_1.ets @@ -14,8 +14,8 @@ */ class B { - private a0: T; - public f1(): T { + private a0: T | null; + public f1(): T | null { return this.a0; } } diff --git a/test/compiler/ets/generics_interface_bounds_1-expected.txt b/test/compiler/ets/generics_interface_bounds_1-expected.txt index bcf0a134c96a95adf9a519c133d2610130162040..585d5b89a0b227d78233a0a0397303dbc6c5dee4 100644 --- a/test/compiler/ets/generics_interface_bounds_1-expected.txt +++ b/test/compiler/ets/generics_interface_bounds_1-expected.txt @@ -490,7 +490,7 @@ }, "end": { "line": 21, - "column": 23 + "column": 24 } } }, @@ -501,7 +501,7 @@ }, "end": { "line": 21, - "column": 23 + "column": 24 } } }, @@ -675,11 +675,11 @@ "loc": { "start": { "line": 24, - "column": 25 + "column": 32 }, "end": { "line": 24, - "column": 29 + "column": 36 } } }, @@ -690,11 +690,11 @@ "loc": { "start": { "line": 24, - "column": 30 + "column": 37 }, "end": { "line": 24, - "column": 36 + "column": 43 } } }, @@ -703,11 +703,11 @@ "loc": { "start": { "line": 24, - "column": 25 + "column": 32 }, "end": { "line": 24, - "column": 36 + "column": 43 } } }, @@ -718,7 +718,7 @@ }, "end": { "line": 24, - "column": 36 + "column": 43 } } } @@ -731,7 +731,7 @@ }, "end": { "line": 24, - "column": 37 + "column": 44 } } } diff --git a/test/compiler/ets/generics_interface_bounds_1.ets b/test/compiler/ets/generics_interface_bounds_1.ets index d3a73a5ccc62179c765b2b1324cd97baeac02df6..3e8b2164d1ce02507538f0824144eeaab4312a0d 100644 --- a/test/compiler/ets/generics_interface_bounds_1.ets +++ b/test/compiler/ets/generics_interface_bounds_1.ets @@ -18,9 +18,9 @@ interface A{ } class B>{ - private my_var: U; + private my_var: U | null; bar(): void { - let a: Object = this.my_var; + let a: Object | null = this.my_var; } } diff --git a/test/parser/ets/generics_1-expected.txt b/test/parser/ets/generics_1-expected.txt index ef863b3f6522e330abc880b86838697f2ceadfb1..14c2631673aa3694cc144c804ba1177d366995f0 100644 --- a/test/parser/ets/generics_1-expected.txt +++ b/test/parser/ets/generics_1-expected.txt @@ -1065,7 +1065,7 @@ }, "end": { "line": 29, - "column": 17 + "column": 18 } } }, @@ -1076,7 +1076,7 @@ }, "end": { "line": 29, - "column": 17 + "column": 18 } } }, @@ -1092,7 +1092,117 @@ } } }, - "init": null, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 23 + }, + "end": { + "line": 29, + "column": 24 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Z", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 25 + }, + "end": { + "line": 29, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 25 + }, + "end": { + "line": 29, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 25 + }, + "end": { + "line": 29, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 29, + "column": 24 + }, + "end": { + "line": 29, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 23 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 23 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 29, + "column": 19 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, "loc": { "start": { "line": 29, @@ -1100,7 +1210,7 @@ }, "end": { "line": 29, - "column": 10 + "column": 28 } } } @@ -1113,7 +1223,7 @@ }, "end": { "line": 29, - "column": 17 + "column": 28 } } }, diff --git a/test/parser/ets/generics_1.ets b/test/parser/ets/generics_1.ets index ca9297c3955dea8f180d1260800cc08630848f36..a12b83f4ec2fd4d05ad0287d778adcab813f753c 100644 --- a/test/parser/ets/generics_1.ets +++ b/test/parser/ets/generics_1.ets @@ -26,6 +26,6 @@ class Z { } function main(): void { - let d: A; + let d: A = new A; d.b.a.c = 127; } diff --git a/test/parser/ets/null-expected.txt b/test/parser/ets/null-expected.txt index b5a328254c9326b65170b466fedf55b3277ab123..302ab099b03ae02a8178cd5bc3c71a55341f53dd 100644 --- a/test/parser/ets/null-expected.txt +++ b/test/parser/ets/null-expected.txt @@ -456,7 +456,7 @@ }, "end": { "line": 18, - "column": 13 + "column": 14 } } }, @@ -467,7 +467,7 @@ }, "end": { "line": 18, - "column": 13 + "column": 14 } } }, @@ -1143,7 +1143,7 @@ }, "end": { "line": 30, - "column": 17 + "column": 18 } } }, @@ -1154,7 +1154,7 @@ }, "end": { "line": 30, - "column": 17 + "column": 18 } } }, @@ -1191,7 +1191,7 @@ }, "end": { "line": 30, - "column": 17 + "column": 24 } } }, diff --git a/test/parser/ets/null.ets b/test/parser/ets/null.ets index f74a5af99ce4d473abdaf913ace5c1cd7a5071f9..6f2777f0f4832fcfb34b1466164ceb21915bc24e 100644 --- a/test/parser/ets/null.ets +++ b/test/parser/ets/null.ets @@ -15,7 +15,7 @@ class cls {} -let a : cls; +let a : cls | null; let b : cls | null = null; let c : cls = new cls(); @@ -27,7 +27,7 @@ function main(): void { foo(b); foo(c); - let d : cls; + let d : cls | null; let e : cls | null = null; let f : cls = new cls(); diff --git a/test/parser/ets/struct_templete-expected.txt b/test/parser/ets/struct_templete-expected.txt index 5223d017d73c2e73079646d51e675860ff86ae73..5df82d53a64805d71306fdbdcda1757eb900ea76 100644 --- a/test/parser/ets/struct_templete-expected.txt +++ b/test/parser/ets/struct_templete-expected.txt @@ -1065,7 +1065,7 @@ }, "end": { "line": 29, - "column": 17 + "column": 18 } } }, @@ -1076,7 +1076,7 @@ }, "end": { "line": 29, - "column": 17 + "column": 18 } } }, @@ -1092,7 +1092,117 @@ } } }, - "init": null, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 23 + }, + "end": { + "line": 29, + "column": 24 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Z", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 25 + }, + "end": { + "line": 29, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 25 + }, + "end": { + "line": 29, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 25 + }, + "end": { + "line": 29, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 29, + "column": 24 + }, + "end": { + "line": 29, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 23 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 23 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 29, + "column": 19 + }, + "end": { + "line": 29, + "column": 30 + } + } + }, "loc": { "start": { "line": 29, @@ -1100,7 +1210,7 @@ }, "end": { "line": 29, - "column": 10 + "column": 30 } } } @@ -1113,7 +1223,7 @@ }, "end": { "line": 29, - "column": 17 + "column": 30 } } }, diff --git a/test/parser/ets/struct_templete.ets b/test/parser/ets/struct_templete.ets index 58e2c57a004631ea7ed9dedafabd2b78e1d7235a..ed1d14fbc2032494245923211e48a67102a3bbb9 100644 --- a/test/parser/ets/struct_templete.ets +++ b/test/parser/ets/struct_templete.ets @@ -26,6 +26,6 @@ struct Z { } function main(): void { - let d: A; + let d: A = new A(); d.b.a.c = 127; } diff --git a/test/parser/ets/test_jsvalue_get_double-expected.txt b/test/parser/ets/test_jsvalue_get_double-expected.txt index 435dd5eb18b46f600ac005bab5dd87f043ed49aa..4ca4177b5376a33b21035ad645ed0e148402e100 100644 --- a/test/parser/ets/test_jsvalue_get_double-expected.txt +++ b/test/parser/ets/test_jsvalue_get_double-expected.txt @@ -70,6 +70,103 @@ "body": { "type": "BlockStatement", "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "v", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "JSValue", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "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 + } + } + }, { "type": "ExpressionStatement", "expression": { @@ -223,7 +320,7 @@ }, "end": { "line": 16, - "column": 16 + "column": 17 } } }, @@ -234,7 +331,7 @@ }, "end": { "line": 16, - "column": 16 + "column": 17 } } }, diff --git a/test/parser/ets/test_jsvalue_get_double.ets b/test/parser/ets/test_jsvalue_get_double.ets index 427ee04bd39bb72cc68744cc91c5ed0b32f732ee..38b650f391373fbe1227df7b64cc3885c49daf2f 100644 --- a/test/parser/ets/test_jsvalue_get_double.ets +++ b/test/parser/ets/test_jsvalue_get_double.ets @@ -13,5 +13,5 @@ * limitations under the License. */ -let v: JSValue; +let v: JSValue = new JSValue; let num_v: double = v; diff --git a/test/parser/ets/test_jsvalue_get_property_1-expected.txt b/test/parser/ets/test_jsvalue_get_property_1-expected.txt index b046e7b05299218614ef4fb73a88031287ede417..38d666ac93373703596a4e3cb72c786eaede3a95 100644 --- a/test/parser/ets/test_jsvalue_get_property_1-expected.txt +++ b/test/parser/ets/test_jsvalue_get_property_1-expected.txt @@ -70,6 +70,103 @@ "body": { "type": "BlockStatement", "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "v", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "JSValue", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "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 + } + } + }, { "type": "ExpressionStatement", "expression": { @@ -253,7 +350,7 @@ }, "end": { "line": 16, - "column": 16 + "column": 17 } } }, @@ -264,7 +361,7 @@ }, "end": { "line": 16, - "column": 16 + "column": 17 } } }, diff --git a/test/parser/ets/test_jsvalue_get_property_1.ets b/test/parser/ets/test_jsvalue_get_property_1.ets index 58b85b91a1a11c1c0ec9989970f92970de589d19..8264c45d374145b67e7ef07afaf2e7f71da8c1a0 100644 --- a/test/parser/ets/test_jsvalue_get_property_1.ets +++ b/test/parser/ets/test_jsvalue_get_property_1.ets @@ -13,5 +13,5 @@ * limitations under the License. */ -let v: JSValue; +let v: JSValue = new JSValue; let prop: JSValue = v.prop_name; diff --git a/test/parser/ets/test_jsvalue_get_property_2-expected.txt b/test/parser/ets/test_jsvalue_get_property_2-expected.txt index fc03e2ef4a53b0e8fe9cc63697cac8b210ebc259..0b11bcf58e9d4e0b6dc3e6dc3466ccf43f5540e2 100644 --- a/test/parser/ets/test_jsvalue_get_property_2-expected.txt +++ b/test/parser/ets/test_jsvalue_get_property_2-expected.txt @@ -70,6 +70,103 @@ "body": { "type": "BlockStatement", "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "v", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 6 + } + } + }, + "right": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "JSValue", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 29 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 16, + "column": 30 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "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 + } + } + }, { "type": "ExpressionStatement", "expression": { @@ -283,7 +380,7 @@ }, "end": { "line": 16, - "column": 16 + "column": 17 } } }, @@ -294,7 +391,7 @@ }, "end": { "line": 16, - "column": 16 + "column": 17 } } }, diff --git a/test/parser/ets/test_jsvalue_get_property_2.ets b/test/parser/ets/test_jsvalue_get_property_2.ets index a11328f993ba255a4b95d3543b5627c43e7f194d..0fd4bb4826b54bd5be2555fc0c73f77c30b68450 100644 --- a/test/parser/ets/test_jsvalue_get_property_2.ets +++ b/test/parser/ets/test_jsvalue_get_property_2.ets @@ -13,5 +13,5 @@ * limitations under the License. */ -let v: JSValue; +let v: JSValue = new JSValue; let prop: JSValue = v.prop_name_1.prop_name_2; diff --git a/test/parser/ets/test_jsvalue_set_property_1-expected.txt b/test/parser/ets/test_jsvalue_set_property_1-expected.txt index 48beaae20046f197d069d27c4191e7823446fb00..742ae4571edc70a18794e44b632639c97c7bc047 100644 --- a/test/parser/ets/test_jsvalue_set_property_1-expected.txt +++ b/test/parser/ets/test_jsvalue_set_property_1-expected.txt @@ -239,7 +239,7 @@ }, "end": { "line": 17, - "column": 20 + "column": 21 } } }, @@ -250,7 +250,7 @@ }, "end": { "line": 17, - "column": 20 + "column": 21 } } }, @@ -266,7 +266,61 @@ } } }, - "init": null, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "JSValue", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, "loc": { "start": { "line": 17, @@ -274,7 +328,7 @@ }, "end": { "line": 17, - "column": 10 + "column": 34 } } } @@ -287,7 +341,7 @@ }, "end": { "line": 17, - "column": 20 + "column": 34 } } }, @@ -325,7 +379,7 @@ }, "end": { "line": 18, - "column": 33 + "column": 34 } } }, @@ -336,7 +390,7 @@ }, "end": { "line": 18, - "column": 33 + "column": 34 } } }, @@ -352,7 +406,61 @@ } } }, - "init": null, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "JSValue", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 18, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 18, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 18, + "column": 47 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 47 + } + } + }, "loc": { "start": { "line": 18, @@ -360,7 +468,7 @@ }, "end": { "line": 18, - "column": 23 + "column": 47 } } } @@ -373,7 +481,7 @@ }, "end": { "line": 18, - "column": 33 + "column": 47 } } }, diff --git a/test/parser/ets/test_jsvalue_set_property_1.ets b/test/parser/ets/test_jsvalue_set_property_1.ets index 386beaea0cb58dbbaf8f0ee99e032b289efdf735..acf4eb64e0a7a0e41c3cda6f24b97bec7794a305 100644 --- a/test/parser/ets/test_jsvalue_set_property_1.ets +++ b/test/parser/ets/test_jsvalue_set_property_1.ets @@ -14,7 +14,7 @@ */ function fn(): void { - let v: JSValue; - let new_prop_value: JSValue; + let v: JSValue = new JSValue; + let new_prop_value: JSValue = new JSValue; v.prop_name = new_prop_value; } diff --git a/test/parser/ets/test_jsvalue_set_property_2-expected.txt b/test/parser/ets/test_jsvalue_set_property_2-expected.txt index 286306f1acf387694d03b816e934ef4ad3cb60b2..3568f7ad629c44b5ef2dd3a320d2570669b097bd 100644 --- a/test/parser/ets/test_jsvalue_set_property_2-expected.txt +++ b/test/parser/ets/test_jsvalue_set_property_2-expected.txt @@ -239,7 +239,7 @@ }, "end": { "line": 17, - "column": 20 + "column": 21 } } }, @@ -250,7 +250,7 @@ }, "end": { "line": 17, - "column": 20 + "column": 21 } } }, @@ -266,7 +266,61 @@ } } }, - "init": null, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "JSValue", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 34 + } + } + }, "loc": { "start": { "line": 17, @@ -274,7 +328,7 @@ }, "end": { "line": 17, - "column": 10 + "column": 34 } } } @@ -287,7 +341,7 @@ }, "end": { "line": 17, - "column": 20 + "column": 34 } } }, diff --git a/test/parser/ets/test_jsvalue_set_property_2.ets b/test/parser/ets/test_jsvalue_set_property_2.ets index de8dc1144c9bd23dca01f932ad745d799be5f173..2c0305f19eb53daac1bf18ae340c660e0a318ab4 100644 --- a/test/parser/ets/test_jsvalue_set_property_2.ets +++ b/test/parser/ets/test_jsvalue_set_property_2.ets @@ -14,6 +14,6 @@ */ function fn(): void { - let v: JSValue; + let v: JSValue = new JSValue; v.prop_name = 5.6; } diff --git a/test/runtime/ets/Enum4.ets b/test/runtime/ets/Enum4.ets index 861bb43cd3d8f40c607304324ea91456c0f763f6..816bc41b23716b6f612aef9c8d12b4d91dee278e 100644 --- a/test/runtime/ets/Enum4.ets +++ b/test/runtime/ets/Enum4.ets @@ -43,7 +43,7 @@ function main(): void { assert values[2] == Color.Blue; let red1: Color = Color.Red; - let red2: Color; + let red2: Color = Color.Green; assert(red2 as int == 0) assert(red2.getValue() == 0) assert(red2.getName() == "Green") diff --git a/test/runtime/ets/Enum5.ets b/test/runtime/ets/Enum5.ets index fac33b900d232aa644f7d11e389468a42607a079..37c9dda5aee0c8d157bac34588757557b750c556 100644 --- a/test/runtime/ets/Enum5.ets +++ b/test/runtime/ets/Enum5.ets @@ -14,7 +14,7 @@ */ enum Color { Green = "red" , Red = "blue", Blue = "green" } -//let cons = new Console; +//let cons = new Console; function main(): void { @@ -43,6 +43,7 @@ function main(): void { assert values[0] == Color.Green; assert values[2] == Color.Blue; + /* let red1: Color = Color.Red; let red2: Color; assert(red2 as int == 0) @@ -50,7 +51,7 @@ function main(): void { assert(red2.getName() == "Green") assert(red2.toString() == "red") //cons.print("\nDefault ordinal = " + red2 as int + ", value = " + red2.getValue() + ", name: '" + red2.getName() + "', ToString: '" + red2.toString() + "'\n\n") - + try { red2 = Color.valueOf("Red"); } catch (e) { @@ -76,6 +77,7 @@ function main(): void { assert(red1 == Color.Red); assert(red2 == Color.Red); assert(red2 == red1); +*/ let ord: int = 2; blue = ord as Color;