Completed
Push — master ( 2a6630...1a6e67 )
by Tomáš
02:50
created

getLineDistanceBetweenNamespaceAndFirstUseStatement()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 8
nc 3
nop 0
crap 4
1
<?php
2
3
declare(strict_types = 1);
4
5
/*
6
 * This file is part of Zenify
7
 * Copyright (c) 2012 Tomas Votruba (http://tomasvotruba.cz)
8
 */
9
10
namespace ZenifyCodingStandard\Helper\Whitespace;
11
12
use PHP_CodeSniffer_File;
13
14
15
final class ClassMetrics
16
{
17
18
	/**
19
	 * @var PHP_CodeSniffer_File
20
	 */
21
	private $file;
22
23
	/**
24
	 * @var int
25
	 */
26
	private $classPosition;
27
28
	/**
29
	 * @var array
30
	 */
31
	private $tokens;
32
33
34 2
	public function __construct(PHP_CodeSniffer_File $file, int $classPosition)
35
	{
36 2
		$this->file = $file;
37 2
		$this->classPosition = $classPosition;
38 2
		$this->tokens = $file->getTokens();
39 2
	}
40
41
42
	/**
43
	 * @return FALSE|int
44
	 */
45 2
	public function getLineDistanceBetweenClassAndLastUseStatement()
46
	{
47 2
		$lastUseStatementPosition = $this->getLastUseStatementPosition();
48 2
		if ( ! $lastUseStatementPosition) {
49
			return FALSE;
50
		}
51
52 2
		return (int) $this->tokens[$this->getClassPositionIncludingComment()]['line']
53 2
			- $this->tokens[$lastUseStatementPosition]['line']
54 2
			- 1;
55
	}
56
57
58
	/**
59
	 * @return FALSE|int
60
	 */
61 2
	public function getLastUseStatementPosition()
62
	{
63 2
		return $this->file->findPrevious(T_USE, $this->classPosition);
64
	}
65
66
67
	/**
68
	 * @return FALSE|int
69
	 */
70 2
	public function getLineDistanceBetweenNamespaceAndFirstUseStatement()
71
	{
72 2
		$namespacePosition = $this->file->findPrevious(T_NAMESPACE, $this->classPosition);
73
74 2
		$nextUseStatementPosition = $this->file->findNext(T_USE, $namespacePosition);
0 ignored issues
show
Bug introduced by
It seems like $namespacePosition defined by $this->file->findPreviou..., $this->classPosition) on line 72 can also be of type boolean; however, PHP_CodeSniffer_File::findNext() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
75 2
		if ( ! $nextUseStatementPosition) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $nextUseStatementPosition of type integer|false is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
76 2
			return FALSE;
77
		}
78
79 2
		if ($this->tokens[$nextUseStatementPosition]['line'] === 1 || $this->isInsideClass($nextUseStatementPosition)) {
80 1
			return FALSE;
81
		}
82
83 2
		return $this->tokens[$nextUseStatementPosition]['line'] - $this->tokens[$namespacePosition]['line'] - 1;
84
	}
85
86
87
	/**
88
	 * @return FALSE|int
89
	 */
90 2
	public function getLineDistanceBetweenClassAndNamespace()
91
	{
92 2
		$namespacePosition = $this->file->findPrevious(T_NAMESPACE, $this->classPosition);
93
94 2
		if ( ! $namespacePosition) {
95
			return FALSE;
96
		}
97
98 2
		$classStartPosition = $this->getClassPositionIncludingComment();
99
100 2
		return $this->tokens[$classStartPosition]['line'] - $this->tokens[$namespacePosition]['line'] - 1;
101
	}
102
103
104
	/**
105
	 * @return FALSE|int
106
	 */
107 2
	private function getClassPositionIncludingComment()
108
	{
109 2
		$classStartPosition = $this->file->findPrevious(T_DOC_COMMENT_OPEN_TAG, $this->classPosition);
110 2
		if ($classStartPosition) {
111 1
			return $classStartPosition;
112
		}
113
114 2
		return $this->classPosition;
115
	}
116
117
118 2
	private function isInsideClass(int $position) : bool
119
	{
120 2
		$prevClassPosition = $this->file->findPrevious(T_CLASS, $position, NULL, FALSE);
121 2
		if ($prevClassPosition) {
122 1
			return TRUE;
123
		}
124
125 2
		return FALSE;
126
	}
127
128
}
129