diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index c78ac64ba9fe7e3ef3070a9a058a2e7686fb89d1..66db3defb7efc139de9e4458f426054d01c5e19a 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -273,38 +273,58 @@ checker::Type *ETSChecker::CheckBinaryOperatorLogical(ir::Expression *left, ir:: UNREACHABLE(); } -std::tuple ETSChecker::CheckBinaryOperatorStrictEqual(ir::Expression *left, lexer::SourcePosition pos, - checker::Type *const left_type, - checker::Type *const right_type) +std::tuple ETSChecker::CheckBinaryOperatorEqual( + ir::Expression *left, ir::Expression *right, lexer::TokenType operation_type, lexer::SourcePosition pos, + checker::Type *const left_type, checker::Type *const right_type, Type *unboxed_l, Type *unboxed_r) { checker::Type *ts_type {}; - if (!(left_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) || - !(right_type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT))) { - ThrowTypeError("Both operands have to be reference types", pos); + checker::Type *op_type {}; + ts_type = GlobalETSBooleanType(); + + if ((left->IsNullLiteral() || right->IsNullLiteral()) && + (left->IsUndefinedLiteral() || right->IsUndefinedLiteral())) { + ts_type = CreateETSBooleanType(operation_type == lexer::TokenType::PUNCTUATOR_EQUAL || + operation_type == lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL); + + return {ts_type, GlobalETSUndefinedType()}; } - Relation()->SetNode(left); - if (!Relation()->IsCastableTo(left_type, right_type) && !Relation()->IsCastableTo(right_type, left_type)) { - ThrowTypeError("The operands of strict equality are not compatible with each other", pos); + if (IsReferenceType(left_type) && IsReferenceType(right_type)) { + // Reference Equality + + Relation()->SetNode(left); + if (!right->IsNullLiteral() && !left->IsNullLiteral() && !right->IsUndefinedLiteral() && + !left->IsUndefinedLiteral() && !Relation()->IsCastableTo(left_type, right_type) && + !Relation()->IsCastableTo(right_type, left_type)) { + if (unboxed_l == nullptr || unboxed_r == nullptr) { + ThrowTypeError("The operands of reference equality are not compatible with each other", pos); + } + + } else { + if (left_type->IsETSDynamicType() || right_type->IsETSDynamicType()) { + return CheckBinaryOperatorEqualDynamic(left, right, pos); + } + + return {ts_type, GlobalETSObjectType()}; + } } - ts_type = GlobalETSBooleanType(); - if (right_type->IsETSDynamicType() && left_type->IsETSDynamicType()) { - return {ts_type, GlobalBuiltinJSValueType()}; + + // Value Equality + auto positive_equal = operation_type == lexer::TokenType::PUNCTUATOR_EQUAL || + operation_type == lexer::TokenType::PUNCTUATOR_STRICT_EQUAL; + + if (left->IsNullLiteral() || right->IsNullLiteral() || left->IsUndefinedLiteral() || right->IsUndefinedLiteral()) { + op_type = left->IsNullLiteral() || left->IsUndefinedLiteral() ? right_type : left_type; + ts_type = CreateETSBooleanType(!positive_equal); + + return {ts_type, op_type}; } - return {ts_type, GlobalETSObjectType()}; -} -std::tuple ETSChecker::CheckBinaryOperatorEqual( - ir::Expression *left, ir::Expression *right, lexer::TokenType operation_type, lexer::SourcePosition pos, - checker::Type *const left_type, checker::Type *const right_type, Type *unboxed_l, Type *unboxed_r) -{ - checker::Type *ts_type {}; if (left_type->IsETSEnumType() && right_type->IsETSEnumType()) { if (!left_type->AsETSEnumType()->IsSameEnumType(right_type->AsETSEnumType())) { ThrowTypeError("Bad operand type, the types of the operands must be the same enum type.", pos); } - ts_type = GlobalETSBooleanType(); return {ts_type, left_type}; } @@ -313,35 +333,38 @@ std::tuple ETSChecker::CheckBinaryOperatorEqual( ThrowTypeError("Bad operand type, the types of the operands must be the same enum type.", pos); } - ts_type = GlobalETSBooleanType(); return {ts_type, left_type}; } - if (left_type->IsETSDynamicType() || right_type->IsETSDynamicType()) { - return CheckBinaryOperatorEqualDynamic(left, right, pos); - } + if (unboxed_l != nullptr && unboxed_r != nullptr) { + if (unboxed_l->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) && + unboxed_r->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN)) { + if (unboxed_l->HasTypeFlag(checker::TypeFlag::CONSTANT) && + unboxed_r->HasTypeFlag(checker::TypeFlag::CONSTANT)) { + const bool res = unboxed_l->AsETSBooleanType()->GetValue() == unboxed_r->AsETSBooleanType()->GetValue(); - if (IsReferenceType(left_type) && IsReferenceType(right_type)) { - ts_type = GlobalETSBooleanType(); - auto *op_type = GlobalETSObjectType(); - return {ts_type, op_type}; - } + ts_type = CreateETSBooleanType(positive_equal ? res : !res); + return {ts_type, op_type}; + } + op_type = GlobalETSBooleanType(); - if (unboxed_l != nullptr && unboxed_l->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) && unboxed_r != nullptr && - unboxed_r->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN)) { - if (unboxed_l->HasTypeFlag(checker::TypeFlag::CONSTANT) && - unboxed_r->HasTypeFlag(checker::TypeFlag::CONSTANT)) { - bool res = unboxed_l->AsETSBooleanType()->GetValue() == unboxed_r->AsETSBooleanType()->GetValue(); + } else if (unboxed_l->HasTypeFlag(checker::TypeFlag::CHAR) && unboxed_r->HasTypeFlag(checker::TypeFlag::CHAR)) { + if (unboxed_l->HasTypeFlag(checker::TypeFlag::CONSTANT) && + unboxed_r->HasTypeFlag(checker::TypeFlag::CONSTANT)) { + const bool res = unboxed_l->AsCharType()->GetValue() == unboxed_r->AsCharType()->GetValue(); - ts_type = CreateETSBooleanType(operation_type == lexer::TokenType::PUNCTUATOR_EQUAL ? res : !res); - return {ts_type, ts_type}; + ts_type = CreateETSBooleanType(positive_equal ? res : !res); + return {ts_type, op_type}; + } + op_type = GlobalCharType(); } - FlagExpressionWithUnboxing(left_type, unboxed_l, left); - FlagExpressionWithUnboxing(right_type, unboxed_r, right); + if (op_type != nullptr) { + FlagExpressionWithUnboxing(left_type, unboxed_l, left); + FlagExpressionWithUnboxing(right_type, unboxed_r, right); - ts_type = GlobalETSBooleanType(); - return {ts_type, ts_type}; + return {ts_type, op_type}; + } } return {nullptr, nullptr}; } @@ -524,9 +547,7 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, break; } case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: - case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: { - return CheckBinaryOperatorStrictEqual(left, pos, left_type, right_type); - } + case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { std::tuple res = diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index b1f99ba5be31df8752d5e681279a7fc6a67bfa98..bb94ce32723754770599def49551ca7acd0e166a 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1341,7 +1341,7 @@ bool ETSChecker::IsTypeBuiltinType(Type *type) bool ETSChecker::IsReferenceType(const Type *type) { return type->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT) || type->IsETSNullLike() || - type->IsETSStringType(); + type->IsETSFunctionType(); } const ir::AstNode *ETSChecker::FindJumpTarget(ir::AstNodeType node_type, const ir::AstNode *node, diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index b67c53ca99d7394fc16a3659e7ed87f311f20174..721f608ceadbfa341ca8f5b0a1b916f21d3b8198 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -51,6 +51,16 @@ void ETSFunctionType::Identical(TypeRelation *relation, Type *other) call_signatures_[0]->Identical(relation, other->AsETSFunctionType()->CallSignatures()[0]); } +void ETSFunctionType::Cast(TypeRelation *const relation, Type *target) +{ + if (!target->IsETSFunctionType()) { + relation->Result(false); + } + + Identical(relation, target); + // TODO(TorokG): Implement casting for function types as specification expects +} + bool ETSFunctionType::AssignmentSource(TypeRelation *relation, Type *target) { if (target->IsETSDynamicType()) { diff --git a/ets2panda/checker/types/ets/etsFunctionType.h b/ets2panda/checker/types/ets/etsFunctionType.h index 012c71251b13b3f46d34a13d7475d1613f580205..915982d7fbd294b57a324ea8e2c436c45e482eb7 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.h +++ b/ets2panda/checker/types/ets/etsFunctionType.h @@ -114,6 +114,7 @@ public: Signature *FirstAbstractSignature(); void ToString(std::stringstream &ss) const override; void Identical(TypeRelation *relation, Type *other) override; + void Cast(TypeRelation *relation, Type *target) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *global_types) override; diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 30b85196537359b852c43094dea5fbb21599e6f6..3b976d1cdbe630c811991f5ce958428608221e7f 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -1814,12 +1814,12 @@ void ETSGen::Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs) } case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: { Label *if_false = AllocLabel(); - BinaryStrictEquality(node, lhs, if_false); + BinaryEquality(node, lhs, if_false); break; } case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: { Label *if_false = AllocLabel(); - BinaryStrictEquality(node, lhs, if_false); + BinaryEquality(node, lhs, if_false); break; } case lexer::TokenType::PUNCTUATOR_LESS_THAN: { @@ -1921,11 +1921,11 @@ void ETSGen::Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, L { switch (op) { case lexer::TokenType::PUNCTUATOR_EQUAL: { - BinaryEqualityCondition(node, lhs, if_false); + BinaryEqualityCondition(node, lhs, if_false); break; } case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - BinaryEqualityCondition(node, lhs, if_false); + BinaryEqualityCondition(node, lhs, if_false); break; } case lexer::TokenType::PUNCTUATOR_LESS_THAN: { @@ -2062,62 +2062,6 @@ void ETSGen::EmitNullishException(const ir::AstNode *node) SetAccumulatorType(nullptr); } -void ETSGen::BinaryEqualityRefDynamic(const ir::AstNode *node, bool test_equal, VReg lhs, VReg rhs, Label *if_false) -{ - // NOTE: vpukhov. implement - LoadAccumulator(node, lhs); - if (test_equal) { - Ra().Emit(node, rhs, if_false); - } else { - Ra().Emit(node, rhs, if_false); - } -} - -void ETSGen::BinaryEqualityRef(const ir::AstNode *node, bool test_equal, VReg lhs, VReg rhs, Label *if_false) -{ - Label *if_true = AllocLabel(); - if (GetVRegType(lhs)->IsETSDynamicType() || GetVRegType(rhs)->IsETSDynamicType()) { - BinaryEqualityRefDynamic(node, test_equal, lhs, rhs, if_false); - return; - } - - if (GetVRegType(lhs)->IsETSNullLike() || GetVRegType(rhs)->IsETSNullLike()) { - LoadAccumulator(node, GetVRegType(lhs)->IsETSNullLike() ? rhs : lhs); - test_equal ? BranchIfNotNullish(node, if_false) : BranchIfNullish(node, if_false); - } else { - Label *if_lhs_nullish = AllocLabel(); - - auto const rhs_nullish_type = GetVRegType(rhs); - - LoadAccumulator(node, lhs); - BranchIfNullish(node, if_lhs_nullish); - ConvertToNonNullish(node); - StoreAccumulator(node, lhs); - - LoadAccumulator(node, rhs); - BranchIfNullish(node, test_equal ? if_false : if_true); - ConvertToNonNullish(node); - StoreAccumulator(node, rhs); - - LoadAccumulator(node, lhs); - if (GetVRegType(lhs)->IsETSStringType()) { - CallThisStatic1(node, lhs, Signatures::BUILTIN_STRING_EQUALS, rhs); - } else { - CallThisVirtual1(node, lhs, Signatures::BUILTIN_OBJECT_EQUALS, rhs); - } - test_equal ? BranchIfFalse(node, if_false) : BranchIfTrue(node, if_false); - JumpTo(node, if_true); - - SetLabel(node, if_lhs_nullish); - LoadAccumulator(node, rhs); - SetAccumulatorType(rhs_nullish_type); - test_equal ? BranchIfNotNullish(node, if_false) : BranchIfNullish(node, if_false); - // fallthrough - } - SetLabel(node, if_true); - SetAccumulatorType(nullptr); -} - void ETSGen::CompileStatements(const ArenaVector &statements) { for (const auto *stmt : statements) { diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 7ee98c5619fb31522e9ada5358b7e9b7f720d1c2..430f1887a71b3fdfeb46cabdc587cc91485d37c1 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -706,9 +706,6 @@ private: } } - void BinaryEqualityRef(const ir::AstNode *node, bool test_equal, VReg lhs, VReg rhs, Label *if_false); - void BinaryEqualityRefDynamic(const ir::AstNode *node, bool test_equal, VReg lhs, VReg rhs, Label *if_false); - template void BinaryNumberComparison(const ir::AstNode *node, VReg lhs, Label *if_false) { @@ -727,25 +724,30 @@ private: template void BinaryEquality(const ir::AstNode *node, VReg lhs, Label *if_false) { - BinaryEqualityCondition(node, lhs, if_false); + BinaryEqualityCondition(node, lhs, if_false); + ToBinaryResult(node, if_false); SetAccumulatorType(Checker()->GlobalETSBooleanType()); } - template + template void BinaryEqualityCondition(const ir::AstNode *node, VReg lhs, Label *if_false) { auto type_kind = checker::ETSChecker::TypeKind(target_type_); switch (type_kind) { - case checker::TypeFlag::ETS_OBJECT: case checker::TypeFlag::ETS_DYNAMIC_TYPE: { - RegScope rs(this); - VReg arg0 = AllocReg(); - StoreAccumulator(node, arg0); - BinaryEqualityRef(node, !std::is_same_v, lhs, arg0, if_false); + if (!std::is_same_v) { + Ra().Emit(node, lhs, if_false); + } else { + Ra().Emit(node, lhs, if_false); + } return; } + case checker::TypeFlag::ETS_OBJECT: { + Ra().Emit(node, lhs, if_false); + break; + } case checker::TypeFlag::DOUBLE: { BinaryFloatingPointComparison(node, lhs, if_false); break; @@ -776,19 +778,6 @@ private: SetAccumulatorType(Checker()->GlobalETSBooleanType()); } - template - void BinaryStrictEquality(const ir::AstNode *node, VReg lhs, Label *if_false) - { - if (GetAccumulatorType()->IsETSDynamicType() || GetVRegType(lhs)->IsETSDynamicType()) { - BinaryDynamicStrictEquality(node, lhs, if_false); - } else { - Ra().Emit(node, lhs, if_false); - } - - ToBinaryResult(node, if_false); - SetAccumulatorType(Checker()->GlobalETSBooleanType()); - } - template void BinaryRelation(const ir::AstNode *node, VReg lhs, Label *if_false) { diff --git a/ets2panda/test/compiler/ets/dynamic-equality-error-expected.txt b/ets2panda/test/compiler/ets/dynamic-equality-error-expected.txt index e573b947a51d29df9a43dbdabfa7e30dc0006759..af5f0e0befcf91f78ebef9afc4f55f7623fe70f3 100644 --- a/ets2panda/test/compiler/ets/dynamic-equality-error-expected.txt +++ b/ets2panda/test/compiler/ets/dynamic-equality-error-expected.txt @@ -1 +1 @@ -TypeError: The operands of strict equality are not compatible with each other [dynamic-equality-error.ets:29:9] +TypeError: The operands of reference equality are not compatible with each other [dynamic-equality-error.ets:29:9] diff --git a/ets2panda/test/compiler/ets/referenceEqualityNotCastable_n-expected.txt b/ets2panda/test/compiler/ets/referenceEqualityNotCastable_n-expected.txt index 43de9aa5285eea7c7dcc2b286473e4c33ea681bb..90b9aebe75b88cd58396f4dff5054de49133f4e7 100644 --- a/ets2panda/test/compiler/ets/referenceEqualityNotCastable_n-expected.txt +++ b/ets2panda/test/compiler/ets/referenceEqualityNotCastable_n-expected.txt @@ -929,4 +929,4 @@ } } } -TypeError: The operands of strict equality are not compatible with each other [referenceEqualityNotCastable_n.ets:22:11] +TypeError: The operands of reference equality are not compatible with each other [referenceEqualityNotCastable_n.ets:22:11] diff --git a/ets2panda/test/compiler/ets/referenceEqualityNotReference_n-expected.txt b/ets2panda/test/compiler/ets/referenceEqualityNotReference_n-expected.txt deleted file mode 100644 index b3de43ef5abc506550213390af2dee122a320479..0000000000000000000000000000000000000000 --- a/ets2panda/test/compiler/ets/referenceEqualityNotReference_n-expected.txt +++ /dev/null @@ -1,548 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 1 - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10 - }, - "end": { - "line": 16, - "column": 14 - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10 - }, - "end": { - "line": 16, - "column": 14 - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "void", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 18 - }, - "end": { - "line": 16, - "column": 22 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 18 - }, - "end": { - "line": 16, - "column": 24 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 18 - }, - "end": { - "line": 16, - "column": 24 - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "a", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 11 - }, - "end": { - "line": 17, - "column": 14 - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 7 - }, - "end": { - "line": 17, - "column": 8 - } - } - }, - "init": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 17, - "column": 17 - }, - "end": { - "line": 17, - "column": 18 - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 7 - }, - "end": { - "line": 17, - "column": 18 - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 17, - "column": 3 - }, - "end": { - "line": 17, - "column": 19 - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "b", - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 11 - }, - "end": { - "line": 18, - "column": 14 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 11 - }, - "end": { - "line": 18, - "column": 16 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 11 - }, - "end": { - "line": 18, - "column": 16 - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 7 - }, - "end": { - "line": 18, - "column": 8 - } - } - }, - "init": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 18, - "column": 17 - }, - "end": { - "line": 18, - "column": 18 - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 7 - }, - "end": { - "line": 18, - "column": 18 - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 18, - "column": 3 - }, - "end": { - "line": 18, - "column": 19 - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 7 - }, - "end": { - "line": 19, - "column": 8 - } - } - }, - "init": { - "type": "BinaryExpression", - "operator": "===", - "left": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 11 - }, - "end": { - "line": 19, - "column": 12 - } - } - }, - "right": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 17 - }, - "end": { - "line": 19, - "column": 18 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 11 - }, - "end": { - "line": 19, - "column": 18 - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 7 - }, - "end": { - "line": 19, - "column": 18 - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 19, - "column": 3 - }, - "end": { - "line": 19, - "column": 19 - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 23 - }, - "end": { - "line": 20, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 14 - }, - "end": { - "line": 20, - "column": 2 - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 14 - }, - "end": { - "line": 20, - "column": 2 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "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 - } - } -} -TypeError: Both operands have to be reference types [referenceEqualityNotReference_n.ets:19:11] diff --git a/ets2panda/test/compiler/ets/referenceEqualityNotReference_n.ets b/ets2panda/test/compiler/ets/referenceEqualityNotReference_n.ets deleted file mode 100644 index c0e489e70daa568c947e2b95885a5c219cca22e6..0000000000000000000000000000000000000000 --- a/ets2panda/test/compiler/ets/referenceEqualityNotReference_n.ets +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -function main(): void { - let a : int = 1; - let b : Int = 1; - let c = a === b; -} diff --git a/ets2panda/test/runtime/ets/array-object.ets b/ets2panda/test/runtime/ets/array-object.ets index 0228add708c70ff3c90a15eaccdabda4c6a1bd83..bb36d33e9ff6b9a3f996d22fee8b786d691f5e85 100644 --- a/ets2panda/test/runtime/ets/array-object.ets +++ b/ets2panda/test/runtime/ets/array-object.ets @@ -36,7 +36,9 @@ function main(): void { assert(arr1 == arr1); assert(arr1 == object_array); assert(arr1 == object); - assert(arr1 != arr2); + +// TypeError: The operands of reference equality are not compatible with each other +// assert(arr1 != arr2); assert(object.equals(arr1 as Object) == true); // Cannot cast type 'int[]' to 'Object[]' diff --git a/ets2panda/test/runtime/ets/dollar_dollar.ets b/ets2panda/test/runtime/ets/dollar_dollar.ets index 24ae08d8a24ffb0cff23686e67e101b940313de9..69ee93d97d24142507639ef2d59d35cf1fa7082f 100644 --- a/ets2panda/test/runtime/ets/dollar_dollar.ets +++ b/ets2panda/test/runtime/ets/dollar_dollar.ets @@ -18,6 +18,6 @@ function main() { let a = "aaaddd" let b = $$a } catch (e) { - assert(e.toString() == "$$ operator can only be used with ARKUI plugin") + assert(e.toString().equals("$$ operator can only be used with ARKUI plugin")) } } diff --git a/ets2panda/test/runtime/ets/notNull.ets b/ets2panda/test/runtime/ets/notNull.ets index 448280c9b28d7112a1693ecc92089fea0d69ebae..f1de266db5077512f703ea814987ae728f56a40d 100644 --- a/ets2panda/test/runtime/ets/notNull.ets +++ b/ets2panda/test/runtime/ets/notNull.ets @@ -51,7 +51,7 @@ function testLocalArray() : void { arr![2][1] = 42; - assert arr[2][1].toString() == "42" : "arr[2][1].toString() must be '42'"; + assert arr[2][1].toString().equals("42") : "arr[2][1].toString() must be '42'"; } function bar(arg : Int | null) : Int { diff --git a/ets2panda/test/runtime/ets/optional-chaining-lazy-evaluation.ets b/ets2panda/test/runtime/ets/optional-chaining-lazy-evaluation.ets index af36ee6e0e2918ed3077f07edfbe63184c06d90a..a91742072793f5f344f12af137195aa95d8867f9 100644 --- a/ets2panda/test/runtime/ets/optional-chaining-lazy-evaluation.ets +++ b/ets2panda/test/runtime/ets/optional-chaining-lazy-evaluation.ets @@ -24,7 +24,6 @@ function main(): void { let obj: Int[] = [11, 21, 31]; number = obj?.[x++]; - let a : Int = 11; - assert(number == a); + assert(number == obj?.[0]); assert(x == 1); // 1 as x was incremented } diff --git a/ets2panda/test/runtime/ets/referenceEquality.ets b/ets2panda/test/runtime/ets/referenceEquality.ets index a9a2b8247860c0154309e7fa0c7e2d34577fc73d..3570f64fc8db43e1c6b5373095b4c11ec7fdf23d 100644 --- a/ets2panda/test/runtime/ets/referenceEquality.ets +++ b/ets2panda/test/runtime/ets/referenceEquality.ets @@ -27,6 +27,13 @@ function ClassEquality(): void { assert (a === b); let c : A = new A(); assert (a !== c); + + assert(new A() != new A()) + let x1 = new A() + let x2 = x1 + assert(x1 == x2) + + assert(5 == new Int(5)) } @@ -37,6 +44,22 @@ function NullEquality(): void { let c : A | null = null; assert (c === null); assert (null === null); + + assert(5 != null) + assert("a string" != null) + assert(5.0 != null) + + let x: A | null = null + assert(x == null) + + assert(null != new Int(5)) + assert(new Double(5) != null) + + let i: Int|null = null + assert(i == null) + + let f: Int|null = 1 + assert(f != null) } @@ -46,6 +69,11 @@ function ArrayEquality(): void { assert (a === b); let c : int[] = [1, 2, 3]; assert (a !== c); + + assert([1, 2, 3] != [1, 2, 3]) + let y1 : Object[] = [] + let y2 = y1 + assert(y1 == y2) } function NumericEquality(): void { diff --git a/ets2panda/test/runtime/ets/string-assignment.ets b/ets2panda/test/runtime/ets/string-assignment.ets index 31953297e27c893f545a3821868de69fde308827..7ebbcf9ed518fb18e2defcc410ffb83cd8dd697a 100644 --- a/ets2panda/test/runtime/ets/string-assignment.ets +++ b/ets2panda/test/runtime/ets/string-assignment.ets @@ -16,5 +16,5 @@ function main(): void { let str = "constant string literal"; // init with a const string literal without "String" annotation -> str shouldn't be const str = "new string value"; - assert (str + "123" == "new string value123") + assert ((str + "123").equals("new string value123")) } diff --git a/ets2panda/test/runtime/ets/string-builder.ets b/ets2panda/test/runtime/ets/string-builder.ets index fb125050393d65df4e6aadd35fa0bb8efdce32c2..d944872d9a9595522da5a304620c93cae2b01466 100644 --- a/ets2panda/test/runtime/ets/string-builder.ets +++ b/ets2panda/test/runtime/ets/string-builder.ets @@ -27,10 +27,10 @@ function concatenate_float(prefix: String, number: float, suffix: String) : Stri function concatenate_compile_time() : void { let x: String = 5 + "10"; - assert x == "510"; + assert x.equals("510"); let y = 5 + "10"; - assert y == "510"; + assert y.equals("510"); } function main(): void { @@ -38,13 +38,13 @@ function main(): void { let a: String = "abc"; a += foo(123); - assert a == "abcd"; + assert a.equals("abcd"); assert count == 1; let const_str: String = 'str' + c'a'; - assert const_str == "stra"; + assert const_str.equals("stra"); - assert concatenate_float('x', 1.0 as float, "y") == "x1y"; + assert concatenate_float('x', 1.0 as float, "y").equals("x1y"); concatenate_compile_time(); } diff --git a/ets2panda/test/runtime/ets/top_level_02.ets b/ets2panda/test/runtime/ets/top_level_02.ets index 17b996c4de8ddfaeaeba86f05e9880d6ef93e8f0..c3de3615a74e34c52e27c55d006e35b57ffb871b 100644 --- a/ets2panda/test/runtime/ets/top_level_02.ets +++ b/ets2panda/test/runtime/ets/top_level_02.ets @@ -45,7 +45,7 @@ catch (e) { } assert(q == 8) -assert(s == "abccba") +assert(s.equals("abccba")) function main(): void { ETSGLOBAL.q = 1; @@ -54,13 +54,13 @@ function main(): void { assert(q == 30) assert(ETSGLOBAL.q == 1) - assert(s == "abccba") + assert(s.equals("abccba")) s = "def"; assert(s == "def") _$init$_(); - assert(s == "abccba") + assert(s.equals("abccba")) assert(q == 30) assert(ETSGLOBAL.q == 8) }