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

ClassDeclarationSniff::processOpen()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 13

Duplication

Lines 19
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 19
loc 19
ccs 0
cts 18
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 13
nc 3
nop 2
crap 12
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\Classes;
11
12
use PEAR_Sniffs_Classes_ClassDeclarationSniff;
13
use PHP_CodeSniffer_File;
14
15
16
/**
17
 * Rules (new to parent class):
18
 * - Opening brace for the %s should be followed by %s empty line(s).
19
 * - Closing brace for the %s should be preceded by %s empty line(s).
20
 */
21
final class ClassDeclarationSniff extends PEAR_Sniffs_Classes_ClassDeclarationSniff
22
{
23
24
	/**
25
	 * @var string
26
	 */
27
	const NAME = 'ZenifyCodingStandard.Classes.ClassDeclaration';
28
29
	/**
30
	 * @var int
31
	 */
32
	public $emptyLinesAfterOpeningBrace = 1;
33
34
	/**
35
	 * @var int
36
	 */
37
	public $emptyLinesBeforeClosingBrace = 1;
38
39
	/**
40
	 * @var PHP_CodeSniffer_File
41
	 */
42
	private $file;
43
44
45
	/**
46
	 * @param PHP_CodeSniffer_File $file
47
	 * @param int $position
48
	 */
49
	public function process(PHP_CodeSniffer_File $file, $position)
50
	{
51
		parent::process($file, $position);
52
		$this->file = $file;
53
54
		// Fix type
55
		$this->emptyLinesAfterOpeningBrace = (int) $this->emptyLinesAfterOpeningBrace;
56
		$this->emptyLinesBeforeClosingBrace = (int) $this->emptyLinesBeforeClosingBrace;
57
58
		$this->processOpen($file, $position);
59
		$this->processClose($file, $position);
60
	}
61
62
63 View Code Duplication
	private function processOpen(PHP_CodeSniffer_File $file, int $position)
64
	{
65
		$tokens = $file->getTokens();
66
		$openingBracePosition = $tokens[$position]['scope_opener'];
67
		$emptyLinesCount = $this->getEmptyLinesAfterOpeningBrace($file, $openingBracePosition);
68
69
		if ($emptyLinesCount !== $this->emptyLinesAfterOpeningBrace) {
70
			$error = 'Opening brace for the %s should be followed by %s empty line(s); %s found.';
71
			$data = [
72
				$tokens[$position]['content'],
73
				$this->emptyLinesAfterOpeningBrace,
74
				$emptyLinesCount,
75
			];
76
			$fix = $file->addFixableError($error, $openingBracePosition, 'OpenBraceFollowedByEmptyLines', $data);
77
			if ($fix) {
78
				$this->fixOpeningBraceSpaces($openingBracePosition, $emptyLinesCount);
79
			}
80
		}
81
	}
82
83
84 View Code Duplication
	private function processClose(PHP_CodeSniffer_File $file, int $position)
85
	{
86
		$tokens = $file->getTokens();
87
		$closeBracePosition = $tokens[$position]['scope_closer'];
88
		$emptyLinesCount = $this->getEmptyLinesBeforeClosingBrace($file, $closeBracePosition);
89
90
		if ($emptyLinesCount !== $this->emptyLinesBeforeClosingBrace) {
91
			$error = 'Closing brace for the %s should be preceded by %s empty line(s); %s found.';
92
			$data = [
93
				$tokens[$position]['content'],
94
				$this->emptyLinesBeforeClosingBrace,
95
				$emptyLinesCount
96
			];
97
			$fix = $file->addFixableError($error, $closeBracePosition, 'CloseBracePrecededByEmptyLines', $data);
98
			if ($fix) {
99
				$this->fixClosingBraceSpaces($closeBracePosition, $emptyLinesCount);
100
			}
101
		}
102
	}
103
104
105
	private function getEmptyLinesBeforeClosingBrace(PHP_CodeSniffer_File $file, int $position) : int
106
	{
107
		$tokens = $file->getTokens();
108
		$prevContent = $file->findPrevious(T_WHITESPACE, ($position - 1), NULL, TRUE);
109
		return $tokens[$position]['line'] - $tokens[$prevContent]['line'] - 1;
110
	}
111
112
113
	private function getEmptyLinesAfterOpeningBrace(PHP_CodeSniffer_File $file, int $position) : int
114
	{
115
		$tokens = $file->getTokens();
116
		$nextContent = $file->findNext(T_WHITESPACE, ($position + 1), NULL, TRUE);
117
		return $tokens[$nextContent]['line'] - $tokens[$position]['line'] - 1;
118
	}
119
120
121 View Code Duplication
	private function fixOpeningBraceSpaces(int $position, int $numberOfSpaces)
122
	{
123
		if ($numberOfSpaces < $this->emptyLinesAfterOpeningBrace) {
124
			for ($i = $numberOfSpaces; $i < $this->emptyLinesAfterOpeningBrace; $i++) {
125
				$this->file->fixer->addContent($position, PHP_EOL);
126
			}
127
128
		} else {
129
			for ($i = $numberOfSpaces; $i > $this->emptyLinesAfterOpeningBrace; $i--) {
130
				$this->file->fixer->replaceToken($position + $i, '');
131
			}
132
		}
133
	}
134
135
136 View Code Duplication
	private function fixClosingBraceSpaces(int $position, int $numberOfSpaces)
137
	{
138
		if ($numberOfSpaces < $this->emptyLinesBeforeClosingBrace) {
139
			for ($i = $numberOfSpaces; $i < $this->emptyLinesBeforeClosingBrace; $i++) {
140
				$this->file->fixer->addContentBefore($position, PHP_EOL);
141
			}
142
143
		} else {
144
			for ($i = $numberOfSpaces; $i > $this->emptyLinesBeforeClosingBrace; $i--) {
145
				$this->file->fixer->replaceToken($position - $i, '');
146
			}
147
		}
148
	}
149
150
}
151