Skip to content

Commit 6d66956

Browse files
authored
Allow self within class method closures (#70)
* Test: self can be used inside class closures * Allow self within closures * Test: more tests for self/static/this in closures
1 parent 30e1278 commit 6d66956

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -450,14 +450,8 @@ protected function checkForStaticOutsideClass(File $phpcsFile, $stackPtr, $varNa
450450
}
451451
$errorClass = $code === T_SELF ? 'SelfOutsideClass' : 'StaticOutsideClass';
452452
$staticRefType = $code === T_SELF ? 'self::' : 'static::';
453-
if (!empty($token['conditions'])) {
454-
if (Helpers::areAnyConditionsAClosure($phpcsFile, $token['conditions'])) {
455-
$phpcsFile->addError("Use of {$staticRefType}%s inside closure.", $stackPtr, $errorClass, ["\${$varName}"]);
456-
return true;
457-
}
458-
if (Helpers::areAnyConditionsAClass($token['conditions'])) {
459-
return false;
460-
}
453+
if (!empty($token['conditions']) && Helpers::areAnyConditionsAClass($token['conditions'])) {
454+
return false;
461455
}
462456
$phpcsFile->addError(
463457
"Use of {$staticRefType}%s outside class definition.",
@@ -760,7 +754,7 @@ protected function processVariable(File $phpcsFile, $stackPtr) {
760754
// Is an optional function/closure parameter with non-null value
761755
// Is closure use declaration of a variable defined within containing scope
762756
// catch (...) block start
763-
// $this within a class (but not within a closure).
757+
// $this within a class.
764758
// $GLOBALS, $_REQUEST, etc superglobals.
765759
// $var part of class::$var static member
766760
// Assignment via =

VariableAnalysis/Tests/CodeAnalysis/VariableAnalysisTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ public function testFunctionWithClosureErrors() {
200200
$phpcsFile->process();
201201
$lines = $this->getErrorLineNumbersFromFile($phpcsFile);
202202
$expectedErrors = [
203-
50,
203+
58,
204+
70,
204205
];
205206
$this->assertEquals($expectedErrors, $lines);
206207
}
@@ -229,6 +230,7 @@ public function testFunctionWithClosureWarnings() {
229230
27,
230231
28,
231232
35,
233+
64,
232234
];
233235
$this->assertEquals($expectedWarnings, $lines);
234236
}

VariableAnalysis/Tests/CodeAnalysis/fixtures/FunctionWithClosureFixture.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,33 @@ function method_with_self_inside_closure() {
5252
echo self::$static_member;
5353
}
5454
}
55+
56+
function function_with_self_in_closure() {
57+
return function() {
58+
return self::$foobar; // should be an error
59+
}
60+
}
61+
62+
function function_with_this_in_closure() {
63+
return function() {
64+
return $this->$foobar; // should be an error
65+
}
66+
}
67+
68+
function function_with_static_in_closure() {
69+
return function() {
70+
return static::$foobar; // should be an error
71+
}
72+
}
73+
74+
class ClassWithStaticInsideClosure {
75+
static $static_member;
76+
77+
function method_with_self_inside_closure() {
78+
echo static::$static_member;
79+
array_map(function () {
80+
echo static::$static_member;
81+
}, array());
82+
echo static::$static_member;
83+
}
84+
}

0 commit comments

Comments
 (0)