Completed
Push — master ( 9b18dc...e19264 )
by Tomáš
18s
created

NamespaceDeclarationSniff::getLinesToNextUse()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 6
cts 6
cp 1
rs 9.4285
cc 3
eloc 7
nc 2
nop 0
crap 3
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\Sniffs\Namespaces;
11
12
use PHP_CodeSniffer_File;
13
use PHP_CodeSniffer_Sniff;
14
15
16
/**
17
 * Rules:
18
 * - There must be x empty line(s) after the namespace declaration or y empty line(s) followed by use statement.
19
 */
20
final class NamespaceDeclarationSniff implements PHP_CodeSniffer_Sniff
21
{
22
23
	/**
24
	 * @var int
25
	 */
26
	public $emptyLinesAfterNamespace = 2;
27
28
	/**
29
	 * @var int
30
	 */
31
	private $emptyLinesBeforeUseStatement;
32
33
	/**
34
	 * @var PHP_CodeSniffer_File
35
	 */
36
	private $file;
37
38
	/**
39
	 * @var int
40
	 */
41
	private $position;
42
43
44
	/**
45
	 * {@inheritdoc}
46
	 */
47 1
	public function register()
48
	{
49 1
		return [T_NAMESPACE];
50
	}
51
52
53
	/**
54
	 * {@inheritdoc}
55
	 */
56 1
	public function process(PHP_CodeSniffer_File $file, $position)
57
	{
58 1
		$this->file = $file;
59 1
		$this->position = $position;
60
61
		// Fix type
62 1
		$this->emptyLinesAfterNamespace = (int) $this->emptyLinesAfterNamespace;
63 1
		$this->emptyLinesBeforeUseStatement = (int) $this->emptyLinesAfterNamespace - 1;
64
65 1
		$linesToNextUse = $this->getLinesToNextUse();
66 1
		$linesToNextClass = $this->getLinesToNextClass();
67
68 1
		if ($linesToNextUse) {
69 1 View Code Duplication
			if ($linesToNextUse !== $this->emptyLinesBeforeUseStatement) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70 1
				$error = 'There should be %s empty line(s) from namespace to use statement; %s found';
71
				$data = [
72 1
					$this->emptyLinesBeforeUseStatement,
73 1
					$linesToNextUse
74
				];
75 1
				$file->addError($error, $position, 'BlankLineAfter', $data);
76
			}
77
78 1 View Code Duplication
		} elseif ($linesToNextClass) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
79 1
			if ($linesToNextClass !== $this->emptyLinesAfterNamespace) {
80 1
				$error = 'There should be %s empty line(s) after the namespace declaration; %s found';
81
				$data = [
82 1
					$this->emptyLinesAfterNamespace,
83 1
					$linesToNextClass
84
				];
85 1
				$file->addError($error, $position, 'BlankLineAfter', $data);
86
			}
87
		}
88 1
	}
89
90
91
	/**
92
	 * @return bool|int
93
	 */
94 1
	private function getLinesToNextUse()
95
	{
96 1
		$tokens = $this->file->getTokens();
97 1
		$nextUse = $this->file->findNext(T_USE, $this->position, NULL, FALSE);
98
99 1
		if ($tokens[$nextUse]['line'] === 1 || $this->isInsideClass($nextUse)) {
0 ignored issues
show
Security Bug introduced by
It seems like $nextUse defined by $this->file->findNext(T_...>position, NULL, FALSE) on line 97 can also be of type false; however, ZenifyCodingStandard\Sni...nSniff::isInsideClass() does only seem to accept integer, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
100 1
			return FALSE;
101
102
		} else {
103 1
			return $tokens[$nextUse]['line'] - $tokens[$this->position]['line'] - 1;
104
		}
105
	}
106
107
108
	/**
109
	 * @return bool|int
110
	 */
111 1
	private function getLinesToNextClass()
112
	{
113 1
		$tokens = $this->file->getTokens();
114 1
		$nextClass = $this->file->findNext(
115 1
			[T_CLASS, T_INTERFACE, T_TRAIT, T_DOC_COMMENT_OPEN_TAG], $this->position, NULL, FALSE
116
		);
117 1
		if ($tokens[$nextClass]['line'] === 1) {
118
			return FALSE;
119
120
		} else {
121 1
			return $tokens[$nextClass]['line'] - $tokens[$this->position]['line'] - 1;
122
		}
123
	}
124
125
126 1
	private function isInsideClass(int $position) : bool
127
	{
128 1
		$prevClassPosition = $this->file->findPrevious(T_CLASS, $position, NULL, FALSE);
129 1
		if ($prevClassPosition) {
130 1
			return TRUE;
131
		}
132 1
		return FALSE;
133
	}
134
135
}
136