comparison vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents
children af1871eacc83
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
1 <?php
2 /**
3 * A local file represents a chunk of text has a file system location.
4 *
5 * @author Greg Sherwood <gsherwood@squiz.net>
6 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
7 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8 */
9
10 namespace PHP_CodeSniffer\Files;
11
12 use PHP_CodeSniffer\Ruleset;
13 use PHP_CodeSniffer\Config;
14 use PHP_CodeSniffer\Util\Cache;
15
16 class LocalFile extends File
17 {
18
19
20 /**
21 * Creates a LocalFile object and sets the content.
22 *
23 * @param string $path The absolute path to the file.
24 * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
25 * @param \PHP_CodeSniffer\Config $config The config data for the run.
26 *
27 * @return void
28 */
29 public function __construct($path, Ruleset $ruleset, Config $config)
30 {
31 $this->path = trim($path);
32 if (is_readable($this->path) === false) {
33 parent::__construct($this->path, $ruleset, $config);
34 $error = 'Error opening file; file no longer exists or you do not have access to read the file';
35 $this->addMessage(true, $error, 1, 1, 'Internal.LocalFile', [], 5, false);
36 $this->ignored = true;
37 return;
38 }
39
40 // Before we go and spend time tokenizing this file, just check
41 // to see if there is a tag up top to indicate that the whole
42 // file should be ignored. It must be on one of the first two lines.
43 if ($config->annotations === true) {
44 $handle = fopen($this->path, 'r');
45 if ($handle !== false) {
46 $firstContent = fgets($handle);
47 $firstContent .= fgets($handle);
48 fclose($handle);
49
50 if (strpos($firstContent, '@codingStandardsIgnoreFile') !== false
51 || stripos($firstContent, 'phpcs:ignorefile') !== false
52 ) {
53 // We are ignoring the whole file.
54 $this->ignored = true;
55 return;
56 }
57 }
58 }
59
60 $this->reloadContent();
61
62 return parent::__construct($this->path, $ruleset, $config);
63
64 }//end __construct()
65
66
67 /**
68 * Loads the latest version of the file's content from the file system.
69 *
70 * @return void
71 */
72 public function reloadContent()
73 {
74 $this->setContent(file_get_contents($this->path));
75
76 }//end reloadContent()
77
78
79 /**
80 * Processes the file.
81 *
82 * @return void
83 */
84 public function process()
85 {
86 if ($this->ignored === true) {
87 return;
88 }
89
90 if ($this->configCache['cache'] === false) {
91 return parent::process();
92 }
93
94 $hash = md5_file($this->path);
95 $cache = Cache::get($this->path);
96 if ($cache !== false && $cache['hash'] === $hash) {
97 // We can't filter metrics, so just load all of them.
98 $this->metrics = $cache['metrics'];
99
100 if ($this->configCache['recordErrors'] === true) {
101 // Replay the cached errors and warnings to filter out the ones
102 // we don't need for this specific run.
103 $this->configCache['cache'] = false;
104 $this->replayErrors($cache['errors'], $cache['warnings']);
105 $this->configCache['cache'] = true;
106 } else {
107 $this->errorCount = $cache['errorCount'];
108 $this->warningCount = $cache['warningCount'];
109 $this->fixableCount = $cache['fixableCount'];
110 }
111
112 if (PHP_CODESNIFFER_VERBOSITY > 0
113 || (PHP_CODESNIFFER_CBF === true && empty($this->config->files) === false)
114 ) {
115 echo "[loaded from cache]... ";
116 }
117
118 $this->numTokens = $cache['numTokens'];
119 $this->fromCache = true;
120 return;
121 }//end if
122
123 if (PHP_CODESNIFFER_VERBOSITY > 1) {
124 echo PHP_EOL;
125 }
126
127 parent::process();
128
129 $cache = [
130 'hash' => $hash,
131 'errors' => $this->errors,
132 'warnings' => $this->warnings,
133 'metrics' => $this->metrics,
134 'errorCount' => $this->errorCount,
135 'warningCount' => $this->warningCount,
136 'fixableCount' => $this->fixableCount,
137 'numTokens' => $this->numTokens,
138 ];
139
140 Cache::set($this->path, $cache);
141
142 // During caching, we don't filter out errors in any way, so
143 // we need to do that manually now by replaying them.
144 if ($this->configCache['recordErrors'] === true) {
145 $this->configCache['cache'] = false;
146 $this->replayErrors($this->errors, $this->warnings);
147 $this->configCache['cache'] = true;
148 }
149
150 }//end process()
151
152
153 /**
154 * Clears and replays error and warnings for the file.
155 *
156 * Replaying errors and warnings allows for filtering rules to be changed
157 * and then errors and warnings to be reapplied with the new rules. This is
158 * particularly useful while caching.
159 *
160 * @param array $errors The list of errors to replay.
161 * @param array $warnings The list of warnings to replay.
162 *
163 * @return void
164 */
165 private function replayErrors($errors, $warnings)
166 {
167 $this->errors = [];
168 $this->warnings = [];
169 $this->errorCount = 0;
170 $this->warningCount = 0;
171 $this->fixableCount = 0;
172
173 foreach ($errors as $line => $lineErrors) {
174 foreach ($lineErrors as $column => $colErrors) {
175 foreach ($colErrors as $error) {
176 $this->activeListener = $error['listener'];
177 $this->addMessage(
178 true,
179 $error['message'],
180 $line,
181 $column,
182 $error['source'],
183 [],
184 $error['severity'],
185 $error['fixable']
186 );
187 }
188 }
189 }
190
191 foreach ($warnings as $line => $lineErrors) {
192 foreach ($lineErrors as $column => $colErrors) {
193 foreach ($colErrors as $error) {
194 $this->activeListener = $error['listener'];
195 $this->addMessage(
196 false,
197 $error['message'],
198 $line,
199 $column,
200 $error['source'],
201 [],
202 $error['severity'],
203 $error['fixable']
204 );
205 }
206 }
207 }
208
209 }//end replayErrors()
210
211
212 }//end class