4
4
5
5
use Safe \PhpStanFunctions \PhpStanFunction ;
6
6
use Safe \PhpStanFunctions \PhpStanFunctionMapReader ;
7
+ use Safe \PhpStanFunctions \PhpStanType ;
7
8
8
9
class Method
9
10
{
@@ -25,22 +26,29 @@ class Method
25
26
* @var Parameter[]|null
26
27
*/
27
28
private $ params = null ;
28
- /**
29
- * @var PhpStanFunctionMapReader
30
- */
31
- private $ phpStanFunctionMapReader ;
32
29
/**
33
30
* @var int
34
31
*/
35
32
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 ;
36
42
37
43
public function __construct (\SimpleXMLElement $ _functionObject , \SimpleXMLElement $ rootEntity , string $ moduleName , PhpStanFunctionMapReader $ phpStanFunctionMapReader , int $ errorType )
38
44
{
39
45
$ this ->functionObject = $ _functionObject ;
40
46
$ this ->rootEntity = $ rootEntity ;
41
47
$ this ->moduleName = $ moduleName ;
42
- $ this ->phpStanFunctionMapReader = $ phpStanFunctionMapReader ;
43
48
$ 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 ());
44
52
}
45
53
46
54
public function getFunctionName (): string
@@ -53,20 +61,9 @@ public function getErrorType(): int
53
61
return $ this ->errorType ;
54
62
}
55
63
56
- public function getReturnType (): string
64
+ public function getSignatureReturnType (): string
57
65
{
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 );
70
67
}
71
68
72
69
/**
@@ -78,7 +75,7 @@ public function getParams(): array
78
75
if (!isset ($ this ->functionObject ->methodparam )) {
79
76
return [];
80
77
}
81
- $ phpStanFunction = $ this ->getPhpStanData () ;
78
+ $ phpStanFunction = $ this ->phpstanSignarure ;
82
79
$ params = [];
83
80
$ i =1 ;
84
81
foreach ($ this ->functionObject ->methodparam as $ param ) {
@@ -124,43 +121,57 @@ private function getDocBlock(): string
124
121
$ i ++;
125
122
}
126
123
127
- $ bestReturnType = $ this ->getBestReturnType ();
128
- if ($ bestReturnType !== 'void ' ) {
129
- $ str .= '@return ' .$ bestReturnType . ' ' .$ this ->getReturnDoc ()."\n" ;
130
- }
124
+ $ str .= $ this ->getReturnDocBlock ();
131
125
132
126
$ str .= '@throws ' .FileCreator::toExceptionName ($ this ->getModuleName ()). "\n" ;
133
127
134
128
return $ str ;
135
129
}
136
130
137
- private function getReturnDoc (): string
131
+ public function getReturnDocBlock (): string
138
132
{
139
133
$ 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 '' ;
141
141
}
142
142
143
143
private function stripReturnFalseText (string $ string ): string
144
144
{
145
145
$ 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
+
156
170
return $ string ;
157
171
}
158
172
159
173
/**
160
174
* Removes a string, even if the string is split on multiple lines.
161
- * @param string $string
162
- * @param string $search
163
- * @return string
164
175
*/
165
176
private function removeString (string $ string , string $ search ): string
166
177
{
@@ -185,24 +196,9 @@ private function getStringForXPath(string $xpath): string
185
196
return trim ($ str );
186
197
}
187
198
188
- private function getBestReturnType (): ?string
199
+ private function getDocBlockReturnType (): ?string
189
200
{
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 );
206
202
}
207
203
208
204
private function getInnerXml (\SimpleXMLElement $ SimpleXMLElement ): string
0 commit comments