Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 101 |
|
0.00% |
0 / 29 |
CRAP | |
0.00% |
0 / 1 |
ConfigBuilder | |
0.00% |
0 / 101 |
|
0.00% |
0 / 29 |
1260 | |
0.00% |
0 / 1 |
setRawOptions | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
make | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setFileList | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
addFiles | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
setExcludedFileList | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
excludeFiles | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
setExcludeFileRegex | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setDirectoryList | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
addDirectories | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
setExcludedDirectoryList | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
excludeDirectories | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
setMinimumSeverity | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
allowMissingProperties | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
allowScalarImplicitCasts | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
allowNullCastsAsAnyType | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
enableDeadCodeDetection | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
shouldDeadCodeDetectionPreferFalseNegatives | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setProgressBarMode | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
30 | |||
setSuppressedIssuesList | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
suppressIssueTypes | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
addGlobalsWithTypes | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
readClassAliases | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
enableRedundantConditionDetection | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setMinimumPHPVersion | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setTargetPHPVersion | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
addPlugins | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
addCustomPlugins | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
enableTaintCheck | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
6 | |||
getTaintCheckPluginName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** @noinspection PhpUnused */ |
3 | |
4 | namespace MediaWikiPhanConfig; |
5 | |
6 | use InvalidArgumentException; |
7 | |
8 | class ConfigBuilder { |
9 | public const PROGRESS_BAR_DISABLED = 0; |
10 | public const PROGRESS_BAR_STANDARD = 1; |
11 | public const PROGRESS_BAR_LONG = 2; |
12 | |
13 | /** @var array */ |
14 | private array $options = []; |
15 | |
16 | /** |
17 | * Sets an array of raw phan options. This should generally be avoided, in favour of the setters below. |
18 | * @param array $options |
19 | * @return self |
20 | */ |
21 | public function setRawOptions( array $options ): self { |
22 | $this->options = array_replace( $this->options, $options ); |
23 | return $this; |
24 | } |
25 | |
26 | /** |
27 | * @return array |
28 | */ |
29 | public function make(): array { |
30 | return $this->options; |
31 | } |
32 | |
33 | /** |
34 | * @param array $list |
35 | * @return $this |
36 | */ |
37 | public function setFileList( array $list ): self { |
38 | $this->options['file_list'] = $list; |
39 | return $this; |
40 | } |
41 | |
42 | /** |
43 | * @param string ...$files |
44 | * @return $this |
45 | */ |
46 | public function addFiles( string ...$files ): self { |
47 | $this->options['file_list'] = array_merge( |
48 | $this->options['file_list'] ?? [], |
49 | $files |
50 | ); |
51 | return $this; |
52 | } |
53 | |
54 | /** |
55 | * @param array $list |
56 | * @return $this |
57 | */ |
58 | public function setExcludedFileList( array $list ): self { |
59 | $this->options['exclude_file_list'] = $list; |
60 | return $this; |
61 | } |
62 | |
63 | /** |
64 | * @param string ...$files |
65 | * @return $this |
66 | */ |
67 | public function excludeFiles( string ...$files ): self { |
68 | $this->options['exclude_file_list'] = array_merge( |
69 | $this->options['exclude_file_list'] ?? [], |
70 | $files |
71 | ); |
72 | return $this; |
73 | } |
74 | |
75 | /** |
76 | * @param string $regex |
77 | * @return $this |
78 | */ |
79 | public function setExcludeFileRegex( string $regex ): self { |
80 | $this->options['exclude_file_regex'] = $regex; |
81 | return $this; |
82 | } |
83 | |
84 | /** |
85 | * @param array $list |
86 | * @return $this |
87 | */ |
88 | public function setDirectoryList( array $list ): self { |
89 | $this->options['directory_list'] = $list; |
90 | return $this; |
91 | } |
92 | |
93 | /** |
94 | * @param string ...$dirs |
95 | * @return $this |
96 | */ |
97 | public function addDirectories( string ...$dirs ): self { |
98 | $this->options['directory_list'] = array_merge( |
99 | $this->options['directory_list'] ?? [], |
100 | $dirs |
101 | ); |
102 | return $this; |
103 | } |
104 | |
105 | /** |
106 | * @param array $list |
107 | * @return $this |
108 | */ |
109 | public function setExcludedDirectoryList( array $list ): self { |
110 | $this->options['exclude_analysis_directory_list'] = $list; |
111 | return $this; |
112 | } |
113 | |
114 | /** |
115 | * @param string ...$dirs |
116 | * @return $this |
117 | */ |
118 | public function excludeDirectories( string ...$dirs ): self { |
119 | $this->options['exclude_analysis_directory_list'] = array_merge( |
120 | $this->options['exclude_analysis_directory_list'] ?? [], |
121 | $dirs |
122 | ); |
123 | return $this; |
124 | } |
125 | |
126 | /** |
127 | * @param int $minSev |
128 | * @return $this |
129 | */ |
130 | public function setMinimumSeverity( int $minSev ): self { |
131 | $this->options['minimum_severity'] = $minSev; |
132 | return $this; |
133 | } |
134 | |
135 | /** |
136 | * @param bool $yn |
137 | * @return $this |
138 | */ |
139 | public function allowMissingProperties( bool $yn ): self { |
140 | $this->options['allow_missing_properties'] = $yn; |
141 | return $this; |
142 | } |
143 | |
144 | /** |
145 | * @param bool $yn |
146 | * @return $this |
147 | */ |
148 | public function allowScalarImplicitCasts( bool $yn ): self { |
149 | $this->options['scalar_implicit_cast'] = $yn; |
150 | return $this; |
151 | } |
152 | |
153 | /** |
154 | * @param bool $yn |
155 | * @return $this |
156 | */ |
157 | public function allowNullCastsAsAnyType( bool $yn ): self { |
158 | $this->options['null_casts_as_any_type'] = $yn; |
159 | return $this; |
160 | } |
161 | |
162 | /** |
163 | * @param bool $yn |
164 | * @return $this |
165 | */ |
166 | public function enableDeadCodeDetection( bool $yn ): self { |
167 | $this->options['dead_code_detection'] = $yn; |
168 | return $this; |
169 | } |
170 | |
171 | /** |
172 | * @param bool $yn |
173 | * @return $this |
174 | */ |
175 | public function shouldDeadCodeDetectionPreferFalseNegatives( bool $yn ): self { |
176 | $this->options['dead_code_detection_prefer_false_negative'] = $yn; |
177 | return $this; |
178 | } |
179 | |
180 | /** |
181 | * @param int $mode One of the PROGRESS_BAR_* constants |
182 | * @return $this |
183 | */ |
184 | public function setProgressBarMode( int $mode ): self { |
185 | switch ( $mode ) { |
186 | case self::PROGRESS_BAR_DISABLED: |
187 | $this->options['progress_bar'] = false; |
188 | break; |
189 | case self::PROGRESS_BAR_STANDARD: |
190 | $this->options['progress_bar'] = true; |
191 | break; |
192 | case self::PROGRESS_BAR_LONG: |
193 | $this->options['progress_bar'] = true; |
194 | $this->options['long_progress_bar'] = true; |
195 | break; |
196 | default: |
197 | throw new InvalidArgumentException( "Invalid $mode" ); |
198 | } |
199 | return $this; |
200 | } |
201 | |
202 | /** |
203 | * @param array $list |
204 | * @return $this |
205 | */ |
206 | public function setSuppressedIssuesList( array $list ): self { |
207 | $this->options['suppress_issue_types'] = $list; |
208 | return $this; |
209 | } |
210 | |
211 | /** |
212 | * @param string ...$types |
213 | * @return $this |
214 | */ |
215 | public function suppressIssueTypes( string ...$types ): self { |
216 | $this->options['suppress_issue_types'] = array_merge( |
217 | $this->options['suppress_issue_types'] ?? [], |
218 | $types |
219 | ); |
220 | return $this; |
221 | } |
222 | |
223 | /** |
224 | * @param array $globals [ 'global_name' => 'union_type' ] |
225 | * @return $this |
226 | */ |
227 | public function addGlobalsWithTypes( array $globals ): self { |
228 | $this->options['globals_type_map'] = array_merge( |
229 | $this->options['globals_type_map'] ?? [], |
230 | $globals |
231 | ); |
232 | return $this; |
233 | } |
234 | |
235 | /** |
236 | * @param bool $yn |
237 | * @return $this |
238 | */ |
239 | public function readClassAliases( bool $yn ): self { |
240 | $this->options['enable_class_alias_support'] = $yn; |
241 | return $this; |
242 | } |
243 | |
244 | /** |
245 | * @param bool $yn |
246 | * @return $this |
247 | */ |
248 | public function enableRedundantConditionDetection( bool $yn ): self { |
249 | $this->options['redundant_condition_detection'] = $yn; |
250 | return $this; |
251 | } |
252 | |
253 | /** |
254 | * Set the minimum PHP version that the codebase should support. |
255 | * @param string $version |
256 | * @return $this |
257 | */ |
258 | public function setMinimumPHPVersion( string $version ): self { |
259 | $this->options['minimum_target_php_version'] = $version; |
260 | return $this; |
261 | } |
262 | |
263 | /** |
264 | * Set the PHP version to be checked against for forward-compatibility warnings. |
265 | * @param string $version |
266 | * @return $this |
267 | */ |
268 | public function setTargetPHPVersion( string $version ): self { |
269 | $this->options['target_php_version'] = $version; |
270 | return $this; |
271 | } |
272 | |
273 | /** |
274 | * Adds one or more built-in plugins. |
275 | * @param string[] $plugins |
276 | * @return self |
277 | */ |
278 | public function addPlugins( array $plugins ): self { |
279 | $this->options['plugins'] = array_merge( |
280 | $this->options['plugins'] ?? [], |
281 | $plugins |
282 | ); |
283 | return $this; |
284 | } |
285 | |
286 | /** |
287 | * Adds one or more custom plugins. |
288 | * |
289 | * @param string[] $plugins |
290 | * @return self |
291 | */ |
292 | public function addCustomPlugins( array $plugins ): self { |
293 | foreach ( $plugins as $plugin ) { |
294 | $this->options['plugins'][] = __DIR__ . "/Plugin/$plugin.php"; |
295 | } |
296 | return $this; |
297 | } |
298 | |
299 | /** |
300 | * @internal |
301 | * This should only be used by the config file in this repo. |
302 | * |
303 | * @param string $curDir |
304 | * @param string $vendorPath |
305 | * @return $this |
306 | */ |
307 | public function enableTaintCheck( |
308 | string $curDir, |
309 | string $vendorPath |
310 | ): self { |
311 | $taintCheckPluginName = $this->getTaintCheckPluginName(); |
312 | $taintCheckPath = $curDir . "/../../phan-taint-check-plugin/$taintCheckPluginName.php"; |
313 | if ( !file_exists( $taintCheckPath ) ) { |
314 | $taintCheckPath = |
315 | "$vendorPath/vendor/mediawiki/phan-taint-check-plugin/$taintCheckPluginName.php"; |
316 | } |
317 | $this->options['plugins'][] = $taintCheckPath; |
318 | // Taint-check specific settings. NOTE: don't remove these lines, even if they duplicate some of |
319 | // the settings above. taint-check may fail hard if one of these settings goes missing. |
320 | $this->options['quick_mode'] = false; |
321 | $this->options['suppress_issue_types'] = array_merge( |
322 | $this->options['suppress_issue_types'], |
323 | [ |
324 | // We obviously don't want to report false positives |
325 | 'SecurityCheck-LikelyFalsePositive', |
326 | // This one still has a lot of false positives |
327 | 'SecurityCheck-PHPSerializeInjection', |
328 | ] |
329 | ); |
330 | return $this; |
331 | } |
332 | |
333 | protected function getTaintCheckPluginName(): string { |
334 | return 'GenericSecurityCheckPlugin'; |
335 | } |
336 | } |