@@ -88,16 +88,23 @@ public function process(File $phpcsFile, $stackPtr)
88
88
$ props = $ phpcsFile ->getMethodProperties ($ stackPtr );
89
89
90
90
// Strip off potential nullable indication.
91
- $ returnType = ltrim ($ props ['return_type ' ], '? ' );
92
- $ returnTypeLower = strtolower ($ returnType );
91
+ $ returnType = ltrim ($ props ['return_type ' ], '? ' );
93
92
94
- if ($ returnType !== ''
95
- && isset ($ this ->phpTypes [$ returnTypeLower ]) === true
96
- ) {
93
+ if ($ returnType !== '' ) {
97
94
$ error = 'PHP return type declarations must be lowercase; expected "%s" but found "%s" ' ;
98
95
$ errorCode = 'ReturnTypeFound ' ;
99
96
100
- $ this ->processType ($ phpcsFile , $ props ['return_type_token ' ], $ returnType , $ error , $ errorCode );
97
+ if (strpos ($ returnType , '| ' ) !== false ) {
98
+ $ this ->processUnionType (
99
+ $ phpcsFile ,
100
+ $ props ['return_type_token ' ],
101
+ $ props ['return_type_end_token ' ],
102
+ $ error ,
103
+ $ errorCode
104
+ );
105
+ } else if (isset ($ this ->phpTypes [strtolower ($ returnType )]) === true ) {
106
+ $ this ->processType ($ phpcsFile , $ props ['return_type_token ' ], $ returnType , $ error , $ errorCode );
107
+ }
101
108
}
102
109
103
110
/*
@@ -111,22 +118,77 @@ public function process(File $phpcsFile, $stackPtr)
111
118
112
119
foreach ($ params as $ param ) {
113
120
// Strip off potential nullable indication.
114
- $ typeHint = ltrim ($ param ['type_hint ' ], '? ' );
115
- $ typeHintLower = strtolower ($ typeHint );
121
+ $ typeHint = ltrim ($ param ['type_hint ' ], '? ' );
116
122
117
- if ($ typeHint !== ''
118
- && isset ($ this ->phpTypes [$ typeHintLower ]) === true
119
- ) {
123
+ if ($ typeHint !== '' ) {
120
124
$ error = 'PHP parameter type declarations must be lowercase; expected "%s" but found "%s" ' ;
121
125
$ errorCode = 'ParamTypeFound ' ;
122
126
123
- $ this ->processType ($ phpcsFile , $ param ['type_hint_token ' ], $ typeHint , $ error , $ errorCode );
127
+ if (strpos ($ typeHint , '| ' ) !== false ) {
128
+ $ this ->processUnionType (
129
+ $ phpcsFile ,
130
+ $ param ['type_hint_token ' ],
131
+ $ param ['type_hint_end_token ' ],
132
+ $ error ,
133
+ $ errorCode
134
+ );
135
+ } else if (isset ($ this ->phpTypes [strtolower ($ typeHint )]) === true ) {
136
+ $ this ->processType ($ phpcsFile , $ param ['type_hint_token ' ], $ typeHint , $ error , $ errorCode );
137
+ }
124
138
}
125
- }
139
+ }//end foreach
126
140
127
141
}//end process()
128
142
129
143
144
+ /**
145
+ * Processes a union type declaration.
146
+ *
147
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
148
+ * @param int $typeDeclStart The position of the start of the type token.
149
+ * @param int $typeDeclEnd The position of the end of the type token.
150
+ * @param string $error Error message template.
151
+ * @param string $errorCode The error code.
152
+ *
153
+ * @return void
154
+ */
155
+ protected function processUnionType (File $ phpcsFile , $ typeDeclStart , $ typeDeclEnd , $ error , $ errorCode )
156
+ {
157
+ $ tokens = $ phpcsFile ->getTokens ();
158
+ $ current = $ typeDeclStart ;
159
+
160
+ do {
161
+ $ endOfType = $ phpcsFile ->findNext (T_TYPE_UNION , $ current , $ typeDeclEnd );
162
+ if ($ endOfType === false ) {
163
+ // This must be the last type in the union.
164
+ $ endOfType = ($ typeDeclEnd + 1 );
165
+ }
166
+
167
+ $ hasNsSep = $ phpcsFile ->findNext (T_NS_SEPARATOR , $ current , $ endOfType );
168
+ if ($ hasNsSep !== false ) {
169
+ // Multi-token class based type. Ignore.
170
+ $ current = ($ endOfType + 1 );
171
+ continue ;
172
+ }
173
+
174
+ // Type consisting of a single token.
175
+ $ startOfType = $ phpcsFile ->findNext (Tokens::$ emptyTokens , $ current , $ endOfType , true );
176
+ if ($ startOfType === false ) {
177
+ // Parse error.
178
+ return ;
179
+ }
180
+
181
+ $ type = $ tokens [$ startOfType ]['content ' ];
182
+ if (isset ($ this ->phpTypes [strtolower ($ type )]) === true ) {
183
+ $ this ->processType ($ phpcsFile , $ startOfType , $ type , $ error , $ errorCode );
184
+ }
185
+
186
+ $ current = ($ endOfType + 1 );
187
+ } while ($ current <= $ typeDeclEnd );
188
+
189
+ }//end processUnionType()
190
+
191
+
130
192
/**
131
193
* Processes a type cast or a singular type declaration.
132
194
*
0 commit comments