From 7e6ca1bbbb1f08eac06cf9e51a1f775d8ad09e7b Mon Sep 17 00:00:00 2001 From: Martin Sajti Date: Fri, 19 Jan 2024 16:18:50 +0100 Subject: [PATCH] Fix null coalescing operator fails with type parameter Refactor flag cleaning in ETSObjectType Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8YNOC Internal issue: #15170 Test: build, new checker tests Signed-off-by: Martin Sajti --- ets2panda/checker/ets/arithmetic.cpp | 26 +- ets2panda/checker/types/ets/etsObjectType.cpp | 20 +- .../null_coalescing_generic_1-expected.txt | 1853 +++++++++++++++++ .../ets/null_coalescing_generic_1.ets | 32 + ...null_coalescing_generic_1_neg-expected.txt | 600 ++++++ .../ets/null_coalescing_generic_1_neg.ets | 19 + 6 files changed, 2537 insertions(+), 13 deletions(-) create mode 100644 ets2panda/test/compiler/ets/null_coalescing_generic_1-expected.txt create mode 100644 ets2panda/test/compiler/ets/null_coalescing_generic_1.ets create mode 100644 ets2panda/test/compiler/ets/null_coalescing_generic_1_neg-expected.txt create mode 100644 ets2panda/test/compiler/ets/null_coalescing_generic_1_neg.ets diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 66b26f3539..de4631e7e3 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -503,9 +503,9 @@ std::tuple ETSChecker::CheckBinaryOperatorInstanceOf(lexer::Sour } Type *ETSChecker::CheckBinaryOperatorNullishCoalescing(ir::Expression *right, lexer::SourcePosition pos, - checker::Type *const leftType, checker::Type *const rightType) + checker::Type *leftType, checker::Type *rightType) { - if (!leftType->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + if (!leftType->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT) && !leftType->IsETSTypeParameter()) { ThrowTypeError("Left-hand side expression must be a reference type.", pos); } @@ -519,12 +519,30 @@ Type *ETSChecker::CheckBinaryOperatorNullishCoalescing(ir::Expression *right, le if (rightType->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { Relation()->SetNode(right); - auto boxedRightType = PrimitiveTypeAsETSBuiltinType(rightType); + auto *const boxedRightType = PrimitiveTypeAsETSBuiltinType(rightType); if (boxedRightType == nullptr) { ThrowTypeError("Invalid right-hand side expression", pos); } right->AddBoxingUnboxingFlags(GetBoxingFlag(boxedRightType)); - return FindLeastUpperBound(nonNullishLeftType, boxedRightType); + rightType = boxedRightType; + } + + if (rightType->IsETSNullType()) { + return CreateNullishType(nonNullishLeftType, TypeFlag::NULL_TYPE, Allocator(), Relation(), + GetGlobalTypesHolder()); + } + + if (rightType->IsETSUndefinedType()) { + return CreateNullishType(nonNullishLeftType, TypeFlag::UNDEFINED, Allocator(), Relation(), + GetGlobalTypesHolder()); + } + + if (nonNullishLeftType->IsETSTypeParameter()) { + nonNullishLeftType = nonNullishLeftType->AsETSTypeParameter()->GetConstraintType(); + } + + if (rightType->IsETSTypeParameter()) { + rightType = rightType->AsETSTypeParameter()->GetConstraintType(); } return FindLeastUpperBound(nonNullishLeftType, rightType); diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 4dfa0dba6f..b00de55a8b 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -392,16 +392,18 @@ void ETSObjectType::Identical(TypeRelation *relation, Type *other) IdenticalUptoNullability(relation, other); } -bool ETSObjectType::CheckIdenticalFlags(ETSObjectFlags target) const +bool ETSObjectType::CheckIdenticalFlags(const ETSObjectFlags target) const { - auto cleanedTargetFlags = static_cast(target & (~ETSObjectFlags::COMPLETELY_RESOLVED)); - cleanedTargetFlags &= ~ETSObjectFlags::INCOMPLETE_INSTANTIATION; - cleanedTargetFlags &= ~ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS; - cleanedTargetFlags &= ~ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY; - auto cleanedSelfFlags = static_cast(ObjectFlags() & (~ETSObjectFlags::COMPLETELY_RESOLVED)); - cleanedSelfFlags &= ~ETSObjectFlags::INCOMPLETE_INSTANTIATION; - cleanedSelfFlags &= ~ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS; - cleanedSelfFlags &= ~ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY; + constexpr auto FLAGS_TO_REMOVE = ETSObjectFlags::COMPLETELY_RESOLVED | ETSObjectFlags::INCOMPLETE_INSTANTIATION | + ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS | + ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY; + + auto cleanedTargetFlags = target; + cleanedTargetFlags &= ~FLAGS_TO_REMOVE; + + auto cleanedSelfFlags = ObjectFlags(); + cleanedSelfFlags &= ~FLAGS_TO_REMOVE; + return cleanedSelfFlags == cleanedTargetFlags; } diff --git a/ets2panda/test/compiler/ets/null_coalescing_generic_1-expected.txt b/ets2panda/test/compiler/ets/null_coalescing_generic_1-expected.txt new file mode 100644 index 0000000000..f309c04503 --- /dev/null +++ b/ets2panda/test/compiler/ets/null_coalescing_generic_1-expected.txt @@ -0,0 +1,1853 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 7 + }, + "end": { + "line": 23, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 11 + }, + "end": { + "line": 23, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 11 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 23, + "column": 11 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "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": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "data", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "exec", + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "pointer", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 24 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "R", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 39 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 11 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 19, + "column": 2 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "R", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 4 + }, + "end": { + "line": 19, + "column": 5 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 4 + }, + "end": { + "line": 19, + "column": 7 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 4 + }, + "end": { + "line": 19, + "column": 7 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + "constraint": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Uint8Array", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 35 + } + } + }, + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "R", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 36 + }, + "end": { + "line": 16, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 36 + }, + "end": { + "line": 16, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 38 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "exec", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 16 + } + } + }, + "arguments": [ + { + "type": "LogicalExpression", + "operator": "??", + "left": { + "type": "Identifier", + "name": "data", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "right": { + "type": "UndefinedLiteral", + "value": undefined, + "loc": { + "start": { + "line": 20, + "column": 25 + }, + "end": { + "line": 20, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 34 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 20, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 6 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 10 + }, + "end": { + "line": 24, + "column": 13 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "bar", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 10 + }, + "end": { + "line": 24, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "data", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 35 + }, + "end": { + "line": 24, + "column": 36 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 35 + }, + "end": { + "line": 24, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 35 + }, + "end": { + "line": 24, + "column": 37 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 29 + }, + "end": { + "line": 24, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 29 + }, + "end": { + "line": 24, + "column": 37 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "void", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 39 + }, + "end": { + "line": 24, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 39 + }, + "end": { + "line": 24, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 39 + }, + "end": { + "line": 24, + "column": 45 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 14 + }, + "end": { + "line": 24, + "column": 15 + } + } + }, + "constraint": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 24 + }, + "end": { + "line": 24, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 24 + }, + "end": { + "line": 24, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 24 + }, + "end": { + "line": 24, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 14 + }, + "end": { + "line": 24, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 24, + "column": 28 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c_class", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 25, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 25, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 25, + "column": 21 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 9 + }, + "end": { + "line": 25, + "column": 16 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 26 + }, + "end": { + "line": 25, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 26 + }, + "end": { + "line": 25, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 26 + }, + "end": { + "line": 25, + "column": 28 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 25, + "column": 22 + }, + "end": { + "line": 25, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 9 + }, + "end": { + "line": 25, + "column": 30 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 30 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "myvar", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 24 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 9 + }, + "end": { + "line": 26, + "column": 14 + } + } + }, + "init": { + "type": "LogicalExpression", + "operator": "??", + "left": { + "type": "Identifier", + "name": "data", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 25 + }, + "end": { + "line": 26, + "column": 29 + } + } + }, + "right": { + "type": "Identifier", + "name": "c_class", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 33 + }, + "end": { + "line": 26, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 25 + }, + "end": { + "line": 26, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 9 + }, + "end": { + "line": 26, + "column": 40 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 26, + "column": 5 + }, + "end": { + "line": 26, + "column": 41 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 44 + }, + "end": { + "line": 27, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 27, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 13 + }, + "end": { + "line": 27, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 1 + }, + "end": { + "line": 27, + "column": 2 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "baz", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 10 + }, + "end": { + "line": 29, + "column": 13 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "baz", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 10 + }, + "end": { + "line": 29, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a0", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 33 + }, + "end": { + "line": 29, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 33 + }, + "end": { + "line": 29, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 33 + }, + "end": { + "line": 29, + "column": 35 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 29 + }, + "end": { + "line": 29, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 29 + }, + "end": { + "line": 29, + "column": 35 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Integral", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 37 + }, + "end": { + "line": 29, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 37 + }, + "end": { + "line": 29, + "column": 47 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 37 + }, + "end": { + "line": 29, + "column": 47 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 14 + }, + "end": { + "line": 29, + "column": 15 + } + } + }, + "constraint": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 24 + }, + "end": { + "line": 29, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 24 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 24 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 14 + }, + "end": { + "line": 29, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 29, + "column": 13 + }, + "end": { + "line": 29, + "column": 28 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "myval", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Short", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 16 + }, + "end": { + "line": 30, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 16 + }, + "end": { + "line": 30, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 16 + }, + "end": { + "line": 30, + "column": 23 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 9 + }, + "end": { + "line": 30, + "column": 14 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 30, + "column": 24 + }, + "end": { + "line": 30, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 9 + }, + "end": { + "line": 30, + "column": 25 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 30, + "column": 5 + }, + "end": { + "line": 30, + "column": 26 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "LogicalExpression", + "operator": "??", + "left": { + "type": "Identifier", + "name": "a0", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 12 + }, + "end": { + "line": 31, + "column": 14 + } + } + }, + "right": { + "type": "Identifier", + "name": "myval", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 18 + }, + "end": { + "line": 31, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 12 + }, + "end": { + "line": 31, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 5 + }, + "end": { + "line": 31, + "column": 24 + } + } + } + ], + "loc": { + "start": { + "line": 29, + "column": 46 + }, + "end": { + "line": 32, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 13 + }, + "end": { + "line": 32, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 13 + }, + "end": { + "line": 32, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 32, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 33, + "column": 1 + } + } +} diff --git a/ets2panda/test/compiler/ets/null_coalescing_generic_1.ets b/ets2panda/test/compiler/ets/null_coalescing_generic_1.ets new file mode 100644 index 0000000000..c9eced6616 --- /dev/null +++ b/ets2panda/test/compiler/ets/null_coalescing_generic_1.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo( + data: C | undefined, + exec: (pointer: C | undefined) => R +): R { + return exec(data ?? undefined); +} + +class C {} +function bar(data: T): void { + let c_class: C = new C(); + let myvar: Object = data ?? c_class; +} + +function baz(a0: T): Integral { + let myval: Short = 2; + return a0 ?? myval; +} diff --git a/ets2panda/test/compiler/ets/null_coalescing_generic_1_neg-expected.txt b/ets2panda/test/compiler/ets/null_coalescing_generic_1_neg-expected.txt new file mode 100644 index 0000000000..d5d5d4f06c --- /dev/null +++ b/ets2panda/test/compiler/ets/null_coalescing_generic_1_neg-expected.txt @@ -0,0 +1,600 @@ +{ + "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": "fos", + "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": "fos", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10 + }, + "end": { + "line": 16, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a0", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 38 + }, + "end": { + "line": 16, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 38 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 38 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 34 + }, + "end": { + "line": 16, + "column": 40 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 34 + }, + "end": { + "line": 16, + "column": 40 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 16, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 16, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 42 + }, + "end": { + "line": 16, + "column": 45 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 15 + } + } + }, + "constraint": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Integral", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 33 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "myval", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Short", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 17, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 17, + "column": 23 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9 + }, + "end": { + "line": 17, + "column": 25 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "LogicalExpression", + "operator": "??", + "left": { + "type": "Identifier", + "name": "a0", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "right": { + "type": "Identifier", + "name": "myval", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 24 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 44 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 19, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 20, + "column": 1 + } + } +} +TypeError: Return statement type is not compatible with the enclosing method's return type. [null_coalescing_generic_1_neg.ets:18:12] diff --git a/ets2panda/test/compiler/ets/null_coalescing_generic_1_neg.ets b/ets2panda/test/compiler/ets/null_coalescing_generic_1_neg.ets new file mode 100644 index 0000000000..557016f5f1 --- /dev/null +++ b/ets2panda/test/compiler/ets/null_coalescing_generic_1_neg.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function fos(a0: T): T { + let myval: Short = 2; + return a0 ?? myval; +} -- Gitee