Skip to content

Commit 73d7b07

Browse files
authored
Merge pull request #454 from PHPCSStandards/develop
Release 1.0.3
2 parents e74812a + 772f8fa commit 73d7b07

File tree

11 files changed

+146
-10
lines changed

11 files changed

+146
-10
lines changed

.github/workflows/update-phpcs-versionnr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
run: git status -vv --untracked=all
6969

7070
- name: Create pull request
71-
uses: peter-evans/create-pull-request@v4
71+
uses: peter-evans/create-pull-request@v5
7272
with:
7373
base: ${{ steps.branches.outputs.BASE }}
7474
branch: ${{ steps.branches.outputs.PR_BRANCH }}

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@ This projects adheres to [Keep a CHANGELOG](https://keepachangelog.com/) and use
99

1010
_Nothing yet._
1111

12+
## [1.0.3] - 2023-04-13
13+
14+
### Changed
15+
16+
#### Other
17+
18+
* Various small housekeeping and maintenance updates.
19+
20+
### Fixed
21+
22+
#### Utils
23+
24+
* The `PassedParameters` class now allows for function calls to global functions called `self()`, `parent()` or `static()`. [#452]
25+
26+
[#452]: https://github.com/PHPCSStandards/PHPCSUtils/pull/452
27+
28+
1229
## [1.0.2] - 2023-03-28
1330

1431
### Changed
@@ -805,6 +822,7 @@ This initial alpha release contains the following utility classes:
805822

806823

807824
[Unreleased]: https://github.com/PHPCSStandards/PHPCSUtils/compare/stable...HEAD
825+
[1.0.3]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.2...1.0.3
808826
[1.0.2]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.1...1.0.2
809827
[1.0.1]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.0...1.0.1
810828
[1.0.0]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.0-rc1...1.0.0

PHPCSUtils/Utils/PassedParameters.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ final class PassedParameters
4747
/**
4848
* Checks if any parameters have been passed.
4949
*
50-
* - If passed a `T_STRING`, `T_NAME_FULLY_QUALIFIED`, `T_NAME_RELATIVE`, `T_NAME_QUALIFIED`
50+
* - If passed a `T_STRING`, `T_NAME_FULLY_QUALIFIED`, `T_NAME_RELATIVE`, `T_NAME_QUALIFIED`,
5151
* or `T_VARIABLE` stack pointer, it will treat it as a function call.
5252
* If a `T_STRING` or `T_VARIABLE` which is *not* a function call is passed, the behaviour is
5353
* undetermined.
5454
* - If passed a `T_ANON_CLASS` stack pointer, it will accept it as a class instantiation.
5555
* - If passed a `T_SELF`, `T_STATIC` or `T_PARENT` stack pointer, it will accept it as a
56-
* class instantiation function call when used like `new self()`.
56+
* class instantiation function call when used like `new self()` (with or without parenthesis).
57+
* When these hierarchiecal keywords are not preceded by the `new` keyword, parenthesis
58+
* will be required for the token to be accepted.
5759
* - If passed a `T_ARRAY` or `T_OPEN_SHORT_ARRAY` stack pointer, it will detect
5860
* whether the array has values or is empty.
5961
* For purposes of backward-compatibility with older PHPCS versions, `T_OPEN_SQUARE_BRACKET`
@@ -89,9 +91,13 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray =
8991
);
9092
}
9193

94+
// Only accept self/static/parent if preceded by `new` or followed by an open parenthesis.
95+
$next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
9296
if (isset(Collections::ooHierarchyKeywords()[$tokens[$stackPtr]['code']]) === true) {
9397
$prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
94-
if ($tokens[$prev]['code'] !== \T_NEW) {
98+
if ($tokens[$prev]['code'] !== \T_NEW
99+
&& ($next !== false && $tokens[$next]['code'] !== \T_OPEN_PARENTHESIS)
100+
) {
95101
throw new RuntimeException(
96102
'The hasParameters() method expects a function call, array, isset or unset token to be passed.'
97103
);
@@ -107,7 +113,6 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray =
107113
);
108114
}
109115

110-
$next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
111116
if ($next === false) {
112117
return false;
113118
}

Tests/BackCompat/BCFile/GetDeclarationNameTest.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ enum Hoo : string
8585
/* testBackedEnumNoSpaceBetweenNameAndColon */
8686
enum Suit: int implements Colorful, CardGame {}
8787

88+
/* testFunctionReturnByRefWithReservedKeywordEach */
89+
function &each() {}
90+
8891
/* testLiveCoding */
8992
// Intentional parse error. This has to be the last test in the file.
9093
function // Comment.

Tests/BackCompat/BCFile/GetDeclarationNameTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ public function dataGetDeclarationName()
192192
'/* testBackedEnumNoSpaceBetweenNameAndColon */',
193193
'Suit',
194194
],
195+
'function-return-by-reference-with-reserved-keyword-each' => [
196+
'/* testFunctionReturnByRefWithReservedKeywordEach */',
197+
'each',
198+
],
195199
];
196200
}
197201
}

Tests/BackCompat/BCFile/GetMethodParametersTest.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ class ConstructorPropertyPromotionWithReadOnly {
206206
public function __construct(public readonly ?int $promotedProp, ReadOnly private string|bool &$promotedToo) {}
207207
}
208208

209+
class ConstructorPropertyPromotionWithReadOnlyNoTypeDeclaration {
210+
/* testPHP81ConstructorPropertyPromotionWithReadOnlyNoTypeDeclaration */
211+
// Intentional fatal error. Readonly properties MUST be typed.
212+
public function __construct(public readonly $promotedProp, ReadOnly private &$promotedToo) {}
213+
}
214+
209215
/* testPHP8ConstructorPropertyPromotionGlobalFunction */
210216
// Intentional fatal error. Property promotion not allowed in non-constructor, but that's not the concern of this method.
211217
function globalFunction(private $x) {}

Tests/BackCompat/BCFile/GetMethodParametersTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,6 +1961,57 @@ public function testPHP81ConstructorPropertyPromotionWithReadOnly()
19611961
$this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected);
19621962
}
19631963

1964+
/**
1965+
* Verify recognition of PHP8 constructor with property promotion using PHP 8.1 readonly keyword
1966+
* without a property type.
1967+
*
1968+
* @return void
1969+
*/
1970+
public function testPHP81ConstructorPropertyPromotionWithReadOnlyNoTypeDeclaration()
1971+
{
1972+
$expected = [];
1973+
$expected[0] = [
1974+
'token' => 8, // Offset from the T_FUNCTION token.
1975+
'name' => '$promotedProp',
1976+
'content' => 'public readonly $promotedProp',
1977+
'has_attributes' => false,
1978+
'pass_by_reference' => false,
1979+
'reference_token' => false,
1980+
'variable_length' => false,
1981+
'variadic_token' => false,
1982+
'type_hint' => '',
1983+
'type_hint_token' => false,
1984+
'type_hint_end_token' => false,
1985+
'nullable_type' => false,
1986+
'property_visibility' => 'public',
1987+
'visibility_token' => 4, // Offset from the T_FUNCTION token.
1988+
'property_readonly' => true,
1989+
'readonly_token' => 6, // Offset from the T_FUNCTION token.
1990+
'comma_token' => 9,
1991+
];
1992+
$expected[1] = [
1993+
'token' => 16, // Offset from the T_FUNCTION token.
1994+
'name' => '$promotedToo',
1995+
'content' => 'ReadOnly private &$promotedToo',
1996+
'has_attributes' => false,
1997+
'pass_by_reference' => true,
1998+
'reference_token' => 15, // Offset from the T_FUNCTION token.
1999+
'variable_length' => false,
2000+
'variadic_token' => false,
2001+
'type_hint' => '',
2002+
'type_hint_token' => false,
2003+
'type_hint_end_token' => false,
2004+
'nullable_type' => false,
2005+
'property_visibility' => 'private',
2006+
'visibility_token' => 13, // Offset from the T_FUNCTION token.
2007+
'property_readonly' => true,
2008+
'readonly_token' => 11, // Offset from the T_FUNCTION token.
2009+
'comma_token' => false,
2010+
];
2011+
2012+
$this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected);
2013+
}
2014+
19642015
/**
19652016
* Verify behaviour when a non-constructor function uses PHP 8 property promotion syntax.
19662017
*

Tests/Utils/ObjectDeclarations/GetNameDiffTest.inc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ interface switch{ // Intentional parse error.
1212
public function someFunction();
1313
}
1414

15+
/* testFunctionReturnByRefWithReservedKeywordParent */
16+
function &parent() {}
17+
18+
/* testFunctionReturnByRefWithReservedKeywordSelf */
19+
function &self() {}
20+
21+
/* testFunctionReturnByRefWithReservedKeywordStatic */
22+
function &static() {}
23+
1524
/* testLiveCoding */
1625
// Intentional parse error. Redundancy testing.
1726
abstract class

Tests/Utils/ObjectDeclarations/GetNameDiffTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ public function dataGetName()
117117
'testMarker' => '/* testInvalidInterfaceName */',
118118
'expected' => 'switch',
119119
],
120+
'function-return-by-reference-with-reserved-keyword-parent' => [
121+
'/* testFunctionReturnByRefWithReservedKeywordParent */',
122+
'parent',
123+
],
124+
'function-return-by-reference-with-reserved-keyword-self' => [
125+
'/* testFunctionReturnByRefWithReservedKeywordSelf */',
126+
'self',
127+
],
128+
'function-return-by-reference-with-reserved-keyword-static' => [
129+
'/* testFunctionReturnByRefWithReservedKeywordStatic */',
130+
'static',
131+
],
120132
];
121133
}
122134
}

Tests/Utils/PassedParameters/HasParametersTest.inc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ class HierarchyKeywordsAsMethodNames {
7474
/* testHasParamsFunctionCall8 */
7575
$a = $this->parent(true);
7676
}
77+
78+
public function callGlobalFunctionsUsingKeywords() {
79+
/* testHasParamsFunctionCall9 */
80+
$a = self(true);
81+
/* testHasParamsFunctionCall10 */
82+
$a = static(true);
83+
/* testHasParamsFunctionCall11 */
84+
$a = parent(true);
85+
}
7786
}
7887

7988
/* testNoParamsFunctionCallFullyQualified */

0 commit comments

Comments
 (0)