2222
2323namespace PackageFactory \ComponentEngine \TypeSystem \Narrower ;
2424
25- use PackageFactory \ComponentEngine \Definition \BinaryOperator ;
2625use PackageFactory \ComponentEngine \Parser \Ast \BinaryOperationNode ;
2726use PackageFactory \ComponentEngine \Parser \Ast \BooleanLiteralNode ;
2827use PackageFactory \ComponentEngine \Parser \Ast \ExpressionNode ;
2928use PackageFactory \ComponentEngine \Parser \Ast \IdentifierNode ;
30- use PackageFactory \ComponentEngine \Parser \ Ast \ NullLiteralNode ;
29+ use PackageFactory \ComponentEngine \TypeSystem \ Resolver \ Expression \ ExpressionTypeResolver ;
3130use PackageFactory \ComponentEngine \TypeSystem \ScopeInterface ;
31+ use PackageFactory \ComponentEngine \TypeSystem \Type \NullType \NullType ;
3232
3333/**
3434 * This class handles the analysis of identifier types that are used in a condition
@@ -68,23 +68,13 @@ public function narrowTypesOfSymbolsIn(ExpressionNode $expressionNode, TypeNarro
6868 $ second = $ binaryOperationNode ->operands ->rest [0 ];
6969
7070 if (
71- ($ first ->root instanceof BooleanLiteralNode
72- && ($ boolean = $ first ->root ) instanceof BooleanLiteralNode
73- // @phpstan-ignore-next-line
74- && $ other = $ second
75- ) || ($ second ->root instanceof BooleanLiteralNode
76- && ($ boolean = $ second ->root ) instanceof BooleanLiteralNode
77- // @phpstan-ignore-next-line
78- && $ other = $ first
71+ (($ boolean = $ first ->root ) instanceof BooleanLiteralNode
72+ && $ other = $ second // @phpstan-ignore-line
73+ ) || (($ boolean = $ second ->root ) instanceof BooleanLiteralNode
74+ && $ other = $ first // @phpstan-ignore-line
7975 )
8076 ) {
81- $ contextBasedOnOperator = match ($ binaryOperationNode ->operator ) {
82- BinaryOperator::EQUAL => $ context ,
83- BinaryOperator::NOT_EQUAL => $ context ->negate (),
84- default => null ,
85- };
86-
87- if (!$ contextBasedOnOperator ) {
77+ if (!$ contextBasedOnOperator = $ context ->basedOnBinaryOperator ($ binaryOperationNode ->operator )) {
8878 return NarrowedTypes::empty ();
8979 }
9080
@@ -94,30 +84,30 @@ public function narrowTypesOfSymbolsIn(ExpressionNode $expressionNode, TypeNarro
9484 );
9585 }
9686
97- // cases
98- // `nullableString === null ? "nullableString is null" : "nullableString is not null"`
99- // `nullableString !== null ? "nullableString is not null" : "nullableString is null"`
100- $ comparedIdentifierValueToNull = match (true ) {
101- // case `nullableString === null`
102- $ first ->root instanceof IdentifierNode && $ second ->root instanceof NullLiteralNode => $ first ->root ->value ,
103- // yodas case `null === nullableString`
104- $ first ->root instanceof NullLiteralNode && $ second ->root instanceof IdentifierNode => $ second ->root ->value ,
105- default => null
106- };
87+ $ expressionTypeResolver = (new ExpressionTypeResolver ($ this ->scope ));
88+ if (
89+ ($ expressionTypeResolver ->resolveTypeOf ($ first )->is (NullType::get ())
90+ && $ other = $ second // @phpstan-ignore-line
91+ ) || ($ expressionTypeResolver ->resolveTypeOf ($ second )->is (NullType::get ())
92+ && $ other = $ first // @phpstan-ignore-line
93+ )
94+ ) {
95+ if (!$ other ->root instanceof IdentifierNode) {
96+ return NarrowedTypes::empty ();
97+ }
98+ $ type = $ this ->scope ->lookupTypeFor ($ other ->root ->value );
99+ if (!$ type ) {
100+ return NarrowedTypes::empty ();
101+ }
107102
108- if ($ comparedIdentifierValueToNull === null ) {
109- return NarrowedTypes::empty ();
110- }
111- $ type = $ this ->scope ->lookupTypeFor ($ comparedIdentifierValueToNull );
112- if (!$ type ) {
113- return NarrowedTypes::empty ();
114- }
103+ if (!$ contextBasedOnOperator = $ context ->basedOnBinaryOperator ($ binaryOperationNode ->operator )) {
104+ return NarrowedTypes::empty ();
105+ }
115106
116- if ($ binaryOperationNode ->operator === BinaryOperator::EQUAL ) {
117- return NarrowedTypes::fromEntry ($ comparedIdentifierValueToNull , $ context ->negate ()->narrowType ($ type ));
118- }
119- if ($ binaryOperationNode ->operator === BinaryOperator::NOT_EQUAL ) {
120- return NarrowedTypes::fromEntry ($ comparedIdentifierValueToNull , $ context ->narrowType ($ type ));
107+ return NarrowedTypes::fromEntry (
108+ $ other ->root ->value ,
109+ $ contextBasedOnOperator ->negate ()->narrowType ($ type )
110+ );
121111 }
122112 }
123113
0 commit comments