@@ -1645,6 +1645,10 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
1645
1645
if ($ leftExpr instanceof AlwaysRememberedExpr) {
1646
1646
$ unwrappedLeftExpr = $ leftExpr ->getExpr ();
1647
1647
}
1648
+ $ unwrappedRightExpr = $ rightExpr ;
1649
+ if ($ rightExpr instanceof AlwaysRememberedExpr) {
1650
+ $ unwrappedRightExpr = $ rightExpr ->getExpr ();
1651
+ }
1648
1652
$ rightType = $ scope ->getType ($ rightExpr );
1649
1653
if (
1650
1654
$ context ->true ()
@@ -1695,124 +1699,151 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
1695
1699
1696
1700
$ specifiedType = $ this ->specifyTypesForConstantBinaryExpression ($ exprNode , $ constantType , $ context , $ scope , $ rootExpr );
1697
1701
if ($ specifiedType !== null ) {
1702
+ if ($ exprNode instanceof AlwaysRememberedExpr) {
1703
+ $ specifiedType ->unionWith (
1704
+ $ this ->create ($ exprNode ->getExpr (), $ constantType , $ context , false , $ scope , $ rootExpr ),
1705
+ );
1706
+ }
1698
1707
return $ specifiedType ;
1699
1708
}
1700
1709
}
1701
1710
1702
- if ($ rightExpr instanceof AlwaysRememberedExpr) {
1703
- $ rightExpr = $ rightExpr ->getExpr ();
1704
- }
1705
-
1706
- if ($ leftExpr instanceof AlwaysRememberedExpr) {
1707
- $ leftExpr = $ leftExpr ->getExpr ();
1708
- }
1709
-
1710
1711
if (
1711
1712
$ context ->true () &&
1712
- $ leftExpr instanceof ClassConstFetch &&
1713
- $ leftExpr ->class instanceof Expr &&
1714
- $ leftExpr ->name instanceof Node \Identifier &&
1715
- $ rightExpr instanceof ClassConstFetch &&
1713
+ $ unwrappedLeftExpr instanceof ClassConstFetch &&
1714
+ $ unwrappedLeftExpr ->class instanceof Expr &&
1715
+ $ unwrappedLeftExpr ->name instanceof Node \Identifier &&
1716
+ $ unwrappedRightExpr instanceof ClassConstFetch &&
1716
1717
$ rightType instanceof ConstantStringType &&
1717
- strtolower ($ leftExpr ->name ->toString ()) === 'class '
1718
+ strtolower ($ unwrappedLeftExpr ->name ->toString ()) === 'class '
1718
1719
) {
1719
1720
return $ this ->specifyTypesInCondition (
1720
1721
$ scope ,
1721
1722
new Instanceof_ (
1722
- $ leftExpr ->class ,
1723
+ $ unwrappedLeftExpr ->class ,
1723
1724
new Name ($ rightType ->getValue ()),
1724
1725
),
1725
1726
$ context ,
1726
1727
$ rootExpr ,
1727
- )->unionWith ($ this ->create ($ expr -> left , $ rightType , $ context , false , $ scope , $ rootExpr ));
1728
+ )->unionWith ($ this ->create ($ leftExpr , $ rightType , $ context , false , $ scope , $ rootExpr ));
1728
1729
}
1729
1730
1730
1731
$ leftType = $ scope ->getType ($ leftExpr );
1731
1732
if (
1732
1733
$ context ->true () &&
1733
- $ rightExpr instanceof ClassConstFetch &&
1734
- $ rightExpr ->class instanceof Expr &&
1735
- $ rightExpr ->name instanceof Node \Identifier &&
1736
- $ leftExpr instanceof ClassConstFetch &&
1734
+ $ unwrappedRightExpr instanceof ClassConstFetch &&
1735
+ $ unwrappedRightExpr ->class instanceof Expr &&
1736
+ $ unwrappedRightExpr ->name instanceof Node \Identifier &&
1737
+ $ unwrappedLeftExpr instanceof ClassConstFetch &&
1737
1738
$ leftType instanceof ConstantStringType &&
1738
- strtolower ($ rightExpr ->name ->toString ()) === 'class '
1739
+ strtolower ($ unwrappedRightExpr ->name ->toString ()) === 'class '
1739
1740
) {
1740
1741
return $ this ->specifyTypesInCondition (
1741
1742
$ scope ,
1742
1743
new Instanceof_ (
1743
- $ rightExpr ->class ,
1744
+ $ unwrappedRightExpr ->class ,
1744
1745
new Name ($ leftType ->getValue ()),
1745
1746
),
1746
1747
$ context ,
1747
1748
$ rootExpr ,
1748
- )->unionWith ($ this ->create ($ expr -> right , $ leftType , $ context , false , $ scope , $ rootExpr ));
1749
+ )->unionWith ($ this ->create ($ rightExpr , $ leftType , $ context , false , $ scope , $ rootExpr ));
1749
1750
}
1750
1751
1751
1752
if ($ context ->false ()) {
1752
1753
$ identicalType = $ scope ->getType ($ expr );
1753
1754
if ($ identicalType instanceof ConstantBooleanType) {
1754
1755
$ never = new NeverType ();
1755
1756
$ contextForTypes = $ identicalType ->getValue () ? $ context ->negate () : $ context ;
1756
- $ leftTypes = $ this ->create ($ expr ->left , $ never , $ contextForTypes , false , $ scope , $ rootExpr );
1757
- $ rightTypes = $ this ->create ($ expr ->right , $ never , $ contextForTypes , false , $ scope , $ rootExpr );
1757
+ $ leftTypes = $ this ->create ($ leftExpr , $ never , $ contextForTypes , false , $ scope , $ rootExpr )
1758
+ ->unionWith ($ this ->create ($ unwrappedLeftExpr , $ never , $ contextForTypes , false , $ scope , $ rootExpr ));
1759
+ $ rightTypes = $ this ->create ($ rightExpr , $ never , $ contextForTypes , false , $ scope , $ rootExpr )
1760
+ ->unionWith ($ this ->create ($ unwrappedRightExpr , $ never , $ contextForTypes , false , $ scope , $ rootExpr ));
1758
1761
return $ leftTypes ->unionWith ($ rightTypes );
1759
1762
}
1760
1763
}
1761
1764
1762
1765
$ types = null ;
1763
- $ exprLeftType = $ scope ->getType ($ expr ->left );
1764
- $ exprRightType = $ scope ->getType ($ expr ->right );
1765
1766
if (
1766
- count ($ exprLeftType ->getFiniteTypes ()) === 1
1767
- || ($ exprLeftType ->isConstantValue ()->yes () && !$ exprRightType ->equals ($ exprLeftType ) && $ exprRightType ->isSuperTypeOf ($ exprLeftType )->yes ())
1767
+ count ($ leftType ->getFiniteTypes ()) === 1
1768
+ || ($ leftType ->isConstantValue ()->yes () && !$ rightType ->equals ($ leftType ) && $ rightType ->isSuperTypeOf ($ leftType )->yes ())
1768
1769
) {
1769
1770
$ types = $ this ->create (
1770
- $ expr -> right ,
1771
- $ exprLeftType ,
1771
+ $ rightExpr ,
1772
+ $ leftType ,
1772
1773
$ context ,
1773
1774
false ,
1774
1775
$ scope ,
1775
1776
$ rootExpr ,
1776
1777
);
1778
+ if ($ rightExpr instanceof AlwaysRememberedExpr) {
1779
+ $ types = $ types ->unionWith ($ this ->create (
1780
+ $ unwrappedRightExpr ,
1781
+ $ leftType ,
1782
+ $ context ,
1783
+ false ,
1784
+ $ scope ,
1785
+ $ rootExpr ,
1786
+ ));
1787
+ }
1777
1788
}
1778
1789
if (
1779
- count ($ exprRightType ->getFiniteTypes ()) === 1
1780
- || ($ exprRightType ->isConstantValue ()->yes () && !$ exprLeftType ->equals ($ exprRightType ) && $ exprLeftType ->isSuperTypeOf ($ exprRightType )->yes ())
1790
+ count ($ rightType ->getFiniteTypes ()) === 1
1791
+ || ($ rightType ->isConstantValue ()->yes () && !$ leftType ->equals ($ rightType ) && $ leftType ->isSuperTypeOf ($ rightType )->yes ())
1781
1792
) {
1782
- $ leftType = $ this ->create (
1783
- $ expr -> left ,
1784
- $ exprRightType ,
1793
+ $ leftTypes = $ this ->create (
1794
+ $ leftExpr ,
1795
+ $ rightType ,
1785
1796
$ context ,
1786
1797
false ,
1787
1798
$ scope ,
1788
1799
$ rootExpr ,
1789
1800
);
1801
+ if ($ leftExpr instanceof AlwaysRememberedExpr) {
1802
+ $ leftTypes = $ leftTypes ->unionWith ($ this ->create (
1803
+ $ unwrappedLeftExpr ,
1804
+ $ rightType ,
1805
+ $ context ,
1806
+ false ,
1807
+ $ scope ,
1808
+ $ rootExpr ,
1809
+ ));
1810
+ }
1790
1811
if ($ types !== null ) {
1791
- $ types = $ types ->unionWith ($ leftType );
1812
+ $ types = $ types ->unionWith ($ leftTypes );
1792
1813
} else {
1793
- $ types = $ leftType ;
1814
+ $ types = $ leftTypes ;
1794
1815
}
1795
1816
}
1796
1817
1797
1818
if ($ types !== null ) {
1798
1819
return $ types ;
1799
1820
}
1800
1821
1801
- $ leftExprString = $ this ->exprPrinter ->printExpr ($ expr -> left );
1802
- $ rightExprString = $ this ->exprPrinter ->printExpr ($ expr -> right );
1822
+ $ leftExprString = $ this ->exprPrinter ->printExpr ($ unwrappedLeftExpr );
1823
+ $ rightExprString = $ this ->exprPrinter ->printExpr ($ unwrappedRightExpr );
1803
1824
if ($ leftExprString === $ rightExprString ) {
1804
- if (!$ expr -> left instanceof Expr \Variable || !$ expr -> right instanceof Expr \Variable) {
1825
+ if (!$ unwrappedLeftExpr instanceof Expr \Variable || !$ unwrappedRightExpr instanceof Expr \Variable) {
1805
1826
return new SpecifiedTypes ([], [], false , [], $ rootExpr );
1806
1827
}
1807
1828
}
1808
1829
1809
1830
if ($ context ->true ()) {
1810
- $ leftTypes = $ this ->create ($ expr ->left , $ exprRightType , $ context , false , $ scope , $ rootExpr );
1811
- $ rightTypes = $ this ->create ($ expr ->right , $ exprLeftType , $ context , false , $ scope , $ rootExpr );
1831
+ $ leftTypes = $ this ->create ($ leftExpr , $ rightType , $ context , false , $ scope , $ rootExpr );
1832
+ $ rightTypes = $ this ->create ($ rightExpr , $ leftType , $ context , false , $ scope , $ rootExpr );
1833
+ if ($ leftExpr instanceof AlwaysRememberedExpr) {
1834
+ $ leftTypes = $ leftTypes ->unionWith (
1835
+ $ this ->create ($ unwrappedLeftExpr , $ rightType , $ context , false , $ scope , $ rootExpr ),
1836
+ );
1837
+ }
1838
+ if ($ rightExpr instanceof AlwaysRememberedExpr) {
1839
+ $ rightTypes = $ rightTypes ->unionWith (
1840
+ $ this ->create ($ unwrappedRightExpr , $ leftType , $ context , false , $ scope , $ rootExpr ),
1841
+ );
1842
+ }
1812
1843
return $ leftTypes ->unionWith ($ rightTypes );
1813
1844
} elseif ($ context ->false ()) {
1814
- return $ this ->create ($ expr -> left , $ exprLeftType , $ context , false , $ scope , $ rootExpr )->normalize ($ scope )
1815
- ->intersectWith ($ this ->create ($ expr -> right , $ exprRightType , $ context , false , $ scope , $ rootExpr )->normalize ($ scope ));
1845
+ return $ this ->create ($ leftExpr , $ leftType , $ context , false , $ scope , $ rootExpr )->normalize ($ scope )
1846
+ ->intersectWith ($ this ->create ($ rightExpr , $ rightType , $ context , false , $ scope , $ rootExpr )->normalize ($ scope ));
1816
1847
}
1817
1848
1818
1849
return new SpecifiedTypes ([], [], false , [], $ rootExpr );
0 commit comments