@@ -67,13 +67,18 @@ private function tearDown(): void
6767
6868 private function parseType (): Ast \Node
6969 {
70- $ type = $ this ->parseAtomic ();
70+ if ($ this ->tokenType === Lexer::TOKEN_NULLABLE ) {
71+ $ type = $ this ->parseNullable ();
7172
72- if ($ this ->tokenType === Lexer::TOKEN_UNION ) {
73- $ type = $ this ->parseUnion ($ type );
73+ } else {
74+ $ type = $ this ->parseAtomic ();
75+
76+ if ($ this ->tokenType === Lexer::TOKEN_UNION ) {
77+ $ type = $ this ->parseUnion ($ type );
7478
75- } elseif ($ this ->tokenType === Lexer::TOKEN_INTERSECTION ) {
76- $ type = $ this ->parseIntersection ($ type );
79+ } elseif ($ this ->tokenType === Lexer::TOKEN_INTERSECTION ) {
80+ $ type = $ this ->parseIntersection ($ type );
81+ }
7782 }
7883
7984 return $ type ;
@@ -135,6 +140,21 @@ private function parseIntersection(Ast\Node $type): Ast\Node
135140 }
136141
137142
143+ private function parseNullable (): Ast \Node
144+ {
145+ $ this ->consume (Lexer::TOKEN_NULLABLE );
146+
147+ $ type = new Ast \SimpleNode ($ this ->value ());
148+ $ this ->consume (Lexer::TOKEN_IDENTIFIER );
149+
150+ if ($ this ->tokenType === Lexer::TOKEN_OPEN_ANGLE_BRACKET ) {
151+ $ type = $ this ->parseGeneric ($ type );
152+ }
153+
154+ return new Ast \NullableNode ($ type );
155+ }
156+
157+
138158 private function parseGeneric (Ast \SimpleNode $ baseType ): Ast \Node
139159 {
140160 $ this ->consume (Lexer::TOKEN_OPEN_ANGLE_BRACKET );
0 commit comments