Skip to content

Commit 52e792a

Browse files
authored
Merge pull request microsoft#337 from PythooonUser/helper-function-on-modified-types
Refactoring modified type behaviors
2 parents 8bb0959 + 6b07add commit 52e792a

8 files changed

+163
-93
lines changed

src/ModifiedTypeInterface.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/*---------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All rights reserved.
4+
* Licensed under the MIT License. See License.txt in the project root for license information.
5+
*--------------------------------------------------------------------------------------------*/
6+
7+
namespace Microsoft\PhpParser;
8+
9+
/**
10+
* Use the ModifiedTypeTrait for convenience in order to implement this interface.
11+
*/
12+
interface ModifiedTypeInterface {
13+
public function hasModifier(int $targetModifier): bool;
14+
public function isPublic(): bool;
15+
public function isStatic(): bool;
16+
}

src/ModifiedTypeTrait.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
/*---------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All rights reserved.
4+
* Licensed under the MIT License. See License.txt in the project root for license information.
5+
*--------------------------------------------------------------------------------------------*/
6+
7+
namespace Microsoft\PhpParser;
8+
9+
trait ModifiedTypeTrait {
10+
/** @var Token[] */
11+
public $modifiers;
12+
13+
public function hasModifier(int $targetModifier): bool {
14+
if ($this->modifiers === null) {
15+
return false;
16+
}
17+
18+
foreach ($this->modifiers as $modifier) {
19+
if ($modifier->kind === $targetModifier) {
20+
return true;
21+
}
22+
}
23+
24+
return false;
25+
}
26+
27+
/**
28+
* Convenience method to check for the existence of the "public" modifier.
29+
* Does not necessarily need to be defined for that type.
30+
*
31+
* @return bool
32+
*/
33+
public function isPublic(): bool {
34+
return $this->hasModifier(TokenKind::PublicKeyword);
35+
}
36+
37+
/**
38+
* Convenience method to check for the existence of the "static" modifier.
39+
* Does not necessarily need to be defined for that type.
40+
*
41+
* @return bool
42+
*/
43+
public function isStatic(): bool {
44+
return $this->hasModifier(TokenKind::StaticKeyword);
45+
}
46+
}

src/Node/ClassConstDeclaration.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\ModifiedTypeInterface;
10+
use Microsoft\PhpParser\ModifiedTypeTrait;
911
use Microsoft\PhpParser\Node;
1012
use Microsoft\PhpParser\Token;
1113

12-
class ClassConstDeclaration extends Node {
13-
14-
/** @var Token[] */
15-
public $modifiers;
14+
class ClassConstDeclaration extends Node implements ModifiedTypeInterface {
15+
use ModifiedTypeTrait;
1616

1717
/** @var Token */
1818
public $constKeyword;

src/Node/MethodDeclaration.php

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@
1010
use Microsoft\PhpParser\DiagnosticKind;
1111
use Microsoft\PhpParser\DiagnosticsProvider;
1212
use Microsoft\PhpParser\FunctionLike;
13+
use Microsoft\PhpParser\ModifiedTypeInterface;
14+
use Microsoft\PhpParser\ModifiedTypeTrait;
1315
use Microsoft\PhpParser\Node;
1416
use Microsoft\PhpParser\Token;
1517
use Microsoft\PhpParser\TokenKind;
1618

17-
class MethodDeclaration extends Node implements FunctionLike {
18-
/** @var Token[] */
19-
public $modifiers;
20-
21-
use FunctionHeader, FunctionReturnType, FunctionBody;
19+
class MethodDeclaration extends Node implements FunctionLike, ModifiedTypeInterface {
20+
use FunctionHeader, FunctionReturnType, FunctionBody, ModifiedTypeTrait;
2221

2322
const CHILD_NAMES = [
2423
'modifiers',
@@ -41,23 +40,12 @@ class MethodDeclaration extends Node implements FunctionLike {
4140
'compoundStatementOrSemicolon'
4241
];
4342

44-
public function hasModifier(int $targetModifier) : bool {
45-
if ($this->modifiers === null) {
46-
return false;
47-
}
48-
foreach ($this->modifiers as $modifier) {
49-
if ($modifier->kind === $targetModifier) {
50-
return true;
51-
}
52-
}
53-
return false;
54-
}
55-
56-
public function isStatic() : bool {
57-
return $this->hasModifier(TokenKind::StaticKeyword);
58-
}
59-
60-
public function getName() {
43+
/**
44+
* Returns the name of the method.
45+
*
46+
* @return string
47+
*/
48+
public function getName(): string {
6149
return $this->name->getText($this->getFileContents());
6250
}
6351

@@ -79,4 +67,64 @@ public function getDiagnosticForNode() {
7967
}
8068
return null;
8169
}
70+
71+
/**
72+
* Returns the signature parts as an array. Use $this::getSignatureFormatted for a user-friendly string version.
73+
*
74+
* @return array
75+
*/
76+
private function getSignatureParts(): array {
77+
$parts = [];
78+
79+
foreach ($this->getChildNodesAndTokens() as $i => $child) {
80+
if ($i === "compoundStatementOrSemicolon") {
81+
return $parts;
82+
}
83+
84+
$parts[] = $child instanceof Token
85+
? $child->getText($this->getFileContents())
86+
: $child->getText();
87+
};
88+
89+
return $parts;
90+
}
91+
92+
/**
93+
* Returns the signature of the method as a formatted string.
94+
*
95+
* @return string
96+
*/
97+
public function getSignatureFormatted(): string {
98+
$signature = implode(" ", $this->getSignatureParts());
99+
return $signature;
100+
}
101+
102+
/**
103+
* Returns the description part of the doc string.
104+
*
105+
* @return string
106+
*/
107+
public function getDescriptionFormatted(): string {
108+
$comment = trim($this->getLeadingCommentAndWhitespaceText(), "\r\n");
109+
$commentParts = explode("\n", $comment);
110+
111+
$description = [];
112+
113+
foreach ($commentParts as $i => $part) {
114+
$part = trim($part, "*\r\t /");
115+
116+
if (strlen($part) <= 0) {
117+
continue;
118+
}
119+
120+
if ($part[0] === "@") {
121+
break;
122+
}
123+
124+
$description[] = $part;
125+
}
126+
127+
$descriptionFormatted = implode(" ", $description);
128+
return $descriptionFormatted;
129+
}
82130
}

src/Node/MissingMemberDeclaration.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\ModifiedTypeInterface;
10+
use Microsoft\PhpParser\ModifiedTypeTrait;
911
use Microsoft\PhpParser\Node;
1012
use Microsoft\PhpParser\Token;
1113

12-
class MissingMemberDeclaration extends Node {
13-
14-
/** @var Token[] */
15-
public $modifiers;
14+
class MissingMemberDeclaration extends Node implements ModifiedTypeInterface {
15+
use ModifiedTypeTrait;
1616

1717
/** @var Token|null needed along with typeDeclaration for what looked like typed property declarations but was missing VariableName */
1818
public $questionToken;

src/Node/PropertyDeclaration.php

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\ModifiedTypeInterface;
10+
use Microsoft\PhpParser\ModifiedTypeTrait;
911
use Microsoft\PhpParser\Node;
1012
use Microsoft\PhpParser\Token;
11-
use Microsoft\PhpParser\TokenKind;
1213

13-
class PropertyDeclaration extends Node {
14-
15-
/** @var Token[] */
16-
public $modifiers;
14+
class PropertyDeclaration extends Node implements ModifiedTypeInterface {
15+
use ModifiedTypeTrait;
1716

1817
/** @var Token|null question token for PHP 7.4 type declaration */
1918
public $questionToken;
@@ -41,16 +40,4 @@ class PropertyDeclaration extends Node {
4140
'propertyElements',
4241
'semicolon'
4342
];
44-
45-
public function isStatic() : bool {
46-
if ($this->modifiers === null) {
47-
return false;
48-
}
49-
foreach ($this->modifiers as $modifier) {
50-
if ($modifier->kind === TokenKind::StaticKeyword) {
51-
return true;
52-
}
53-
}
54-
return false;
55-
}
5643
}

src/Node/TraitSelectOrAliasClause.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@
66

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\ModifiedTypeInterface;
10+
use Microsoft\PhpParser\ModifiedTypeTrait;
911
use Microsoft\PhpParser\Node;
1012
use Microsoft\PhpParser\Token;
1113

12-
class TraitSelectOrAliasClause extends Node {
14+
class TraitSelectOrAliasClause extends Node implements ModifiedTypeInterface {
15+
use ModifiedTypeTrait;
16+
1317
/** @var QualifiedName|Node\Expression\ScopedPropertyAccessExpression */
1418
public $name;
1519

1620
/** @var Token */
1721
public $asOrInsteadOfKeyword;
1822

19-
/** @var Token[] */
20-
public $modifiers;
21-
2223
/** @var QualifiedName|Node\Expression\ScopedPropertyAccessExpression */
2324
public $targetName;
2425

tools/PrintApiDocumentation.php

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@
55
*--------------------------------------------------------------------------------------------*/
66

77
use Microsoft\PhpParser\Node\MethodDeclaration;
8-
use Microsoft\PhpParser\Node\PropertyDeclaration;
98
use Microsoft\PhpParser\Node\Statement\ClassDeclaration;
109
use Microsoft\PhpParser\Parser;
11-
use Microsoft\PhpParser\Token;
12-
use Microsoft\PhpParser\TokenKind;
1310

1411
require_once __DIR__ . "/../src/bootstrap.php";
1512

@@ -32,41 +29,30 @@
3229

3330
foreach ($files as $file) {
3431
$ast = $parser->parseSourceFile(file_get_contents($file));
32+
3533
foreach ($ast->getDescendantNodes() as $descendant) {
3634
if ($descendant instanceof ClassDeclaration) {
3735
$className = $descendant->name->getText($descendant->getFileContents());
3836
echo "## " . $className . PHP_EOL;
3937

4038
// TODO consider not having a separate classMemberDeclarations node
4139
foreach ($descendant->classMembers->classMemberDeclarations as $member) {
40+
// TODO: Maybe ask a class directly for all its method declarations
4241
if ($member instanceof MethodDeclaration) {
43-
// TODO this should be a helper function on any modified types
44-
foreach ($member->modifiers as $modifier) {
45-
if ($modifier->kind === TokenKind::PublicKeyword) {
46-
$fileContents = $member->getFileContents();
47-
$signature = implode(" ", getSignatureParts($member));
48-
$comment = trim($member->getLeadingCommentAndWhitespaceText(), "\r\n");
42+
if (!$member->isPublic()) {
43+
continue;
44+
}
4945

50-
$commentParts = explode("\n", $comment);
51-
$description = [];
52-
foreach ($commentParts as $i=>$part) {
53-
$part = trim($part, "*\r\t /");
54-
if (isset($part[0])) {
55-
if ($part[0] === "@") {
56-
break;
57-
}
58-
$description[] = $part;
59-
}
60-
}
61-
$comment = implode(" ", $description);
62-
if (strlen(trim($comment, " \t")) === 0) {
63-
$comment = "> TODO: add doc comment\n";
64-
}
65-
echo "### " . $className . "::" . $member->name->getText($member->getFileContents()) . PHP_EOL;
66-
echo $comment . PHP_EOL;
67-
echo "```php\n$signature\n```" . PHP_EOL;
68-
}
46+
$signature = $member->getSignatureFormatted();
47+
48+
$description = $member->getDescriptionFormatted();
49+
if (strlen($description) <= 0) {
50+
$description = "> TODO: add doc comment\n";
6951
}
52+
53+
echo "### " . $className . "::" . $member->getName() . PHP_EOL;
54+
echo $description . PHP_EOL;
55+
echo "```php\n$signature\n```" . PHP_EOL;
7056
}
7157
}
7258
}
@@ -76,17 +62,3 @@
7662
echo "## Node types
7763
> TODO: complete documentation - in addition to the helper methods on the Node base class,
7864
every Node object has properties specific to the Node type. Browse `src/Node/` to explore these properties.";
79-
80-
function getSignatureParts(MethodDeclaration $methodDeclaration) : array {
81-
// TODO - something like this in API?
82-
$parts = [];
83-
foreach ($methodDeclaration->getChildNodesAndTokens() as $i=>$child) {
84-
if ($i === "compoundStatementOrSemicolon") {
85-
return $parts;
86-
}
87-
$parts[] = $child instanceof Token
88-
? $child->getText($methodDeclaration->getFileContents())
89-
: $child->getText();
90-
};
91-
return $parts;
92-
}

0 commit comments

Comments
 (0)