Skip to content

Commit 1b1b2b5

Browse files
authored
Add phpdoc and phpstan (#94)
* Add phpdoc to VariableAnalysisSniff class * Add phpstan * Fix phpstan errors * Add phpstan to CircleCI * Add phpdoc to Helpers * Fix phpstan errors for Helpers * Add phpdoc to ScopeInfo * Add phpdoc to Constants * Add phpdoc to VariableInfo * Add `lint-self` script * Remove unused variables * Make lint-self use PWD * Add lint to circleci
1 parent acfe65c commit 1b1b2b5

File tree

8 files changed

+533
-96
lines changed

8 files changed

+533
-96
lines changed

.circleci/config.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
version: 2
22
jobs:
3-
build:
3+
build_php7:
4+
docker:
5+
- image: circleci/php:7.3.1
6+
steps:
7+
- checkout
8+
- run: COMPOSER=composer.json composer install
9+
- run: COMPOSER=composer.json composer test
10+
- run: COMPOSER=composer.json composer phpstan
11+
- run: COMPOSER=composer.json composer lint
12+
- run: COMPOSER=composer.json composer lint-self
13+
build_php5:
414
docker:
515
- image: circleci/php:5.6.40-zts-stretch-node-browsers-legacy
616
steps:
717
- checkout
818
- run: COMPOSER=composer.circleci.json composer install
919
- run: COMPOSER=composer.circleci.json composer test
20+
workflows:
21+
version: 2
22+
build_php_versions:
23+
jobs:
24+
- build_php5
25+
- build_php7

VariableAnalysis/Lib/Constants.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ class Constants {
77
* Array of known pass-by-reference functions and the argument(s) which are passed
88
* by reference, the arguments are numbered starting from 1 and an elipsis '...'
99
* means all argument numbers after the previous should be considered pass-by-reference.
10+
*
11+
* @return array[]
1012
*/
1113
public static function getPassByReferenceFunctions() {
1214
return [
@@ -35,7 +37,6 @@ public static function getPassByReferenceFunctions() {
3537
'array_walk_recursive' => [1],
3638
'arsort' => [1],
3739
'asort' => [1],
38-
'asort' => [1],
3940
'bindColumn' => [2],
4041
'bindParam' => [2],
4142
'bind_param' => [2, 3, '...'],
@@ -202,7 +203,6 @@ public static function getPassByReferenceFunctions() {
202203
'sqlite_open' => [3],
203204
'sqlite_popen' => [3],
204205
'sqlite_query' => [4],
205-
'sqlite_query' => [4],
206206
'sqlite_unbuffered_query' => [4],
207207
'sscanf' => [3, '...'],
208208
'str_ireplace' => [4],
@@ -238,6 +238,9 @@ public static function getPassByReferenceFunctions() {
238238
];
239239
}
240240

241+
/**
242+
* @return array[]
243+
*/
241244
public static function getWordPressPassByReferenceFunctions() {
242245
return [
243246
'wp_parse_str' => [2],
@@ -247,6 +250,8 @@ public static function getWordPressPassByReferenceFunctions() {
247250

248251
/**
249252
* A regexp for matching variable names in double-quoted strings.
253+
*
254+
* @return string
250255
*/
251256
public static function getDoubleQuotedVarRegexp() {
252257
return '|(?<!\\\\)(?:\\\\{2})*\${?([a-zA-Z0-9_]+)}?|';

VariableAnalysis/Lib/Helpers.php

Lines changed: 111 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,73 @@
55
use PHP_CodeSniffer\Files\File;
66

77
class Helpers {
8+
/**
9+
* @param File $phpcsFile
10+
* @param int $stackPtr
11+
*
12+
* @return int|bool
13+
*/
814
public static function findContainingOpeningSquareBracket(File $phpcsFile, $stackPtr) {
9-
$tokens = $phpcsFile->getTokens();
1015
$previousStatementPtr = self::getPreviousStatementPtr($phpcsFile, $stackPtr);
1116
return $phpcsFile->findPrevious(T_OPEN_SHORT_ARRAY, $stackPtr - 1, $previousStatementPtr);
1217
}
1318

19+
/**
20+
* @param File $phpcsFile
21+
* @param int $stackPtr
22+
*
23+
* @return int|bool
24+
*/
1425
public static function findContainingClosingSquareBracket(File $phpcsFile, $stackPtr) {
15-
$tokens = $phpcsFile->getTokens();
1626
$endOfStatementPtr = $phpcsFile->findNext([T_SEMICOLON], $stackPtr + 1);
17-
if (! $endOfStatementPtr) {
27+
if (is_bool($endOfStatementPtr)) {
1828
return false;
1929
}
2030
return $phpcsFile->findNext(T_CLOSE_SHORT_ARRAY, $stackPtr + 1, $endOfStatementPtr);
2131
}
2232

33+
/**
34+
* @param File $phpcsFile
35+
* @param int $stackPtr
36+
*
37+
* @return int
38+
*/
2339
public static function getPreviousStatementPtr(File $phpcsFile, $stackPtr) {
24-
return $phpcsFile->findPrevious([T_SEMICOLON, T_CLOSE_CURLY_BRACKET], $stackPtr - 1) ?: 1;
40+
$result = $phpcsFile->findPrevious([T_SEMICOLON, T_CLOSE_CURLY_BRACKET], $stackPtr - 1);
41+
return is_bool($result) ? 1 : $result;
2542
}
2643

44+
/**
45+
* @param File $phpcsFile
46+
* @param int $stackPtr
47+
*
48+
* @return int|bool
49+
*/
2750
public static function findContainingOpeningBracket(File $phpcsFile, $stackPtr) {
2851
$tokens = $phpcsFile->getTokens();
2952
if (isset($tokens[$stackPtr]['nested_parenthesis'])) {
3053
$openPtrs = array_keys($tokens[$stackPtr]['nested_parenthesis']);
31-
return end($openPtrs);
54+
return (int)end($openPtrs);
3255
}
3356
return false;
3457
}
3558

59+
/**
60+
* @param File $phpcsFile
61+
* @param int $stackPtr
62+
*
63+
* @return int|bool
64+
*/
3665
public static function findParenthesisOwner(File $phpcsFile, $stackPtr) {
37-
$tokens = $phpcsFile->getTokens();
3866
return $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true);
3967
}
4068

69+
/**
70+
* @param File $phpcsFile
71+
* @param int[] $conditions
72+
*
73+
* @return bool
74+
*/
4175
public static function areAnyConditionsAClosure(File $phpcsFile, array $conditions) {
4276
// self within a closure is invalid
4377
$tokens = $phpcsFile->getTokens();
@@ -50,6 +84,12 @@ public static function areAnyConditionsAClosure(File $phpcsFile, array $conditio
5084
return false;
5185
}
5286

87+
88+
/**
89+
* @param int[] $conditions
90+
*
91+
* @return bool
92+
*/
5393
public static function areAnyConditionsAClass(array $conditions) {
5494
foreach (array_reverse($conditions, true) as $scopePtr => $scopeCode) {
5595
if ($scopeCode === T_CLASS || $scopeCode === T_TRAIT) {
@@ -59,6 +99,11 @@ public static function areAnyConditionsAClass(array $conditions) {
5999
return false;
60100
}
61101

102+
/**
103+
* @param int[] $conditions
104+
*
105+
* @return bool
106+
*/
62107
public static function areConditionsWithinFunctionBeforeClass(array $conditions) {
63108
// Return true if the token conditions are within a function before
64109
// they are within a class.
@@ -74,6 +119,12 @@ public static function areConditionsWithinFunctionBeforeClass(array $conditions)
74119
return false;
75120
}
76121

122+
/**
123+
* @param File $phpcsFile
124+
* @param int $openPtr
125+
*
126+
* @return int|bool
127+
*/
77128
public static function findPreviousFunctionPtr(File $phpcsFile, $openPtr) {
78129
// Function names are T_STRING, and return-by-reference is T_BITWISE_AND,
79130
// so we look backwards from the opening bracket for the first thing that
@@ -87,13 +138,13 @@ public static function findPreviousFunctionPtr(File $phpcsFile, $openPtr) {
87138
* @param File $phpcsFile
88139
* @param int $stackPtr
89140
*
90-
* @return int|false
141+
* @return int|bool
91142
*/
92143
public static function findFunctionCall(File $phpcsFile, $stackPtr) {
93144
$tokens = $phpcsFile->getTokens();
94145

95146
$openPtr = Helpers::findContainingOpeningBracket($phpcsFile, $stackPtr);
96-
if ($openPtr) {
147+
if (is_int($openPtr)) {
97148
// First non-whitespace thing and see if it's a T_STRING function name
98149
$functionPtr = $phpcsFile->findPrevious(T_WHITESPACE, $openPtr - 1, null, true, null, true);
99150
if ($tokens[$functionPtr]['code'] === T_STRING) {
@@ -103,6 +154,12 @@ public static function findFunctionCall(File $phpcsFile, $stackPtr) {
103154
return false;
104155
}
105156

157+
/**
158+
* @param File $phpcsFile
159+
* @param int $stackPtr
160+
*
161+
* @return array[]|false
162+
*/
106163
public static function findFunctionCallArguments(File $phpcsFile, $stackPtr) {
107164
$tokens = $phpcsFile->getTokens();
108165

@@ -129,19 +186,27 @@ public static function findFunctionCallArguments(File $phpcsFile, $stackPtr) {
129186
$argPtrs = [];
130187
$lastPtr = $openPtr;
131188
$lastArgComma = $openPtr;
132-
while (($nextPtr = $phpcsFile->findNext(T_COMMA, $lastPtr + 1, $closePtr)) !== false) {
189+
$nextPtr = $phpcsFile->findNext(T_COMMA, $lastPtr + 1, $closePtr);
190+
while (is_int($nextPtr)) {
133191
if (Helpers::findContainingOpeningBracket($phpcsFile, $nextPtr) == $openPtr) {
134192
// Comma is at our level of brackets, it's an argument delimiter.
135193
array_push($argPtrs, range($lastArgComma + 1, $nextPtr - 1));
136194
$lastArgComma = $nextPtr;
137195
}
138196
$lastPtr = $nextPtr;
197+
$nextPtr = $phpcsFile->findNext(T_COMMA, $lastPtr + 1, $closePtr);
139198
}
140199
array_push($argPtrs, range($lastArgComma + 1, $closePtr - 1));
141200

142201
return $argPtrs;
143202
}
144203

204+
/**
205+
* @param File $phpcsFile
206+
* @param int $stackPtr
207+
*
208+
* @return int
209+
*/
145210
public static function findWhereAssignExecuted(File $phpcsFile, $stackPtr) {
146211
$tokens = $phpcsFile->getTokens();
147212

@@ -171,6 +236,12 @@ public static function findWhereAssignExecuted(File $phpcsFile, $stackPtr) {
171236
return $assignEndTokens[0];
172237
}
173238

239+
/**
240+
* @param File $phpcsFile
241+
* @param int $stackPtr
242+
*
243+
* @return int|bool
244+
*/
174245
public static function isNextThingAnAssign(File $phpcsFile, $stackPtr) {
175246
$tokens = $phpcsFile->getTokens();
176247

@@ -184,16 +255,27 @@ public static function isNextThingAnAssign(File $phpcsFile, $stackPtr) {
184255
return false;
185256
}
186257

258+
/**
259+
* @param string $varName
260+
*
261+
* @return string
262+
*/
187263
public static function normalizeVarName($varName) {
188-
return preg_replace('/[{}$]/', '', $varName);
264+
$result = preg_replace('/[{}$]/', '', $varName);
265+
return $result ? $result : $varName;
189266
}
190267

268+
/**
269+
* @param File $phpcsFile
270+
* @param int $stackPtr
271+
*
272+
* @return int|bool
273+
*/
191274
public static function findFunctionPrototype(File $phpcsFile, $stackPtr) {
192275
$tokens = $phpcsFile->getTokens();
193-
$token = $tokens[$stackPtr];
194276

195277
$openPtr = Helpers::findContainingOpeningBracket($phpcsFile, $stackPtr);
196-
if ($openPtr === false) {
278+
if (! is_int($openPtr)) {
197279
return false;
198280
}
199281
$functionPtr = Helpers::findPreviousFunctionPtr($phpcsFile, $openPtr);
@@ -226,7 +308,7 @@ public static function findVariableScope(File $phpcsFile, $stackPtr) {
226308
}
227309

228310
$scopePtr = Helpers::findFunctionPrototype($phpcsFile, $stackPtr);
229-
if ($scopePtr !== false) {
311+
if (is_int($scopePtr)) {
230312
return $scopePtr;
231313
}
232314

@@ -239,6 +321,11 @@ public static function findVariableScope(File $phpcsFile, $stackPtr) {
239321
return 0;
240322
}
241323

324+
/**
325+
* @param string $message
326+
*
327+
* @return void
328+
*/
242329
public static function debug($message) {
243330
if (! defined('PHP_CODESNIFFER_VERBOSITY')) {
244331
return;
@@ -247,4 +334,15 @@ public static function debug($message) {
247334
echo PHP_EOL . "VariableAnalysisSniff: DEBUG: $message" . PHP_EOL;
248335
}
249336
}
337+
338+
/**
339+
* @param string $pattern
340+
* @param string $value
341+
*
342+
* @return string[]
343+
*/
344+
public static function splitStringToArray($pattern, $value) {
345+
$result = preg_split($pattern, $value);
346+
return is_array($result) ? $result : [];
347+
}
250348
}

VariableAnalysis/Lib/ScopeInfo.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
* Holds details of a scope.
77
*/
88
class ScopeInfo {
9+
/**
10+
* @var int
11+
*/
912
public $owner;
10-
public $opener;
11-
public $closer;
13+
14+
/**
15+
* @var VariableInfo[]
16+
*/
1217
public $variables = [];
1318

1419
public function __construct($currScope) {

0 commit comments

Comments
 (0)