Completed
Pull Request — master (#41)
by Tomáš
07:50 queued 04:44
created

ControlSignatureSniff::isCommentOnTheSameLine()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 5
nc 2
nop 2
crap 2
1
<?php
2
3
/*
4
 * This file is part of Zenify
5
 * Copyright (c) 2012 Tomas Votruba (http://tomasvotruba.cz)
6
 */
7
8
namespace ZenifyCodingStandard\Sniffs\ControlStructures;
9
10
use PHP_CodeSniffer_File;
11
use PHP_CodeSniffer_Sniff;
12
13
14
/**
15
 * Rules:
16
 * - Same as @see Squiz_Sniffs_ControlStructures_ControlSignatureSniff
17
 * - This modification allows comments
18
 */
19
final class ControlSignatureSniff implements PHP_CodeSniffer_Sniff
20
{
21
22
	/**
23
	 * @var PHP_CodeSniffer_File
24
	 */
25
	private $file;
26
27
	/**
28
	 * @var int
29
	 */
30
	private $position;
31
32
	/**
33
	 * @var array
34
	 */
35
	private $tokens;
36
37
38
	/**
39
	 * {@inheritdoc}
40
	 */
41 1
	public function register()
42
	{
43 1
		return [T_TRY, T_CATCH, T_DO, T_WHILE, T_FOR, T_IF, T_FOREACH, T_ELSE, T_ELSEIF];
44
	}
45
46
47
	/**
48
	 * {@inheritdoc}
49
	 */
50 1
	public function process(PHP_CodeSniffer_File $file, $position)
51
	{
52 1
		$this->file = $file;
53 1
		$this->position = $position;
54 1
		$this->tokens = $tokens = $file->getTokens();
55
56 1
		$this->ensureSingleSpaceAfterKeyword();
57 1
		$this->ensureSingleSpaceAfterClosingParenthesis();
58 1
		$this->ensureNewlineAfterOpeningBrace();
59
60
		// Only want to check multi-keyword structures from here on.
61 1
		if ($tokens[$position]['code'] === T_TRY || $tokens[$position]['code'] === T_DO) {
62 1
			$closer = $tokens[$position]['scope_closer'];
63
64 1
		} elseif ($tokens[$position]['code'] === T_ELSE || $tokens[$position]['code'] === T_ELSEIF) {
65 1
			$closer = $file->findPrevious(T_CLOSE_CURLY_BRACKET, ($position - 1));
66
67
		} else {
68 1
			return;
69
		}
70
71
		// Single space after closing brace.
72 1
		$found = 1;
73 1
		if ($tokens[($closer + 1)]['code'] !== T_WHITESPACE) {
74 1
			$found = 0;
75
76
		} else {
77 1
			if ($tokens[($closer + 1)]['content'] !== ' ') {
78
				if (strpos($tokens[($closer + 1)]['content'], $file->eolChar) !== FALSE) {
79
					$found = 'newline';
80
81
				} else {
82
					$found = strlen($tokens[($closer + 1)]['content']);
83
				}
84
			}
85
		}
86
87 1
		if ($found !== 1) {
88 1
			$error = 'Expected 1 space after closing brace; %s found';
89 1
			$data = [$found];
90 1
			$file->addError($error, $closer, 'SpaceAfterCloseBrace', $data);
91
		}
92 1
	}
93
94
95 1
	private function ensureSingleSpaceAfterKeyword()
96
	{
97 1
		$found = 1;
98 1
		if ($this->tokens[($this->position + 1)]['code'] !== T_WHITESPACE) {
99 1
			$found = 0;
100
101 1
		} elseif ($this->tokens[($this->position + 1)]['content'] !== ' ') {
102 1
			if (strpos($this->tokens[($this->position + 1)]['content'], $this->file->eolChar) !== FALSE) {
103
				$found = 'newline';
104
105
			} else {
106 1
				$found = strlen($this->tokens[($this->position + 1)]['content']);
107
			}
108
		}
109
110 1
		if ($found !== 1) {
111 1
			$error = 'Expected 1 space after %s keyword; %s found';
112
			$data = [
113 1
				strtoupper($this->tokens[$this->position]['content']),
114 1
				$found,
115
			];
116 1
			$this->file->addError($error, $this->position, 'SpaceAfterKeyword', $data);
117
		}
118 1
	}
119
120
121 1
	private function ensureSingleSpaceAfterClosingParenthesis()
122
	{
123 1
		if (isset($this->tokens[$this->position]['parenthesis_closer']) === TRUE
124 1
			&& isset($this->tokens[$this->position]['scope_opener']) === TRUE
125
		) {
126 1
			$closer = $this->tokens[$this->position]['parenthesis_closer'];
127 1
			$opener = $this->tokens[$this->position]['scope_opener'];
128 1
			$content = $this->file->getTokensAsString(($closer + 1), ($opener - $closer - 1));
129 1
			if ($content !== ' ') {
130 1
				$error = 'Expected 1 space after closing parenthesis; found "%s"';
131 1
				$data = [str_replace($this->file->eolChar, '\n', $content)];
132 1
				$this->file->addError($error, $closer, 'SpaceAfterCloseParenthesis', $data);
133
			}
134
		}
135 1
	}
136
137
138 1
	private function ensureNewlineAfterOpeningBrace()
139
	{
140 1
		if (isset($this->tokens[$this->position]['scope_opener']) === TRUE) {
141 1
			$opener = $this->tokens[$this->position]['scope_opener'];
142 1
			$next = $this->file->findNext(T_WHITESPACE, ($opener + 1), NULL, TRUE);
143 1
			$found = ($this->tokens[$next]['line'] - $this->tokens[$opener]['line']);
144 1
			if ($found !== 1) {
145 1
				if ( ! $this->isCommentOnTheSameLine($this->file, $opener)) {
146 1
					$error = 'Expected 1 newline after opening brace; %s found';
147 1
					$data = [$found];
148 1
					$this->file->addError($error, $opener, 'NewlineAfterOpenBrace', $data);
149
				}
150
			}
151
152 1
		} elseif ($this->tokens[$this->position]['code'] === T_WHILE) {
153 1
			$closerPosition = $this->tokens[$this->position]['parenthesis_closer'];
154 1
			$this->ensureZeroSpacesAfterParenthesisCloser($closerPosition);
155
		}
156 1
	}
157
158
159
	/**
160
	 * @param PHP_CodeSniffer_File $file
161
	 * @param int $position
162
	 * @return bool
163
	 */
164 1
	private function isCommentOnTheSameLine(PHP_CodeSniffer_File $file, $position)
165
	{
166 1
		$isComment = $file->findNext(T_COMMENT, ($position + 1), NULL);
167 1
		if ($this->tokens[$isComment]['line'] === $this->tokens[$position]['line']) {
168 1
			return TRUE;
169
		}
170 1
		return FALSE;
171
	}
172
173
174
	/**
175
	 * @param int $closerPosition
176
	 */
177 1
	private function ensureZeroSpacesAfterParenthesisCloser($closerPosition)
178
	{
179 1
		$found = 0;
180 1
		if ($this->tokens[($closerPosition + 1)]['code'] === T_WHITESPACE) {
181
			if (strpos($this->tokens[($closerPosition + 1)]['content'], $this->file->eolChar) !== FALSE) {
182
				$found = 'newline';
183
184
			} else {
185
				$found = strlen($this->tokens[($closerPosition + 1)]['content']);
186
			}
187
		}
188 1
		if ($found !== 0) {
189
			$error = 'Expected 0 spaces before semicolon; %s found';
190
			$data = [$found];
191
			$this->file->addError($error, $closerPosition, 'SpaceBeforeSemicolon', $data);
192
		}
193 1
	}
194
195
}
196