44
55use Safe \PhpStanFunctions \PhpStanFunction ;
66use Safe \PhpStanFunctions \PhpStanFunctionMapReader ;
7+ use Safe \PhpStanFunctions \PhpStanType ;
78
89class Method
910{
@@ -25,22 +26,29 @@ class Method
2526 * @var Parameter[]|null
2627 */
2728 private $ params = null ;
28- /**
29- * @var PhpStanFunctionMapReader
30- */
31- private $ phpStanFunctionMapReader ;
3229 /**
3330 * @var int
3431 */
3532 private $ errorType ;
33+ /**
34+ * The function prototype from the phpstan internal documentation (functionMap.php)
35+ * @var PhpStanFunction|null
36+ */
37+ private $ phpstanSignarure ;
38+ /**
39+ * @var PhpStanType
40+ */
41+ private $ returnType ;
3642
3743 public function __construct (\SimpleXMLElement $ _functionObject , \SimpleXMLElement $ rootEntity , string $ moduleName , PhpStanFunctionMapReader $ phpStanFunctionMapReader , int $ errorType )
3844 {
3945 $ this ->functionObject = $ _functionObject ;
4046 $ this ->rootEntity = $ rootEntity ;
4147 $ this ->moduleName = $ moduleName ;
42- $ this ->phpStanFunctionMapReader = $ phpStanFunctionMapReader ;
4348 $ this ->errorType = $ errorType ;
49+ $ functionName = $ this ->getFunctionName ();
50+ $ this ->phpstanSignarure = $ phpStanFunctionMapReader ->hasFunction ($ functionName ) ? $ phpStanFunctionMapReader ->getFunction ($ functionName ) : null ;
51+ $ this ->returnType = $ this ->phpstanSignarure ? $ this ->phpstanSignarure ->getReturnType () : new PhpStanType ($ this ->functionObject ->type ->__toString ());
4452 }
4553
4654 public function getFunctionName (): string
@@ -53,20 +61,9 @@ public function getErrorType(): int
5361 return $ this ->errorType ;
5462 }
5563
56- public function getReturnType (): string
64+ public function getSignatureReturnType (): string
5765 {
58- // If the function returns a boolean, since false is for error, true is for success.
59- // Let's replace this with a "void".
60- $ type = $ this ->functionObject ->type ->__toString ();
61- if ($ type === 'bool ' ) {
62- return 'void ' ;
63- }
64- // Some types are completely weird. For instance, oci_new_collection returns a "OCI-Collection" (with a dash, yup)
65- if (\strpos ($ type , '- ' ) !== false ) {
66- return 'mixed ' ;
67- }
68-
69- return Type::toRootNamespace ($ type );
66+ return $ this ->returnType ->getSignatureType ($ this ->errorType );
7067 }
7168
7269 /**
@@ -78,7 +75,7 @@ public function getParams(): array
7875 if (!isset ($ this ->functionObject ->methodparam )) {
7976 return [];
8077 }
81- $ phpStanFunction = $ this ->getPhpStanData () ;
78+ $ phpStanFunction = $ this ->phpstanSignarure ;
8279 $ params = [];
8380 $ i =1 ;
8481 foreach ($ this ->functionObject ->methodparam as $ param ) {
@@ -124,43 +121,57 @@ private function getDocBlock(): string
124121 $ i ++;
125122 }
126123
127- $ bestReturnType = $ this ->getBestReturnType ();
128- if ($ bestReturnType !== 'void ' ) {
129- $ str .= '@return ' .$ bestReturnType . ' ' .$ this ->getReturnDoc ()."\n" ;
130- }
124+ $ str .= $ this ->getReturnDocBlock ();
131125
132126 $ str .= '@throws ' .FileCreator::toExceptionName ($ this ->getModuleName ()). "\n" ;
133127
134128 return $ str ;
135129 }
136130
137- private function getReturnDoc (): string
131+ public function getReturnDocBlock (): string
138132 {
139133 $ returnDoc = $ this ->getStringForXPath ("//docbook:refsect1[@role='returnvalues']/docbook:para " );
140- return $ this ->stripReturnFalseText ($ returnDoc );
134+ $ returnDoc = $ this ->stripReturnFalseText ($ returnDoc );
135+
136+ $ bestReturnType = $ this ->getDocBlockReturnType ();
137+ if ($ bestReturnType !== 'void ' ) {
138+ return '@return ' .$ bestReturnType . ' ' .$ returnDoc ."\n" ;
139+ }
140+ return '' ;
141141 }
142142
143143 private function stripReturnFalseText (string $ string ): string
144144 {
145145 $ string = \strip_tags ($ string );
146- $ string = $ this ->removeString ($ string , 'or FALSE on failure ' );
147- $ string = $ this ->removeString ($ string , 'may return FALSE ' );
148- $ string = $ this ->removeString ($ string , 'and FALSE on failure ' );
149- $ string = $ this ->removeString ($ string , 'on success, or FALSE otherwise ' );
150- $ string = $ this ->removeString ($ string , 'or FALSE on error ' );
151- $ string = $ this ->removeString ($ string , 'or FALSE if an error occurred ' );
152- $ string = $ this ->removeString ($ string , ' Returns FALSE otherwise. ' );
153- $ string = $ this ->removeString ($ string , ' and FALSE if an error occurred ' );
154- $ string = $ this ->removeString ($ string , ', NULL if the field does not exist ' );
155- $ string = $ this ->removeString ($ string , 'the function will return TRUE, or FALSE otherwise ' );
146+ switch ($ this ->errorType ) {
147+ case self ::NULLSY_TYPE :
148+ $ string = $ this ->removeString ($ string , ', or NULL if an error occurs ' );
149+ $ string = $ this ->removeString ($ string , ' and NULL on failure ' );
150+ $ string = $ this ->removeString ($ string , ' or NULL on failure ' );
151+ break ;
152+
153+ case self ::FALSY_TYPE :
154+ $ string = $ this ->removeString ($ string , 'or FALSE on failure ' );
155+ $ string = $ this ->removeString ($ string , '. Returns FALSE on error ' );
156+ $ string = $ this ->removeString ($ string , 'may return FALSE ' );
157+ $ string = $ this ->removeString ($ string , 'and FALSE on failure ' );
158+ $ string = $ this ->removeString ($ string , 'on success, or FALSE otherwise ' );
159+ $ string = $ this ->removeString ($ string , 'or FALSE on error ' );
160+ $ string = $ this ->removeString ($ string , 'or FALSE if an error occurred ' );
161+ $ string = $ this ->removeString ($ string , ' Returns FALSE otherwise. ' );
162+ $ string = $ this ->removeString ($ string , ' and FALSE if an error occurred ' );
163+ $ string = $ this ->removeString ($ string , 'the function will return TRUE, or FALSE otherwise ' );
164+ break ;
165+
166+ default :
167+ throw new \RuntimeException ('Incorrect error type. ' );
168+ }
169+
156170 return $ string ;
157171 }
158172
159173 /**
160174 * Removes a string, even if the string is split on multiple lines.
161- * @param string $string
162- * @param string $search
163- * @return string
164175 */
165176 private function removeString (string $ string , string $ search ): string
166177 {
@@ -185,24 +196,9 @@ private function getStringForXPath(string $xpath): string
185196 return trim ($ str );
186197 }
187198
188- private function getBestReturnType (): ?string
199+ private function getDocBlockReturnType (): ?string
189200 {
190- $ phpStanFunction = $ this ->getPhpStanData ();
191- // Get the type from PhpStan database first, then from the php doc.
192- if ($ phpStanFunction !== null ) {
193- return Type::toRootNamespace ($ phpStanFunction ->getReturnType ());
194- } else {
195- return Type::toRootNamespace ($ this ->getReturnType ());
196- }
197- }
198-
199- private function getPhpStanData (): ?PhpStanFunction
200- {
201- $ functionName = $ this ->getFunctionName ();
202- if (!$ this ->phpStanFunctionMapReader ->hasFunction ($ functionName )) {
203- return null ;
204- }
205- return $ this ->phpStanFunctionMapReader ->getFunction ($ functionName );
201+ return $ this ->returnType ->getDocBlockType ($ this ->errorType );
206202 }
207203
208204 private function getInnerXml (\SimpleXMLElement $ SimpleXMLElement ): string
0 commit comments