Skip to content

Commit 0145399

Browse files
committed
Update code to PHPStan Level 3
Added ReturnTypeWillChange Fix return type for Expression Add type hints for returned variables Add generic parameter for delimted list Fixing type hints Ignore co-variance error Remove TODO - it already must always be a Node Ignore error Add missing types Update phpstan to level 3 Add phpstan to dev reqs No need to install phpstan independently Do not override unary expression operand It seems to me that the operand can be any expression Added token to operand types -- should this be MissingToken? Include tokens in return types ExpressionStatement => EchoStatement It seems this is always an EchoStatement not an ExpressionStatement unaryExpressionOrHigher can return a ThrowExpression Remove overridden property Add Token to union Remove QualifiedName and rename local variable Remove unused import Add return types Remove trailing whitespace Add MissingToken type
1 parent a35ec03 commit 0145399

17 files changed

+49
-38
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ cache:
2525
- validation/frameworks
2626

2727
before_script:
28-
- if [[ $STATIC_ANALYSIS = true ]]; then composer require phpstan/phpstan --no-update; fi
2928
- composer install
3029
- set -e # Stop on first error.
3130
- phpenv config-rm xdebug.ini || true

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"php": ">=7.2"
77
},
88
"require-dev": {
9-
"phpunit/phpunit": "^8.5.15"
9+
"phpunit/phpunit": "^8.5.15",
10+
"phpstan/phpstan": "^1.8"
1011
},
1112
"license": "MIT",
1213
"authors": [

phpstan.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
parameters:
2-
level: 2
2+
level: 3
33
paths:
44
- src/
55
ignoreErrors:

src/Node.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ public function getRoot() : Node {
140140
while ($node->parent !== null) {
141141
$node = $node->parent;
142142
}
143+
144+
/** @var SourceFileNode $node */
143145
return $node;
144146
}
145147

@@ -613,6 +615,7 @@ public function getNamespaceDefinition() {
613615
$namespaceDefinition = null;
614616
}
615617

618+
/** @var NamespaceDefinition|null $namespaceDefinition */
616619
return $namespaceDefinition;
617620
}
618621

src/Node/EnumCaseDeclaration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class EnumCaseDeclaration extends Node {
1616
/** @var Token */
1717
public $caseKeyword;
1818

19-
/** @var QualifiedName */
19+
/** @var Token */
2020
public $name;
2121

2222
/** @var Token|null */

src/Node/Expression/AssignmentExpression.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class AssignmentExpression extends BinaryExpression {
1313

14-
/** @var Expression */
14+
/** @var Expression|Token */
1515
public $leftOperand;
1616

1717
/** @var Token */

src/Node/Expression/BinaryExpression.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111

1212
class BinaryExpression extends Expression {
1313

14-
/** @var Expression */
14+
/** @var Expression|Token */
1515
public $leftOperand;
1616

1717
/** @var Token */
1818
public $operator;
1919

20-
/** @var Expression */
20+
/** @var Expression|Token */
2121
public $rightOperand;
2222

2323
const CHILD_NAMES = [

src/Node/Expression/PrefixUpdateExpression.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ class PrefixUpdateExpression extends UnaryExpression {
1313
/** @var Token */
1414
public $incrementOrDecrementOperator;
1515

16-
/** @var Variable */
17-
public $operand;
18-
1916
const CHILD_NAMES = [
2017
'incrementOrDecrementOperator',
2118
'operand'

src/Node/Expression/SubscriptExpression.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Microsoft\PhpParser\Node\Expression;
88

9+
use Microsoft\PhpParser\MissingToken;
910
use Microsoft\PhpParser\Node\Expression;
1011
use Microsoft\PhpParser\Token;
1112

@@ -17,7 +18,7 @@ class SubscriptExpression extends Expression {
1718
/** @var Token */
1819
public $openBracketOrBrace;
1920

20-
/** @var Expression */
21+
/** @var Expression|MissingToken */
2122
public $accessExpression;
2223

2324
/** @var Token */

src/Node/Expression/UnaryExpression.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
namespace Microsoft\PhpParser\Node\Expression;
88

99
use Microsoft\PhpParser\Node\Expression;
10+
use Microsoft\PhpParser\Token;
1011

1112
class UnaryExpression extends Expression {
12-
/** @var UnaryExpression|Variable */
13+
/** @var Expression|Variable|Token */
1314
public $operand;
1415

1516
const CHILD_NAMES = [

src/Node/Expression/UnaryOpExpression.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ class UnaryOpExpression extends UnaryExpression {
1313
/** @var Token */
1414
public $operator;
1515

16-
/** @var UnaryExpression */
17-
public $operand;
18-
1916
const CHILD_NAMES = [
2017
'operator',
2118
'operand'

src/Node/FunctionReturnType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\MissingToken;
910
use Microsoft\PhpParser\Token;
1011

1112
trait FunctionReturnType {
@@ -14,6 +15,6 @@ trait FunctionReturnType {
1415
// TODO: This may be the wrong choice if ?type can ever be mixed with other types in union types
1516
/** @var Token|null */
1617
public $questionToken;
17-
/** @var DelimitedList\QualifiedNameList|null */
18+
/** @var DelimitedList\QualifiedNameList|null|MissingToken */
1819
public $returnTypeList;
1920
}

src/Node/MissingMemberDeclaration.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\MissingToken;
910
use Microsoft\PhpParser\ModifiedTypeInterface;
1011
use Microsoft\PhpParser\ModifiedTypeTrait;
1112
use Microsoft\PhpParser\Node;
@@ -20,7 +21,7 @@ class MissingMemberDeclaration extends Node implements ModifiedTypeInterface {
2021
/** @var Token|null needed along with typeDeclaration for what looked like typed property declarations but was missing VariableName */
2122
public $questionToken;
2223

23-
/** @var DelimitedList\QualifiedNameList|null */
24+
/** @var DelimitedList\QualifiedNameList|null|MissingToken */
2425
public $typeDeclarationList;
2526

2627
const CHILD_NAMES = [

src/Node/NamespaceUseClause.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\MissingToken;
910
use Microsoft\PhpParser\Node;
1011
use Microsoft\PhpParser\Node\DelimitedList;
1112
use Microsoft\PhpParser\Token;
1213

1314
class NamespaceUseClause extends Node {
14-
/** @var QualifiedName */
15+
/** @var QualifiedName|MissingToken */
1516
public $namespaceName;
1617
/** @var NamespaceAliasingClause */
1718
public $namespaceAliasingClause;

src/Node/Statement/InlineHtml.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class InlineHtml extends StatementNode {
2020
public $scriptSectionStartTag;
2121

2222
/**
23-
* @var ExpressionStatement|null used to represent the expression echoed by `<?=` while parsing.
23+
* @var EchoStatement|null used to represent the expression echoed by `<?=` while parsing.
2424
*
2525
* This should always be null in the returned AST,
2626
* and is deliberately excluded from CHILD_NAMES.

src/Node/Statement/NamespaceDefinition.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Microsoft\PhpParser\Node\Statement;
88

9+
use Microsoft\PhpParser\MissingToken;
910
use Microsoft\PhpParser\Node\QualifiedName;
1011
use Microsoft\PhpParser\Node\StatementNode;
1112
use Microsoft\PhpParser\Token;
@@ -17,7 +18,7 @@
1718
class NamespaceDefinition extends StatementNode {
1819
/** @var Token */
1920
public $namespaceKeyword;
20-
/** @var QualifiedName|null */
21+
/** @var QualifiedName|null|MissingToken */
2122
public $name;
2223
/** @var CompoundStatementNode|Token */
2324
public $compoundStatementOrSemicolon;

src/Parser.php

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ private function parseClassDeclaration($parentNode) : Node {
691691
return $classNode;
692692
}
693693

694-
private function parseClassMembers($parentNode) : Node {
694+
private function parseClassMembers($parentNode) : ClassMembersNode {
695695
$classMembers = new ClassMembersNode();
696696
$classMembers->openBrace = $this->eat1(TokenKind::OpenBraceToken);
697697
$classMembers->classMemberDeclarations = $this->parseList($classMembers, ParseContext::ClassMembers);
@@ -804,7 +804,7 @@ private function parseAttributeGroups($parentNode): array
804804
}
805805

806806
/**
807-
* @return DelimitedList\AttributeElementList
807+
* @return DelimitedList\AttributeElementList|null
808808
*/
809809
private function parseAttributeElementList(AttributeGroup $parentNode) {
810810
return $this->parseDelimitedList(
@@ -1638,13 +1638,14 @@ private function isParameterStartFn() {
16381638
}
16391639

16401640
/**
1641-
* @param string $className (name of subclass of DelimitedList)
1641+
* @template TDelimitedList of DelimitedList
1642+
* @param class-string<TDelimitedList> $className (name of subclass of DelimitedList)
16421643
* @param int|int[] $delimiter
16431644
* @param callable $isElementStartFn
16441645
* @param callable $parseElementFn
16451646
* @param Node $parentNode
16461647
* @param bool $allowEmptyElements
1647-
* @return DelimitedList|null instance of $className
1648+
* @return TDelimitedList|null instance of $className
16481649
*/
16491650
private function parseDelimitedList($className, $delimiter, $isElementStartFn, $parseElementFn, $parentNode, $allowEmptyElements = false) {
16501651
// TODO consider allowing empty delimiter to be more tolerant
@@ -1994,7 +1995,7 @@ private function parseWhileStatement($parentNode) {
19941995
/**
19951996
* @param Node $parentNode
19961997
* @param bool $force
1997-
* @return Node|MissingToken|array - The expression, or a missing token, or (if $force) an array containing a missed and skipped token
1998+
* @return Expression|MissingToken|array - The expression, or a missing token, or (if $force) an array containing a missed and skipped token
19981999
*/
19992000
private function parseExpression($parentNode, $force = false) {
20002001
$token = $this->getCurrentToken();
@@ -2020,7 +2021,7 @@ private function parseExpressionFn() {
20202021

20212022
/**
20222023
* @param Node $parentNode
2023-
* @return Expression
2024+
* @return UnaryExpression|MissingToken|Variable|ThrowExpression
20242025
*/
20252026
private function parseUnaryExpressionOrHigher($parentNode) {
20262027
$token = $this->getCurrentToken();
@@ -3200,9 +3201,16 @@ private function parseMemberAccessExpression($expression):MemberAccessExpression
32003201
private function parseScopedPropertyAccessExpression($expression, $fallbackParentNode): ScopedPropertyAccessExpression {
32013202
$scopedPropertyAccessExpression = new ScopedPropertyAccessExpression();
32023203
$scopedPropertyAccessExpression->parent = $expression->parent ?? $fallbackParentNode;
3204+
32033205
if ($expression instanceof Node) {
32043206
$expression->parent = $scopedPropertyAccessExpression;
3205-
$scopedPropertyAccessExpression->scopeResolutionQualifier = $expression; // TODO ensure always a Node
3207+
3208+
// scopeResolutionQualifier does not accept `Node` but
3209+
// `Expression|QualifiedName|Token`. I'm not sure if we can depend
3210+
// on that being the case.
3211+
//
3212+
// @phpstan-ignore-next-line
3213+
$scopedPropertyAccessExpression->scopeResolutionQualifier = $expression;
32063214
}
32073215

32083216
$scopedPropertyAccessExpression->doubleColon = $this->eat1(TokenKind::ColonColonToken);
@@ -3350,18 +3358,18 @@ private function parseClassConstDeclaration($parentNode, $modifiers) {
33503358
}
33513359

33523360
private function parseEnumCaseDeclaration($parentNode) {
3353-
$classConstDeclaration = new EnumCaseDeclaration();
3354-
$classConstDeclaration->parent = $parentNode;
3355-
$classConstDeclaration->caseKeyword = $this->eat1(TokenKind::CaseKeyword);
3356-
$classConstDeclaration->name = $this->eat($this->nameOrKeywordOrReservedWordTokens);
3357-
$classConstDeclaration->equalsToken = $this->eatOptional1(TokenKind::EqualsToken);
3358-
if ($classConstDeclaration->equalsToken !== null) {
3361+
$enumCaseDeclaration = new EnumCaseDeclaration();
3362+
$enumCaseDeclaration->parent = $parentNode;
3363+
$enumCaseDeclaration->caseKeyword = $this->eat1(TokenKind::CaseKeyword);
3364+
$enumCaseDeclaration->name = $this->eat($this->nameOrKeywordOrReservedWordTokens);
3365+
$enumCaseDeclaration->equalsToken = $this->eatOptional1(TokenKind::EqualsToken);
3366+
if ($enumCaseDeclaration->equalsToken !== null) {
33593367
// TODO add post-parse rule that checks for invalid assignments
3360-
$classConstDeclaration->assignment = $this->parseExpression($classConstDeclaration);
3368+
$enumCaseDeclaration->assignment = $this->parseExpression($enumCaseDeclaration);
33613369
}
3362-
$classConstDeclaration->semicolon = $this->eat1(TokenKind::SemicolonToken);
3370+
$enumCaseDeclaration->semicolon = $this->eat1(TokenKind::SemicolonToken);
33633371

3364-
return $classConstDeclaration;
3372+
return $enumCaseDeclaration;
33653373
}
33663374

33673375
/**
@@ -3434,7 +3442,7 @@ private function parseQualifiedNameCatchList($parentNode) {
34343442
return $result;
34353443
}
34363444

3437-
private function parseInterfaceDeclaration($parentNode) {
3445+
private function parseInterfaceDeclaration($parentNode): InterfaceDeclaration {
34383446
$interfaceDeclaration = new InterfaceDeclaration(); // TODO verify not nested
34393447
$interfaceDeclaration->parent = $parentNode;
34403448
$interfaceDeclaration->interfaceKeyword = $this->eat1(TokenKind::InterfaceKeyword);
@@ -3444,7 +3452,7 @@ private function parseInterfaceDeclaration($parentNode) {
34443452
return $interfaceDeclaration;
34453453
}
34463454

3447-
private function parseInterfaceMembers($parentNode) : Node {
3455+
private function parseInterfaceMembers($parentNode) : InterfaceMembers {
34483456
$interfaceMembers = new InterfaceMembers();
34493457
$interfaceMembers->openBrace = $this->eat1(TokenKind::OpenBraceToken);
34503458
$interfaceMembers->interfaceMemberDeclarations = $this->parseList($interfaceMembers, ParseContext::InterfaceMembers);

0 commit comments

Comments
 (0)