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

IfElseTryCatchFinallySniff::process()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 18
cts 18
cp 1
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 20
nc 3
nop 2
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\WhiteSpace;
11
12
use PHP_CodeSniffer_File;
13
use PHP_CodeSniffer_Sniff;
14
use ZenifyCodingStandard\Helper\Whitespace\EmptyLinesResizer;
15
16
17
/**
18
 * Rules:
19
 * - Else/elseif/catch/finally statement should be preceded by x empty line(s)
20
 */
21
final class IfElseTryCatchFinallySniff implements PHP_CodeSniffer_Sniff
22
{
23
24
	/**
25
	 * @var string
26
	 */
27
	const NAME = 'ZenifyCodingStandard.WhiteSpace.IfElseTryCatchFinally';
28
29
	/**
30
	 * @var int
31
	 */
32
	private $requiredEmptyLineCountBeforeStatement = 1;
33
34
	/**
35
	 * @var PHP_CodeSniffer_File
36
	 */
37
	private $file;
38
39
	/**
40
	 * @var int
41
	 */
42
	private $position;
43
44
	/**
45
	 * @var array
46
	 */
47
	private $tokens;
48
49
50
	/**
51
	 * @return int[]
52
	 */
53 2
	public function register() : array
54
	{
55 2
		return [T_ELSE, T_ELSEIF, T_CATCH, T_FINALLY];
56
	}
57
58
59
	/**
60
	 * @param PHP_CodeSniffer_File $file
61
	 * @param int $position
62
	 */
63 2
	public function process(PHP_CodeSniffer_File $file, $position)
64
	{
65 2
		$this->file = $file;
66 2
		$this->position = $position;
67 2
		$this->tokens = $file->getTokens();
68
69
		// Fix type
70 2
		$this->requiredEmptyLineCountBeforeStatement = (int) $this->requiredEmptyLineCountBeforeStatement;
71
72 2
		$emptyLineCountBeforeStatement = $this->getEmptyLinesCountBefore();
73 2
		if ($emptyLineCountBeforeStatement === $this->requiredEmptyLineCountBeforeStatement) {
74 2
			return;
75
		}
76
77 2
		$error = sprintf(
78 2
			'%s statement should be preceded by %s empty line(s); %s found',
79 2
			ucfirst($this->tokens[$position]['content']),
80 2
			$this->requiredEmptyLineCountBeforeStatement,
81
			$emptyLineCountBeforeStatement
82
		);
83 2
		$fix = $file->addFixableError($error, $position);
84 2
		if ($fix) {
85 1
			EmptyLinesResizer::resizeLines(
86
				$file,
87 1
				$this->findFirstPositionInCurrentLine($position),
88
				$emptyLineCountBeforeStatement,
89 1
				$this->requiredEmptyLineCountBeforeStatement
90
			);
91
		}
92 2
	}
93
94
95 2
	private function getEmptyLinesCountBefore() : int
96
	{
97 2
		$currentLine = $this->tokens[$this->position]['line'];
98 2
		$previousPosition = $this->position;
99
100
		do {
101 2
			$previousPosition--;
102
		} while (
103 2
			$currentLine === $this->tokens[$previousPosition]['line']
104 2
			|| $this->tokens[$previousPosition]['code'] === T_WHITESPACE
105
		);
106
107 2
		return $this->tokens[$this->position]['line'] - $this->tokens[$previousPosition]['line'] - 1;
108
	}
109
110
111 1
	private function findFirstPositionInCurrentLine(int $position) : int
112
	{
113 1
		$currentPosition = $position;
114 1
		$line = $this->tokens[$position]['line'];
115 1
		while ($this->tokens[$currentPosition]['line'] === $line) {
116 1
			$currentPosition--;
117
		}
118
119 1
		return $currentPosition;
120
	}
121
122
}
123