From 8bec5fc743826fd4f9195deb8af7b97bfb004fc0 Mon Sep 17 00:00:00 2001 From: Jack Robertson Date: Mon, 26 Jul 2021 08:50:12 +0100 Subject: [PATCH 1/3] Add expected behaviour tests --- tests/TypeReconciliation/ReconcilerTest.php | 2 ++ tests/TypeReconciliation/TypeTest.php | 30 +++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/tests/TypeReconciliation/ReconcilerTest.php b/tests/TypeReconciliation/ReconcilerTest.php index a328306d516..d122def8c55 100644 --- a/tests/TypeReconciliation/ReconcilerTest.php +++ b/tests/TypeReconciliation/ReconcilerTest.php @@ -110,6 +110,8 @@ public function providerTestReconcilation(): array 'notSomeClassWithSomeClassPipeBool' => ['bool', '!SomeClass', 'SomeClass|bool'], 'notSomeClassWithSomeClassPipeNull' => ['null', '!SomeClass', 'SomeClass|null'], 'notSomeClassWithAPipeB' => ['B', '!A', 'A|B'], + 'notDateTimeWithDateTimeInterface' => ['DateTimeImmutable', '!DateTime', 'DateTimeInterface'], + 'notDateTimeImmutableWithDateTimeInterface' => ['DateTime', '!DateTimeImmutable', 'DateTimeInterface'], 'myObjectWithSomeClassPipeBool' => ['SomeClass', 'SomeClass', 'SomeClass|bool'], 'myObjectWithAPipeB' => ['A', 'A', 'A|B'], diff --git a/tests/TypeReconciliation/TypeTest.php b/tests/TypeReconciliation/TypeTest.php index 1565fbbd593..b354065c7be 100644 --- a/tests/TypeReconciliation/TypeTest.php +++ b/tests/TypeReconciliation/TypeTest.php @@ -1073,6 +1073,36 @@ function foo($arr): void { */ function consume($input): void{}' ], + 'notDateTimeWithDateTimeInterface' => [ + 'add($dateInterval); + + return $dateTime; + } else { + return $dateTime->add($dateInterval); + } + } + ', + ], + 'notDateTimeImmutableWithDateTimeInterface' => [ + 'add($dateInterval); + } else { + $dateTime->add($dateInterval); + + return $dateTime; + } + } + ', + ], ]; } From 0e6160c1e0a302e68fd06ee1db7d3683cb2671f5 Mon Sep 17 00:00:00 2001 From: Jack Robertson Date: Mon, 26 Jul 2021 13:41:52 +0100 Subject: [PATCH 2/3] Update DateTimeInterface type reconciliation --- .../Internal/Type/NegatedAssertionReconciler.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Psalm/Internal/Type/NegatedAssertionReconciler.php b/src/Psalm/Internal/Type/NegatedAssertionReconciler.php index bcd0fb30707..f091c75b598 100644 --- a/src/Psalm/Internal/Type/NegatedAssertionReconciler.php +++ b/src/Psalm/Internal/Type/NegatedAssertionReconciler.php @@ -208,6 +208,21 @@ public static function reconcile( return $existing_var_type; } + if (!$is_equality + && ($assertion === 'DateTime' || $assertion === 'DateTimeImmutable') + && isset($existing_var_atomic_types['DateTimeInterface']) + ) { + $existing_var_type->removeType('DateTimeInterface'); + + if ($assertion === 'DateTime') { + $existing_var_type->addType(new TNamedObject('DateTimeImmutable')); + } else { + $existing_var_type->addType(new TNamedObject('DateTime')); + } + + return $existing_var_type; + } + if (strtolower($assertion) === 'traversable' && isset($existing_var_atomic_types['iterable']) ) { From c8574a63477b92574d7354550ce2ae3d928eb0d7 Mon Sep 17 00:00:00 2001 From: Jack Robertson Date: Mon, 26 Jul 2021 13:56:15 +0100 Subject: [PATCH 3/3] Simplify FQNs --- tests/TypeReconciliation/TypeTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/TypeReconciliation/TypeTest.php b/tests/TypeReconciliation/TypeTest.php index b354065c7be..75f42828c4f 100644 --- a/tests/TypeReconciliation/TypeTest.php +++ b/tests/TypeReconciliation/TypeTest.php @@ -1075,10 +1075,10 @@ function consume($input): void{}' ], 'notDateTimeWithDateTimeInterface' => [ 'add($dateInterval); return $dateTime; @@ -1090,10 +1090,10 @@ function foo(\DateTimeInterface $dateTime): DateTimeInterface { ], 'notDateTimeImmutableWithDateTimeInterface' => [ 'add($dateInterval); } else { $dateTime->add($dateInterval);