2222
2323namespace PackageFactory \ComponentEngine \TypeSystem \Scope \ShallowScope ;
2424
25+ use PackageFactory \ComponentEngine \Definition \BinaryOperator ;
26+ use PackageFactory \ComponentEngine \Parser \Ast \BinaryOperationNode ;
2527use PackageFactory \ComponentEngine \Parser \Ast \ExpressionNode ;
2628use PackageFactory \ComponentEngine \Parser \Ast \IdentifierNode ;
29+ use PackageFactory \ComponentEngine \Parser \Ast \NullLiteralNode ;
2730use PackageFactory \ComponentEngine \Parser \Ast \TypeReferenceNode ;
2831use PackageFactory \ComponentEngine \TypeSystem \ScopeInterface ;
2932use PackageFactory \ComponentEngine \TypeSystem \Type \NullType \NullType ;
@@ -34,21 +37,42 @@ final class TernaryBranchScope implements ScopeInterface
3437{
3538 public function __construct (
3639 private readonly ExpressionNode $ conditionNode ,
37- private readonly TypeInterface $ conditionType ,
3840 private readonly bool $ isBranchLeft ,
3941 private readonly ScopeInterface $ parentScope
4042 ) {
4143 }
4244
4345 public function lookupTypeFor (string $ name ): ?TypeInterface
4446 {
47+ $ type = $ this ->parentScope ->lookupTypeFor ($ name );
48+
49+ if (!$ type instanceof UnionType || !$ type ->containsNull ()) {
50+ return $ type ;
51+ }
52+
4553 if ($ this ->conditionNode ->root instanceof IdentifierNode && $ this ->conditionNode ->root ->value === $ name ) {
46- if ($ this ->conditionType instanceof UnionType && $ this ->conditionType ->containsNull ()) {
47- return $ this ->isBranchLeft ? $ this ->conditionType ->withoutNull () : NullType::get ();
54+ return $ this ->isBranchLeft ? $ type ->withoutNull () : NullType::get ();
55+ }
56+
57+ if (($ binaryOperationNode = $ this ->conditionNode ->root ) instanceof BinaryOperationNode) {
58+ foreach ($ binaryOperationNode ->operands as $ operand ) {
59+ if (!$ operand ->root instanceof NullLiteralNode
60+ && !($ operand ->root instanceof IdentifierNode && $ operand ->root ->value === $ name )
61+ ) {
62+ return $ type ;
63+ }
64+ }
65+
66+ if ($ binaryOperationNode ->operator === BinaryOperator::EQUAL ) {
67+ return $ this ->isBranchLeft ? NullType::get () : $ type ->withoutNull ();
68+ }
69+
70+ if ($ binaryOperationNode ->operator === BinaryOperator::NOT_EQUAL ) {
71+ return $ this ->isBranchLeft ? $ type ->withoutNull () : NullType::get ();
4872 }
4973 }
5074
51- return $ this -> parentScope -> lookupTypeFor ( $ name ) ;
75+ return $ type ;
5276 }
5377
5478 public function resolveTypeReference (TypeReferenceNode $ typeReferenceNode ): TypeInterface
0 commit comments