Refactoring modified type behaviors
This commit is contained in:
Родитель
b4f5f2c9c2
Коммит
6b07addab5
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
namespace Microsoft\PhpParser;
|
||||
|
||||
/**
|
||||
* Use the ModifiedTypeTrait for convenience in order to implement this interface.
|
||||
*/
|
||||
interface ModifiedTypeInterface {
|
||||
public function hasModifier(int $targetModifier): bool;
|
||||
public function isPublic(): bool;
|
||||
public function isStatic(): bool;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
namespace Microsoft\PhpParser;
|
||||
|
||||
trait ModifiedTypeTrait {
|
||||
/** @var Token[] */
|
||||
public $modifiers;
|
||||
|
||||
public function hasModifier(int $targetModifier): bool {
|
||||
if ($this->modifiers === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->modifiers as $modifier) {
|
||||
if ($modifier->kind === $targetModifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to check for the existence of the "public" modifier.
|
||||
* Does not necessarily need to be defined for that type.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPublic(): bool {
|
||||
return $this->hasModifier(TokenKind::PublicKeyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to check for the existence of the "static" modifier.
|
||||
* Does not necessarily need to be defined for that type.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isStatic(): bool {
|
||||
return $this->hasModifier(TokenKind::StaticKeyword);
|
||||
}
|
||||
}
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
namespace Microsoft\PhpParser\Node;
|
||||
|
||||
use Microsoft\PhpParser\ModifiedTypeInterface;
|
||||
use Microsoft\PhpParser\ModifiedTypeTrait;
|
||||
use Microsoft\PhpParser\Node;
|
||||
use Microsoft\PhpParser\Token;
|
||||
|
||||
class ClassConstDeclaration extends Node {
|
||||
|
||||
/** @var Token[] */
|
||||
public $modifiers;
|
||||
class ClassConstDeclaration extends Node implements ModifiedTypeInterface {
|
||||
use ModifiedTypeTrait;
|
||||
|
||||
/** @var Token */
|
||||
public $constKeyword;
|
||||
|
|
|
@ -10,15 +10,14 @@ use Microsoft\PhpParser\Diagnostic;
|
|||
use Microsoft\PhpParser\DiagnosticKind;
|
||||
use Microsoft\PhpParser\DiagnosticsProvider;
|
||||
use Microsoft\PhpParser\FunctionLike;
|
||||
use Microsoft\PhpParser\ModifiedTypeInterface;
|
||||
use Microsoft\PhpParser\ModifiedTypeTrait;
|
||||
use Microsoft\PhpParser\Node;
|
||||
use Microsoft\PhpParser\Token;
|
||||
use Microsoft\PhpParser\TokenKind;
|
||||
|
||||
class MethodDeclaration extends Node implements FunctionLike {
|
||||
/** @var Token[] */
|
||||
public $modifiers;
|
||||
|
||||
use FunctionHeader, FunctionReturnType, FunctionBody;
|
||||
class MethodDeclaration extends Node implements FunctionLike, ModifiedTypeInterface {
|
||||
use FunctionHeader, FunctionReturnType, FunctionBody, ModifiedTypeTrait;
|
||||
|
||||
const CHILD_NAMES = [
|
||||
'modifiers',
|
||||
|
@ -41,23 +40,12 @@ class MethodDeclaration extends Node implements FunctionLike {
|
|||
'compoundStatementOrSemicolon'
|
||||
];
|
||||
|
||||
public function hasModifier(int $targetModifier) : bool {
|
||||
if ($this->modifiers === null) {
|
||||
return false;
|
||||
}
|
||||
foreach ($this->modifiers as $modifier) {
|
||||
if ($modifier->kind === $targetModifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isStatic() : bool {
|
||||
return $this->hasModifier(TokenKind::StaticKeyword);
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
/**
|
||||
* Returns the name of the method.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->name->getText($this->getFileContents());
|
||||
}
|
||||
|
||||
|
@ -79,4 +67,64 @@ class MethodDeclaration extends Node implements FunctionLike {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature parts as an array. Use $this::getSignatureFormatted for a user-friendly string version.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getSignatureParts(): array {
|
||||
$parts = [];
|
||||
|
||||
foreach ($this->getChildNodesAndTokens() as $i => $child) {
|
||||
if ($i === "compoundStatementOrSemicolon") {
|
||||
return $parts;
|
||||
}
|
||||
|
||||
$parts[] = $child instanceof Token
|
||||
? $child->getText($this->getFileContents())
|
||||
: $child->getText();
|
||||
};
|
||||
|
||||
return $parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature of the method as a formatted string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSignatureFormatted(): string {
|
||||
$signature = implode(" ", $this->getSignatureParts());
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description part of the doc string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescriptionFormatted(): string {
|
||||
$comment = trim($this->getLeadingCommentAndWhitespaceText(), "\r\n");
|
||||
$commentParts = explode("\n", $comment);
|
||||
|
||||
$description = [];
|
||||
|
||||
foreach ($commentParts as $i => $part) {
|
||||
$part = trim($part, "*\r\t /");
|
||||
|
||||
if (strlen($part) <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($part[0] === "@") {
|
||||
break;
|
||||
}
|
||||
|
||||
$description[] = $part;
|
||||
}
|
||||
|
||||
$descriptionFormatted = implode(" ", $description);
|
||||
return $descriptionFormatted;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
namespace Microsoft\PhpParser\Node;
|
||||
|
||||
use Microsoft\PhpParser\ModifiedTypeInterface;
|
||||
use Microsoft\PhpParser\ModifiedTypeTrait;
|
||||
use Microsoft\PhpParser\Node;
|
||||
use Microsoft\PhpParser\Token;
|
||||
|
||||
class MissingMemberDeclaration extends Node {
|
||||
|
||||
/** @var Token[] */
|
||||
public $modifiers;
|
||||
class MissingMemberDeclaration extends Node implements ModifiedTypeInterface {
|
||||
use ModifiedTypeTrait;
|
||||
|
||||
/** @var Token|null needed along with typeDeclaration for what looked like typed property declarations but was missing VariableName */
|
||||
public $questionToken;
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
|
||||
namespace Microsoft\PhpParser\Node;
|
||||
|
||||
use Microsoft\PhpParser\ModifiedTypeInterface;
|
||||
use Microsoft\PhpParser\ModifiedTypeTrait;
|
||||
use Microsoft\PhpParser\Node;
|
||||
use Microsoft\PhpParser\Token;
|
||||
use Microsoft\PhpParser\TokenKind;
|
||||
|
||||
class PropertyDeclaration extends Node {
|
||||
|
||||
/** @var Token[] */
|
||||
public $modifiers;
|
||||
class PropertyDeclaration extends Node implements ModifiedTypeInterface {
|
||||
use ModifiedTypeTrait;
|
||||
|
||||
/** @var Token|null question token for PHP 7.4 type declaration */
|
||||
public $questionToken;
|
||||
|
@ -41,16 +40,4 @@ class PropertyDeclaration extends Node {
|
|||
'propertyElements',
|
||||
'semicolon'
|
||||
];
|
||||
|
||||
public function isStatic() : bool {
|
||||
if ($this->modifiers === null) {
|
||||
return false;
|
||||
}
|
||||
foreach ($this->modifiers as $modifier) {
|
||||
if ($modifier->kind === TokenKind::StaticKeyword) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,19 +6,20 @@
|
|||
|
||||
namespace Microsoft\PhpParser\Node;
|
||||
|
||||
use Microsoft\PhpParser\ModifiedTypeInterface;
|
||||
use Microsoft\PhpParser\ModifiedTypeTrait;
|
||||
use Microsoft\PhpParser\Node;
|
||||
use Microsoft\PhpParser\Token;
|
||||
|
||||
class TraitSelectOrAliasClause extends Node {
|
||||
class TraitSelectOrAliasClause extends Node implements ModifiedTypeInterface {
|
||||
use ModifiedTypeTrait;
|
||||
|
||||
/** @var QualifiedName|Node\Expression\ScopedPropertyAccessExpression */
|
||||
public $name;
|
||||
|
||||
/** @var Token */
|
||||
public $asOrInsteadOfKeyword;
|
||||
|
||||
/** @var Token[] */
|
||||
public $modifiers;
|
||||
|
||||
/** @var QualifiedName|Node\Expression\ScopedPropertyAccessExpression */
|
||||
public $targetName;
|
||||
|
||||
|
|
|
@ -5,11 +5,8 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
use Microsoft\PhpParser\Node\MethodDeclaration;
|
||||
use Microsoft\PhpParser\Node\PropertyDeclaration;
|
||||
use Microsoft\PhpParser\Node\Statement\ClassDeclaration;
|
||||
use Microsoft\PhpParser\Parser;
|
||||
use Microsoft\PhpParser\Token;
|
||||
use Microsoft\PhpParser\TokenKind;
|
||||
|
||||
require_once __DIR__ . "/../src/bootstrap.php";
|
||||
|
||||
|
@ -32,6 +29,7 @@ echo "> Note: This documentation was auto-generated using this parser to help do
|
|||
|
||||
foreach ($files as $file) {
|
||||
$ast = $parser->parseSourceFile(file_get_contents($file));
|
||||
|
||||
foreach ($ast->getDescendantNodes() as $descendant) {
|
||||
if ($descendant instanceof ClassDeclaration) {
|
||||
$className = $descendant->name->getText($descendant->getFileContents());
|
||||
|
@ -39,34 +37,22 @@ foreach ($files as $file) {
|
|||
|
||||
// TODO consider not having a separate classMemberDeclarations node
|
||||
foreach ($descendant->classMembers->classMemberDeclarations as $member) {
|
||||
// TODO: Maybe ask a class directly for all its method declarations
|
||||
if ($member instanceof MethodDeclaration) {
|
||||
// TODO this should be a helper function on any modified types
|
||||
foreach ($member->modifiers as $modifier) {
|
||||
if ($modifier->kind === TokenKind::PublicKeyword) {
|
||||
$fileContents = $member->getFileContents();
|
||||
$signature = implode(" ", getSignatureParts($member));
|
||||
$comment = trim($member->getLeadingCommentAndWhitespaceText(), "\r\n");
|
||||
|
||||
$commentParts = explode("\n", $comment);
|
||||
$description = [];
|
||||
foreach ($commentParts as $i=>$part) {
|
||||
$part = trim($part, "*\r\t /");
|
||||
if (isset($part[0])) {
|
||||
if ($part[0] === "@") {
|
||||
break;
|
||||
}
|
||||
$description[] = $part;
|
||||
}
|
||||
}
|
||||
$comment = implode(" ", $description);
|
||||
if (strlen(trim($comment, " \t")) === 0) {
|
||||
$comment = "> TODO: add doc comment\n";
|
||||
}
|
||||
echo "### " . $className . "::" . $member->name->getText($member->getFileContents()) . PHP_EOL;
|
||||
echo $comment . PHP_EOL;
|
||||
echo "```php\n$signature\n```" . PHP_EOL;
|
||||
}
|
||||
if (!$member->isPublic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$signature = $member->getSignatureFormatted();
|
||||
|
||||
$description = $member->getDescriptionFormatted();
|
||||
if (strlen($description) <= 0) {
|
||||
$description = "> TODO: add doc comment\n";
|
||||
}
|
||||
|
||||
echo "### " . $className . "::" . $member->getName() . PHP_EOL;
|
||||
echo $description . PHP_EOL;
|
||||
echo "```php\n$signature\n```" . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,17 +62,3 @@ foreach ($files as $file) {
|
|||
echo "## Node types
|
||||
> TODO: complete documentation - in addition to the helper methods on the Node base class,
|
||||
every Node object has properties specific to the Node type. Browse `src/Node/` to explore these properties.";
|
||||
|
||||
function getSignatureParts(MethodDeclaration $methodDeclaration) : array {
|
||||
// TODO - something like this in API?
|
||||
$parts = [];
|
||||
foreach ($methodDeclaration->getChildNodesAndTokens() as $i=>$child) {
|
||||
if ($i === "compoundStatementOrSemicolon") {
|
||||
return $parts;
|
||||
}
|
||||
$parts[] = $child instanceof Token
|
||||
? $child->getText($methodDeclaration->getFileContents())
|
||||
: $child->getText();
|
||||
};
|
||||
return $parts;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче