NPathComplexityAnalyzer::visitSwitchStatement()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 10
c 0
b 0
f 0
ccs 7
cts 7
cp 1
rs 10
cc 3
nc 3
nop 2
crap 3
1
<?php
2
/**
3
 * This file is part of PDepend.
4
 *
5
 * PHP Version 5
6
 *
7
 * Copyright (c) 2008-2017 Manuel Pichler <[email protected]>.
8
 * All rights reserved.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 *
14
 *   * Redistributions of source code must retain the above copyright
15
 *     notice, this list of conditions and the following disclaimer.
16
 *
17
 *   * Redistributions in binary form must reproduce the above copyright
18
 *     notice, this list of conditions and the following disclaimer in
19
 *     the documentation and/or other materials provided with the
20
 *     distribution.
21
 *
22
 *   * Neither the name of Manuel Pichler nor the names of his
23
 *     contributors may be used to endorse or promote products derived
24
 *     from this software without specific prior written permission.
25
 *
26
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
 * POSSIBILITY OF SUCH DAMAGE.
38
 *
39
 * @copyright 2008-2017 Manuel Pichler. All rights reserved.
40
 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
41
 */
42
43
namespace PDepend\Metrics\Analyzer;
44
45
use PDepend\Metrics\AbstractCachingAnalyzer;
46
use PDepend\Metrics\AnalyzerFilterAware;
47
use PDepend\Metrics\AnalyzerNodeAware;
48
use PDepend\Source\AST\AbstractASTCallable;
49
use PDepend\Source\AST\ASTArtifact;
50
use PDepend\Source\AST\ASTBooleanAndExpression;
51
use PDepend\Source\AST\ASTBooleanOrExpression;
52
use PDepend\Source\AST\ASTConditionalExpression;
53
use PDepend\Source\AST\ASTElseIfStatement;
54
use PDepend\Source\AST\ASTExpression;
55
use PDepend\Source\AST\ASTFunction;
56
use PDepend\Source\AST\ASTIfStatement;
57
use PDepend\Source\AST\ASTInterface;
58
use PDepend\Source\AST\ASTLogicalAndExpression;
59
use PDepend\Source\AST\ASTLogicalOrExpression;
60
use PDepend\Source\AST\ASTLogicalXorExpression;
61
use PDepend\Source\AST\ASTMethod;
62
use PDepend\Source\AST\ASTNamespace;
63
use PDepend\Source\AST\ASTNode;
64
use PDepend\Source\AST\ASTStatement;
65
use PDepend\Source\AST\ASTSwitchLabel;
66
use PDepend\Util\MathUtil;
67
68
/**
69
 * This analyzer calculates the NPath complexity of functions and methods. The
70
 * NPath complexity metric measures the acyclic execution paths through a method
71
 * or function. See Nejmeh, Communications of the ACM Feb 1988 pp 188-200.
72
 *
73
 * @copyright 2008-2017 Manuel Pichler. All rights reserved.
74
 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
75
 */
76
class NPathComplexityAnalyzer extends AbstractCachingAnalyzer implements AnalyzerFilterAware, AnalyzerNodeAware
77
{
78
    /**
79
     * Metrics provided by the analyzer implementation.
80
     */
81
    const M_NPATH_COMPLEXITY = 'npath';
82
83
    /**
84
     * Processes all {@link ASTNamespace} code nodes.
85
     *
86
     * @return void
87
     */
88 2
    public function analyze($namespaces)
89
    {
90 2
        if ($this->metrics === null) {
91 2
            $this->loadCache();
92 2
            $this->fireStartAnalyzer();
93
94 2
            $this->metrics = array();
95 2
            foreach ($namespaces as $namespace) {
96 2
                $namespace->accept($this);
97
            }
98
99 2
            $this->fireEndAnalyzer();
100 2
            $this->unloadCache();
101
        }
102 2
    }
103
104
    /**
105
     * This method will return an <b>array</b> with all generated metric values
106
     * for the node with the given <b>$id</b> identifier. If there are no
107
     * metrics for the requested node, this method will return an empty <b>array</b>.
108
     *
109
     * <code>
110
     * array(
111
     *     'npath'  =>  '17'
112
     * )
113
     * </code>
114
     *
115
     * @return array<string, string>
116
     */
117 38
    public function getNodeMetrics(ASTArtifact $artifact)
118
    {
119 38
        $metric = array();
120 38
        if (isset($this->metrics[$artifact->getId()])) {
121 38
            $metric = array(self::M_NPATH_COMPLEXITY  =>  $this->metrics[$artifact->getId()]);
122
        }
123 38
        return $metric;
124
    }
125
126
    /**
127
     * Visits a code interface object.
128
     *
129
     * @return void
130
     */
131
    public function visitInterface(ASTInterface $interface)
132
    {
133
        // Empty visit method, we don't want interface metrics
134
    }
135
136
    /**
137
     * Visits a function node.
138
     *
139
     * @return void
140
     */
141 9
    public function visitFunction(ASTFunction $function)
142
    {
143 9
        $this->fireStartFunction($function);
144
145 9
        if (false === $this->restoreFromCache($function)) {
146 9
            $this->calculateComplexity($function);
147
        }
148
149 9
        $this->fireEndFunction($function);
150 9
    }
151
152
    /**
153
     * Visits a method node.
154
     *
155
     * @return void
156
     */
157 29
    public function visitMethod(ASTMethod $method)
158
    {
159 29
        $this->fireStartMethod($method);
160
161 29
        if (false === $this->restoreFromCache($method)) {
162 29
            $this->calculateComplexity($method);
163
        }
164
165 29
        $this->fireEndMethod($method);
166 29
    }
167
168
    /**
169
     * This method will calculate the NPath complexity for the given callable
170
     * instance.
171
     *
172
     * @return void
173
     *
174
     * @since  0.9.12
175
     */
176 38
    protected function calculateComplexity(AbstractASTCallable $callable)
177
    {
178 38
        $npath = '1';
179 38
        foreach ($callable->getChildren() as $child) {
180 38
            $stmt  = $child->accept($this, $npath);
0 ignored issues
show
Bug introduced by
$npath of type string is incompatible with the type PDepend\Source\AST\T expected by parameter $data of PDepend\Source\AST\AbstractASTNode::accept(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

180
            $stmt  = $child->accept($this, /** @scrutinizer ignore-type */ $npath);
Loading history...
181 38
            $npath = MathUtil::mul($npath, $stmt);
182
        }
183
184 38
        $this->metrics[$callable->getId()] = $npath;
185 38
    }
186
187
    /**
188
     * This method calculates the NPath Complexity of a conditional-statement,
189
     * the meassured value is then returned as a string.
190
     *
191
     * <code>
192
     * <expr1> ? <expr2> : <expr3>
193
     *
194
     * -- NP(?) = NP(<expr1>) + NP(<expr2>) + NP(<expr3>) + 2 --
195
     * </code>
196
     *
197
     * @param ASTNode        $node
198
     * @param numeric-string $data
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
199
     *
200
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
201
     *
202
     * @since  0.9.12
203
     */
204 12
    public function visitConditionalExpression($node, $data)
205
    {
206
        // Calculate the complexity of the condition
207 12
        $parent = $node->getParent()->getChild(0);
208 12
        $npath = $this->sumComplexity($parent);
209
210
        // New PHP 5.3 ifsetor-operator $x ?: $y
211 12
        if (count($node->getChildren()) === 1) {
212 2
            $npath = MathUtil::mul($npath, '2');
213
        }
214
215
        // The complexity of each child has no minimum
216 12
        foreach ($node->getChildren() as $child) {
217 12
            $cn = $this->sumComplexity($child);
218 12
            $npath = MathUtil::add($npath, $cn);
219
        }
220
221
        // Add 2 for the branching per the NPath spec
222 12
        $npath = MathUtil::add($npath, '2');
223
224 12
        return MathUtil::mul($npath, $data);
225
    }
226
227
    /**
228
     * This method calculates the NPath Complexity of a do-while-statement, the
229
     * meassured value is then returned as a string.
230
     *
231
     * <code>
232
     * do
233
     *   <do-range>
234
     * while (<expr>)
235
     * S;
236
     *
237
     * -- NP(do) = NP(<do-range>) + NP(<expr>) + 1 --
238
     * </code>
239
     *
240
     * @param ASTNode        $node The currently visited node.
241
     * @param numeric-string $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
242
     *
243
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
244
     *
245
     * @since  0.9.12
246
     */
247 2
    public function visitDoWhileStatement($node, $data)
248
    {
249 2
        $stmt = $node->getChild(0)->accept($this, '1');
250 2
        $expr = $this->sumComplexity($node->getChild(1));
251
252 2
        $npath = MathUtil::add($expr, $stmt);
253 2
        $npath = MathUtil::add($npath, '1');
254
255 2
        return MathUtil::mul($npath, $data);
256
    }
257
258
    /**
259
     * This method calculates the NPath Complexity of an elseif-statement, the
260
     * meassured value is then returned as a string.
261
     *
262
     * <code>
263
     * elseif (<expr>)
264
     *   <elseif-range>
265
     * S;
266
     *
267
     * -- NP(elseif) = NP(<elseif-range>) + NP(<expr>) + 1 --
268
     *
269
     *
270
     * elseif (<expr>)
271
     *   <elseif-range>
272
     * else
273
     *   <else-range>
274
     * S;
275
     *
276
     * -- NP(if) = NP(<if-range>) + NP(<expr>) + NP(<else-range> --
277
     * </code>
278
     *
279
     * @param ASTElseIfStatement $node The currently visited node.
280
     * @param numeric-string     $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
281
     *
282
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
283
     *
284
     * @since  0.9.12
285
     */
286 2
    public function visitElseIfStatement($node, $data)
287
    {
288 2
        $npath = $this->sumComplexity($node->getChild(0));
289 2
        foreach ($node->getChildren() as $child) {
290 2
            if ($child instanceof ASTStatement) {
291 2
                $expr  = $child->accept($this, '1');
0 ignored issues
show
Bug introduced by
'1' of type string is incompatible with the type PDepend\Source\AST\T expected by parameter $data of PDepend\Source\AST\AbstractASTNode::accept(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

291
                $expr  = $child->accept($this, /** @scrutinizer ignore-type */ '1');
Loading history...
292 2
                $npath = MathUtil::add($npath, $expr);
293
            }
294
        }
295
296 2
        if (!$node->hasElse()) {
297 1
            $npath = MathUtil::add($npath, '1');
298
        }
299
300 2
        return MathUtil::mul($npath, $data);
301
    }
302
303
    /**
304
     * This method calculates the NPath Complexity of a for-statement, the
305
     * meassured value is then returned as a string.
306
     *
307
     * <code>
308
     * for (<expr1>; <expr2>; <expr3>)
309
     *   <for-range>
310
     * S;
311
     *
312
     * -- NP(for) = NP(<for-range>) + NP(<expr1>) + NP(<expr2>) + NP(<expr3>) + 1 --
313
     * </code>
314
     *
315
     * @param ASTNode        $node The currently visited node.
316
     * @param numeric-string $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
317
     *
318
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
319
     *
320
     * @since  0.9.12
321
     */
322 5
    public function visitForStatement($node, $data)
323
    {
324 5
        $npath = '1';
325 5
        foreach ($node->getChildren() as $child) {
326 5
            if ($child instanceof ASTStatement) {
327 5
                $stmt  = $child->accept($this, '1');
0 ignored issues
show
Bug introduced by
'1' of type string is incompatible with the type PDepend\Source\AST\T expected by parameter $data of PDepend\Source\AST\AbstractASTNode::accept(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

327
                $stmt  = $child->accept($this, /** @scrutinizer ignore-type */ '1');
Loading history...
328 5
                $npath = MathUtil::add($npath, $stmt);
329 4
            } elseif ($child instanceof ASTExpression) {
330 4
                $expr  = $this->sumComplexity($child);
331 4
                $npath = MathUtil::add($npath, $expr);
332
            }
333
        }
334
335 5
        return MathUtil::mul($npath, $data);
336
    }
337
338
    /**
339
     * This method calculates the NPath Complexity of a for-statement, the
340
     * meassured value is then returned as a string.
341
     *
342
     * <code>
343
     * fpreach (<expr>)
344
     *   <foreach-range>
345
     * S;
346
     *
347
     * -- NP(foreach) = NP(<foreach-range>) + NP(<expr>) + 1 --
348
     * </code>
349
     *
350
     * @param ASTNode        $node The currently visited node.
351
     * @param numeric-string $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
352
     *
353
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
354
     *
355
     * @since  0.9.12
356
     */
357 6
    public function visitForeachStatement($node, $data)
358
    {
359 6
        $npath = $this->sumComplexity($node->getChild(0));
360 6
        $npath = MathUtil::add($npath, '1');
361
362 6
        foreach ($node->getChildren() as $child) {
363 6
            if ($child instanceof ASTStatement) {
364 6
                $stmt  = $child->accept($this, '1');
0 ignored issues
show
Bug introduced by
'1' of type string is incompatible with the type PDepend\Source\AST\T expected by parameter $data of PDepend\Source\AST\AbstractASTNode::accept(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

364
                $stmt  = $child->accept($this, /** @scrutinizer ignore-type */ '1');
Loading history...
365 6
                $npath = MathUtil::add($npath, $stmt);
366
            }
367
        }
368
369 6
        return MathUtil::mul($npath, $data);
370
    }
371
372
    /**
373
     * This method calculates the NPath Complexity of an if-statement, the
374
     * meassured value is then returned as a string.
375
     *
376
     * <code>
377
     * if (<expr>)
378
     *   <if-range>
379
     * S;
380
     *
381
     * -- NP(if) = NP(<if-range>) + NP(<expr>) + 1 --
382
     *
383
     *
384
     * if (<expr>)
385
     *   <if-range>
386
     * else
387
     *   <else-range>
388
     * S;
389
     *
390
     * -- NP(if) = NP(<if-range>) + NP(<expr>) + NP(<else-range> --
391
     * </code>
392
     *
393
     * @param ASTIfStatement $node The currently visited node.
394
     * @param numeric-string $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
395
     *
396
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
397
     *
398
     * @since  0.9.12
399
     */
400 16
    public function visitIfStatement($node, $data)
401
    {
402 16
        $npath = $this->sumComplexity($node->getChild(0));
403
404 16
        foreach ($node->getChildren() as $child) {
405 16
            if ($child instanceof ASTStatement) {
406 16
                $stmt  = $child->accept($this, '1');
0 ignored issues
show
Bug introduced by
'1' of type string is incompatible with the type PDepend\Source\AST\T expected by parameter $data of PDepend\Source\AST\AbstractASTNode::accept(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

406
                $stmt  = $child->accept($this, /** @scrutinizer ignore-type */ '1');
Loading history...
407 16
                $npath = MathUtil::add($npath, $stmt);
408
            }
409
        }
410
411 16
        if (!$node->hasElse()) {
412 14
            $npath = MathUtil::add($npath, '1');
413
        }
414
415 16
        return MathUtil::mul($npath, $data);
416
    }
417
418
    /**
419
     * This method calculates the NPath Complexity of a return-statement, the
420
     * meassured value is then returned as a string.
421
     *
422
     * <code>
423
     * return <expr>;
424
     *
425
     * -- NP(return) = NP(<expr>) --
426
     * </code>
427
     *
428
     * @param ASTNode        $node The currently visited node.
429
     * @param numeric-string $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
430
     *
431
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
432
     *
433
     * @since  0.9.12
434
     */
435 11
    public function visitReturnStatement($node, $data)
436
    {
437 11
        if (($npath = $this->sumComplexity($node)) === '0') {
438 7
            return $data;
439
        }
440 6
        return MathUtil::mul($npath, $data);
441
    }
442
443
    /**
444
     * This method calculates the NPath Complexity of a switch-statement, the
445
     * meassured value is then returned as a string.
446
     *
447
     * <code>
448
     * switch (<expr>)
449
     *   <case-range1>
450
     *   <case-range2>
451
     *   ...
452
     *   <default-range>
453
     *
454
     * -- NP(switch) = NP(<expr>) + NP(<default-range>) +  NP(<case-range1>) ... --
455
     * </code>
456
     *
457
     * @param ASTNode        $node The currently visited node.
458
     * @param numeric-string $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
459
     *
460
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
461
     *
462
     * @since  0.9.12
463
     */
464 5
    public function visitSwitchStatement($node, $data)
465
    {
466 5
        $npath = $this->sumComplexity($node->getChild(0));
467 5
        foreach ($node->getChildren() as $child) {
468 5
            if ($child instanceof ASTSwitchLabel) {
469 5
                $label = $child->accept($this, '1');
0 ignored issues
show
Bug introduced by
'1' of type string is incompatible with the type PDepend\Source\AST\T expected by parameter $data of PDepend\Source\AST\AbstractASTNode::accept(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

469
                $label = $child->accept($this, /** @scrutinizer ignore-type */ '1');
Loading history...
470 5
                $npath = MathUtil::add($npath, $label);
471
            }
472
        }
473 5
        return MathUtil::mul($npath, $data);
474
    }
475
476
    /**
477
     * This method calculates the NPath Complexity of a try-catch-statement, the
478
     * meassured value is then returned as a string.
479
     *
480
     * <code>
481
     * try
482
     *   <try-range>
483
     * catch
484
     *   <catch-range>
485
     *
486
     * -- NP(try) = NP(<try-range>) + NP(<catch-range>) --
487
     *
488
     *
489
     * try
490
     *   <try-range>
491
     * catch
492
     *   <catch-range1>
493
     * catch
494
     *   <catch-range2>
495
     * ...
496
     *
497
     * -- NP(try) = NP(<try-range>) + NP(<catch-range1>) + NP(<catch-range2>) ... --
498
     * </code>
499
     *
500
     * @param ASTNode        $node The currently visited node.
501
     * @param numeric-string $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
502
     *
503
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
504
     *
505
     * @since  0.9.12
506
     */
507 3
    public function visitTryStatement($node, $data)
508
    {
509 3
        $npath = '0';
510 3
        foreach ($node->getChildren() as $child) {
511 3
            if ($child instanceof ASTStatement) {
512 3
                $stmt  = $child->accept($this, '1');
0 ignored issues
show
Bug introduced by
'1' of type string is incompatible with the type PDepend\Source\AST\T expected by parameter $data of PDepend\Source\AST\AbstractASTNode::accept(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

512
                $stmt  = $child->accept($this, /** @scrutinizer ignore-type */ '1');
Loading history...
513 3
                $npath = MathUtil::add($npath, $stmt);
514
            }
515
        }
516 3
        return MathUtil::mul($npath, $data);
517
    }
518
519
    /**
520
     * This method calculates the NPath Complexity of a while-statement, the
521
     * meassured value is then returned as a string.
522
     *
523
     * <code>
524
     * while (<expr>)
525
     *   <while-range>
526
     * S;
527
     *
528
     * -- NP(while) = NP(<while-range>) + NP(<expr>) + 1 --
529
     * </code>
530
     *
531
     * @param ASTNode        $node The currently visited node.
532
     * @param numeric-string $data The previously calculated npath value.
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
533
     *
534
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
535
     *
536
     * @since  0.9.12
537
     */
538 3
    public function visitWhileStatement($node, $data)
539
    {
540 3
        $expr = $this->sumComplexity($node->getChild(0));
541 3
        $stmt = $node->getChild(1)->accept($this, '1');
542
543 3
        $npath = MathUtil::add($expr, $stmt);
544 3
        $npath = MathUtil::add($npath, '1');
545
546 3
        return MathUtil::mul($npath, $data);
547
    }
548
549
    /**
550
     * Calculates the expression sum of the given node.
551
     *
552
     * @param ASTNode $node The currently visited node.
553
     *
554
     * @return numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
555
     *
556
     * @since  0.9.12
557
     *
558
     * @todo   I don't like this method implementation, it should be possible to
559
     *       implement this method with more visitor behavior for the boolean
560
     *       and logical expressions.
561
     */
562 35
    public function sumComplexity($node)
563
    {
564 35
        $sum = '0';
565 35
        if ($node instanceof ASTConditionalExpression) {
566 6
            $sum = MathUtil::add($sum, $node->accept($this, '1'));
0 ignored issues
show
Bug introduced by
'1' of type string is incompatible with the type PDepend\Source\AST\T expected by parameter $data of PDepend\Source\AST\AbstractASTNode::accept(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

566
            $sum = MathUtil::add($sum, $node->accept($this, /** @scrutinizer ignore-type */ '1'));
Loading history...
567 35
        } elseif ($node instanceof ASTBooleanAndExpression
568 35
            || $node instanceof ASTBooleanOrExpression
569 35
            || $node instanceof ASTLogicalAndExpression
570 35
            || $node instanceof ASTLogicalOrExpression
571 35
            || $node instanceof ASTLogicalXorExpression
572
        ) {
573 10
            $sum = MathUtil::add($sum, '1');
574
        } else {
575 35
            foreach ($node->getChildren() as $child) {
576 32
                $expr = $this->sumComplexity($child);
0 ignored issues
show
Bug introduced by
It seems like $child can also be of type PDepend\Source\AST\ASTArtifact; however, parameter $node of PDepend\Metrics\Analyzer...alyzer::sumComplexity() does only seem to accept PDepend\Source\AST\ASTNode, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

576
                $expr = $this->sumComplexity(/** @scrutinizer ignore-type */ $child);
Loading history...
577 32
                $sum  = MathUtil::add($sum, $expr);
578
            }
579
        }
580 35
        return $sum;
581
    }
582
}
583